{{ message }}
Repository navigation
fix: keep injected package names stable in suffixed environments - #2072
Merged
Merged
Conversation
for more information, see https://pre-commit.ci
reinstall re-injected packages without --with-suffix, so it dropped their suffixed apps and, being forced, took over unsuffixed apps of the same name from other environments. Pass the suffix like install-all does. Key injected records by their own package name so metadata files where earlier pipx versions saved a suffixed key heal on read, and compare the canonical form of suffixed names in uninject so suffixes such as _x match.
This was referenced Oct 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

In a venv installed with
--suffix, an injected package is renamed each time its record is rewritten. Afterpipx install pycowsay --suffix @1andpipx inject pycowsay@1 black --with-suffix, onepipx upgrade --include-injected pycowsay@1turns the keyblackintoblack@1(a second run givesblack@1@1). Thenpipx uninject pycowsay@1 blackreports "black is not in the pycowsay@1 venv",pipx pinadds a secondblack@1entry, andpipx reinstall pycowsay@1fails withInvalid requirement: 'black @ 1'.PipxMetadata.from_dictrebuilt theinjected_packageskeys asf"{name}{suffix}", while the writer (Venv.update_package_metadata) anddocs/reference/metadata.rstkey them by package name, withsuffixas a separate field. Every read-modify-write therefore appended the suffix again. This keeps the bare name as the key, stopsrun_post_install_actionsfrom rebinding the key to the display name, and letsuninjectacceptpkg@1as before by matching the record's own suffix.Visible change:
pipx list --include-injectednow showsblackinstead ofblack@1under a suffixed venv. Metadata already corrupted on disk is not repaired.Test:
pytest tests/test_upgrade.py -k suffix_keepsfails on main (uninjectexits 1 after the upgrade) and passes here. A broader run of upgrade, pin, uninject, inject, list, reinstall, install and related modules passed, excepttest_install_fetch_missing_python_invalid[3.1-fetch-python-missing], which fails the same way on main.ruff check/format --checkandtyare clean on the changed files;pre-commit run --all-fileswas not run.pre-commit run --all-files)changelog.d/folder (choose a type:feature,bugfix,doc,removal, ormisc)