-
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
Idea: Discard candidates that do not match a requirement's extras #11913
Comments
Thinking on it a bit more is the current behavior introduces some "if logic" in to the requirements that you would lose from my proposal. For example let's say you specified I guess I don't understand if this is intended and/or desirable. |
Ignoring missing extras during the resolution process is intentional, and intended for backwards compatibility with the behaviour we had in the legacy resolver. Do you have an example set of requirements that demonstrate the problematic behaviour here? I think having clearer management of extras and their direct dependency could be useful (eg: enforcing a visit of the
Since we order a requirement/candidate for visiting prior to getting the dependency metadata, I don't think this is possible.
This would be a significant breaking change and it's not clear what the value of this would be. |
If we treat a package with extra as a logical dependant of the real package (i.e. how the resolver constructs this internally), specifying a non-existent extra would correspond to specifying a non-existent project as dependency. Discarding a candidate without the matching extras is the natural thing to do following the same logic. The current behaviour is so because the legacy resolver does not actually treats a package with extras as a dependant, but performs some convoluted merging logic with unclear original intention that’s probably forever lost in the memory lane. I guess what I’m trying to say is I think the proposal is a logically sound thing to do. The problem is however compatibility. We do have means to do such things ( |
In agreement with everything that @uranusjr says, and that the trickiest piece for end users is when a transitive dependency declares a dependency on a non-existent extra. Since they won’t have direct control over stuff, they can’t dictate how things should behave. |
So while I do have some examples that display this behavior the more motivating idea came from the recent addition of extras to Pandas requirements: https://pandas.pydata.org/docs/dev/whatsnew/v2.0.0.html#installing-optional-dependencies-with-pip-extras If someone two years from now adds
They're going to be surprised when none of the excel functions work even though "pip installed the requirements fine", or worse pip is going to go wild backtracking unnecessarily. As has been stated this particular solution is probably not the way, but I do think it is a real concern as extras are increasingly used. |
#11961 is a real life example of this issue happening. As you can see Pip finds a solution to these requirements e.g. this command works on Pip 23.0.1 but with multiple warnings:
But this command fails because Pip has found a solution by discarding the extra component which the user never intended as optional:
Perhaps if changing the current behavior is not acceptable then a new syntax could be introduced where a user can explicitly state an extra is non-optional? p.s. this specific example is fixed by the backtracking improvements in Pip 23.1+ |
Closing this on Pip side for now. I still strongly think that Pip should at least implement an option, but I suspect another configuration option that affects resolution will add a support burden greater than Pip is capable of. If users have a great need for this option then rip provides a configuration option for this. I am often testing rip with lots of tricky resolution situations, and hope this year it will be mature enough to reccomend to users who need a feature it offers that Pip doesn't. |
What's the problem this feature will solve?
Currently when a requirement has an extra but a candidate contains no such extra a warning is printed: https://github.com/pypa/pip/blob/23.0.1/src/pip/_internal/resolution/resolvelib/candidates.py#L498
This scenario could happen either because:
Both of these situations are likely not desirable, for example if an extra is chosen but backtracking goes back to the point where that extra doesn't exist likely this is not a desired version of the package.
In general by having these extras be optional there is an ambiguity in the requirements meaning a user can't be sure whether they are getting
foo[bar]
or justfoo
.Describe the solution you'd like
Discard candidates that do not include the extra, reducing the size of the space needed to search to find a solution when backtracking.
Alternative Solutions
Additional context
This warning came up in many cases where I purposefully tried to create obtuse requirements that would take a long time to resolve as part of testing #11908.
Also this would be slightly backwards incompatible in terms of resolution, I suspect if accepted it would need to be introduced behind a feature flag.
Code of Conduct
The text was updated successfully, but these errors were encountered: