def direct_url(self) -> dict[str, Any] | None: """PEP 610 direct_url.json data""" req = self.req if isinstance(req, VcsRequirement): if req.editable: assert self.ireq.source_dir return _filter_none({ "url": pip_shims.path_to_url(self.ireq.source_dir), "dir_info": { "editable": True }, "subdirectory": req.subdirectory, }) return _filter_none({ "url": url_without_fragments(req.repo), "vcs_info": _filter_none({ "vcs": req.vcs, "requested_revision": req.ref, "commit_id": self.revision, }), "subdirectory": req.subdirectory, }) elif isinstance(req, FileRequirement): if req.is_local_dir: return _filter_none({ "url": url_without_fragments(req.url), "dir_info": _filter_none({"editable": req.editable or None}), "subdirectory": req.subdirectory, }) url = expand_env_vars_in_auth( req.url.replace( "${PROJECT_ROOT}", self.environment.project.root.as_posix(). lstrip( # type: ignore "/"), )) with self.environment.get_finder() as finder: hash_cache = self.environment.project.make_hash_cache() hash_cache.session = finder.session # type: ignore return _filter_none({ "url": url_without_fragments(url), "archive_info": { "hash": hash_cache.get_hash(pip_shims.Link(url)).replace( ":", "=") }, "subdirectory": req.subdirectory, }) else: return None
def is_satisfied_by(self, requirement: Requirement, candidate: Candidate) -> bool: if isinstance(requirement, PythonRequirement): return is_python_satisfied_by(requirement, candidate) elif candidate.identify() in self.overrides: return True if not requirement.is_named: return not candidate.req.is_named and url_without_fragments( candidate.req.url) == url_without_fragments(requirement.url) version = candidate.version or candidate.metadata.version # Allow prereleases if: 1) it is not specified in the tool settings or # 2) the candidate doesn't come from PyPI index. allow_prereleases = (self.allow_prereleases in (True, None) or not candidate.req.is_named) return requirement.specifier.contains(version, allow_prereleases)
def _identify_candidate(self, candidate: Candidate) -> tuple: url = getattr(candidate.req, "url", None) return ( candidate.identify(), candidate.version if not url else None, url_without_fragments(url) if url else None, candidate.req.editable, )
def as_line(self) -> str: project_name = f"{self.project_name}" if self.project_name else "" extras = f"[{','.join(sorted(self.extras))}]" if self.extras else "" marker = self._format_marker() url = url_without_fragments(self.url) if self.editable: return f"-e {url}#egg={project_name}{extras}{marker}" delimiter = " @ " if project_name else "" return f"{project_name}{extras}{delimiter}{url}{marker}"
def _parse_url(self) -> None: if self.url.startswith("git@"): self.url = "ssh://" + self.url[4:].replace(":", "/") if not self.name: self._parse_name_from_url() if not self.name: raise RequirementError( "VCS requirement must provide a 'egg=' fragment.") self.repo = url_without_fragments(self.url)
def is_satisfied_by(self, requirement: Requirement, candidate: Candidate) -> bool: if not requirement.is_named: return not candidate.req.is_named and url_without_fragments( candidate.req.url) == url_without_fragments(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 = self.allow_prereleases if allow_prereleases is None: # if not specified, should allow what `find_candidates()` returns allow_prereleases = True requires_python = self.requires_python & requirement.requires_python return requirement.specifier.contains( candidate.version, allow_prereleases) and requires_python.is_subset( candidate.requires_python)
def as_line(self) -> str: project_name = f"{self.project_name}" if self.project_name else "" extras = f"[{','.join(sorted(self.extras))}]" if self.extras else "" marker = self._format_marker() url = url_without_fragments(self.url) if self.editable or self.subdirectory: fragments = f"egg={project_name}{extras}" if self.subdirectory: fragments = f"{fragments}&subdirectory={self.subdirectory}" return f"{'-e ' if self.editable else ''}{url}#{fragments}{marker}" delimiter = " @ " if project_name else "" return f"{project_name}{extras}{delimiter}{url}{marker}"
def _parse_url(self) -> None: if self.url.startswith("git@"): self.url = add_ssh_scheme_to_git_uri(self.url) if not self.name: self._parse_name_from_url() repo = url_without_fragments(self.url) ref = None parsed = urlparse.urlparse(repo) if "@" in parsed.path: path, ref = parsed.path.split("@", 1) repo = urlparse.urlunparse(parsed._replace(path=path)) self.repo, self.ref = repo, ref
def _parse_name_from_url(self) -> None: parsed = urlparse.urlparse(self.url) fragments = dict(urlparse.parse_qsl(parsed.fragment)) if "egg" in fragments: egg_info = urlparse.unquote(fragments["egg"]) name, extras = strip_extras(egg_info) self.name = name self.extras = extras if not self.name: filename = os.path.basename(url_without_fragments(self.url)) if filename.endswith(".whl"): self.name, self.version = parse_name_version_from_wheel(filename)
def _parse_url(self) -> None: vcs, url_no_vcs = self.url.split("+", 1) if url_no_vcs.startswith("git@"): url_no_vcs = add_ssh_scheme_to_git_uri(url_no_vcs) self.url = f"{vcs}+{url_no_vcs}" if not self.name: self._parse_name_from_url() repo = url_without_fragments(url_no_vcs) ref = None parsed = urlparse.urlparse(repo) if "@" in parsed.path: path, ref = parsed.path.split("@", 1) repo = urlparse.urlunparse(parsed._replace(path=path)) self.repo, self.ref = repo, ref
def _parse_url(self) -> None: if self.url.startswith("git@"): self.url = add_ssh_scheme_to_git_uri(self.url) if not self.name: self._parse_name_from_url() if not self.name: raise RequirementError("VCS requirement must provide a 'egg=' fragment.") repo = url_without_fragments(self.url) ref = None parsed = urlparse.urlparse(repo) if "@" in parsed.path: path, ref = parsed.path.split("@", 1) repo = urlparse.urlunparse(parsed._replace(path=path)) self.repo, self.ref = repo, ref
def _parse_url(self) -> None: vcs, url_no_vcs = self.url.split("+", 1) if url_no_vcs.startswith("git@"): url_no_vcs = add_ssh_scheme_to_git_uri(url_no_vcs) self.url = f"{vcs}+{url_no_vcs}" if not self.name: self._parse_name_from_url() repo = url_without_fragments(url_no_vcs) ref: str | None = None parsed = urlparse.urlparse(url_no_vcs) fragments = dict(urlparse.parse_qsl(parsed.fragment)) if "subdirectory" in fragments: self.subdirectory = fragments["subdirectory"] if "@" in parsed.path: path, ref = parsed.path.split("@", 1) repo = urlparse.urlunparse(parsed._replace(path=path)) self.repo, self.ref = repo, ref # type: ignore
def _parse_name_from_url(self) -> None: parsed = urlparse.urlparse(self.url) fragments = dict(urlparse.parse_qsl(parsed.fragment)) if "egg" in fragments: egg_info = urlparse.unquote(fragments["egg"]) name, extras = strip_extras(egg_info) self.name = name self.extras = extras if not self.name: filename = os.path.basename(url_without_fragments(self.url)) if filename.endswith(".whl"): self.name, self.version = parse_name_version_from_wheel(filename) else: match = _egg_info_re.match(filename) # Filename is like `<name>-<version>.tar.gz`, where name will be # extracted and version will be left to be determined from the metadata. if match: self.name = match.group(1)