|
4 | 4 |
|
5 | 5 | from pip._internal.exceptions import (
|
6 | 6 | DistributionNotFound,
|
| 7 | + HashError, |
7 | 8 | InstallationError,
|
| 9 | + InstallationSubprocessError, |
| 10 | + MetadataInconsistent, |
8 | 11 | UnsupportedPythonVersion,
|
9 | 12 | UnsupportedWheel,
|
10 | 13 | )
|
|
33 | 36 | ExplicitRequirement,
|
34 | 37 | RequiresPythonRequirement,
|
35 | 38 | SpecifierRequirement,
|
| 39 | + UnsatisfiableRequirement, |
36 | 40 | )
|
37 | 41 |
|
38 | 42 | if MYPY_CHECK_RUNNING:
|
@@ -96,6 +100,7 @@ def __init__(
|
96 | 100 |
|
97 | 101 | self._link_candidate_cache = {} # type: Cache[LinkCandidate]
|
98 | 102 | self._editable_candidate_cache = {} # type: Cache[EditableCandidate]
|
| 103 | + self._build_failures = {} # type: Cache[InstallationError] |
99 | 104 |
|
100 | 105 | if not ignore_installed:
|
101 | 106 | self._installed_dists = {
|
@@ -130,20 +135,34 @@ def _make_candidate_from_link(
|
130 | 135 | name, # type: Optional[str]
|
131 | 136 | version, # type: Optional[_BaseVersion]
|
132 | 137 | ):
|
133 |
| - # type: (...) -> Candidate |
| 138 | + # type: (...) -> Optional[Candidate] |
134 | 139 | # TODO: Check already installed candidate, and use it if the link and
|
135 | 140 | # editable flag match.
|
| 141 | + if link in self._build_failures: |
| 142 | + return None |
136 | 143 | if template.editable:
|
137 | 144 | if link not in self._editable_candidate_cache:
|
138 |
| - self._editable_candidate_cache[link] = EditableCandidate( |
139 |
| - link, template, factory=self, name=name, version=version, |
140 |
| - ) |
| 145 | + try: |
| 146 | + self._editable_candidate_cache[link] = EditableCandidate( |
| 147 | + link, template, factory=self, |
| 148 | + name=name, version=version, |
| 149 | + ) |
| 150 | + except (InstallationSubprocessError, MetadataInconsistent) as e: |
| 151 | + logger.warning("Discarding %s. %s", link, e) |
| 152 | + self._build_failures[link] = e |
| 153 | + return None |
141 | 154 | base = self._editable_candidate_cache[link] # type: BaseCandidate
|
142 | 155 | else:
|
143 | 156 | if link not in self._link_candidate_cache:
|
144 |
| - self._link_candidate_cache[link] = LinkCandidate( |
145 |
| - link, template, factory=self, name=name, version=version, |
146 |
| - ) |
| 157 | + try: |
| 158 | + self._link_candidate_cache[link] = LinkCandidate( |
| 159 | + link, template, factory=self, |
| 160 | + name=name, version=version, |
| 161 | + ) |
| 162 | + except (InstallationSubprocessError, MetadataInconsistent) as e: |
| 163 | + logger.warning("Discarding %s. %s", link, e) |
| 164 | + self._build_failures[link] = e |
| 165 | + return None |
147 | 166 | base = self._link_candidate_cache[link]
|
148 | 167 | if extras:
|
149 | 168 | return ExtrasCandidate(base, extras)
|
@@ -204,13 +223,16 @@ def iter_index_candidates():
|
204 | 223 | for ican in reversed(icans):
|
205 | 224 | if not all_yanked and ican.link.is_yanked:
|
206 | 225 | continue
|
207 |
| - yield self._make_candidate_from_link( |
| 226 | + candidate = self._make_candidate_from_link( |
208 | 227 | link=ican.link,
|
209 | 228 | extras=extras,
|
210 | 229 | template=template,
|
211 | 230 | name=name,
|
212 | 231 | version=ican.version,
|
213 | 232 | )
|
| 233 | + if candidate is None: |
| 234 | + continue |
| 235 | + yield candidate |
214 | 236 |
|
215 | 237 | return FoundCandidates(
|
216 | 238 | iter_index_candidates,
|
@@ -274,6 +296,10 @@ def make_requirement_from_install_req(self, ireq, requested_extras):
|
274 | 296 | name=canonicalize_name(ireq.name) if ireq.name else None,
|
275 | 297 | version=None,
|
276 | 298 | )
|
| 299 | + if cand is None: |
| 300 | + if not ireq.name: |
| 301 | + raise self._build_failures[ireq.link] |
| 302 | + return UnsatisfiableRequirement(canonicalize_name(ireq.name)) |
277 | 303 | return self.make_requirement_from_candidate(cand)
|
278 | 304 |
|
279 | 305 | def make_requirement_from_candidate(self, candidate):
|
|
0 commit comments