Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions src/resolvelib/resolvers.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ def _push_new_state(self):
state = State(
mapping=base.mapping.copy(),
criteria=base.criteria.copy(),
backtrack_causes=base.backtrack_causes[:],
backtrack_causes=base.backtrack_causes.copy(),
)
self._states.append(state)

Expand Down Expand Up @@ -340,7 +340,7 @@ def resolve(self, requirements, max_rounds):
State(
mapping=collections.OrderedDict(),
criteria={},
backtrack_causes=[],
backtrack_causes=set(),
)
]
for r in requirements:
Expand Down Expand Up @@ -378,11 +378,15 @@ def resolve(self, requirements, max_rounds):
# an unpinned state, so we can work on it in the next round.
self._r.resolving_conflicts(causes=causes)
success = self._backtrack()
self.state.backtrack_causes[:] = causes

# Dead ends everywhere. Give up.
if not success:
raise ResolutionImpossible(self.state.backtrack_causes)
raise ResolutionImpossible(causes)

# Update backtrack causes
backtrack_causes = self._causes_to_names(causes)
self.state.backtrack_causes.clear()
self.state.backtrack_causes.update(backtrack_causes)
else:
# Pinning was successful. Push a new state to do another pin.
self._push_new_state()
Expand All @@ -391,6 +395,12 @@ def resolve(self, requirements, max_rounds):

raise ResolutionTooDeep(max_rounds)

@staticmethod
def _causes_to_names(causes):
return {c.requirement.name for c in causes} | {
c.parent.name for c in causes if c.parent
}


def _has_route_to_root(criteria, key, all_keys, connected):
if key in connected:
Expand Down