Skip to content

Commit 32d66d2

Browse files
authored
Upgrade resolvelib to 1.0.1 (#11879)
Co-authored-by: Pradyun Gedam <[email protected]>
1 parent ade3826 commit 32d66d2

File tree

4 files changed

+42
-17
lines changed

4 files changed

+42
-17
lines changed

news/resolvelib.vendor.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Upgrade resolvelib to 0.9.0
1+
Upgrade resolvelib to 1.0.1

src/pip/_vendor/resolvelib/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"ResolutionTooDeep",
1212
]
1313

14-
__version__ = "0.9.0"
14+
__version__ = "1.0.1"
1515

1616

1717
from .providers import AbstractProvider, AbstractResolver

src/pip/_vendor/resolvelib/resolvers.py

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import collections
2+
import itertools
23
import operator
34

45
from .providers import AbstractResolver
@@ -191,8 +192,8 @@ def _remove_information_from_criteria(self, criteria, parents):
191192
information
192193
for information in criterion.information
193194
if (
194-
information[1] is None
195-
or self._p.identify(information[1]) not in parents
195+
information.parent is None
196+
or self._p.identify(information.parent) not in parents
196197
)
197198
],
198199
criterion.incompatibilities,
@@ -266,8 +267,8 @@ def _attempt_to_pin_criterion(self, name):
266267
# end, signal for backtracking.
267268
return causes
268269

269-
def _backtrack(self):
270-
"""Perform backtracking.
270+
def _backjump(self, causes):
271+
"""Perform backjumping.
271272
272273
When we enter here, the stack is like this::
273274
@@ -283,22 +284,46 @@ def _backtrack(self):
283284
284285
Each iteration of the loop will:
285286
286-
1. Discard Z.
287-
2. Discard Y but remember its incompatibility information gathered
287+
1. Identify Z. The incompatibility is not always caused by the latest
288+
state. For example, given three requirements A, B and C, with
289+
dependencies A1, B1 and C1, where A1 and B1 are incompatible: the
290+
last state might be related to C, so we want to discard the
291+
previous state.
292+
2. Discard Z.
293+
3. Discard Y but remember its incompatibility information gathered
288294
previously, and the failure we're dealing with right now.
289-
3. Push a new state Y' based on X, and apply the incompatibility
295+
4. Push a new state Y' based on X, and apply the incompatibility
290296
information from Y to Y'.
291-
4a. If this causes Y' to conflict, we need to backtrack again. Make Y'
297+
5a. If this causes Y' to conflict, we need to backtrack again. Make Y'
292298
the new Z and go back to step 2.
293-
4b. If the incompatibilities apply cleanly, end backtracking.
299+
5b. If the incompatibilities apply cleanly, end backtracking.
294300
"""
301+
incompatible_reqs = itertools.chain(
302+
(c.parent for c in causes if c.parent is not None),
303+
(c.requirement for c in causes),
304+
)
305+
incompatible_deps = {self._p.identify(r) for r in incompatible_reqs}
295306
while len(self._states) >= 3:
296307
# Remove the state that triggered backtracking.
297308
del self._states[-1]
298309

299-
# Retrieve the last candidate pin and known incompatibilities.
300-
broken_state = self._states.pop()
301-
name, candidate = broken_state.mapping.popitem()
310+
# Ensure to backtrack to a state that caused the incompatibility
311+
incompatible_state = False
312+
while not incompatible_state:
313+
# Retrieve the last candidate pin and known incompatibilities.
314+
try:
315+
broken_state = self._states.pop()
316+
name, candidate = broken_state.mapping.popitem()
317+
except (IndexError, KeyError):
318+
raise ResolutionImpossible(causes)
319+
current_dependencies = {
320+
self._p.identify(d)
321+
for d in self._p.get_dependencies(candidate)
322+
}
323+
incompatible_state = not current_dependencies.isdisjoint(
324+
incompatible_deps
325+
)
326+
302327
incompatibilities_from_broken = [
303328
(k, list(v.incompatibilities))
304329
for k, v in broken_state.criteria.items()
@@ -403,10 +428,10 @@ def resolve(self, requirements, max_rounds):
403428

404429
if failure_causes:
405430
causes = [i for c in failure_causes for i in c.information]
406-
# Backtrack if pinning fails. The backtrack process puts us in
431+
# Backjump if pinning fails. The backjump process puts us in
407432
# an unpinned state, so we can work on it in the next round.
408433
self._r.resolving_conflicts(causes=causes)
409-
success = self._backtrack()
434+
success = self._backjump(causes)
410435
self.state.backtrack_causes[:] = causes
411436

412437
# Dead ends everywhere. Give up.

src/pip/_vendor/vendor.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ requests==2.28.2
1515
rich==12.6.0
1616
pygments==2.13.0
1717
typing_extensions==4.4.0
18-
resolvelib==0.9.0
18+
resolvelib==1.0.1
1919
setuptools==65.6.3
2020
six==1.16.0
2121
tenacity==8.1.0

0 commit comments

Comments
 (0)