def parse_requirement(line: str, editable: bool = False) -> Requirement: m = VCS_REQ.match(line) if m is not None: r = VcsRequirement.parse(line, m.groupdict()) else: try: r = NamedRequirement.parse(line) # type: Requirement except RequirementParseError as e: m = FILE_REQ.match(line) if m is not None: r = FileRequirement.parse(line, m.groupdict()) else: raise RequirementError(str(e)) from None else: if r.url: r = FileRequirement(name=r.name, url=r.url, extras=r.extras) if editable: if r.is_vcs or r.is_file_or_url and r.is_local_dir: r.editable = True else: raise RequirementError( "Editable requirement is only supported for VCS link" " or local directory.") return r
def parse_requirement(line: str, editable: bool = False) -> Requirement: m = _vcs_req_re.match(line) r: Requirement if m is not None: r = VcsRequirement.create(**m.groupdict()) else: try: package_req = PackageRequirement(line) # type: ignore except (RequirementParseError, InvalidRequirement) as e: m = _file_req_re.match(line) if m is None: raise RequirementError(str(e)) from None r = FileRequirement.create(**m.groupdict()) else: r = Requirement.from_pkg_requirement(package_req) if editable: if r.is_vcs or r.is_file_or_url and r.is_local_dir: # type: ignore assert isinstance(r, FileRequirement) r.editable = True else: raise RequirementError( "Editable requirement is only supported for VCS link" " or local directory." ) return r
def _check_installable(self) -> None: if not (self.path.joinpath("setup.py").exists() or self.path.joinpath("pyproject.toml").exists()): raise RequirementError( f"The local path '{self.path}' is not installable.") result = Setup.from_directory(self.path.absolute()) self.name = result.name
def __post_init__(self) -> None: super().__post_init__() self._parse_url() if self.path and not self.path.exists(): raise RequirementError(f"The local path {self.path} does not exist.") if self.is_local_dir: self._check_installable()
def get_metadata(self, allow_all_wheels: bool = True) -> Optional[Metadata]: """Get the metadata of the candidate. For editable requirements, egg info are produced, otherwise a wheel is built. """ if self.metadata is not None: return self.metadata ireq = self.ireq if self.link and not ireq.link: ireq.link = self.link built = self.environment.build(ireq, self.hashes, allow_all_wheels) if self.req.editable: if not self.req.is_local_dir and not self.req.is_vcs: raise RequirementError( "Editable installation is only supported for " "local directory and VCS location." ) sdist = get_sdist(built) self.metadata = sdist.metadata if sdist else None else: # It should be a wheel path. self.wheel = Wheel(built) self.metadata = self.wheel.metadata if not self.name: self.name = self.metadata.name self.req.name = self.name if not self.version: self.version = self.metadata.version self.link = ireq.link return self.metadata
def marker(self, value) -> None: try: m = self._marker = get_marker(value) if not m: self.marker_no_python, self.requires_python = None, PySpecSet() else: self.marker_no_python, self.requires_python = m.split_pyspec() except InvalidMarker as e: raise RequirementError("Invalid marker: %s" % str(e)) from None
def _check_installable(self) -> None: if not (self.path.joinpath("setup.py").exists() or self.path.joinpath("pyproject.toml").exists()): raise RequirementError( f"The local path '{self.path}' is not installable.") result = SetupReader.read_from_directory( self.path.absolute().as_posix()) # TODO: Assign a temp name for PEP 517 local package. self.name = result["name"]
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 __init__(self, **kwargs): super().__init__(**kwargs) self.path = Path(self.path) if self.path else None self.version = None self._parse_url() if self.path and not self.path.exists(): raise RequirementError(f"The local path {self.path} does not exist.") if self.is_local_dir: self._check_installable()
def parse( cls, line: str, parsed: Optional[Dict[str, Optional[str]]] = None ) -> "NamedRequirement": r = cls() try: PackageRequirement.__init__(r, line) r.marker = get_marker(r.marker) except InvalidMarker as e: raise RequirementError("Invalid marker: %s" % str(e)) from None return r
def __init__(self, **kwargs: Any) -> None: super().__init__(**kwargs) self.path = (Path(str(self.path).replace("${PROJECT_ROOT}", ".")) if self.path else None) self.version = None self._parse_url() if self.path and not self.path.exists(): raise RequirementError( f"The local path {self.path} does not exist.") if self.is_local_dir: self._check_installable()
def as_ireq(self, **kwargs: Any) -> InstallRequirement: line_for_req = self.as_line() try: if self.editable: line_for_req = line_for_req[3:].strip() ireq = install_req_from_editable(line_for_req, **kwargs) else: ireq = install_req_from_line(line_for_req, **kwargs) except Exception as e: raise RequirementError(e) ireq.req = self # type: ignore return ireq
def create(cls: Type[T], **kwargs: Any) -> T: if "marker" in kwargs: try: kwargs["marker"] = get_marker(kwargs["marker"]) except InvalidMarker as e: raise RequirementError("Invalid marker: %s" % str(e)) from None if "extras" in kwargs and isinstance(kwargs["extras"], str): kwargs["extras"] = tuple( e.strip() for e in kwargs["extras"][1:-1].split(",")) version = kwargs.pop("version", None) if version: kwargs["specifier"] = get_specifier(version) return cls(**kwargs)
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 get_metadata(self, allow_all_wheels: bool = True, raising: bool = False) -> Optional[Metadata]: """Get the metadata of the candidate. For editable requirements, egg info are produced, otherwise a wheel is built. If raising is True, error will pop when the package fails to build. """ if self.metadata is not None: return self.metadata ireq = self.ireq if self.link and not ireq.link: ireq.link = self.link try: built = self.environment.build(ireq, self.hashes, allow_all_wheels) except BuildError: if raising: raise termui.logger.warn( "Failed to build package, try parsing project files.") meta_dict = SetupReader.read_from_directory( ireq.unpacked_source_directory) meta_dict.update(summary="UNKNOWN") meta_dict["requires_python"] = meta_dict.pop( "python_requires", None) self.metadata = Namespace(**meta_dict) else: if self.req.editable: if not self.req.is_local_dir and not self.req.is_vcs: raise RequirementError( "Editable installation is only supported for " "local directory and VCS location.") sdist = get_sdist(built) self.metadata = sdist.metadata if sdist else None else: # It should be a wheel path. self.wheel = Wheel(built) self.metadata = self.wheel.metadata if not self.name: self.name = self.metadata.name self.req.name = self.name if not self.version: self.version = self.metadata.version self.link = ireq.link return self.metadata