diff --git a/src/poetry/utils/pip.py b/src/poetry/utils/pip.py index 5e6d5835bc6..6367f647507 100644 --- a/src/poetry/utils/pip.py +++ b/src/poetry/utils/pip.py @@ -31,7 +31,7 @@ def pip_install( # lot of packages. args = ["install", "--disable-pip-version-check", "--prefix", str(environment.path)] - if not is_wheel: + if not is_wheel and not editable: args.insert(1, "--use-pep517") if upgrade: diff --git a/tests/conftest.py b/tests/conftest.py index 6dee1e1b032..8fc6c88d154 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,5 +1,6 @@ from __future__ import annotations +import contextlib import logging import os import re @@ -244,29 +245,45 @@ def _pep517_metadata(cls: PackageInfo, path: Path) -> PackageInfo: ) -@pytest.fixture -def environ() -> Iterator[None]: +@contextlib.contextmanager +def isolated_environment( + environ: dict[str, Any] | None = None, clear: bool = False +) -> Iterator[None]: original_environ = dict(os.environ) + if clear: + os.environ.clear() + + if environ: + os.environ.update(environ) + yield os.environ.clear() os.environ.update(original_environ) +@pytest.fixture +def environ() -> Iterator[None]: + with isolated_environment(): + yield + + +@pytest.fixture +def clean_environ() -> Iterator[None]: + with isolated_environment(clear=True): + yield + + @pytest.fixture(autouse=True) def isolate_environ() -> Iterator[None]: """Ensure the environment is isolated from user configuration.""" - original_environ = dict(os.environ) - - for var in os.environ: - if var.startswith("POETRY_"): - del os.environ[var] + with isolated_environment(): + for var in os.environ: + if var.startswith("POETRY_"): + del os.environ[var] - yield - - os.environ.clear() - os.environ.update(original_environ) + yield @pytest.fixture(autouse=True) diff --git a/tests/fixtures/extended_project/build.py b/tests/fixtures/extended_project/build.py index e69de29bb2d..7a12c342719 100644 --- a/tests/fixtures/extended_project/build.py +++ b/tests/fixtures/extended_project/build.py @@ -0,0 +1,12 @@ +from __future__ import annotations + +from pathlib import Path +from typing import Any + + +def build(setup_kwargs: dict[str, Any]): + assert setup_kwargs["name"] == "extended-project" + assert setup_kwargs["version"] == "1.2.3" + + dynamic_module = Path(__file__).parent / "extended_project" / "built.py" + dynamic_module.write_text("# Generated by build.py") diff --git a/tests/fixtures/extended_project/pyproject.toml b/tests/fixtures/extended_project/pyproject.toml index ecb7deb9107..15b72917b0f 100644 --- a/tests/fixtures/extended_project/pyproject.toml +++ b/tests/fixtures/extended_project/pyproject.toml @@ -20,8 +20,10 @@ classifiers = [ "Topic :: Software Development :: Libraries :: Python Modules" ] -build = "build.py" +[tool.poetry.build] +script = "build.py" +generate-setup-file = true # Requirements [tool.poetry.dependencies] -python = "~2.7 || ^3.4" +python = "^3.7" diff --git a/tests/masonry/builders/test_editable_builder.py b/tests/masonry/builders/test_editable_builder.py index cbd91f4dcdd..5b6bb6eb7c0 100644 --- a/tests/masonry/builders/test_editable_builder.py +++ b/tests/masonry/builders/test_editable_builder.py @@ -12,9 +12,12 @@ from poetry.factory import Factory from poetry.masonry.builders.editable import EditableBuilder +from poetry.repositories.installed_repository import InstalledRepository +from poetry.utils.env import EnvCommandError from poetry.utils.env import EnvManager from poetry.utils.env import MockEnv from poetry.utils.env import VirtualEnv +from poetry.utils.env import ephemeral_environment if TYPE_CHECKING: @@ -203,6 +206,41 @@ def test_builder_falls_back_on_setup_and_pip_for_packages_with_build_scripts( assert [] == env.executed +def test_builder_setup_generation_runs_with_pip_editable( + tmp_dir: str, clean_environ: None +): + # create an isolated copy of the project + fixture = Path(__file__).parent.parent.parent / "fixtures" / "extended_project" + extended_project = Path(tmp_dir) / "extended_project" + + shutil.copytree(fixture, extended_project) + assert extended_project.exists() + + poetry = Factory().create_poetry(extended_project) + + # we need a venv with setuptools since we are verifying setup.py builds + with ephemeral_environment(flags={"no-setuptools": False}) as venv: + builder = EditableBuilder(poetry, venv, NullIO()) + builder.build() + + # is the package installed? + repository = InstalledRepository.load(venv) + assert repository.package("extended-project", "1.2.3") + + # check for the module built by build.py + try: + output = venv.run_python_script( + "from extended_project import built; print(built.__file__)" + ).strip() + except EnvCommandError: + pytest.fail("Unable to import built module") + else: + built_py = Path(output) + + # ensure the package was installed as editable + assert built_py == extended_project / "extended_project" / "built.py" + + def test_builder_installs_proper_files_when_packages_configured( project_with_include: Poetry, tmp_venv: VirtualEnv ):