Skip to content

fix(backend): honor install_before for pipx installs#9105

Closed
risu729 wants to merge 4 commits intojdx:mainfrom
risu729:copilot/install-before-pipx
Closed

fix(backend): honor install_before for pipx installs#9105
risu729 wants to merge 4 commits intojdx:mainfrom
risu729:copilot/install-before-pipx

Conversation

@risu729
Copy link
Copy Markdown
Contributor

@risu729 risu729 commented Apr 15, 2026

See renovatebot/renovate#41654

Summary

  • forward install_before to transitive Python package resolution when pipx: tools are installed through uv
  • pass uv's --exclude-newer <timestamp> flag on the uv install path only
  • leave the pipx fallback path unchanged
  • update docs for the uv-only transitive release-age behavior
  • add focused unit coverage for uv --exclude-newer argument generation

uv compatibility

--exclude-newer was added in astral-sh/uv#2166 and is included in https://github.com/astral-sh/uv/releases/tag/0.1.15 (released in Mar 2024), so we do not need to check the uv version before using this flag.

Tests

  • cargo fmt --check
  • git diff --check
  • cargo test -q uv_exclude_newer_args

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.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 adds support for transitive installation date constraints in the pipx and uvx backends by setting the PIP_EXCLUDE_NEWER and UV_EXCLUDE_NEWER environment variables. It introduces a PipxInstaller enum and helper methods to apply these constraints based on a provided timestamp. Unit tests have been added to verify the environment variable generation. I have no feedback to provide.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 15, 2026

Greptile Summary

This PR adds support for install_before cutoff in the pipx backend when installing through uv, by passing --exclude-newer <timestamp> to uv tool install. The uv path now propagates the cutoff to transitive dependency resolution; the pipx fallback path is intentionally unchanged. Documentation is updated in three places and a targeted unit test is added.

Confidence Score: 5/5

Safe to merge — the change is minimal, well-tested, and matches uv's documented CLI interface.

The implementation correctly uses uv tool install --exclude-newer, confirmed by uv's CLI reference. The jiff::Timestamp::to_string() format (RFC 3339 with Z suffix) matches exactly what uv expects. The pipx fallback path is intentionally unchanged and documented. Unit tests cover both the Some and None cases. No P0 or P1 findings.

No files require special attention.

Important Files Changed

Filename Overview
src/backend/pipx.rs Adds uv_exclude_newer_args helper and injects --exclude-newer into the uv tool install command; unit tests verify both the presence and absence of the flag.
docs/dev-tools/backends/pipx.md Adds accurate prose documenting the uv-only --exclude-newer behavior and its absence from the pipx fallback path.
docs/dev-tools/mise-lock.md Updates the lockfile docs to mention pipx (uv path) alongside npm as backends that forward the install_before cutoff to transitive resolution.
docs/tips-and-tricks.md Extends the install_before tip to reference both the npm and pipx backend docs.
settings.toml Adds a note to the install_before setting description listing npm and pipx (uv path) as transitive-cutoff-aware backends.

Sequence Diagram

sequenceDiagram
    participant mise
    participant InstallContext
    participant PIPXBackend
    participant uv as uv tool install
    participant pipx as pipx install

    mise->>InstallContext: before_date (Option<Timestamp>)
    InstallContext->>PIPXBackend: install_version_(ctx, tv)

    alt uv is installed (use_uvx = true)
        PIPXBackend->>PIPXBackend: uvx_cmd("tool", "install", pipx_request)
        PIPXBackend->>PIPXBackend: uv_exclude_newer_args(ctx.before_date)
        note over PIPXBackend: Some(ts) → ["--exclude-newer", ts.to_string()]<br/>None → []
        PIPXBackend->>uv: uv tool install pkg --exclude-newer timestamp
        uv-->>PIPXBackend: installed (transitive deps filtered by date)
    else pipx fallback (use_uvx = false)
        PIPXBackend->>pipx: pipx install pkg
        pipx-->>PIPXBackend: installed (no date cutoff on transitive deps)
    end
Loading

Reviews (4): Last reviewed commit: "Merge branch 'main' into copilot/install..." | Re-trigger Greptile

Comment thread src/backend/pipx.rs Outdated
@risu729 risu729 marked this pull request as ready for review April 17, 2026 08:20
Copy link
Copy Markdown
Contributor Author

risu729 commented Apr 17, 2026

Closing in favor of #9190, which includes the uv --exclude-newer behavior from this PR and adds the pipx fallback behavior in the same small diff.

This comment was generated by an AI coding assistant.

@risu729 risu729 closed this Apr 17, 2026
@risu729 risu729 deleted the copilot/install-before-pipx branch April 17, 2026 10:28
jdx pushed a commit that referenced this pull request Apr 17, 2026
Supersedes and includes #9105.

## Summary
- forward `install_before` to transitive Python package resolution when
`pipx:` tools are installed through uv
- pass uv's `--exclude-newer <timestamp>` flag on the uv install path
- pass pip's `--uploaded-prior-to <timestamp>` flag through `pipx
install --pip-args` on the pipx fallback path
- remove any inherited `PIPX_SHARED_LIBS` before invoking pipx so pipx
falls back to `PIPX_HOME/shared`
- update docs now that both uv and pipx install paths forward the cutoff
- add focused unit coverage for uv and pipx argument generation

## uv compatibility
`--exclude-newer` was added in astral-sh/uv#2166
and is included in https://github.com/astral-sh/uv/releases/tag/0.1.15,
so we do not need to check the uv version before using this flag.

## Why we can always use `--uploaded-prior-to`
`--uploaded-prior-to` was added in
pypa/pip#13625 and released in pip 26.0,
announced on January 31, 2026:
https://discuss.python.org/t/announcement-pip-26-0-release/105947. PyPI
currently lists pip 26.0.1 as the latest release as of April 17, 2026:
https://pypi.org/project/pip/.

pipx does not use a fixed bundled pip. It creates or reuses a shared
virtual environment containing pip and ensures that shared pip is
updated to the latest version:
https://pipx.pypa.io/stable/how-pipx-works/. In the current pipx source,
shared pip is installed/upgraded with `pip >= 23.1` and no upper bound,
so normal PyPI access gets the latest pip:
https://github.com/pypa/pipx/blob/main/src/pipx/shared_libs.py.

mise sets `PIPX_HOME` to the tool version's install path when invoking
the pipx fallback. That install path is prepared before the backend
runs: fresh installs create a new install directory, and `mise install
--force` uninstalls the existing version, removes the install path, and
recreates it before calling `pipx install`. With pipx's default
behavior, `PIPX_SHARED_LIBS` resolves to `<install_path>/shared`, which
is new for that install and can be initialized/upgraded by pipx to the
latest pip.

## Why unsetting `PIPX_SHARED_LIBS` is acceptable
`PIPX_SHARED_LIBS` is a real pipx override: it can point pipx's shared
pip virtualenv outside `PIPX_HOME`. pipx documents that it defaults to
`PIPX_HOME/shared`, but can be overridden:
https://pipx.pypa.io/stable/reference/environment-variables/. It can be
useful for deliberate CI caching or ephemeral `PIPX_HOME` setups, but it
only shares the packaging toolchain, especially pip. It does not make
installed pipx apps share their application dependencies.

For mise-managed `pipx:` installs, inheriting an external
`PIPX_SHARED_LIBS` is unsafe for this feature because it can point at an
older shared pip that does not support `--uploaded-prior-to`. It also
makes the mise install path no longer self-contained, because pipx app
venvs can contain absolute `.pth` pointers into that external shared
libs path. Moving, deleting, or changing that external path can break
later `pipx upgrade`, `pipx inject`, or `pipx runpip` operations.

I could not find public discussions indicating that users commonly rely
on `PIPX_SHARED_LIBS` for mise-managed pipx installs, and the default
pipx guidance is to leave it unset unless there is a specific reason. So
excluding this inherited variable for mise's pipx subprocesses should
not be breaking for most users, and it avoids a footgun where a global
shell/profile setting silently changes mise's install behavior.

Related pipx docs for shared pip maintenance:
-
https://pipx.pypa.io/stable/reference/examples/#pipx-upgrade-shared-examples
- https://pipx.pypa.io/stable/reference/cli/#pipx-upgrade-shared

## Tests
- `cargo fmt --check`
- `git diff --check`
- `cargo test -q uv_exclude_newer_args`
- `cargo test -q pip_uploaded_prior_to_args`

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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