Skip to content

Commit

Permalink
Resolve direct and pinned requirements first
Browse files Browse the repository at this point in the history
  • Loading branch information
uranusjr committed Dec 3, 2020
1 parent 30eeb9c commit 289488b
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 1 deletion.
2 changes: 2 additions & 0 deletions news/9185.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
New resolver: Resolve direct and pinned (``==`` or ``===``) requirements first
to improve resolver performance.
26 changes: 25 additions & 1 deletion src/pip/_internal/resolution/resolvelib/provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,33 @@ def get_preference(
information # type: Sequence[Tuple[Requirement, Candidate]]
):
# type: (...) -> Any
"""Produce a sort key for given requirement based on preference.
The lower the return value is, the more preferred this group of
arguments is.
Currently pip considers the followings in order:
* Prefer if any of the known requirements points to an explicit URL.
* If equal, prefer if any requirements contain `===` and `==`.
* If equal, prefer user-specified (non-transitive) requirements.
* If equal, order alphabetically for consistency (helps debuggability).
"""

def _get_restrictive_rating(requirements):
# type: (Iterable[Requirement]) -> int
lookups = (r.get_candidate_lookup() for r in requirements)
cands, ireqs = zip(*lookups)
if any(cand is not None for cand in cands):
return 0
if any(ireq.is_pinned for ireq in ireqs if ireq is not None):
return 1
return 2

restrictive = _get_restrictive_rating(req for req, _ in information)
transitive = all(parent is not None for _, parent in information)
key = next(iter(candidates)).name if candidates else ""
return (transitive, key)
return (restrictive, transitive, key)

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

0 comments on commit 289488b

Please sign in to comment.