Skip to content

fix(pipx): declare python as a backend dependency#9678

Merged
jdx merged 1 commit intomainfrom
fix/pipx-python-dependency
May 7, 2026
Merged

fix(pipx): declare python as a backend dependency#9678
jdx merged 1 commit intomainfrom
fix/pipx-python-dependency

Conversation

@jdx
Copy link
Copy Markdown
Owner

@jdx jdx commented May 7, 2026

Summary

Fixes backend/test_pipx_deep_dependencies_slow failing on release PRs (e.g. #9620 → run https://github.com/jdx/mise/actions/runs/25473978595).

#9571 removed registry-level depends = ["python"] from registry/pipx.toml and moved it to test.tools (which only feeds mise test-tool, not real installs). That broke pipx_cmd's dependency_toolset PATH prepend: pipx.pyz uses #!/usr/bin/env python3, and without mise's python in front of $HOME/bin the kernel resolves whatever python3 it finds first. In the failing test, that's the test's deliberate fail stub:

CALL TO SYSTEM python3! args: /tmp/.../mise/installs/pipx/1.5.0/pipx install mkdocs==1.6.0
mise ERROR pipx failed

The fix moves the dependency into PIPXBackend::get_dependencies itself, matching how cargo declares "rust", npm declares "node", gem declares "ruby", dotnet declares "dotnet", go declares "go", and spm declares "swift". pipx was the only language-package backend that wasn't declaring its runtime — it had been getting it transitively through the registry, which is now gone.

Audit of other backends

I checked every backend that uses dependency_toolset/dependency_which to spawn subprocesses:

Backend Runtime declared OK?
pipx python (this PR) fixed
cargo rust yes
npm node yes
gem ruby yes
dotnet dotnet yes
go go yes
spm swift yes
aqua/github/http/etc. n/a (just download/extract) yes
vfox reads PLUGIN.depends from plugin metadata yes

So pipx was the only at-risk site.

Test plan

  • mise run test:e2e backend/test_pipx_deep_dependencies_slow passes locally
  • Other pipx tests still pass: test_pipx_extras, test_pipx_direct_dependencies, test_pipx_custom_registry, test_pipx_uvx, test_pipx_venv_symlink, test_pipx_postinstall_hook
  • mise run lint clean

🤖 Generated with Claude Code


Note

Low Risk
Low risk: small dependency-list change limited to the pipx backend, mainly affecting install/runtime PATH resolution.

Overview
Ensures the pipx backend explicitly depends on python (in addition to pipx) so pipx.pyz’s #!/usr/bin/env python3 resolves to mise-managed Python via dependency_toolset rather than an arbitrary system python3 on PATH.

Reviewed by Cursor Bugbot for commit 0ce5045. Bugbot is set up for automated code reviews on this repo. Configure here.

#9571 removed the registry-level `depends = ["python"]` from pipx.toml,
which broke `pipx_cmd`'s dependency_toolset PATH prepend: pipx.pyz uses
`#!/usr/bin/env python3`, so without mise's python ahead of `$HOME/bin`,
the kernel resolves whatever python3 is on PATH first.

Move the dependency into the pipx backend itself, matching how cargo
declares "rust", npm declares "node", gem declares "ruby", etc.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request updates the PIPXBackend in src/backend/pipx.rs to include "python" as a mandatory dependency. This change ensures that pipx.pyz uses the correct python version by allowing the dependency toolset to prioritize it on the PATH. I have no feedback to provide as no review comments were submitted.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 7, 2026

Greptile Summary

This PR fixes a regression introduced in #9571, which removed the depends = ["python"] registry-level declaration from registry/pipx.toml without adding an equivalent in the backend code, breaking pipx_cmd's dependency_toolset PATH prepend.

  • Adds "python" to PIPXBackend::get_dependencies(), ensuring mise's Python is prepended to $PATH before pipx is invoked, so pipx.pyz's #!/usr/bin/env python3 shebang resolves the correct interpreter.
  • Aligns pipx with the established pattern used by cargo, npm, gem, dotnet, go, and spm backends, all of which explicitly declare their runtime language in get_dependencies().

Confidence Score: 4/5

Safe to merge; the change is a one-line targeted fix to a real regression with a clear root cause and well-tested analogs elsewhere in the codebase.

The fix is minimal, correct, and directly mirrors a pattern used by six other backends. The only wrinkle is that python is now always a hard dependency even on the uvx code path where uv manages its own interpreter, which could cause an unintended Python installation for users who exclusively use uvx. This is worth a follow-up consideration but does not affect correctness of the bug fix itself.

No files require special attention beyond the single-line change in src/backend/pipx.rs.

Comments Outside Diff (1)

  1. src/backend/pipx.rs, line 57-59 (link)

    P2 Python pulled in even when uvx is active

    When use_uvx is true, pipx_cmd is never called, so pipx.pyz's #!/usr/bin/env python3 shebang is never invoked. uvx_cmd delegates to uv, which manages its own Python environment internally. Despite this, get_dependencies now unconditionally lists "python", meaning a user who sets MISE_PIPX_UVX=true (or has uv available so the uvx path is always taken) will still cause mise to auto-install Python as a hard dependency. uv is rightly listed under get_optional_dependencies since it's optional — a similar argument could be made for python when uvx is in use. This is a behavioural change worth being aware of, even if the simpler uniform policy is intentional.

    Fix in Claude Code

Fix All in Claude Code

Reviews (1): Last reviewed commit: "fix(pipx): declare python as a backend d..." | Re-trigger Greptile

@jdx jdx merged commit 0aaecab into main May 7, 2026
35 of 36 checks passed
@jdx jdx deleted the fix/pipx-python-dependency branch May 7, 2026 11:46
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 7, 2026

Hyperfine Performance

mise x -- echo

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.5.1 x -- echo 20.3 ± 1.1 18.3 26.1 1.00
mise x -- echo 20.4 ± 1.2 18.4 34.3 1.01 ± 0.08

mise env

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.5.1 env 23.0 ± 5.0 17.3 35.5 1.11 ± 0.31
mise env 20.7 ± 3.5 17.6 35.7 1.00
✅ Performance improvement for env is 11%

mise hook-env

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.5.1 hook-env 20.9 ± 1.3 18.4 28.0 1.00 ± 0.08
mise hook-env 20.9 ± 1.1 18.6 26.4 1.00

mise ls

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.5.1 ls 18.3 ± 1.3 16.2 24.4 1.00 ± 0.09
mise ls 18.3 ± 1.2 16.5 26.8 1.00

xtasks/test/perf

Command mise-2026.5.1 mise Variance
install (cached) 141ms 140ms +0%
ls (cached) 67ms 66ms +1%
bin-paths (cached) 71ms 72ms -1%
task-ls (cached) 549ms 553ms +0%

mise-en-dev added a commit that referenced this pull request May 7, 2026
### 🚀 Features

- **(aqua)** support registry libc variants by @jdx in
[#9652](#9652)
- **(bin-paths)** add executable names output by @risu729 in
[#9617](#9617)

### 🐛 Bug Fixes

- **(aqua)** preserve configured file extensions by @risu729 in
[#9611](#9611)
- **(aqua)** support registry file links by @risu729 in
[#9610](#9610)
- **(backend)** reject bare package backend names by @risu729 in
[#9608](#9608)
- **(backend)** apply inline tool option overrides by @risu729 in
[#9306](#9306)
- **(backend)** skip versions host for local tool opts by @risu729 in
[#9568](#9568)
- **(github)** chmod explicit archive bin by @risu729 in
[#9609](#9609)
- **(install)** skip remote-versions refresh in prefer-offline mode by
@jdx in [#9627](#9627)
- **(lock)** scope targets to active project root by @risu729 in
[#9319](#9319)
- **(lockfile)** respect existing platforms during auto-lock by @jdx in
[#9621](#9621)
- **(pipx)** filter yanked pypi releases by @risu729 in
[#9607](#9607)
- **(pipx)** declare python as a backend dependency by @jdx in
[#9678](#9678)
- **(schema)** update refs to $defs in mise-registry-tool.json by
@risu729 in [#9671](#9671)
- **(task)** terminate parallel siblings on failure via process groups
by @jdx in [#9655](#9655)
- **(task)** stable MISE_PROJECT_ROOT for monorepo tasks, add
MISE_MONOREPO_ROOT by @jdx in
[#9657](#9657)
- **(trust)** run enter hooks after trusting config by @risu729 in
[#9634](#9634)
- **(ui)** stop clearing screen for prompts by @jdx in
[#9619](#9619)
- use /bin/cp on macos by @pdehlke in
[#9656](#9656)

### 🚜 Refactor

- **(aqua)** store aqua var defaults as strings by @risu729 in
[#9645](#9645)
- **(config)** support structured TOML values in registry backend
options by @risu729 in [#9584](#9584)
- **(deps)** remove serde_derive dependency by @risu729 in
[#9670](#9670)
- **(deps)** remove anyhow dependency by @risu729 in
[#9661](#9661)
- **(deps)** use std::sync::LazyLock instead of once_cell::Lazy by
@risu729 in [#9668](#9668)
- **(schema)** generate task schema from mise schema by @risu729 in
[#9581](#9581)
- **(schema)** reuse task props with unevaluatedProperties by @risu729
in [#9582](#9582)
- **(schema)** reuse registry common types by @risu729 in
[#9648](#9648)
- **(schema)** reuse plugin script config by @risu729 in
[#9647](#9647)
- **(schema)** use $defs in schema files by @risu729 in
[#9646](#9646)

### 📚 Documentation

- **(node)** add tips for enabling node idiomatic by @fu050409 in
[#9675](#9675)

### 🧪 Testing

- **(cli)** remove nondeterministic tool depends assertion by @risu729
in [#9633](#9633)
- **(e2e)** pin uv to 0.11.8 around astral-sh/uv#19278 by @jdx in
[#9618](#9618)
- **(e2e)** wait for docker env cleanup by @risu729 in
[#9631](#9631)
- **(zig)** use official zig instead of mach mirror by @jdx in
[#9659](#9659)

### 📦️ Dependency Updates

- fall through to hash check when providers have no outputs by @jdx in
[#9622](#9622)
- bump Cargo.lock by @jdx in
[#9625](#9625)

### 📦 Registry

- remove registry depends by @risu729 in
[#9571](#9571)
- add code-review-graph (pipx:code-review-graph) by @chautruonglong in
[#9673](#9673)

### Chore

- **(ci)** split large registry test-tool changes by @risu729 in
[#9628](#9628)
- **(ci)** make perf script robust to runner noise by @jdx in
[#9635](#9635)
- **(ci)** skip hyperfine comments without permission by @risu729 in
[#9629](#9629)

### New Contributors

- @chautruonglong made their first contribution in
[#9673](#9673)
- @pdehlke made their first contribution in
[#9656](#9656)

## 📦 Aqua Registry Updates

### New Packages (5)

-
[`anthropics/anthropic-cli`](https://github.com/anthropics/anthropic-cli)
- [`crates.io/wasmi_cli`](https://github.com/wasmi-labs/wasmi)
- [`openclaw/gogcli`](https://github.com/openclaw/gogcli)
- `racket-lang.org/racket-minimal`
- [`runs-on/cli`](https://github.com/runs-on/cli)

### Updated Packages (13)

- [`UpCloudLtd/upcloud-cli`](https://github.com/UpCloudLtd/upcloud-cli)
- [`aristocratos/btop`](https://github.com/aristocratos/btop)
- [`dprint/dprint`](https://github.com/dprint/dprint)
- [`j178/prek`](https://github.com/j178/prek)
- [`jdx/hk`](https://github.com/jdx/hk)
- [`jdx/mise`](https://github.com/jdx/mise)
- [`jdx/usage`](https://github.com/jdx/usage)
- [`jreleaser/jreleaser`](https://github.com/jreleaser/jreleaser)
-
[`jreleaser/jreleaser/standalone`](https://github.com/jreleaser/jreleaser)
- [`pnpm/pnpm`](https://github.com/pnpm/pnpm)
- [`suzuki-shunsuke/cmdx`](https://github.com/suzuki-shunsuke/cmdx)
- [`suzuki-shunsuke/ghir`](https://github.com/suzuki-shunsuke/ghir)
- [`twpayne/chezmoi`](https://github.com/twpayne/chezmoi)
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