1
- import functools
2
1
import itertools
2
+ import operator
3
3
4
4
from pip ._vendor .six .moves import collections_abc # type: ignore
5
5
6
6
from pip ._internal .utils .compat import lru_cache
7
7
from pip ._internal .utils .typing import MYPY_CHECK_RUNNING
8
8
9
9
if MYPY_CHECK_RUNNING :
10
- from typing import Any , Callable , Iterator , Optional , Set
10
+ from typing import Callable , Iterator , Optional , Set
11
11
12
12
from pip ._vendor .packaging .version import _BaseVersion
13
13
@@ -24,11 +24,6 @@ def _deduplicated_by_version(candidates):
24
24
yield candidate
25
25
26
26
27
- def _replaces_sort_key (installed , candidate ):
28
- # type: (Candidate, Candidate) -> Any
29
- return (candidate .version , candidate is installed )
30
-
31
-
32
27
def _insert_installed (installed , others ):
33
28
# type: (Candidate, Iterator[Candidate]) -> Iterator[Candidate]
34
29
"""Iterator for ``FoundCandidates``.
@@ -37,12 +32,15 @@ def _insert_installed(installed, others):
37
32
already-installed package. Candidates from index are returned in their
38
33
normal ordering, except replaced when the version is already installed.
39
34
40
- The sort key prefers the installed candidate over candidates of the same
41
- version from the index, so it is chosen on de-duplication.
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.
42
40
"""
43
41
candidates = sorted (
44
- itertools .chain (others , [installed ]),
45
- key = functools . partial ( _replaces_sort_key , installed ),
42
+ itertools .chain ([installed ], others ),
43
+ key = operator . attrgetter ( "version" ),
46
44
reverse = True ,
47
45
)
48
46
return iter (candidates )
0 commit comments