-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DistInfoDistribution._compute_dependencies fails if the package has extras_require that are PEP440 versions. #4356
Comments
I looked a bit more into this, and I'm understanding a bit more of what's going on. I hope this will help find a good fix: This call:
tries to gather all requirements for which there is either no marker, or for which the marker, when setting As an example, given the following requirements:
Now, as I pointed out in my initial comment, the issue happens with the 4th requirements. So, it looks like the issue is from either:
While this seems outside of the hand of Thanks to whoever will take the time to read all this and reply :) . |
Hmm passing in |
Allright, thanks for your input! |
Small update: This still occurs with pip 10 (commit 8f4f15a). About that, I submitted a PR in pypa/packaging to deal with this a while ago, but my tests brought up some legitimate questions, putting a pause on the change. Should I take another approach and fix this from |
Is this still awaiting a fix, or did a change to |
Waiting on a fix. |
Pushing this down the road to the next release since I don't think this'd happen in time for 18.0. |
Pushing this down the road since I don't think this'd happen in time for 18.1. |
Reproduced this with the current version of pip as well:
|
Why not just do the same #11112 (passing empty string extra instead of None) in pip/src/pip/_vendor/pkg_resources/__init__.py Lines 3035 to 3040 in a8ba0ee
--- common = frozenset(reqs_for_extra(None))
+++ common = frozenset(reqs_for_extra('')) This change also needs new packaging release for pkg_resources because of this pypa/packaging#545. I tried to write some tests but it fails without this pr # pkg_resources/tests/test_resources.py
def test_marker_evaluation_with_extras2(self):
"""Extras are also evaluated as markers at resolution time."""
ad = pkg_resources.Environment([])
ws = WorkingSet([])
Foo = Distribution.from_filename(
"/foo_dir/Foo-1.2.dist-info",
metadata=Metadata(("METADATA", "Provides-Extra: 3.2.1\n"
"Requires-Dist: quux; extra=='3.2.1'"))
)
ad.add(Foo)
assert list(ws.resolve(parse_requirements("Foo"), ad)) == [Foo]
quux = Distribution.from_filename("/foo_dir/quux-1.0.dist-info")
ad.add(quux)
res = list(ws.resolve(parse_requirements("Foo[3.2.1]"), ad))
assert res == [Foo, quux] |
It was fixed, I can't reproduce with 23.1.2 |
Closing, then. |
Description:
I have a package which provides extras. The extras keys happen to have the format of PEP440 versions, such as
3.2.1
or3.0
.When installing the package using
pip install
, I end up with an exception (see in the "What I've run" section).Note: While this occured using
pip
, I'm not exactly sure who is beign faulty (pip, setuptools, pkg_resources, packaging?)What I've run:
Here's the setup.py to make a package that reproduces the issue:
Then, make a wheel:
Then, install the package (not even using the extra):
And the result:
What I figured out
I went around the code in the stack trace and managed to figure what's happening:
The
TypeError
comes from trying to parseNone
as apackaging.Version
object.The
None
comes fromDistInfoDistribution._compute_dependencies
, with this call:common = frozenset(reqs_for_extra(None))
.Later, during the markers evaluation in
packaging.markers
, at line 185, we have this function:As
rhs
is the extra key, a PEP440 version (3.2.1
), theSpecifier
creation succeeds, and we callreturn spec.contains(lhs)
. In this case,lhs
is theNone
I pointed out earlier, which cause theTypeError
when trying to parse it as a version.Note that if
rhs
was not a version-like string (such asfoobar
orsecurity
), theSpecifier
creation would fail, (I think) and we would executeoper = _operators.get(op.serialize())
andreturn oper(lhs, rhs)
instead.How to fix
I'm not sure. I feel like the logic in
_eval_op
is not precise enough, or maybe the marker evaluation is not meant to be used this way. I'm not familiar enough with pip/pkg_ressources/packaging structure and interaction to tell what's going to happen if I change any of this.I'd need the input of someone with a lot more knowledge about the project to help sort this out.
I tried making this as clear as possible, but don't hesitate to ask for details.
The text was updated successfully, but these errors were encountered: