-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Description
Description
According to pip install --help, the --upgrade flag with --target is documented as:
"Use --upgrade to replace existing packages in <dir> with new versions."
However, in practice, when using pip install --target <dir> --upgrade, existing package versions are not removed. Instead, the new version is added alongside the old one, resulting in multiple .dist-info directories for the same package.
This behavior leads to ambiguous and incorrect results when tools rely on importlib.metadata, which expects a single installed distribution per package.
Why This Matters
-
pip install --targetis commonly used by:- language tooling
- plugin systems
- build tools
- embedded runtimes
-
Multiple .dist-info directories for the same package:
- break importlib.metadata
- cause version resolution bugs
- force downstream tools to implement manual cleanup logic
This makes --target installs unsafe for repeated upgrades unless users manually delete old package metadata.
Expected behavior
When using:
pip install <package> --upgrade --target <dir>
pip should remove:
- older .dist-info directories
- legacy .egg-info directories (if present)
- associated package files (where applicable)
so that only one version of the package remains in the target directory, matching the behavior of standard (non---target) installs.
Expected directory contents::
typing_extensions.py
typing_extensions-4.12.2.dist-info/
pip version
25.3
Python version
python 3.13
OS
Windows
How to Reproduce
Steps to Reproduce
# Create a clean target directory
mkdir -p /tmp/pip-target-test
# Install an older version
pip install typing-extensions==4.8.0 --target /tmp/pip-target-test
# Install a newer version using --upgrade
pip install typing-extensions==4.12.2 --upgrade --target /tmp/pip-target-test
Output
Directory contents after both installs
$ ls /tmp/pip-target-test
typing_extensions.py
typing_extensions-4.8.0.dist-info
typing_extensions-4.12.2.dist-info
Code of Conduct
- I agree to follow the PSF Code of Conduct.