Skip to content

Commit

Permalink
Lazy-evaluate candidates with installed inserted
Browse files Browse the repository at this point in the history
  • Loading branch information
uranusjr committed Dec 15, 2020
1 parent 3b01eb3 commit 6b9f9f8
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 12 deletions.
5 changes: 5 additions & 0 deletions news/9246.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
New resolver: Discard a candidate if it fails to provide metadata from source,
or if the provided metadata is inconsistent, instead of quitting outright. This
implemented is taken from 20.2.2, with a fix that always makes the resolver
iterate through candidates from indexes lazily, to avoid downloading candidates
we do not need.
26 changes: 14 additions & 12 deletions src/pip/_internal/resolution/resolvelib/found_candidates.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import itertools
import operator

from pip._vendor.six.moves import collections_abc # type: ignore

Expand Down Expand Up @@ -32,18 +31,21 @@ def _insert_installed(installed, others):
already-installed package. Candidates from index are returned in their
normal ordering, except replaced when the version is already installed.
Since candidates from index are already sorted by reverse version order,
`sorted()` here would keep the ordering mostly intact, only shuffling the
already-installed candidate into the correct position. We put the already-
installed candidate in front of those from the index, so it's put in front
after sorting due to Python sorting's stableness guarentee.
The implementation iterates through and yields other candidates, but insert
the installed candidate exactly once before we start yielding older or
equivalent candidates, or after all other candidates if they are all newer.
"""
candidates = sorted(
itertools.chain([installed], others),
key=operator.attrgetter("version"),
reverse=True,
)
return iter(candidates)
installed_yielded = False
for candidate in others:
# If the installed candidate if better, yield it first.
if not installed_yielded and installed.version >= candidate.version:
yield installed
installed_yielded = True
yield candidate

# If the installed candidate is older than all other candidates.
if not installed_yielded:
yield installed


class FoundCandidates(collections_abc.Sequence):
Expand Down

0 comments on commit 6b9f9f8

Please sign in to comment.