@@ -138,13 +138,16 @@ def _fail_if_link_is_unsupported_wheel(self, link: Link) -> None:
138138 raise UnsupportedWheel (msg )
139139
140140 def _make_extras_candidate (
141- self , base : BaseCandidate , extras : FrozenSet [str ]
141+ self ,
142+ base : BaseCandidate ,
143+ extras : FrozenSet [str ],
144+ ireq : Optional [InstallRequirement ] = None ,
142145 ) -> ExtrasCandidate :
143146 cache_key = (id (base ), extras )
144147 try :
145148 candidate = self ._extras_candidate_cache [cache_key ]
146149 except KeyError :
147- candidate = ExtrasCandidate (base , extras )
150+ candidate = ExtrasCandidate (base , extras , ireq = ireq )
148151 self ._extras_candidate_cache [cache_key ] = candidate
149152 return candidate
150153
@@ -161,7 +164,7 @@ def _make_candidate_from_dist(
161164 self ._installed_candidate_cache [dist .canonical_name ] = base
162165 if not extras :
163166 return base
164- return self ._make_extras_candidate (base , extras )
167+ return self ._make_extras_candidate (base , extras , ireq = template )
165168
166169 def _make_candidate_from_link (
167170 self ,
@@ -223,7 +226,7 @@ def _make_candidate_from_link(
223226
224227 if not extras :
225228 return base
226- return self ._make_extras_candidate (base , extras )
229+ return self ._make_extras_candidate (base , extras , ireq = template )
227230
228231 def _iter_found_candidates (
229232 self ,
@@ -389,16 +392,17 @@ def find_candidates(
389392 # candidates from entries from extra-less identifier.
390393 with contextlib .suppress (InvalidRequirement ):
391394 parsed_requirement = get_requirement (identifier )
392- explicit_candidates .update (
393- self ._iter_explicit_candidates_from_base (
394- requirements .get (parsed_requirement .name , ()),
395- frozenset (parsed_requirement .extras ),
396- ),
397- )
398- for req in requirements .get (parsed_requirement .name , []):
399- _ , ireq = req .get_candidate_lookup ()
400- if ireq is not None :
401- ireqs .append (ireq )
395+ if parsed_requirement .name != identifier :
396+ explicit_candidates .update (
397+ self ._iter_explicit_candidates_from_base (
398+ requirements .get (parsed_requirement .name , ()),
399+ frozenset (parsed_requirement .extras ),
400+ ),
401+ )
402+ for req in requirements .get (parsed_requirement .name , []):
403+ _ , ireq = req .get_candidate_lookup ()
404+ if ireq is not None :
405+ ireqs .append (ireq )
402406
403407 # Add explicit candidates from constraints. We only do this if there are
404408 # known ireqs, which represent requirements not already explicit. If
@@ -444,7 +448,6 @@ def find_candidates(
444448 def _make_requirements_from_install_req (
445449 self , ireq : InstallRequirement , requested_extras : Iterable [str ]
446450 ) -> list [Requirement ]:
447- # TODO: docstring
448451 """
449452 Returns requirement objects associated with the given InstallRequirement. In
450453 most cases this will be a single object but the following special cases exist:
@@ -454,7 +457,6 @@ def _make_requirements_from_install_req(
454457 extra. This allows centralized constraint handling for the base,
455458 resulting in fewer candidate rejections.
456459 """
457- # TODO: implement -> split in base req with constraint and extra req without
458460 if not ireq .match_markers (requested_extras ):
459461 logger .info (
460462 "Ignoring %s: markers '%s' don't match your environment" ,
@@ -466,6 +468,10 @@ def _make_requirements_from_install_req(
466468 if ireq .extras and ireq .req .specifier :
467469 return [
468470 SpecifierRequirement (ireq , drop_extras = True ),
471+ # TODO: put this all the way at the back to have even fewer candidates?
472+ # TODO: probably best to keep specifier as it makes the report
473+ # slightly more readable -> should also update SpecReq constructor
474+ # and req.constructors.install_req_without
469475 SpecifierRequirement (ireq , drop_specifier = True ),
470476 ]
471477 else :
0 commit comments