From 16d6333ce659d049b864eb38c9741afcde46e5de Mon Sep 17 00:00:00 2001 From: Damian Date: Thu, 16 Sep 2021 13:18:04 -0400 Subject: [PATCH 1/9] Store failure cause and provide to _get_preference --- src/resolvelib/resolvers.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/resolvelib/resolvers.py b/src/resolvelib/resolvers.py index 4248442..f085c77 100644 --- a/src/resolvelib/resolvers.py +++ b/src/resolvelib/resolvers.py @@ -113,6 +113,7 @@ def __init__(self, provider, reporter): self._p = provider self._r = reporter self._states = [] + self._failure_casues = [] @property def state(self): @@ -185,6 +186,7 @@ def _get_preference(self, name): self.state.criteria, operator.attrgetter("information"), ), + failure_causes=self._failure_causes ) def _is_current_pin_satisfying(self, name, criterion): @@ -369,11 +371,12 @@ def resolve(self, requirements, max_rounds): # Backtrack if pinning fails. The backtrack process puts us in # an unpinned state, so we can work on it in the next round. success = self._backtrack() + self._failure_causes = [i for c in failure_causes for i in c.information] # Dead ends everywhere. Give up. if not success: causes = [i for c in failure_causes for i in c.information] - raise ResolutionImpossible(causes) + raise ResolutionImpossible(self._failure_causes) else: # Pinning was successful. Push a new state to do another pin. self._push_new_state() From dd951e9a68c32dc9dc77e91dcf896d7efdf76a41 Mon Sep 17 00:00:00 2001 From: Damian Date: Thu, 16 Sep 2021 16:45:50 -0400 Subject: [PATCH 2/9] Fix typo --- src/resolvelib/resolvers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/resolvelib/resolvers.py b/src/resolvelib/resolvers.py index f085c77..868dce0 100644 --- a/src/resolvelib/resolvers.py +++ b/src/resolvelib/resolvers.py @@ -113,7 +113,7 @@ def __init__(self, provider, reporter): self._p = provider self._r = reporter self._states = [] - self._failure_casues = [] + self._failure_causes = [] @property def state(self): From 73d1bf9395cc873f8b3661d4d7e010c661f3015c Mon Sep 17 00:00:00 2001 From: Damian Date: Mon, 20 Sep 2021 11:48:23 -0400 Subject: [PATCH 3/9] Remove uncessary recalculation of failure causes --- src/resolvelib/resolvers.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/resolvelib/resolvers.py b/src/resolvelib/resolvers.py index 868dce0..b533df6 100644 --- a/src/resolvelib/resolvers.py +++ b/src/resolvelib/resolvers.py @@ -375,7 +375,6 @@ def resolve(self, requirements, max_rounds): # Dead ends everywhere. Give up. if not success: - causes = [i for c in failure_causes for i in c.information] raise ResolutionImpossible(self._failure_causes) else: # Pinning was successful. Push a new state to do another pin. From 02782f700b9d35698c5d5e54b7d9f4d199f88058 Mon Sep 17 00:00:00 2001 From: Damian Date: Tue, 21 Sep 2021 16:11:56 -0400 Subject: [PATCH 4/9] Store backtrack causes on state instead of an instance variable --- src/resolvelib/resolvers.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/resolvelib/resolvers.py b/src/resolvelib/resolvers.py index b533df6..6cb6c09 100644 --- a/src/resolvelib/resolvers.py +++ b/src/resolvelib/resolvers.py @@ -99,7 +99,7 @@ def __init__(self, round_count): # Resolution state in a round. -State = collections.namedtuple("State", "mapping criteria") +State = collections.namedtuple("State", "mapping criteria backtrack_causes") class Resolution(object): @@ -113,7 +113,6 @@ def __init__(self, provider, reporter): self._p = provider self._r = reporter self._states = [] - self._failure_causes = [] @property def state(self): @@ -132,6 +131,7 @@ def _push_new_state(self): state = State( mapping=base.mapping.copy(), criteria=base.criteria.copy(), + backtrack_causes=base.backtrack_causes.copy(), ) self._states.append(state) @@ -186,7 +186,7 @@ def _get_preference(self, name): self.state.criteria, operator.attrgetter("information"), ), - failure_causes=self._failure_causes + backtrack_causes=self.state.backtrack_causes ) def _is_current_pin_satisfying(self, name, criterion): @@ -234,7 +234,7 @@ def _attempt_to_pin_criterion(self, name): # backtracking looks at this mapping to get the last pin. self.state.mapping.pop(name, None) self.state.mapping[name] = candidate - + return [] # All candidates tried, nothing works. This criterion is a dead @@ -337,7 +337,11 @@ def resolve(self, requirements, max_rounds): self._r.starting() # Initialize the root state. - self._states = [State(mapping=collections.OrderedDict(), criteria={})] + self._states = [ + State(mapping=collections.OrderedDict(), + criteria={}, + backtrack_causes=[]) + ] for r in requirements: try: self._add_to_criteria(self.state.criteria, r, parent=None) @@ -371,11 +375,13 @@ def resolve(self, requirements, max_rounds): # Backtrack if pinning fails. The backtrack process puts us in # an unpinned state, so we can work on it in the next round. success = self._backtrack() - self._failure_causes = [i for c in failure_causes for i in c.information] + self.state.backtrack_causes[:] = [ + i for c in failure_causes for i in c.information + ] # Dead ends everywhere. Give up. if not success: - raise ResolutionImpossible(self._failure_causes) + raise ResolutionImpossible(self.state.backtrack_causes) else: # Pinning was successful. Push a new state to do another pin. self._push_new_state() From 0f253d0b99b485af35f78e3db7bd2b5219f0c106 Mon Sep 17 00:00:00 2001 From: Damian Date: Tue, 21 Sep 2021 16:20:44 -0400 Subject: [PATCH 5/9] Remove accidental space --- src/resolvelib/resolvers.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/resolvelib/resolvers.py b/src/resolvelib/resolvers.py index 6cb6c09..c6e9031 100644 --- a/src/resolvelib/resolvers.py +++ b/src/resolvelib/resolvers.py @@ -234,7 +234,6 @@ def _attempt_to_pin_criterion(self, name): # backtracking looks at this mapping to get the last pin. self.state.mapping.pop(name, None) self.state.mapping[name] = candidate - return [] # All candidates tried, nothing works. This criterion is a dead From 11c9d2ecc9013213ec4c66eace60ef3b1c4bfb71 Mon Sep 17 00:00:00 2001 From: Damian Date: Tue, 21 Sep 2021 16:21:16 -0400 Subject: [PATCH 6/9] Add back newline --- src/resolvelib/resolvers.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/resolvelib/resolvers.py b/src/resolvelib/resolvers.py index c6e9031..38de2d9 100644 --- a/src/resolvelib/resolvers.py +++ b/src/resolvelib/resolvers.py @@ -234,6 +234,7 @@ def _attempt_to_pin_criterion(self, name): # backtracking looks at this mapping to get the last pin. self.state.mapping.pop(name, None) self.state.mapping[name] = candidate + return [] # All candidates tried, nothing works. This criterion is a dead From 621b9f2fc4211f79ca6cf8638cd29e4e9c76dbe6 Mon Sep 17 00:00:00 2001 From: Damian Date: Tue, 21 Sep 2021 20:22:38 -0400 Subject: [PATCH 7/9] Fix linter errors --- src/resolvelib/resolvers.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/resolvelib/resolvers.py b/src/resolvelib/resolvers.py index 38de2d9..e7625ce 100644 --- a/src/resolvelib/resolvers.py +++ b/src/resolvelib/resolvers.py @@ -186,7 +186,7 @@ def _get_preference(self, name): self.state.criteria, operator.attrgetter("information"), ), - backtrack_causes=self.state.backtrack_causes + backtrack_causes=self.state.backtrack_causes, ) def _is_current_pin_satisfying(self, name, criterion): @@ -338,10 +338,12 @@ def resolve(self, requirements, max_rounds): # Initialize the root state. self._states = [ - State(mapping=collections.OrderedDict(), - criteria={}, - backtrack_causes=[]) - ] + State( + mapping=collections.OrderedDict(), + criteria={}, + backtrack_causes=[], + ) + ] for r in requirements: try: self._add_to_criteria(self.state.criteria, r, parent=None) @@ -376,8 +378,8 @@ def resolve(self, requirements, max_rounds): # an unpinned state, so we can work on it in the next round. success = self._backtrack() self.state.backtrack_causes[:] = [ - i for c in failure_causes for i in c.information - ] + i for c in failure_causes for i in c.information + ] # Dead ends everywhere. Give up. if not success: From eb3495e7689f89e15c534d64b084261938114f21 Mon Sep 17 00:00:00 2001 From: Damian Date: Sat, 25 Sep 2021 20:51:08 -0400 Subject: [PATCH 8/9] Fix failing tests --- tests/functional/cocoapods/test_resolvers_cocoapods.py | 9 ++++++++- tests/functional/python/test_resolvers_python.py | 9 ++++++++- .../swift-package-manager/test_resolvers_swift.py | 9 ++++++++- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/tests/functional/cocoapods/test_resolvers_cocoapods.py b/tests/functional/cocoapods/test_resolvers_cocoapods.py index 685743c..54876c9 100644 --- a/tests/functional/cocoapods/test_resolvers_cocoapods.py +++ b/tests/functional/cocoapods/test_resolvers_cocoapods.py @@ -105,7 +105,14 @@ def __init__(self, filename): def identify(self, requirement_or_candidate): return requirement_or_candidate.name - def get_preference(self, identifier, resolutions, candidates, information): + def get_preference( + self, + identifier, + resolutions, + candidates, + information, + backtrack_causes, + ): return sum(1 for _ in candidates[identifier]) def _iter_matches(self, name, requirements, incompatibilities): diff --git a/tests/functional/python/test_resolvers_python.py b/tests/functional/python/test_resolvers_python.py index 916b23a..0881666 100644 --- a/tests/functional/python/test_resolvers_python.py +++ b/tests/functional/python/test_resolvers_python.py @@ -72,7 +72,14 @@ def identify(self, requirement_or_candidate): return "{}[{}]".format(name, extras_str) return name - def get_preference(self, identifier, resolutions, candidates, information): + def get_preference( + self, + identifier, + resolutions, + candidates, + information, + backtrack_causes, + ): transitive = all(p is not None for _, p in information[identifier]) return (transitive, identifier) diff --git a/tests/functional/swift-package-manager/test_resolvers_swift.py b/tests/functional/swift-package-manager/test_resolvers_swift.py index 76b7f39..8d8fd54 100644 --- a/tests/functional/swift-package-manager/test_resolvers_swift.py +++ b/tests/functional/swift-package-manager/test_resolvers_swift.py @@ -79,7 +79,14 @@ def __init__(self, filename): def identify(self, requirement_or_candidate): return requirement_or_candidate.container["identifier"] - def get_preference(self, identifier, resolutions, candidates, information): + def get_preference( + self, + identifier, + resolutions, + candidates, + information, + backtrack_causes, + ): return sum(1 for _ in candidates[identifier]) def _iter_matches(self, identifier, requirements, incompatibilities): From 4a9a17f75f9f34f13bffac1a64b4999760ec94b9 Mon Sep 17 00:00:00 2001 From: Damian Date: Sat, 25 Sep 2021 20:58:49 -0400 Subject: [PATCH 9/9] Fix for Python 2.7, is this needed? --- src/resolvelib/resolvers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/resolvelib/resolvers.py b/src/resolvelib/resolvers.py index e7625ce..35e00fa 100644 --- a/src/resolvelib/resolvers.py +++ b/src/resolvelib/resolvers.py @@ -131,7 +131,7 @@ def _push_new_state(self): state = State( mapping=base.mapping.copy(), criteria=base.criteria.copy(), - backtrack_causes=base.backtrack_causes.copy(), + backtrack_causes=base.backtrack_causes[:], ) self._states.append(state)