21
21
)
22
22
23
23
if MYPY_CHECK_RUNNING :
24
- from typing import Dict , Optional , Set , Tuple , TypeVar
24
+ from typing import Dict , Iterator , Optional , Set , Tuple , TypeVar
25
25
26
26
from pip ._vendor .packaging .specifiers import SpecifierSet
27
27
from pip ._vendor .packaging .version import _BaseVersion
28
28
from pip ._vendor .pkg_resources import Distribution
29
29
from pip ._vendor .resolvelib import ResolutionImpossible
30
30
31
31
from pip ._internal .index .package_finder import PackageFinder
32
- from pip ._internal .models .candidate import InstallationCandidate
33
32
from pip ._internal .models .link import Link
34
33
from pip ._internal .operations .prepare import RequirementPreparer
35
34
from pip ._internal .req .req_install import InstallRequirement
@@ -66,7 +65,7 @@ def __init__(
66
65
67
66
if not ignore_installed :
68
67
self ._installed_dists = {
69
- dist .project_name : dist
68
+ canonicalize_name ( dist .project_name ) : dist
70
69
for dist in get_installed_distributions ()
71
70
}
72
71
else :
@@ -93,6 +92,8 @@ def _make_candidate_from_link(
93
92
version = None , # type: Optional[_BaseVersion]
94
93
):
95
94
# type: (...) -> Candidate
95
+ # TODO: Check already installed candidate, and use it if the link and
96
+ # editable flag match.
96
97
if parent .editable :
97
98
if link not in self ._editable_candidate_cache :
98
99
self ._editable_candidate_cache [link ] = EditableCandidate (
@@ -109,32 +110,40 @@ def _make_candidate_from_link(
109
110
return ExtrasCandidate (base , extras )
110
111
return base
111
112
112
- def make_candidate_from_ican (
113
- self ,
114
- ican , # type: InstallationCandidate
115
- extras , # type: Set[str]
116
- parent , # type: InstallRequirement
117
- ) :
118
- # type: (...) -> Candidate
119
- dist = self . _installed_dists . get ( ican . name )
120
- should_use_installed_dist = (
121
- not self . _force_reinstall and
122
- dist is not None and
123
- dist . parsed_version == ican . version
113
+ def iter_found_candidates ( self , ireq , extras ):
114
+ # type: (InstallRequirement, Set[str]) -> Iterator[Candidate]
115
+ name = canonicalize_name ( ireq . req . name )
116
+ if not self . _force_reinstall :
117
+ installed_dist = self . _installed_dists . get ( name )
118
+ else :
119
+ installed_dist = None
120
+
121
+ found = self . finder . find_best_candidate (
122
+ project_name = ireq . req . name ,
123
+ specifier = ireq . req . specifier ,
124
+ hashes = ireq . hashes ( trust_internet = False ),
124
125
)
125
- if not should_use_installed_dist :
126
- return self ._make_candidate_from_link (
126
+ for ican in found .iter_applicable ():
127
+ if (installed_dist is not None and
128
+ installed_dist .parsed_version == ican .version ):
129
+ continue
130
+ yield self ._make_candidate_from_link (
127
131
link = ican .link ,
128
132
extras = extras ,
129
- parent = parent ,
130
- name = canonicalize_name ( ican . name ) ,
133
+ parent = ireq ,
134
+ name = name ,
131
135
version = ican .version ,
132
136
)
133
- return self ._make_candidate_from_dist (
134
- dist = dist ,
135
- extras = extras ,
136
- parent = parent ,
137
- )
137
+
138
+ # Return installed distribution if it matches the specifier. This is
139
+ # done last so the resolver will prefer it over downloading links.
140
+ if (installed_dist is not None and
141
+ installed_dist .parsed_version in ireq .req .specifier ):
142
+ yield self ._make_candidate_from_dist (
143
+ dist = installed_dist ,
144
+ extras = extras ,
145
+ parent = ireq ,
146
+ )
138
147
139
148
def make_requirement_from_install_req (self , ireq ):
140
149
# type: (InstallRequirement) -> Requirement
0 commit comments