-
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
Duplicate distributions with distinct extras #3198
Conversation
20944d5
to
88af44d
Compare
existing_req.extras = tuple( | ||
set(existing_req.extras).union( | ||
set(install_req.extras))) | ||
return [existing_req] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like if you pip install foo[bar]==1.1 foo[baz]==1.2
you will end up, silently, with foo[bar,baz]==1.1 ?
This does not seem right to me, you should be comparing install_req.req.specifier
with existing_req.req.specifier
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems as though this code should be located elsewhere.
If the requirement has not been switched from a constraint to a req, the req on the command line is silently dropped.
" and not existing_req.constraint" is killing this code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree it needs to apply whether constraint or not. A new test case is needed to demonstrate this.
@xavfernandez yes, it will give you the union of extras without cross-checking all the version details - that is however consistent with all the other handling we do of conflicting specifiers. I think its better than ignoring the extras entirely as we do today, and is a stepping stone to the full resolver scenario.
I think a worthwhile thing to do would be an expected failure test showing that this should error (as should many other conflicting specifier cases) and we can make sure we cater for this when the resolver branch matures.
I think this also needs the tests from #3105 |
Reviewed 3 of 3 files at r1. tests/data/packages/LocalExtras/setup.py, line 27 [r1] (raw file): Comments from the review on Reviewable.io |
88af44d
to
1cc36bf
Compare
Reviewed 5 of 5 files at r2. pip/req/req_set.py, line 241 [r1] (raw file): pip/req/req_set.py, line 251 [r2] (raw file): pip/req/req_set.py, line 281 [r2] (raw file): tests/functional/test_install_reqs.py, line 356 [r2] (raw file): findstyle in (location, name) 2 x 2 x 4 x 4 x 4 combinations. Some can be trimmed - (e.g. we only need one case where all three places extras can turn up with them set to the same value), so the extras-style really is more like (none, unique-to-position, same-as-another position). A bit of though should get a sane set of nested loops to express this, or perhaps you can use py.tests's built in scenarios support (I'm not sure if its up to this or not - but if a loop can express it it probably can. I'm not too worried about editable here, since editable doesn't change process handling, its location vs index lookups that can do that because of the late binding of metadata. This suggestion may be overkill of course; it all feeds through add_requirement, so lets look at it from that angle: the more conditionals it has, we need to feed into each one. The first conditional is
Thats clearly going to drop stuff on pip install . .[foo] Then we've got the bit already reviewed you added, and Sachi's, respectively, adding extras to a non-extra existing dep and adding extras to a constraint existing dep. I think thats sufficient, and since I know you have tests that cover both those cases, I'm happy to ignore the unnamed case since thats already broken in myriad ways; we can overhaul it separately. I don't see the expected failure that @xavfernandez asked we add though: given package p with where adding in extras makes the install unsatisfiable, have an error occur. e.g.conflictingextras depends on simple==1.0, but conflictextras[bad] depends on simple==2.0 pip install conflictingextras conflictextras[bad] Comments from the review on Reviewable.io |
1cc36bf
to
3dca30d
Compare
Review status: 3 of 6 files reviewed at latest revision, 6 unresolved discussions. tests/functional/test_install_reqs.py, line 431 [r3] (raw file): Comments from the review on Reviewable.io |
Compare extras when checking if a requirement has already been specified, and take a union of the extras before installation. Co-Authored-By: Sachi King <[email protected]> Closes pypa#3046, pypa#3189
3dca30d
to
dc8e7f0
Compare
@rbtcollins: it depends whether With top-level requirement (directly provided by the user or from a requirement file) pip always honors them or crashes in case of double-requirement.
|
@xavfernandez pip is inconsistent on that today - consider "pip install . ." I think this is a sufficiently useful thing that the risk is worth taking. Without it you cannot have e.g. test dependencies in an extra and then install_require on foo, and also have e.g. in dev-requirements.txt foo[testsupport]. The resolver is just around the corner where we'll stop giving duplicate requirement errors altogether... |
@rbtcollins point taken ☺ |
I think perhaps a comment, rather than the message changing? |
So, looks good to me. Reviewed 2 of 3 files at r3, 1 of 1 files at r4. Comments from the review on Reviewable.io |
Duplicate distributions with distinct extras
Any duplicate distributions will currently raise an error, even if
their extras are different: for example, 'pip install bar bar[foo]'.
Detect this situation, and union the extras together.
Closes #3189