|
1 | 1 | import itertools |
2 | | -import operator |
3 | 2 |
|
4 | 3 | from pip._vendor.six.moves import collections_abc # type: ignore |
5 | 4 |
|
@@ -32,18 +31,23 @@ def _insert_installed(installed, others): |
32 | 31 | already-installed package. Candidates from index are returned in their |
33 | 32 | normal ordering, except replaced when the version is already installed. |
34 | 33 |
|
35 | | - Since candidates from index are already sorted by reverse version order, |
36 | | - `sorted()` here would keep the ordering mostly intact, only shuffling the |
37 | | - already-installed candidate into the correct position. We put the already- |
38 | | - installed candidate in front of those from the index, so it's put in front |
39 | | - after sorting due to Python sorting's stableness guarentee. |
| 34 | + The implementation iterates through and yields other candidates, but insert |
| 35 | + the installed candidate exactly once before we start yielding older or |
| 36 | + equivalent candidates, or after all other candidates if they are all newer. |
40 | 37 | """ |
41 | | - candidates = sorted( |
42 | | - itertools.chain([installed], others), |
43 | | - key=operator.attrgetter("version"), |
44 | | - reverse=True, |
45 | | - ) |
46 | | - return iter(candidates) |
| 38 | + installed_yielded = False |
| 39 | + |
| 40 | + for candidate in others: |
| 41 | + # If the installed candidate if better, yield it first. |
| 42 | + if not installed_yielded and installed.version >= candidate.version: |
| 43 | + yield installed |
| 44 | + installed_yielded = True |
| 45 | + |
| 46 | + yield candidate |
| 47 | + |
| 48 | + # If the installed candidate is older than all other candidates. |
| 49 | + if not installed_yielded: |
| 50 | + yield installed |
47 | 51 |
|
48 | 52 |
|
49 | 53 | class FoundCandidates(collections_abc.Sequence): |
|
0 commit comments