Files
William Tan 3b316e6ac7 fix(modern-python): suggest exact uv run python so shim advice works outside projects (#196)
* fix(modern-python): suggest exact `uv run python` so the advice works outside projects

The python/python3 shim suggested `uv run $cmd ...`, echoing back whichever
name was invoked. For `python3` that advice is self-defeating on machines
with no uv-managed interpreters: uv resolves the `python3` command through
an ordinary PATH lookup, which hits the shim again and fails with the same
suggestion. uv special-cases the exact command name `python` (uv >= 0.4.0)
and executes its resolved interpreter directly, so always suggesting
`uv run python ...` works everywhere.

Reproduced on stock Debian + uv 0.11.27 (apt python3, zero managed
pythons, no project): `uv run python3 script.py` fails via the shim while
`uv run python script.py` succeeds, across script/-c/-m/REPL forms.

Reported in #195.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(modern-python): satisfy shellcheck SC2016 in new bats assertions

Escaped backticks in double quotes instead of literal backticks in
single quotes, which shellcheck flags as a possible unintended
non-expansion.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(modern-python): requote shim suggestions and carry all arguments through

Review findings on #196: the -m branch interpolated only the module name,
so `python -m http.server 8000` suggested a command missing the port, and
`${*}` flattened arguments without quoting, so `python -c 'print(1+1)'`
suggested a command that is a bash syntax error if run verbatim (plus a
trailing space inside the backticks for bare invocations). Both branches
now build the suggestion from %q-requoted arguments, with regression tests
for each case.

Also consolidates the exact-`python` rationale into a single canonical
copy in the shim's header comment; README, setup-shims.sh, and the bats
file now point there instead of paraphrasing it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-29 15:16:05 -04:00

46 lines
1.3 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
# PATH shim for python/python3 — intercepts bare invocations and
# suggests the uv equivalent. Works for both names via $0.
cmd="$(basename "$0")"
# Canonical rationale for the suggestion's shape (the README,
# setup-shims.sh, and python-shim.bats point here):
#
# Suggestions always use the exact name `python`, never `python3`: uv
# special-cases the `python` command (uv >= 0.4.0) and executes its resolved
# interpreter directly instead of a PATH lookup, so the suggested command
# works even outside a project, where `uv run python3` would resolve back
# to this shim.
#
# Arguments are requoted with %q so the suggestion stays runnable when they
# contain spaces or shell metacharacters (e.g. -c 'print(1+1)').
args=""
if (($#)); then
args="$(printf ' %q' "$@")"
fi
case "${1:-}" in
-m)
case "${2:-}" in
pip)
echo "ERROR: \`$cmd -m pip\` is not supported. Use:" >&2
echo " uv add <package> # add a dependency" >&2
echo " uv remove <package> # remove a dependency" >&2
;;
*)
if (($# < 2)); then
args=" -m <module>"
fi
echo "ERROR: Use \`uv run python$args\` instead of \`$cmd$args\`" >&2
;;
esac
;;
*)
echo "ERROR: Use \`uv run python$args\` instead of \`$cmd$args\`" >&2
;;
esac
exit 1