Skip to content
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

Rework resolution ordering to consider "depth" #10032

Merged
merged 1 commit into from Jun 23, 2021

Conversation

uranusjr
Copy link
Member

End goal is to resolve #9455.

This modifies Provider.get_preference() to try to calculate a package’s “depth” in the dependency graph, and resolve packages closer to the root first. This works pretty well for #9455.

I also tweaked the preference logic a little to prioritise “shallow” dependencies over those with non-pinning operators. This means that previously foo>2 would be preferred over bar even if the latter is user-specified, but now bar is resolved first. This is from a few examples I tried that had the same priority logic issue (the one in #9455, apache-airflow[all], and #9187 (comment)); in a reasonably maintained and mature project, almost all dependencies would have some kind of version constraints, but those generally are so wide they are really not meaningfully better than bare requirements, so I de-prioritised that part.

I’m not quite sure how we can know if this is indeed a better implementation in the big picture, however. We probably should roll this out with a feature flag (i.e. keep the current implement behind --use-deprecated), but even with that we can’t be sure about tradeoffs if some people report negative impact, because those being impacted positively won’t report anything 😟

@uranusjr uranusjr added C: dependency resolution About choosing which dependencies to install C: new resolver labels May 31, 2021
@uranusjr uranusjr force-pushed the new-resolver-order-projects-by-depth branch 3 times, most recently from f9844f2 to eb548fc Compare May 31, 2021 20:58
news/9455.feature.rst Outdated Show resolved Hide resolved
@BrownTruck

This comment has been minimized.

@BrownTruck BrownTruck added the needs rebase or merge PR has conflicts with current master label Jun 16, 2021
@uranusjr uranusjr force-pushed the new-resolver-order-projects-by-depth branch from eb548fc to d0f7a23 Compare June 16, 2021 07:23
@pypa-bot pypa-bot removed the needs rebase or merge PR has conflicts with current master label Jun 16, 2021
@uranusjr uranusjr added this to the 21.2 milestone Jun 16, 2021
@uranusjr uranusjr force-pushed the new-resolver-order-projects-by-depth branch from d0f7a23 to dae7ad7 Compare June 16, 2021 07:56
@pradyunsg
Copy link
Member

It seems to me that an easy win here is to have a boolean for "is this user requested", for making sure we get to user requested requirements first.

Changing the strategy between BFS vs DFS is... well, I'm torn. It's not going to solve the underlying problem but only shift the cases where the problem occurs. On the other hand, we don't have evidence either way for which set of "situation this happens in" is less common, and implementing + trying this out is the only way to know.

I think what we really need is some way to determine "what candidates are implicated in this conflict" and then trigger some sort of back jumping/tree pruning in the resolver logic. That's something that'll need to happen in resolvelib side though, and annoyingly difficult. :)

All this isn't to say "don't do this". Rather, that this is annoyingly difficult and using --use-feature to roll this out is basically required here IMO.

@pradyunsg
Copy link
Member

It seems to me that an easy win here is to have a boolean for "is this user requested", for making sure we get to user requested requirements first.

Maybe we already do this?

@uranusjr
Copy link
Member Author

uranusjr commented Jun 16, 2021

It seems to me that an easy win here is to have a boolean for "is this user requested", for making sure we get to user requested requirements first.

Maybe we already do this?

Yes, we already do this.

Changing the strategy between BFS vs DFS

The current strategy is not DFS. It resolves user-requested requirements first (i.e. BFS only for the first layer), but treats everything else the same. This brings some interesting attributes. Take the following setup as an example:

. -- setup.py
  `- requirements.txt

where setup.py has

with open("requirements.txt") as f:
    install_requires = f.read().split()

setup(name="my-project", version="1", install_requires=install_requires)

Currently pip install -r ./requirements.txt and pip install . would resolve dependencies in different orders (and potentially producing different results), because packages are all top-level dependencies when listed in requirements.txt , but not when they are dependencies of my-project, so the user-requested optimisation doesn’t apply to the latter usage.

This PR is basically introducing a generalisation to the user-requested dependency optimisation. Rather than treating the user-requested (top-level) dependencies specially, all dependencies are assigned a depth (distance to the top-level dependencies), and are resolved in that order. User-requested dependencies are the shallowest (depth 1) and therefore resolved first (like they are right now), and dependencies of them have depth 2 and resolved next, and so on.

@uranusjr uranusjr force-pushed the new-resolver-order-projects-by-depth branch from dae7ad7 to 9cf2e60 Compare June 16, 2021 10:17
@uranusjr uranusjr force-pushed the new-resolver-order-projects-by-depth branch from 9cf2e60 to f5f9135 Compare June 16, 2021 21:28
@uranusjr uranusjr marked this pull request as ready for review June 23, 2021 20:51
@pradyunsg pradyunsg merged commit 4561b1f into pypa:main Jun 23, 2021
@uranusjr uranusjr deleted the new-resolver-order-projects-by-depth branch June 27, 2021 16:51
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 28, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
C: dependency resolution About choosing which dependencies to install
Projects
None yet
5 participants