@@ -56,9 +56,33 @@ def get_preference(
56
56
information # type: Sequence[Tuple[Requirement, Candidate]]
57
57
):
58
58
# 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 )
59
83
transitive = all (parent is not None for _ , parent in information )
60
84
key = next (iter (candidates )).name if candidates else ""
61
- return (transitive , key )
85
+ return (restrictive , transitive , key )
62
86
63
87
def find_matches (self , requirements ):
64
88
# type: (Sequence[Requirement]) -> Iterable[Candidate]
0 commit comments