Fail installation on conflicting package metadata
See original GitHub issueWhat’s the problem this feature will solve?
Currently pip outputs a warning if package metadata does not align with the package name indicated in a direct URL or #egg=
fragment.
Examples:
$ echo "from setuptools import setup; setup(name='hello')" > setup.py
$ pip install "file://$PWD#egg=world"
Processing /tmp/user/1000/tmp.lNdCZnnvx5
WARNING: Generating metadata for package world produced metadata for project name hello. Fix your #egg=world fragments.
Installing collected packages: hello
Running setup.py install for hello ... done
Successfully installed hello-0.0.0
$ pip install "world @ file://$PWD"
Processing /tmp/user/1000/tmp.lNdCZnnvx5
WARNING: Generating metadata for package world produced metadata for project name hello. Fix your #egg=world fragments.
Installing collected packages: hello
Found existing installation: hello 0.0.0
Uninstalling hello-0.0.0:
Successfully uninstalled hello-0.0.0
Running setup.py install for hello ... done
Successfully installed hello-0.0.0
The warning is traced from here.
Describe the solution you’d like
I would like this to be a hard failure, and I think we should apply the same policy across-the-board with respect to metadata. If information acquired at one stage in package processing (whether provided by the user or derived some other way) doesn’t match the metadata determined at a later stage for the same package, then the whole installation process should fail.
The kinds of metadata I had in mind specifically were:
- Name (from direct URL,
#egg=
fragment, or simple API) - Version (from
#egg=
fragment or simple API) - Python/platform compatibility (from wheel tags in filename or
data-requires-python
in simple API)
Taking this approach would ensure that the dependency resolution in #988 isn’t made more complicated or delayed due to backwards-compatibility concerns.
Alternative Solutions
If we can’t fully trust the metadata other than from the package itself, then either:
- We must support back-tracking to before the assumption about the package data was used - so wasting time downloading such packages and potentially complicating dependency resolution logic, or
- We must not trust any metadata except what the package itself outputs (via
setup.py egg_info
,prepare_metadata_for_build_wheel
, or*.dist-info/METADATA
in a wheel) - very time-consuming as we have to download all packages, or - We say it’s undefined behavior and continue tracing a warning - bad UX since the warning can be easily missed compared to a failure
Additional context
- #988, which prompted this issue
Issue Analytics
- State:
- Created 4 years ago
- Comments:12 (11 by maintainers)
Top GitHub Comments
The
#egg=
part (or its modern equivalent, PEP 508foo @ url
syntax) is a “hint” for the resolver so it knows the URL is used to satisfyfoo
(there are other historical meanings that are not relevant anymore). It is not needed for top-level requirements in the new resolver because the new resolver is smart enough to download the package and inspect the name automatically. In stead of removing it altogether, you can also just change the#egg=
value to match the actual package name.With #9264, the only thing undone (and undecided) here is whether we should reject a package if its
data-requires-python
andRequires-Python:
do not match. I’m leaning toward let’s not bother, since the Python requirement is only an installation check, and the mismatch is not consequential.