From cc3b57a526e3466d548ff20dd81e819abd488e32 Mon Sep 17 00:00:00 2001 From: Brandon White Date: Thu, 13 Aug 2026 17:26:39 -0500 Subject: [PATCH] fix: expand editable path dependencies under Poetry >= 2.3.0 Poetry 2.3.0 changed the default of installer.re-resolve from true to false (python-poetry/poetry#10622). On that path, Installer._do_install sources its install targets from Locker.locked_packages() rather than Locker.locked_repository(). VenvBundler's CustomLocker only overrode locked_repository() to clear develop mode, so develop = true path dependencies were bundled as editable installs, leaving a .pth file pointing at the original source tree and making the bundle non-portable. Override locked_packages() as well, sharing the develop-clearing loop between both overrides. The existing test did not catch this because the simple_project_with_editable_dep fixture's lock file was lock-version 1.0, and Poetry forces re-resolution for lock files older than 2.1, so only the working path was ever exercised. Regenerate that fixture to lock-version 2.1 (content-hash unchanged) and parametrize the test over both installer.re-resolve values. --- .../bundlers/venv_bundler.py | 18 ++++++++++++++++-- tests/bundlers/test_venv_bundler.py | 9 ++++++++- .../poetry.lock | 17 ++++++++++------- 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/poetry_plugin_bundle/bundlers/venv_bundler.py b/src/poetry_plugin_bundle/bundlers/venv_bundler.py index 1f7cbb9..37ca710 100644 --- a/src/poetry_plugin_bundle/bundlers/venv_bundler.py +++ b/src/poetry_plugin_bundle/bundlers/venv_bundler.py @@ -6,11 +6,13 @@ if TYPE_CHECKING: + from collections.abc import Iterable from pathlib import Path from cleo.io.io import IO from cleo.io.outputs.section_output import SectionOutput from packaging.utils import NormalizedName + from poetry.packages.transitive_package_info import TransitivePackageInfo from poetry.poetry import Poetry from poetry.repositories.lockfile_repository import LockfileRepository from poetry.utils.env import Env @@ -149,12 +151,24 @@ def create_venv_at_path( self._write(io, f"{message}: Installing dependencies") class CustomLocker(Locker): + @staticmethod + def _disable_develop(packages: Iterable[Package]) -> None: + for package in packages: + package.develop = False + def locked_repository(self) -> LockfileRepository: repo = super().locked_repository() - for package in repo.packages: - package.develop = False + self._disable_develop(repo.packages) return repo + def locked_packages(self) -> dict[Package, TransitivePackageInfo]: + # Poetry >= 2.3.0 defaults installer.re-resolve to false, and on + # that path the installer takes its install targets from + # locked_packages() rather than locked_repository(). + packages = super().locked_packages() + self._disable_develop(packages) + return packages + custom_locker = CustomLocker(poetry.locker.lock, poetry.locker._pyproject_data) installer = Installer( diff --git a/tests/bundlers/test_venv_bundler.py b/tests/bundlers/test_venv_bundler.py index 787dac7..cdc5fb2 100644 --- a/tests/bundlers/test_venv_bundler.py +++ b/tests/bundlers/test_venv_bundler.py @@ -320,13 +320,20 @@ def test_bundler_passes_compile_flag( assert expected == io.fetch_output() +@pytest.mark.parametrize("re_resolve", [True, False]) def test_bundler_editable_deps( - io: BufferedIO, tmpdir: str, poetry: Poetry, mocker: MockerFixture, config: Config + io: BufferedIO, + tmpdir: str, + poetry: Poetry, + mocker: MockerFixture, + config: Config, + re_resolve: bool, ) -> None: poetry = Factory().create_poetry( Path(__file__).parent.parent / "fixtures" / "simple_project_with_editable_dep" ) poetry.set_config(config) + config.config["installer"]["re-resolve"] = re_resolve install_spy = mocker.spy(Install, "__init__") mocker.patch("poetry.installation.executor.Executor._execute_operation") diff --git a/tests/fixtures/simple_project_with_editable_dep/poetry.lock b/tests/fixtures/simple_project_with_editable_dep/poetry.lock index d3ac38d..5ee0748 100644 --- a/tests/fixtures/simple_project_with_editable_dep/poetry.lock +++ b/tests/fixtures/simple_project_with_editable_dep/poetry.lock @@ -1,17 +1,20 @@ -[metadata] -lock-version = "1.0" -content-hash = "4bf28231e477206338f6afc67df322e7b3601fdbf1d704521e1676a33603768b" -python-versions = "~2.7 || ^3.4" +# This file is automatically @generated by Poetry 2.3.0 and should not be changed by hand. [[package]] name = "bar" -version = "0.1.0" -description = "" +version = "1.2.3" +description = "Some description." optional = false -python-versions = "*" +python-versions = "~2.7 || ^3.4" +groups = ["main"] files = [] develop = true [package.source] type = "directory" url = "bar" + +[metadata] +lock-version = "2.1" +python-versions = "~2.7 || ^3.4" +content-hash = "4bf28231e477206338f6afc67df322e7b3601fdbf1d704521e1676a33603768b"