From de14ca20fb6f28b387df1b4e3a5fcfdd93f265ef Mon Sep 17 00:00:00 2001 From: Pradyun Gedam <3275593+pradyunsg@users.noreply.github.com> Date: Tue, 29 Sep 2020 15:04:51 +0530 Subject: [PATCH] Merge pull request #8924 from uranusjr/new-resolver-try-user-requested-combinations-first --- news/8924.feature | 2 ++ .../_internal/resolution/resolvelib/provider.py | 17 ++++++++++++----- 2 files changed, 14 insertions(+), 5 deletions(-) create mode 100644 news/8924.feature diff --git a/news/8924.feature b/news/8924.feature new file mode 100644 index 00000000000..c607aa0d06b --- /dev/null +++ b/news/8924.feature @@ -0,0 +1,2 @@ +New resolver: Tweak resolution logic to improve user experience when +user-supplied requirements conflict. diff --git a/src/pip/_internal/resolution/resolvelib/provider.py b/src/pip/_internal/resolution/resolvelib/provider.py index b2eb9d06ea5..bf704db3726 100644 --- a/src/pip/_internal/resolution/resolvelib/provider.py +++ b/src/pip/_internal/resolution/resolvelib/provider.py @@ -51,7 +51,7 @@ def __init__( self._constraints = constraints self._ignore_dependencies = ignore_dependencies self._upgrade_strategy = upgrade_strategy - self.user_requested = user_requested + self._user_requested = user_requested def _sort_matches(self, matches): # type: (Iterable[Candidate]) -> Sequence[Candidate] @@ -92,7 +92,7 @@ def _eligible_for_upgrade(name): if self._upgrade_strategy == "eager": return True elif self._upgrade_strategy == "only-if-needed": - return (name in self.user_requested) + return (name in self._user_requested) return False def sort_key(c): @@ -123,11 +123,18 @@ def get_preference( self, resolution, # type: Optional[Candidate] candidates, # type: Sequence[Candidate] - information # type: Sequence[Tuple[Requirement, Candidate]] + information # type: Sequence[Tuple[Requirement, Optional[Candidate]]] ): # type: (...) -> Any - # Use the "usual" value for now - return len(candidates) + """Return a sort key to determine what dependency to look next. + + A smaller value makes a dependency higher priority. We put direct + (user-requested) dependencies first since they may contain useful + user-specified version ranges. Users tend to expect us to catch + problems in them early as well. + """ + transitive = all(parent is not None for _, parent in information) + return (transitive, len(candidates)) def find_matches(self, requirements): # type: (Sequence[Requirement]) -> Iterable[Candidate]