Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

utils/env: use isolated build for build.py envs #9227

Merged
merged 1 commit into from
Mar 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 10 additions & 12 deletions src/poetry/utils/env/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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"<c1>{requirement}</c1>"
Expand All @@ -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:
Expand Down
44 changes: 21 additions & 23 deletions tests/utils/env/test_env.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 = """\

Expand Down Expand Up @@ -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(
Expand Down