Skip to content

Commit 2253ed3

Browse files
Prefer backtracking on dependencies involved in the most recent conflict
This can significantly reduce the amount of backtracking required, by avoiding backtracking on unrelated packages in the dependency graph. Co-authored-by: Pradyun Gedam <[email protected]>
1 parent 04b9ece commit 2253ed3

File tree

2 files changed

+20
-1
lines changed

2 files changed

+20
-1
lines changed

news/10479.feature.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
When backtracking during dependency resolution, prefer the dependencies which are involved in the most recent conflict. This can significantly reduce the amount of backtracking required.

src/pip/_internal/resolution/resolvelib/provider.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,13 @@ def __init__(
6666
def identify(self, requirement_or_candidate: Union[Requirement, Candidate]) -> str:
6767
return requirement_or_candidate.name
6868

69-
def get_preference(
69+
def get_preference( # type: ignore
7070
self,
7171
identifier: str,
7272
resolutions: Mapping[str, Candidate],
7373
candidates: Mapping[str, Iterator[Candidate]],
7474
information: Mapping[str, Iterable["PreferenceInformation"]],
75+
backtrack_causes: Sequence["PreferenceInformation"],
7576
) -> "Preference":
7677
"""Produce a sort key for given requirement based on preference.
7778
@@ -132,11 +133,17 @@ def get_preference(
132133
# while we work on "proper" branch pruning techniques.
133134
delay_this = identifier == "setuptools"
134135

136+
# Prefer the causes of backtracking on the assumption that the problem
137+
# resolving the dependency tree is related to the failures that caused
138+
# the backtracking
139+
backtrack_cause = self.is_backtrack_cause(identifier, backtrack_causes)
140+
135141
return (
136142
not requires_python,
137143
delay_this,
138144
not direct,
139145
not pinned,
146+
not backtrack_cause,
140147
inferred_depth,
141148
requested_order,
142149
not unfree,
@@ -195,3 +202,14 @@ def is_satisfied_by(self, requirement: Requirement, candidate: Candidate) -> boo
195202
def get_dependencies(self, candidate: Candidate) -> Sequence[Requirement]:
196203
with_requires = not self._ignore_dependencies
197204
return [r for r in candidate.iter_dependencies(with_requires) if r is not None]
205+
206+
@staticmethod
207+
def is_backtrack_cause(
208+
identifier: str, backtrack_causes: Sequence["PreferenceInformation"]
209+
) -> bool:
210+
for backtrack_cause in backtrack_causes:
211+
if identifier == backtrack_cause.requirement.name:
212+
return True
213+
if backtrack_cause.parent and identifier == backtrack_cause.parent.name:
214+
return True
215+
return False

0 commit comments

Comments
 (0)