From f18552a90bf307c8cadb630776aaf64e9179c4d2 Mon Sep 17 00:00:00 2001 From: Stefano Bennati Date: Fri, 23 Dec 2022 17:30:45 +0100 Subject: [PATCH] fix infinite loop for resolvable conflicts. The dependency resolution might enter in an infinite loop if there are dependency conflicts, even though they can be resolved. The issue arises because a package causing the dependency conflict is not removed from the list of unsatisfied names, even if the resolution is successful, causing it's dependencies to be processed over and over. This change can be tested with the following requirements: ``` boto3==1.10.16 s3fs seaborn ``` Signed-off-by: Stefano Bennati --- src/resolvelib/resolvers.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/resolvelib/resolvers.py b/src/resolvelib/resolvers.py index 49e30c7..71d0e57 100644 --- a/src/resolvelib/resolvers.py +++ b/src/resolvelib/resolvers.py @@ -412,6 +412,13 @@ def resolve(self, requirements, max_rounds): # Dead ends everywhere. Give up. if not success: raise ResolutionImpossible(self.state.backtrack_causes) + else: + criterion = self.state.criteria[name] + # Put newly-pinned candidate at the end. This is essential because + # backtracking looks at this mapping to get the last pin. + for candidate in criterion.candidates: + self.state.mapping.pop(name, None) + self.state.mapping[name] = candidate else: # discard as information sources any invalidated names # (unsatisfied names that were previously satisfied)