Skip to content

Commit 289488b

Browse files
committed
Resolve direct and pinned requirements first
1 parent 30eeb9c commit 289488b

File tree

2 files changed

+27
-1
lines changed

2 files changed

+27
-1
lines changed

news/9185.feature.rst

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
New resolver: Resolve direct and pinned (``==`` or ``===``) requirements first
2+
to improve resolver performance.

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

+25-1
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,33 @@ def get_preference(
5656
information # type: Sequence[Tuple[Requirement, Candidate]]
5757
):
5858
# type: (...) -> Any
59+
"""Produce a sort key for given requirement based on preference.
60+
61+
The lower the return value is, the more preferred this group of
62+
arguments is.
63+
64+
Currently pip considers the followings in order:
65+
66+
* Prefer if any of the known requirements points to an explicit URL.
67+
* If equal, prefer if any requirements contain `===` and `==`.
68+
* If equal, prefer user-specified (non-transitive) requirements.
69+
* If equal, order alphabetically for consistency (helps debuggability).
70+
"""
71+
72+
def _get_restrictive_rating(requirements):
73+
# type: (Iterable[Requirement]) -> int
74+
lookups = (r.get_candidate_lookup() for r in requirements)
75+
cands, ireqs = zip(*lookups)
76+
if any(cand is not None for cand in cands):
77+
return 0
78+
if any(ireq.is_pinned for ireq in ireqs if ireq is not None):
79+
return 1
80+
return 2
81+
82+
restrictive = _get_restrictive_rating(req for req, _ in information)
5983
transitive = all(parent is not None for _, parent in information)
6084
key = next(iter(candidates)).name if candidates else ""
61-
return (transitive, key)
85+
return (restrictive, transitive, key)
6286

6387
def find_matches(self, requirements):
6488
# type: (Sequence[Requirement]) -> Iterable[Candidate]

0 commit comments

Comments
 (0)