def _iter_candidates_from_constraints( self, identifier: str, constraint: Constraint, template: InstallRequirement, ) -> Iterator[Candidate]: """Produce explicit candidates from constraints. This creates "fake" InstallRequirement objects that are basically clones of what "should" be the template, but with original_link set to link. """ for link in constraint.links: self._fail_if_link_is_unsupported_wheel(link) candidate = self._make_candidate_from_link( link, extras=frozenset(), template=install_req_from_link_and_ireq(link, template), name=canonicalize_name(identifier), version=None, ) if candidate: yield candidate
def find_candidates( self, identifier: str, requirements: Mapping[str, Iterator[Requirement]], incompatibilities: Mapping[str, Iterator[Candidate]], constraint: Constraint, prefers_installed: bool, ) -> Iterable[Candidate]: # Since we cache all the candidates, incompatibility identification # can be made quicker by comparing only the id() values. incompat_ids = {id(c) for c in incompatibilities.get(identifier, ())} explicit_candidates = set() # type: Set[Candidate] ireqs = [] # type: List[InstallRequirement] for req in requirements[identifier]: cand, ireq = req.get_candidate_lookup() if cand is not None and id(cand) not in incompat_ids: explicit_candidates.add(cand) if ireq is not None: ireqs.append(ireq) for link in constraint.links: if not ireqs: # If we hit this condition, then we cannot construct a candidate. # However, if we hit this condition, then none of the requirements # provided an ireq, so they must have provided an explicit candidate. # In that case, either the candidate matches, in which case this loop # doesn't need to do anything, or it doesn't, in which case there's # nothing this loop can do to recover. break if link.is_wheel: wheel = Wheel(link.filename) # Check whether the provided wheel is compatible with the target # platform. if not wheel.supported(self._finder.target_python.get_tags()): # We are constrained to install a wheel that is incompatible with # the target architecture, so there are no valid candidates. # Return early, with no candidates. return () # Create a "fake" InstallRequirement that's basically a clone of # what "should" be the template, but with original_link set to link. # Using the given requirement is necessary for preserving hash # requirements, but without the original_link, direct_url.json # won't be created. ireq = install_req_from_link_and_ireq(link, ireqs[0]) candidate = self._make_candidate_from_link( link, extras=frozenset(), template=ireq, name=canonicalize_name(ireq.name) if ireq.name else None, version=None, ) if candidate is None: # _make_candidate_from_link returns None if the wheel fails to build. # We are constrained to install this wheel, so there are no valid # candidates. # Return early, with no candidates. return () explicit_candidates.add(candidate) # If none of the requirements want an explicit candidate, we can ask # the finder for candidates. if not explicit_candidates: return self._iter_found_candidates( ireqs, constraint.specifier, constraint.hashes, prefers_installed, incompat_ids, ) return (c for c in explicit_candidates if constraint.is_satisfied_by(c) and all( req.is_satisfied_by(c) for req in requirements[identifier]))