diff --git a/src/poetry/packages/locker.py b/src/poetry/packages/locker.py index f87c490d70f..20645c7fec6 100644 --- a/src/poetry/packages/locker.py +++ b/src/poetry/packages/locker.py @@ -574,7 +574,7 @@ def _dump_package( if package.extras: extras = {} for name, deps in sorted(package.extras.items()): - extras[name] = sorted(dep.base_pep_508_name for dep in deps) + extras[name] = sorted(dep.to_pep_508(with_extras=False) for dep in deps) data["extras"] = extras diff --git a/tests/installation/fixtures/with-pypi-repository.test b/tests/installation/fixtures/with-pypi-repository.test index ce79893c9a8..85534e2aa53 100644 --- a/tests/installation/fixtures/with-pypi-repository.test +++ b/tests/installation/fixtures/with-pypi-repository.test @@ -106,7 +106,7 @@ files = [ [package.extras] docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7) ; platform_python_implementation != \"PyPy\"", "pytest-checkdocs (>=2.4)", "pytest-cov ; platform_python_implementation != \"PyPy\"", "pytest-enabler (>=1.3)", "pytest-flake8 ; python_version < \"3.12\"", "pytest-mypy (>=0.9.1) ; platform_python_implementation != \"PyPy\"", "pytest-perf", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] [[package]] diff --git a/tests/packages/test_locker.py b/tests/packages/test_locker.py index 89623cb62ec..7dce9bfeebf 100644 --- a/tests/packages/test_locker.py +++ b/tests/packages/test_locker.py @@ -1293,6 +1293,100 @@ def test_locker_dumps_dependency_extras_in_correct_order( assert content == expected +def test_locker_dumps_extras_with_constraints( + locker: Locker, + root: ProjectPackage, + fixture_base: Path, + transitive_info: TransitivePackageInfo, +) -> None: + package_a = get_package("A", "1.0.0") + + package_httpx_new = Factory.create_dependency( + "httpx", + {"version": "2.0.0", "python": ">=3.7", "extras": ["brotli"]}, + root_dir=fixture_base, + ) + + package_httpx_old = Factory.create_dependency( + "httpx", {"version": "1.0.0", "python": "<3.7"}, root_dir=fixture_base + ) + + package_a.extras = { + canonicalize_name("http"): [package_httpx_new, package_httpx_old], + } + + locker.set_lock_data(root, {package_a: transitive_info}) + + with locker.lock.open(encoding="utf-8") as f: + content = f.read() + + expected = f"""\ +# {GENERATED_COMMENT} + +[[package]] +name = "A" +version = "1.0.0" +description = "" +optional = false +python-versions = "*" +groups = ["main"] +files = [] + +[package.extras] +http = ["httpx (==1.0.0) ; python_version < \\"3.7\\"", "httpx[brotli] (==2.0.0) ; python_version >= \\"3.7\\""] + +[metadata] +lock-version = "2.1" +python-versions = "*" +content-hash = "115cf985d932e9bf5f540555bbdd75decbb62cac81e399375fc19f6277f8c1d8" +""" + + assert content == expected + + +def test_locker_properly_loads_extras_with_constraints(locker: Locker) -> None: + content = f"""\ +# {GENERATED_COMMENT} + +[[package]] +name = "A" +version = "1.0.0" +description = "" +optional = false +python-versions = "*" +groups = ["main"] +files = [] + +[package.extras] +http = ["httpx (==1.0.0) ; python_version < \\"3.7\\"", "httpx[brotli] (==2.0.0) ; python_version >= \\"3.7\\""] + +[metadata] +lock-version = "2.1" +python-versions = "*" +content-hash = "115cf985d932e9bf5f540555bbdd75decbb62cac81e399375fc19f6277f8c1d8" +""" + + with open(locker.lock, "w", encoding="utf-8") as f: + f.write(content) + + packages = locker.locked_repository().packages + + assert len(packages) == 1 + + package = packages[0] + assert len(package.extras) == 1 + + httpx_deps = package.extras[canonicalize_name("http")] + assert len(httpx_deps) == 2 + + assert httpx_deps[0].constraint == Version.parse("1.0.0") + assert str(httpx_deps[0].python_constraint) == "<3.7" + + assert httpx_deps[1].constraint == Version.parse("2.0.0") + assert str(httpx_deps[1].python_constraint) == ">=3.7" + assert httpx_deps[1].extras == {"brotli"} + + def test_locked_repository_uses_root_dir_of_package( locker: Locker, mocker: MockerFixture ) -> None: