From 9541a45bf40424a2e2f6fb63b442fea7aba37af6 Mon Sep 17 00:00:00 2001 From: Arun Babu Neelicattu Date: Sun, 24 Mar 2024 17:55:37 +0100 Subject: [PATCH] utils/env: use isolated build for build.py envs --- src/poetry/utils/env/__init__.py | 22 ++++++++-------- tests/utils/env/test_env.py | 44 +++++++++++++++----------------- 2 files changed, 31 insertions(+), 35 deletions(-) diff --git a/src/poetry/utils/env/__init__.py b/src/poetry/utils/env/__init__.py index e99abda922f..b460a545595 100644 --- a/src/poetry/utils/env/__init__.py +++ b/src/poetry/utils/env/__init__.py @@ -35,7 +35,8 @@ from collections.abc import Iterator from cleo.io.io import IO - from poetry.core.poetry import Poetry as CorePoetry + + from poetry.poetry import Poetry @contextmanager @@ -56,7 +57,7 @@ def ephemeral_environment( @contextmanager def build_environment( - poetry: CorePoetry, env: Env | None = None, io: IO | None = None + poetry: Poetry, env: Env | None = None, io: IO | None = None ) -> Iterator[Env]: """ If a build script is specified for the project, there could be additional build @@ -66,7 +67,10 @@ def build_environment( environment is returned. """ if not env or poetry.package.build_script: - with ephemeral_environment(executable=env.python if env else None) as venv: + with ephemeral_environment( + executable=env.python if env else None, + flags={"no-pip": True, "no-setuptools": True, "no-wheel": True}, + ) as venv: if io: requires = [ f"{requirement}" @@ -78,16 +82,10 @@ def build_environment( f" {', '.join(requires)}" ) - output = venv.run_pip( - "install", - "--disable-pip-version-check", - "--ignore-installed", - "--no-input", - *poetry.pyproject.build_system.requires, - ) + from poetry.utils.isolated_build import IsolatedEnv - if io and io.is_debug() and output: - io.write_error(output) + isolated_env = IsolatedEnv(venv, poetry.pool) + isolated_env.install(poetry.pyproject.build_system.requires) yield venv else: diff --git a/tests/utils/env/test_env.py b/tests/utils/env/test_env.py index d631e151156..e3ee2f2c473 100644 --- a/tests/utils/env/test_env.py +++ b/tests/utils/env/test_env.py @@ -24,13 +24,17 @@ from poetry.utils.env import SystemEnv from poetry.utils.env import VirtualEnv from poetry.utils.env import build_environment +from poetry.utils.env import ephemeral_environment if TYPE_CHECKING: + from typing import Iterator + from pytest_mock import MockerFixture from poetry.poetry import Poetry from tests.types import FixtureDirGetter + from tests.types import SetProjectContext MINIMAL_SCRIPT = """\ @@ -463,35 +467,29 @@ def test_env_finds_fallback_executables_for_generic_env( @pytest.fixture -def extended_without_setup_poetry(fixture_dir: FixtureDirGetter) -> Poetry: - poetry = Factory().create_poetry(fixture_dir("extended_project_without_setup")) - - return poetry +def extended_without_setup_poetry( + fixture_dir: FixtureDirGetter, set_project_context: SetProjectContext +) -> Iterator[Poetry]: + with set_project_context("extended_project_without_setup") as cwd: + yield Factory().create_poetry(cwd) def test_build_environment_called_build_script_specified( - mocker: MockerFixture, extended_without_setup_poetry: Poetry, tmp_path: Path + mocker: MockerFixture, + extended_without_setup_poetry: Poetry, ) -> None: - project_env = MockEnv(path=tmp_path / "project") - ephemeral_env = MockEnv(path=tmp_path / "ephemeral") + patched_install = mocker.patch("poetry.utils.isolated_build.IsolatedEnv.install") - mocker.patch( - "poetry.utils.env.ephemeral_environment" - ).return_value.__enter__.return_value = ephemeral_env + with ephemeral_environment() as project_env: + import poetry.utils.env + + spy = mocker.spy(poetry.utils.env, "ephemeral_environment") + + with build_environment(extended_without_setup_poetry, project_env): + assert patched_install.call_count == 1 + assert patched_install.call_args == mocker.call(["poetry-core", "cython"]) - with build_environment(extended_without_setup_poetry, project_env) as env: - assert env == ephemeral_env - assert env.executed == [ # type: ignore[attr-defined] - [ - str(sys.executable), - str(env.pip_embedded), - "install", - "--disable-pip-version-check", - "--ignore-installed", - "--no-input", - *extended_without_setup_poetry.pyproject.build_system.requires, - ] - ] + assert spy.call_count == 1 def test_build_environment_not_called_without_build_script_specified(