pipx upgrade reports "already at latest version" for local-path installs without checking an index
Summary
When a package was installed from a local path, pipx upgrade reports "already at latest version X" even though it never consulted an index. The wording asserts something pipx did not check, so an install can sit many releases behind while the command reassures you it is current.
Reproduce
$ pipx install ./mypkg-0.14.0-py3-none-any.whl # local file, not an index
$ # …0.15.1 is published to PyPI in the meantime…
$ pipx upgrade mypkg
mypkg is already at latest version 0.14.0 (location: /Users/me/.local/pipx/venvs/mypkg)pipx_metadata.json shows why:
{"main_package": {"package": "mypkg",
"package_or_url": "/private/tmp/mypkg-0.14.0-py3-none-any.whl"}}upgrade re-resolves package_or_url, finds the same unchanged file, and concludes "latest".
Expected
Re-resolving a pinned local path is reasonable. Calling the result "already at latest version" is not, because no index was queried. Something like:
mypkg was installed from a local path (/private/tmp/mypkg-0.14.0-py3-none-any.whl)
and is pinned to it; upgrade cannot check an index. Reinstall from the package name
to track releases: pipx install --force mypkgEven just "no newer version at the installed source" would avoid asserting a fact that was never checked.
Impact
This is silent. The version is real, the exit code is 0, and the message says current — so there is nothing to notice. In our case a CLI stayed on 0.14.0 across two releases; the local wheel had been installed once for testing and never revisited.
Secondary: the documented workaround fails
The natural fix is rejected when the uv backend is in use:
$ pipx install --force mypkg
Installing to existing venv 'mypkg'
error: Failed to create virtual environment
Caused by: A virtual environment already exists at: .
hint: Use the `--clear` flag or set `UV_VENV_CLEAR=1` to replace the existing virtual environment
⚠️ Not removing existing venv … because it was not created in this sessionpipx uninstall mypkg && pipx install mypkg works. If --force is meant to cover this, it looks like the uv path needs --clear.
Environment
- macOS, pipx with the uv backend
- Both behaviours reproduced against a real local-wheel install
Source: pypa/pipx