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 26, 2020
1 parent 92ad717 commit 8e55757
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 12 deletions.
4 changes: 4 additions & 0 deletions news/9203.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
New resolver: Discard a faulty distribution, instead of quitting outright.
This implementation 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.
4 changes: 4 additions & 0 deletions news/9246.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
New resolver: Discard a source distribution if it fails to generate metadata,
instead of quitting outright. This implementation 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,6 +1,5 @@
import functools
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, inserting
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 is 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 8e55757

Please sign in to comment.