Lazy-evaluate candidates with installed inserted

This commit is contained in:
Tzu-ping Chung 2020-12-15 17:08:35 +08:00
parent 92ad717612
commit 8e55757a2f
3 changed files with 22 additions and 12 deletions

4
news/9203.bugfix.rst Normal file
View File

@ -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
news/9246.bugfix.rst Normal file
View File

@ -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.

View File

@ -1,6 +1,5 @@
import functools
import itertools
import operator
from pip._vendor.six.moves import collections_abc # type: ignore
@ -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):