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

Store failure cause and provide to _get_preference #84

Merged
merged 9 commits into from
Sep 26, 2021
18 changes: 14 additions & 4 deletions src/resolvelib/resolvers.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down Expand Up @@ -131,6 +131,7 @@ def _push_new_state(self):
state = State(
mapping=base.mapping.copy(),
criteria=base.criteria.copy(),
backtrack_causes=base.backtrack_causes[:],
)
self._states.append(state)

Expand Down Expand Up @@ -185,6 +186,7 @@ def _get_preference(self, name):
self.state.criteria,
operator.attrgetter("information"),
),
backtrack_causes=self.state.backtrack_causes,
)

def _is_current_pin_satisfying(self, name, criterion):
Expand Down Expand Up @@ -335,7 +337,13 @@ 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)
Expand Down Expand Up @@ -369,11 +377,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.state.backtrack_causes[:] = [
i for c in failure_causes for i in c.information
]
notatallshaw marked this conversation as resolved.
Show resolved Hide resolved

# 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.state.backtrack_causes)
else:
# Pinning was successful. Push a new state to do another pin.
self._push_new_state()
Expand Down
9 changes: 8 additions & 1 deletion tests/functional/cocoapods/test_resolvers_cocoapods.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
9 changes: 8 additions & 1 deletion tests/functional/python/test_resolvers_python.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down