Skip to content

Commit f8b84c7

Browse files
committed
Implement extra-ed requirement merging
When a requirement is requested multiple times, some via a direct URL ("req @ URL") and some not but with extras ("req[extra] VERSION"), the resolver previous could not correctly find "req[extra]" if "req" is available in an index. This additional logic makes the resolver, when encountering a requirement with identifier "req[extra]", to also look for explicit candidates listed under "req", and add them as found matches for "req[extra]".
1 parent cbc9f53 commit f8b84c7

File tree

2 files changed

+26
-0
lines changed

2 files changed

+26
-0
lines changed

news/8785.bugfix.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
New resolver: When a requirement is requested both via a direct URL
2+
(``req @ URL``) and via version specifier with extras (``req[extra]``), the
3+
resolver will now be able to use the URL to correctly resolve the requirement
4+
with extras.

src/pip/_internal/resolution/resolvelib/factory.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@
1616
cast,
1717
)
1818

19+
from pip._vendor.packaging.requirements import (
20+
InvalidRequirement,
21+
Requirement as PackagingRequirement,
22+
)
1923
from pip._vendor.packaging.specifiers import SpecifierSet
2024
from pip._vendor.packaging.utils import NormalizedName, canonicalize_name
2125
from pip._vendor.pkg_resources import Distribution
@@ -296,6 +300,24 @@ def find_candidates(
296300
if ireq is not None:
297301
ireqs.append(ireq)
298302

303+
# If the current identifier contains extras, also add explicit
304+
# candidates from entries from extra-less identifier.
305+
try:
306+
identifier_req = PackagingRequirement(identifier)
307+
except InvalidRequirement:
308+
base_identifier = None
309+
extras = frozenset()
310+
else:
311+
base_identifier = identifier_req.name
312+
extras = frozenset(identifier_req.extras)
313+
if base_identifier and base_identifier in requirements:
314+
for req in requirements[base_identifier]:
315+
base_cand, _ = req.get_candidate_lookup()
316+
if base_cand is None:
317+
continue
318+
candidate = self._make_extras_candidate(base_cand, extras)
319+
explicit_candidates.add(candidate)
320+
299321
# If none of the requirements want an explicit candidate, we can ask
300322
# the finder for candidates.
301323
if not explicit_candidates:

0 commit comments

Comments
 (0)