Skip to content

fix(modern-python): suggest exact uv run python so shim advice works outside projects#196

Open
Ninja3047 wants to merge 3 commits into
mainfrom
fix/python-shim-exact-python-suggestion
Open

fix(modern-python): suggest exact uv run python so shim advice works outside projects#196
Ninja3047 wants to merge 3 commits into
mainfrom
fix/python-shim-exact-python-suggestion

Conversation

@Ninja3047

@Ninja3047 Ninja3047 commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Bug

As reported in #195: the python/python3 shim's suggested command can be a dead end. The shim echoes back whichever name was invoked (uv run $cmd ...), and for python3 that advice fails on any machine with no uv-managed interpreters (fresh CI runners, devcontainers, stock Ubuntu/Debian): outside a project, uv resolves the python3 command through an ordinary PATH lookup, which hits the shim again and errors with the same suggestion — an infinite advice loop for the agent.

Reproduced on a stock ghcr.io/astral-sh/uv:debian container (apt python3, zero managed Pythons, no env overrides, no project):

$ uv run python3 script.py
ERROR: Use `uv run python3 script.py` instead of `python3 script.py`

Fix

uv special-cases the exact command name python (target.eq_ignore_ascii_case("python")RunCommand::Python in crates/uv/src/commands/project/run.rs, present since at least uv 0.4.0): uv run python ... executes uv's resolved interpreter directly with no PATH lookup, so it can never resolve back to the shim.

The shim now always suggests the exact-python spelling — uv run python ... / uv run python -m ... — regardless of whether python or python3 was intercepted (the "instead of" half still quotes what was actually run). Verified on the same stock Debian container and on macOS that the suggested form succeeds for script, -c, -m module, and REPL invocations, inside and outside projects.

This is an alternative to the passthrough approach in #195: the shim stays a pure print-and-exit blocker (no UV env detection, PATH walking, or exec-loop guards), keeps working when UV leaks in from ancestors like uv run claude or Agent SDK apps launched via uv run, and lowers the uv floor from 0.6.0 to 0.4.0. Known non-goal: nested tooling under uv run that hardcodes python3 (e.g. a Makefile) still gets blocked with advice it can't follow mechanically — acceptable for an agent-facing nudge, and #195's passthrough remains a possible follow-up if that case matters.

Also updates the README/setup-shims.sh rationale (the old "uv run prepends its venv bin/" claim only holds inside a project or with managed interpreters installed).

Tests

  • python-shim.bats: two new tests assert the suggestion uses exact uv run python (never python3) when invoked via the python3 symlink, for both script and -m forms; the existing symlink test now checks the "instead of" side. All 10 pass (bats 1.12), full shims suite 35/35 green.
  • shellcheck -x (0.11.0) and shfmt -i 2 -ci (3.13.1) clean.
  • check_claude_loadability.py / check_codex_loadability.py pass.
  • Version bumped 1.5.2 → 1.5.3 in plugin.json and root marketplace.json.

🤖 Generated with Claude Code

… 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 <[email protected]>
@Ninja3047 Ninja3047 requested a review from dguido as a code owner July 6, 2026 22:03

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.

Tip: disable this comment in your organization's Code Review settings.

Ninja3047 and others added 2 commits July 6, 2026 18:05
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 <[email protected]>
…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 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant