def get_dependencies( self, candidate: Candidate ) -> tuple[list[Requirement], PySpecSet, str]: """Get (dependencies, python_specifier, summary) of the candidate.""" requires_python, summary = "", "" requirements: list[str] = [] last_ext_info = None for getter in self.dependency_generators(): try: requirements, requires_python, summary = getter(candidate) except CandidateInfoNotFound: last_ext_info = sys.exc_info() continue break else: if last_ext_info is not None: raise last_ext_info[1].with_traceback(last_ext_info[2]) # type: ignore reqs = [parse_requirement(line) for line in requirements] if candidate.req.extras: # XXX: If the requirement has extras, add the original candidate # (without extras) as its dependency. This ensures the same package with # different extras resolve to the same version. self_req = dataclasses.replace(candidate.req, extras=None, marker=None) reqs.append(self_req) # Store the metadata on the candidate for caching candidate.requires_python = requires_python candidate.summary = summary return reqs, PySpecSet(requires_python), summary
def get_locked_candidates( self, section: Optional[str] = None ) -> Dict[str, Candidate]: if not self.lockfile_file.is_file(): return {} section = section or "default" result = {} for package in [dict(p) for p in self.lockfile.get("package", [])]: if section != "__all__" and section not in package["sections"]: continue version = package.get("version") if version: package["version"] = f"=={version}" package_name = package.pop("name") summary = package.pop("summary", None) dependencies = [ Requirement.from_req_dict(k, v) for k, v in package.pop("dependencies", {}).items() ] req = Requirement.from_req_dict(package_name, dict(package)) can = Candidate(req, self.environment, name=package_name, version=version) can.marker = req.marker can.requires_python = str(req.requires_python) can.dependencies = dependencies can.summary = summary can.hashes = { item["file"]: item["hash"] for item in self.lockfile["metadata"].get( f"{package_name} {version}", [] ) } or None result[identify(req)] = can if section in ("default", "__all__") and self.meta.name: result[safe_name(self.meta.name).lower()] = self.make_self_candidate(True) return result
def _find_candidates(self, requirement: Requirement) -> Iterable[Candidate]: for version, candidate in self._pypi_data.get(requirement.key, {}).items(): c = Candidate( requirement, self.environment, name=requirement.project_name, version=version, ) c.requires_python = candidate.get("requires_python", "") c.link = _FakeLink() yield c
def is_satisfied_by(self, requirement: Requirement, candidate: Candidate) -> bool: if not requirement.is_named: return not candidate.req.is_named and candidate.req.url == requirement.url if not candidate.version: candidate.get_metadata() if getattr(candidate, "_preferred", False) and not candidate._requires_python: candidate.requires_python = str( self.repository.get_dependencies(candidate)[1] ) allow_prereleases = requirement.allow_prereleases if allow_prereleases is None: allow_prereleases = self.allow_prereleases if allow_prereleases is None: # if not specified, should allow what `find_candidates()` returns allow_prereleases = True return requirement.specifier.contains( candidate.version, allow_prereleases ) and self.requires_python.is_subset(candidate.requires_python)
def find_candidates( self, requirement: Requirement, requires_python: PySpecSet = PySpecSet(), allow_prereleases: Optional[bool] = None, allow_all: bool = False, ) -> List[Candidate]: if allow_prereleases is None: allow_prereleases = requirement.allow_prereleases cans = [] for version, candidate in self._pypi_data.get(requirement.key, {}).items(): c = Candidate( requirement, self.environment, name=requirement.project_name, version=version, ) c.requires_python = candidate.get("requires_python", "") cans.append(c) sorted_cans = sorted( (c for c in cans if requirement.specifier.contains(c.version, allow_prereleases)), key=lambda c: c.version, reverse=True, ) if not allow_all: sorted_cans = [ can for can in sorted_cans if requires_python.is_subset(can.requires_python) ] if not sorted_cans and allow_prereleases is None: # No non-pre-releases is found, force pre-releases now sorted_cans = sorted( (c for c in cans if requirement.specifier.contains(c.version, True)), key=lambda c: c.version, reverse=True, ) return sorted_cans