Commit 711ddd8c by David Hotham Committed by Randy Döring

Have the Chef return Paths instead of Links

parent d9eab03d
......@@ -6,13 +6,12 @@ import json
from pathlib import Path
from typing import TYPE_CHECKING
from poetry.core.packages.utils.link import Link
from poetry.installation.chooser import InvalidWheelName
from poetry.installation.chooser import Wheel
if TYPE_CHECKING:
from poetry.core.packages.utils.link import Link
from poetry.config.config import Config
from poetry.utils.env import Env
......@@ -25,19 +24,19 @@ class Chef:
Path(config.get("cache-dir")).expanduser().joinpath("artifacts")
)
def get_cached_archive_for_link(self, link: Link) -> Link | None:
def get_cached_archive_for_link(self, link: Link) -> Path | None:
archives = self.get_cached_archives_for_link(link)
if not archives:
return None
candidates: list[tuple[float | None, Link]] = []
candidates: list[tuple[float | None, Path]] = []
for archive in archives:
if not archive.is_wheel:
if archive.suffix != ".whl":
candidates.append((float("inf"), archive))
continue
try:
wheel = Wheel(archive.filename)
wheel = Wheel(archive.name)
except InvalidWheelName:
continue
......@@ -53,16 +52,16 @@ class Chef:
return min(candidates)[1]
def get_cached_archives_for_link(self, link: Link) -> list[Link]:
def get_cached_archives_for_link(self, link: Link) -> list[Path]:
cache_dir = self.get_cache_directory_for_link(link)
archive_types = ["whl", "tar.gz", "tar.bz2", "bz2", "zip"]
links = []
paths = []
for archive_type in archive_types:
for archive in cache_dir.glob(f"*.{archive_type}"):
links.append(Link(archive.as_uri()))
paths.append(Path(archive))
return links
return paths
def get_cache_directory_for_link(self, link: Link) -> Path:
key_parts = {"url": link.url_without_fragment}
......
......@@ -17,7 +17,6 @@ from typing import cast
from cleo.io.null_io import NullIO
from poetry.core.packages.file_dependency import FileDependency
from poetry.core.packages.utils.link import Link
from poetry.core.packages.utils.utils import url_to_path
from poetry.core.pyproject.toml import PyProjectTOML
from poetry.installation.chef import Chef
......@@ -114,7 +113,7 @@ class Executor:
return self
def pip_install(
self, req: Path | Link, upgrade: bool = False, editable: bool = False
self, req: Path, upgrade: bool = False, editable: bool = False
) -> int:
try:
pip_install(req, self._env, upgrade=upgrade, editable=editable)
......@@ -463,7 +462,7 @@ class Executor:
if package.source_type == "git":
return self._install_git(operation)
archive: Link | Path
archive: Path
if package.source_type == "file":
archive = self._prepare_file(operation)
elif package.source_type == "url":
......@@ -606,15 +605,15 @@ class Executor:
return status_code
def _download(self, operation: Install | Update) -> Link | Path:
def _download(self, operation: Install | Update) -> Path:
link = self._chooser.choose_for(operation.package)
return self._download_link(operation, link)
def _download_link(self, operation: Install | Update, link: Link) -> Link | Path:
def _download_link(self, operation: Install | Update, link: Link) -> Path:
package = operation.package
archive: Link | Path | None
archive: Path | None
archive = self._chef.get_cached_archive_for_link(link)
if archive is None:
# No cached distributions was found, so we download and prepare it
......@@ -638,20 +637,14 @@ class Executor:
return archive
@staticmethod
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,
)
def _validate_archive_hash(archive: Path, package: Package) -> str:
file_dep = FileDependency(package.name, archive)
archive_hash: str = "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"Hash for {package} from archive {archive.name} not found in"
f" known hashes (was: {archive_hash})"
)
......
......@@ -2,9 +2,6 @@ from __future__ import annotations
from typing import TYPE_CHECKING
from poetry.core.packages.utils.link import Link
from poetry.core.packages.utils.utils import url_to_path
from poetry.exceptions import PoetryException
from poetry.utils.env import EnvCommandError
......@@ -16,13 +13,12 @@ if TYPE_CHECKING:
def pip_install(
path: Path | Link,
path: Path,
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
......
......@@ -23,11 +23,11 @@ if TYPE_CHECKING:
[
(
"https://files.python-poetry.org/demo-0.1.0.tar.gz",
"file:///foo/demo-0.1.0-cp38-cp38-macosx_10_15_x86_64.whl",
"/cache/demo-0.1.0-cp38-cp38-macosx_10_15_x86_64.whl",
),
(
"https://example.com/demo-0.1.0-cp38-cp38-macosx_10_15_x86_64.whl",
"file:///foo/demo-0.1.0-cp38-cp38-macosx_10_15_x86_64.whl",
"/cache/demo-0.1.0-cp38-cp38-macosx_10_15_x86_64.whl",
),
],
)
......@@ -50,16 +50,16 @@ def test_get_cached_archive_for_link(
chef,
"get_cached_archives_for_link",
return_value=[
Link("file:///foo/demo-0.1.0-py2.py3-none-any"),
Link("file:///foo/demo-0.1.0.tar.gz"),
Link("file:///foo/demo-0.1.0-cp38-cp38-macosx_10_15_x86_64.whl"),
Link("file:///foo/demo-0.1.0-cp37-cp37-macosx_10_15_x86_64.whl"),
Path("/cache/demo-0.1.0-py2.py3-none-any"),
Path("/cache/demo-0.1.0.tar.gz"),
Path("/cache/demo-0.1.0-cp38-cp38-macosx_10_15_x86_64.whl"),
Path("/cache/demo-0.1.0-cp37-cp37-macosx_10_15_x86_64.whl"),
],
)
archive = chef.get_cached_archive_for_link(Link(link))
assert Link(cached) == archive
assert Path(cached) == archive
def test_get_cached_archives_for_link(config: Config, mocker: MockerFixture):
......@@ -82,9 +82,7 @@ def test_get_cached_archives_for_link(config: Config, mocker: MockerFixture):
)
assert archives
assert set(archives) == {
Link(path.as_uri()) for path in distributions.glob("demo-0.1.0*")
}
assert set(archives) == {Path(path) for path in distributions.glob("demo-0.1.0*")}
def test_get_cache_directory_for_link(config: Config, config_cache_dir: Path):
......
......@@ -436,11 +436,8 @@ def test_executor_should_not_write_pep610_url_references_for_cached_package(
config: Config,
io: BufferedIO,
):
link_cached = Link(
fixture_dir("distributions")
.joinpath("demo-0.1.0-py2.py3-none-any.whl")
.as_uri()
)
link_cached = fixture_dir("distributions") / "demo-0.1.0-py2.py3-none-any.whl"
mocker.patch(
"poetry.installation.executor.Executor._download", return_value=link_cached
)
......@@ -564,12 +561,8 @@ def test_executor_should_use_cached_link_and_hash(
mocker: MockerFixture,
fixture_dir: FixtureDirGetter,
):
# Produce a file:/// URI that is a valid link
link_cached = Link(
fixture_dir("distributions")
.joinpath("demo-0.1.0-py2.py3-none-any.whl")
.as_uri()
)
link_cached = fixture_dir("distributions") / "demo-0.1.0-py2.py3-none-any.whl"
mocker.patch(
"poetry.installation.chef.Chef.get_cached_archive_for_link",
return_value=link_cached,
......
......@@ -6,9 +6,6 @@ from typing import TYPE_CHECKING
import pytest
from poetry.core.packages.utils.link import Link
from poetry.core.packages.utils.utils import path_to_url
from poetry.utils.pip import pip_install
......@@ -28,17 +25,6 @@ def test_pip_install_successful(
assert "Successfully installed demo-0.1.0" in result
def test_pip_install_link(
tmp_dir: str, tmp_venv: VirtualEnv, fixture_dir: FixtureDirGetter
):
file_path = Link(
path_to_url(fixture_dir("distributions/demo-0.1.0-py2.py3-none-any.whl"))
)
result = pip_install(file_path, tmp_venv)
assert "Successfully installed demo-0.1.0" in result
def test_pip_install_with_keyboard_interrupt(
tmp_dir: str,
tmp_venv: VirtualEnv,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment