|
16 | 16 | cast, |
17 | 17 | ) |
18 | 18 |
|
| 19 | +from pip._vendor.packaging.requirements import InvalidRequirement |
| 20 | +from pip._vendor.packaging.requirements import Requirement as PackagingRequirement |
19 | 21 | from pip._vendor.packaging.specifiers import SpecifierSet |
20 | 22 | from pip._vendor.packaging.utils import NormalizedName, canonicalize_name |
21 | 23 | from pip._vendor.pkg_resources import Distribution |
|
53 | 55 | ExtrasCandidate, |
54 | 56 | LinkCandidate, |
55 | 57 | RequiresPythonCandidate, |
| 58 | + is_base_candidate, |
56 | 59 | ) |
57 | 60 | from .found_candidates import FoundCandidates, IndexCandidateInfo |
58 | 61 | from .requirements import ( |
@@ -296,6 +299,27 @@ def find_candidates( |
296 | 299 | if ireq is not None: |
297 | 300 | ireqs.append(ireq) |
298 | 301 |
|
| 302 | + # If the current identifier contains extras, also add explicit |
| 303 | + # candidates from entries from extra-less identifier. |
| 304 | + try: |
| 305 | + identifier_req = PackagingRequirement(identifier) |
| 306 | + except InvalidRequirement: |
| 307 | + base_identifier = None |
| 308 | + extras: FrozenSet[str] = frozenset() |
| 309 | + else: |
| 310 | + base_identifier = identifier_req.name |
| 311 | + extras = frozenset(identifier_req.extras) |
| 312 | + if base_identifier and base_identifier in requirements: |
| 313 | + for req in requirements[base_identifier]: |
| 314 | + base_cand, _ = req.get_candidate_lookup() |
| 315 | + if base_cand is None or not is_base_candidate(base_cand): |
| 316 | + continue |
| 317 | + candidate = self._make_extras_candidate( |
| 318 | + cast(BaseCandidate, base_cand), |
| 319 | + extras, |
| 320 | + ) |
| 321 | + explicit_candidates.add(candidate) |
| 322 | + |
299 | 323 | # If none of the requirements want an explicit candidate, we can ask |
300 | 324 | # the finder for candidates. |
301 | 325 | if not explicit_candidates: |
|
0 commit comments