def test_url_to_path(url, win_expected, non_win_expected): if sys.platform == "win32": expected_path = win_expected else: expected_path = non_win_expected if expected_path is None: with pytest.raises(ValueError): url_to_path(url) else: assert url_to_path(url) == Path(expected_path)
def create_package_from_pep610(cls, distribution: metadata.Distribution) -> Package: path = Path(str(distribution._path)) # type: ignore[attr-defined] source_type = None source_url = None source_reference = None source_resolved_reference = None develop = False url_reference = json.loads( path.joinpath("direct_url.json").read_text(encoding="utf-8") ) if "archive_info" in url_reference: # File or URL distribution if url_reference["url"].startswith("file:"): # File distribution source_type = "file" source_url = url_to_path(url_reference["url"]).as_posix() else: # URL distribution source_type = "url" source_url = url_reference["url"] elif "dir_info" in url_reference: # Directory distribution source_type = "directory" source_url = url_to_path(url_reference["url"]).as_posix() develop = url_reference["dir_info"].get("editable", False) elif "vcs_info" in url_reference: # VCS distribution source_type = url_reference["vcs_info"]["vcs"] source_url = url_reference["url"] source_resolved_reference = url_reference["vcs_info"]["commit_id"] source_reference = url_reference["vcs_info"].get( "requested_revision", source_resolved_reference ) package = Package( distribution.metadata["name"], distribution.metadata["version"], source_type=source_type, source_url=source_url, source_reference=source_reference, source_resolved_reference=source_resolved_reference, develop=develop, ) package.description = distribution.metadata.get( # type: ignore[attr-defined] "summary", "", ) return package
def pip_install( path: Union["Path", Link], environment: "Env", editable: bool = False, deps: bool = False, upgrade: bool = False, ) -> Union[int, str]: path = url_to_path(path.url) if isinstance(path, Link) else path is_wheel = path.suffix == ".whl" # We disable version check here as we are already pinning to version available in # either the virtual environment or the virtualenv package embedded wheel. Version # checks are a wasteful network call that adds a lot of wait time when installing a # lot of packages. args = [ "install", "--disable-pip-version-check", "--prefix", str(environment.path) ] if not is_wheel: args.insert(1, "--use-pep517") if upgrade: args.append("--upgrade") if not deps: args.append("--no-deps") if editable: if not path.is_dir(): raise PoetryException( "Cannot install non directory dependencies in editable mode") args.append("-e") args.append(str(path)) try: return environment.run_pip(*args) except EnvCommandError as e: if sys.version_info < (3, 7) and not is_wheel: # Under certain Python3.6 installs vendored pip wheel does not contain # zip-safe pep517 lib. In this cases we create an isolated ephemeral virtual # environment. with ephemeral_environment(executable=environment.python, with_pip=True, with_setuptools=True) as env: return environment.run( *env.get_pip_command(), *args, env={ **os.environ, "PYTHONPATH": str(env.purelib) }, ) raise PoetryException(f"Failed to install {path.as_posix()}") from e
def _validate_archive_hash(archive: Path | Link, package: Package) -> str: archive_path = (url_to_path(archive.url) if isinstance(archive, Link) else archive) file_dep = FileDependency( package.name, archive_path, ) archive_hash = "sha256:" + file_dep.hash() known_hashes = {f["hash"] for f in package.files} if archive_hash not in known_hashes: raise RuntimeError( f"Hash for {package} from archive {archive_path.name} not found in" f" known hashes (was: {archive_hash})") return archive_hash
def _download_link(self, operation, link): package = operation.package archive = self._chef.get_cached_archive_for_link(link) if archive is link: # No cached distributions was found, so we download and prepare it try: archive = self._download_archive(operation, link) except BaseException: cache_directory = self._chef.get_cache_directory_for_link(link) cached_file = cache_directory.joinpath(link.filename) # We can't use unlink(missing_ok=True) because it's not available # in pathlib2 for Python 2.7 if cached_file.exists(): cached_file.unlink() raise # TODO: Check readability of the created archive if not link.is_wheel: archive = self._chef.prepare(archive) if package.files: hashes = {f["hash"] for f in package.files} hash_types = {h.split(":")[0] for h in hashes} archive_hashes = set() archive_path = (url_to_path(archive.url) if isinstance( archive, Link) else archive) for hash_type in hash_types: archive_hashes.add("{}:{}".format( hash_type, FileDependency(package.name, archive_path).hash(hash_type), )) if archive_hashes.isdisjoint(hashes): raise RuntimeError( "Invalid hashes ({}) for {} using archive {}. Expected one of {}." .format( ", ".join(sorted(archive_hashes)), package, archive_path.name, ", ".join(sorted(hashes)), )) return archive
def pip_install( path: Path | Link, environment: Env, editable: bool = False, deps: bool = False, upgrade: bool = False, ) -> int | str: path = url_to_path(path.url) if isinstance(path, Link) else path is_wheel = path.suffix == ".whl" # We disable version check here as we are already pinning to version available in # either the virtual environment or the virtualenv package embedded wheel. Version # checks are a wasteful network call that adds a lot of wait time when installing a # lot of packages. args = [ "install", "--disable-pip-version-check", "--prefix", str(environment.path) ] if not is_wheel: args.insert(1, "--use-pep517") if upgrade: args.append("--upgrade") if not deps: args.append("--no-deps") if editable: if not path.is_dir(): raise PoetryException( "Cannot install non directory dependencies in editable mode") args.append("-e") args.append(str(path)) try: return environment.run_pip(*args) except EnvCommandError as e: raise PoetryException(f"Failed to install {path.as_posix()}") from e
def create_from_pep_508(cls, name: str, relative_to: Path | None = None) -> Dependency: """ Resolve a PEP-508 requirement string to a `Dependency` instance. If a `relative_to` path is specified, this is used as the base directory if the identified dependency is of file or directory type. """ from poetry.core.packages.url_dependency import URLDependency from poetry.core.packages.utils.link import Link from poetry.core.packages.utils.utils import is_archive_file from poetry.core.packages.utils.utils import is_installable_dir from poetry.core.packages.utils.utils import is_url from poetry.core.packages.utils.utils import path_to_url from poetry.core.packages.utils.utils import strip_extras from poetry.core.packages.utils.utils import url_to_path from poetry.core.packages.vcs_dependency import VCSDependency from poetry.core.utils.patterns import wheel_file_re from poetry.core.vcs.git import ParsedUrl from poetry.core.version.requirements import Requirement # Removing comments parts = name.split(" #", 1) name = parts[0].strip() if len(parts) > 1: rest = parts[1] if " ;" in rest: name += " ;" + rest.split(" ;", 1)[1] req = Requirement(name) name = req.name link = None if is_url(name): link = Link(name) elif req.url: link = Link(req.url) else: path_str = os.path.normpath(os.path.abspath(name)) p, extras = strip_extras(path_str) if os.path.isdir(p) and (os.path.sep in name or name.startswith(".")): if not is_installable_dir(p): raise ValueError( f"Directory {name!r} is not installable. File 'setup.py' " "not found.") link = Link(path_to_url(p)) elif is_archive_file(p): link = Link(path_to_url(p)) # it's a local file, dir, or url if link: is_file_uri = link.scheme == "file" is_relative_uri = is_file_uri and re.search(r"\.\./", link.url) # Handle relative file URLs if is_file_uri and is_relative_uri: path = Path(link.path) if relative_to: path = relative_to / path link = Link(path_to_url(path)) # wheel file version = None if link.is_wheel: m = wheel_file_re.match(link.filename) if not m: raise ValueError(f"Invalid wheel name: {link.filename}") name = m.group("name") version = m.group("ver") dep: Dependency | None = None if link.scheme.startswith("git+"): url = ParsedUrl.parse(link.url) dep = VCSDependency( name, "git", url.url, rev=url.rev, directory=url.subdirectory, extras=req.extras, ) elif link.scheme == "git": dep = VCSDependency(name, "git", link.url_without_fragment, extras=req.extras) elif link.scheme in ["http", "https"]: dep = URLDependency(name, link.url, extras=req.extras) elif is_file_uri: # handle RFC 8089 references path = url_to_path(req.url) dep = _make_file_or_dir_dep(name=name, path=path, base=relative_to, extras=req.extras) else: with suppress(ValueError): # this is a local path not using the file URI scheme dep = _make_file_or_dir_dep( name=name, path=Path(req.url), base=relative_to, extras=req.extras, ) if dep is None: dep = Dependency(name, version or "*", extras=req.extras) if version: dep._constraint = parse_constraint(version) else: constraint: VersionConstraint | str if req.pretty_constraint: constraint = req.constraint else: constraint = "*" dep = Dependency(name, constraint, extras=req.extras) if req.marker: dep.marker = req.marker return dep
def test_url_to_path_path_to_url_symmetry_win(): path = r"C:\tmp\file" assert url_to_path(path_to_url(path)) == Path(path) unc_path = r"\\unc\share\path" assert url_to_path(path_to_url(unc_path)) == Path(unc_path)