-
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
Improve how dependency resolver order packages to resolve to avoid trying versions not related to an actual conflict #9455
Comments
Thanks for the detailed report! The issue here is logically similar to what is described here (read the discussion started from the linked comment; messages prior are about the “resolver is slow” issue in a broader sense). Quoting myself from the discussion:
As I mentioned in the same issue, there are various strategies being experiemented on to improve the logic, and this is definitely a valuable example to observe. If only I can find more energy to actually come up with an implementatio… |
Thanks for the speedy response @uranusjr ! 🙇 I'm sorry I ended up creating a duplicate, I swear I searched all the resolver issues before posting this, but I didn't notice it was related to that one. 😅 🤦 Feel free to close this one if it doesn't add anything useful and/or you prefer to track it on the other one. |
It’s perfectly fine! That thread grew way too long for anyone not following the issue tracker intimately to reasonably read. It’s also unfortunate the discussion is buried so low in the thread. I’ll use this one to track the resolution priority logic improvement specifically. |
Edit from maintainer: this issue is also tracking the subthread started in #9187 (comment) that focuses on
get_preference()
improvements.Description
I had conflicting dependencies between a private package
package2
and its dependencypackage1
.When installing
package2
withpip
, it seems it detects the conflict betweenpackage2
and its dependencypackage1
, because it starts the backtracking process.But then it downloads several versions of other sub-dependencies, instead of erroring out right after noticing the actual unresolvable dependency conflict.
What I expected
I expected it to error out right away after finding the unresolvable conflict between the two
fastapi
versions. Instead of continuing and trying with many versions of sub-dependencies.Example
Here's a minimal, self-contained, reproducible example:
Inside some project directory, create a venv, e.g.:
$ python3.7 -m venv .env3.7
Activate the venv:
$ source ./.env3.7/bin/activate
Upgrade
pip
:Install
wheel
:Then, create a first package
package1
, by creating a file:with:
Then create another package
package2
, that depends onpackage1
, creating a file:with:
The current file tree looks like this:
Now, go to
./package1/
and build the wheel for that package (so that it can be used while installingpackage2
):Now go to
./package2/
and try to install it withpip
, pointing to the dependencypackage1
wheel directory:The final error output is perfect, it shows the conflict between
fastapi
versions.🚨 What is not right, is that it first downloads several versions of
pydantic
, despite already having enough information to know it won't be able to solve thefastapi
conflict.After fixing the
fastapi
conflict, it no longer tries to download many versions of Pydantic. But I would think it wouldn't be necessary to download many versions of one dependency to realize a conflict in another one.Making it worse
I would think the above are the minimum steps to reproduce the problem. Although in the case above it's not that terrible, as it will take some seconds/minutes to download all the Pydantic versions and then error out the conflict in
fastapi
.But it gets worse when there are other dependencies. Even non-conflicting dependencies. Because the resolver will download many versions of those dependencies and their sub-dependencies before showing the conflict.
And by downloading many unnecessary versions of many dependencies, it can take a really long time.
And in some cases, even error out something else, completely unrelated to the actual conflict, after not being able to build a very old version of some sub-dependency (this specific point behaves differently in
pip
installed frommaster
, more on that in the end).To see it in the example above, modify the file:
To include:
So it would now be:
And then try again to install it:
pip install -f ../package1/dist/ .
In this very simple example, in my computer that already has all those packages in cache (so not even counting download time), it takes 1m49s.
And the error is not related to the actual dependency conflict, but actually about not being able to build an old version of some dependency down the dependency tree:
Output
Here's the very long output if you want to check it:
Additional information
I also tried upgrading
setuptools
, but then I got another unrelated error from one of the sub-dependencies that was trying to import a deprecated module/object from it. So I removed that part to avoid more confusion.These are the packages I have in my environment:
I also tried installing pip from
master
with:$ python -m pip install -U "pip @ https://github.com/pypa/pip/archive/master.zip"
And then after that, it still downloads all those versions, shows the same error as above, and continues downloading. So, the final error is not as strange, but it takes even longer (it's still running after more than 10m).
The text was updated successfully, but these errors were encountered: