diff --git a/src/poetry/packages/locker.py b/src/poetry/packages/locker.py index 35a035f7535..5460031a820 100644 --- a/src/poetry/packages/locker.py +++ b/src/poetry/packages/locker.py @@ -409,13 +409,13 @@ def _dump_package(self, package: Package) -> dict[str, Any]: if package.extras: extras = {} - for name, deps in package.extras.items(): + for name, deps in sorted(package.extras.items()): # TODO: This should use dep.to_pep_508() once this is fixed # https://github.com/python-poetry/poetry-core/pull/102 - extras[name] = [ + extras[name] = sorted( dep.base_pep_508_name if not dep.constraint.is_any() else dep.name 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 27fee8ce755..ac57e43ec7b 100644 --- a/tests/installation/fixtures/with-pypi-repository.test +++ b/tests/installation/fixtures/with-pypi-repository.test @@ -7,7 +7,7 @@ optional = false python-versions = "*" [package.extras] -dev = ["coverage", "hypothesis", "pympler", "pytest", "six", "zope-interface", "sphinx", "zope-interface"] +dev = ["coverage", "hypothesis", "pympler", "pytest", "six", "sphinx", "zope-interface", "zope-interface"] docs = ["sphinx", "zope-interface"] tests = ["coverage", "hypothesis", "pympler", "pytest", "six", "zope-interface"] @@ -72,14 +72,6 @@ pluggy = ">=0.5,<0.7" funcsigs = {"version" = "*", "markers" = "python_version < \"3.0\""} colorama = {"version" = "*", "markers" = "sys_platform == \"win32\""} -[[package]] -name = "six" -version = "1.11.0" -description = "Python 2 and 3 compatibility utilities" -category = "dev" -optional = false -python-versions = "*" - [[package]] name = "setuptools" version = "39.2.0" @@ -92,6 +84,14 @@ python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*" certs = ["certifi (==2016.9.26)"] ssl = ["wincertstore (==0.2)"] +[[package]] +name = "six" +version = "1.11.0" +description = "Python 2 and 3 compatibility utilities" +category = "dev" +optional = false +python-versions = "*" + [metadata] python-versions = "*" lock-version = "1.1" diff --git a/tests/installation/test_installer.py b/tests/installation/test_installer.py index 2aee63d9701..452ff425da9 100644 --- a/tests/installation/test_installer.py +++ b/tests/installation/test_installer.py @@ -14,7 +14,6 @@ from cleo.io.null_io import NullIO from cleo.io.outputs.buffered_output import BufferedOutput from cleo.io.outputs.output import Verbosity -from deepdiff import DeepDiff from poetry.core.packages.dependency_group import MAIN_GROUP from poetry.core.packages.dependency_group import DependencyGroup from poetry.core.packages.package import Package @@ -1164,7 +1163,7 @@ def test_installer_with_pypi_repository( expected = fixture("with-pypi-repository") - assert not DeepDiff(expected, locker.written_data, ignore_order=True) + assert expected == locker.written_data def test_run_installs_with_local_file( diff --git a/tests/installation/test_installer_old.py b/tests/installation/test_installer_old.py index cdf62563374..baa59649ce9 100644 --- a/tests/installation/test_installer_old.py +++ b/tests/installation/test_installer_old.py @@ -8,7 +8,6 @@ import pytest from cleo.io.null_io import NullIO -from deepdiff import DeepDiff from poetry.core.packages.project_package import ProjectPackage from poetry.core.toml.file import TOMLFile @@ -833,7 +832,7 @@ def test_installer_with_pypi_repository( expected = fixture("with-pypi-repository") - assert not DeepDiff(expected, locker.written_data, ignore_order=True) + assert expected == locker.written_data def test_run_installs_with_local_file( diff --git a/tests/packages/test_locker.py b/tests/packages/test_locker.py index e0ed720bf94..f41fc2ba056 100644 --- a/tests/packages/test_locker.py +++ b/tests/packages/test_locker.py @@ -778,6 +778,51 @@ def test_locker_dumps_subdir(locker: Locker, root: ProjectPackage) -> None: assert content == expected +def test_locker_dumps_dependency_extras_in_correct_order( + locker: Locker, root: ProjectPackage +): + root_dir = Path(__file__).parent.parent.joinpath("fixtures") + package_a = get_package("A", "1.0.0") + Factory.create_dependency("B", "1.0.0", root_dir=root_dir) + Factory.create_dependency("C", "1.0.0", root_dir=root_dir) + package_first = Factory.create_dependency("first", "1.0.0", root_dir=root_dir) + package_second = Factory.create_dependency("second", "1.0.0", root_dir=root_dir) + package_third = Factory.create_dependency("third", "1.0.0", root_dir=root_dir) + + package_a.extras = { + "C": [package_third, package_second, package_first], + "B": [package_first, package_second, package_third], + } + + locker.set_lock_data(root, [package_a]) + + with locker.lock.open(encoding="utf-8") as f: + content = f.read() + + expected = """[[package]] +name = "A" +version = "1.0.0" +description = "" +category = "main" +optional = false +python-versions = "*" + +[package.extras] +B = ["first (==1.0.0)", "second (==1.0.0)", "third (==1.0.0)"] +C = ["first (==1.0.0)", "second (==1.0.0)", "third (==1.0.0)"] + +[metadata] +lock-version = "1.1" +python-versions = "*" +content-hash = "115cf985d932e9bf5f540555bbdd75decbb62cac81e399375fc19f6277f8c1d8" + +[metadata.files] +A = [] +""" + + assert content == expected + + def test_locked_repository_uses_root_dir_of_package( locker: Locker, mocker: MockerFixture ):