-
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
Add --no-backtracking option for new resolver #9258
Conversation
7f5dd8e
to
1f203ce
Compare
1f203ce
to
38d8eb0
Compare
Adds a new option `--no-backtracking` to the new resolver. Off by default (no change to default behaviour), enabling this option prevents us from running the backtracking behaviour when pinning fails and instead skip directly to the error reporting. This can be especially useful in a CI situation, where the developer is interested in knowing about conflicts up front in order to manually solve them, or is worried about allowing for a potentially large amount of time spent in backtracking.
38d8eb0
to
3a6efb3
Compare
Personally I think “only try the best version available” is a valid strategy, but this particular implementation should not be accepted for two reasons. First, the Second, the patch is suboptimal. Again, the user intention is for the resolver to not try older versions, but this implementation directly introduces a branch in the core of the algorithm, without trying to explore ways to express the idea as a general case. I believe the idea of “try only one version” can be expressed and implemented by merly changing the input of the algorithm, without changing the algorithm itself. |
@uranusjr thank you for the insight -- appreciate the prompt response! Apologies, I was not aware that I'm not sure Similarly, I think the branch in the core of the algorithm was the best way to make this change in the upstream algorithm -- I'll add a more specific comment on the other PR for us to chat through there, but I was not attempting to tell the resolver to "only attempt the best option" (though I could see the idea of As an example, the issue which original brought me here was my company's CI systems taking >3 hours and eventually timing out when our Renovatebot attempted to build with the new
|
It’s not so much about having multiple resolvers as it is evolving/iterating on the resolution proceeds and making optimisations to it. |
With a "--limit-bactracking 1" option it may be easier to catch quickly what is the new wheel or wheel version that derails your CI process. Some people pay for the CI , so they may prefer an early fail, the planet also. The constraint.txt file is less practical |
I was thinking about the same (although to get what you expect the number of backtracking should be 0 instead of 1?), but "number of backtracking" is even more tightly coupled with the resolver algorithm than "only allow the newest version". |
But |
I took 1 in my example as mainly it's the new version of a wheel that causes pain, so a backtracking of 1 allows me to slip and should handle well the problem till I look to logs 1 or 2 days later Then when awake or available, I can do a pass with 0 backtracking to make it fail, if the log is not obvious enough . It's just a suggestion, I didn't look in resolver code, so it can be a bad or impractical idea |
I actually think limiting backtracking is a good idea, and would be very useful for debugging conflicts. But it is too internal to be exposed as a pip option. Maybe we can make it an (undocumented) environment variable instead, and “brand” it as a mechanism for debugging when you need it, and not a stable thing for people to depend on in the build chain etc.? |
In my case it would be perfect to have a non-documented or non-stable option, time for the ecosystem to mature/adapt and the resolver to do 3 cycles of refinement. And maybe this intellectual idea won't work. |
I could definitely get behind the idea of an option like this in the short term, as that would help get me and my team unblocked on the current round of "takes too long to resolve" errors. Would something along the lines of That said, I think there could be some real value in determining how to do this in a more stable and documented way; I suspect that no matter how good this or any future resolvers get there will always be cases where users would benefit from being able to force early exiting (eg. short dev loop, avoid costly CI, porting over old libraries with lots of preexisting libraries, maybe an occasional e2e test, ...) and some cases where they'll want the full resolver to run (eg. especially in dev mode to help them added dependencies correctly!) Maybe this is something worth making explicit in the |
Something in between. The environment variable can be defined in pip, and resolvelib can take it as an int argument |
Hello! I am an automated bot and I have noticed that this pull request is not currently able to be merged. If you are able to either merge the |
fwiw, what is the latest pip version without this backtracking stuff? I need to get rid of this major PITA now .. |
This comment has been minimized.
This comment has been minimized.
@oberstet https://pyfound.blogspot.com/2019/12/moss-czi-support-pip.html and https://pyfound.blogspot.com/2020/03/new-pip-resolver-to-roll-out-this-year.html Please be mindful of what you're saying about work other people have done. |
Closing since this hasn't been updated in a while and has significant merge conflicts. Feel free to open an updated PR! :) Thanks @TheKevJames for the PR! |
@pradyunsg sorry for the tone, I am just "upset" because of the huge pain this incurred on my side. in my world, there are zero upsides (we've been fine with pip), but a huge amount of work resulting from the fallout of this. and I am still on it. anyways, I am pinning our OSS projects to pip v19.3.1 now. current pip is going into some endless loop .. |
Thanks, I understand that and I do empathise. Please take a look at #9187 (comment), and if possible, provide us with a reproducer for the issue there so that we can investigate why the resolver is doing what it's doing. |
I think this is what happens fwiw, since I don't have time currently to minimize and extract that into a reproducing simple case. the complete pinned deps however are (can't freeze, since it now uses our upstream forks in deps): https://gist.github.com/oberstet/8c1e9b992f4c6fbbf5b96c649322a6c5
now, with the old pip, we just get some warnings. nevertheless, it works. because the version range limits in the libs down in the DAG are too limiting, and so they still technically work. or, that is: the version that happens to be installed works nevertheless. thus: historically, we've been fighting installation order for those 130 deps, and introduced some manually selected lib version down the DAG in the upper app requirements. to pin the "right" version. this was also a pain. now, pip resolver can't find a formal solution .. I guess ... because there is none .. and will just work and work, consume CPU, and never continue actually installing deps. all of that is a big mess. in my desperation, I now even forked upstream packages, to relax the version limits there. and finally: I want to simply get rid of a bunch of our deps .. it is too hard to manage. also, I came to the conclusion that version range limits are particular bad in community libraries that are widely used upstream, and hence have a high probability of running into the confluent DAG issue. which is one reason why our own libraries have "open ended" limits .. we only specify a lower version bound in the deps of our libraries. |
IMHO backtracking should be opt-in not opt-out. I love the idea that pip won't let me install packages that conflict with existing packages. But I cannot use it right now because it can't even resolve that. I'm left with opting out. IMHO, pip should validate that a package can be installed, but not provide any default implementation that undermines installing one package (which is my situation). Re flag naming: I overall agree with the sentiment of not coupling user-exposed flags to internal implementation details. I would say that my experience with this feature is that I do need to understand the internal implementation to understand why a resolution strategy is taking SO MUCH LONGER and look for a workaround (without much information to go on #9215). It's actually not the algorithm that takes this extra time, but the data dependencies. A few suggestions for how to name a flag.
|
Could you provide some backing evidence for this proposal? From my understanding, no mainstream package managers do this. |
I've just encountered this. The error and the cyclical dependency was my fault - but the hang meant I spent a chunk of time going down the wrong avenues to figure out what went wrong (I'm not a newbie, but I'm far from experienced when it comes to the python ecosystem). Running with the latest stable
My
The issue is that Great tool, btw, and I've done lots of work with DAG's, so I know how painful they can be sometimes! |
Adds a new option
--no-backtracking
to the new resolver. Off bydefault (no change to default behaviour), enabling this option prevents
us from running the backtracking behaviour when pinning fails and
instead skip directly to the error reporting.
This can be especially useful in a CI situation, where the developer is
interested in knowing about conflicts up front in order to manually
solve them, or is worried about allowing for a potentially large amount
of time spent in backtracking.
My goal here is mostly to help with the various issues such as #9254,
#9215, and #9187 -- being able to enable this flag is very useful for helping
in reducing backtracking (as per the recommendations in the guide).
Options 2, 3, and 4 of that guide mostly amount to "determine which
packages have conflicts and update your constraints/requirements files to
avoid those issues". By being able to "fail fast", we allow users who are
interested in using any of those options to take advantage of the awesome
ResolutionImpossible
debug output without having to wait for what couldpotentially be hours worth of attempts from the resolver (see linked issues).
Still TODO:
resolvelib
(Allow resolution to skip backtracking sarugaku/resolvelib#66)-- that'll need to get merged and released as
resolvelib==0.5.4
(orgreater), then re-vendored.