diff --git a/poetry.lock b/poetry.lock index d7470c271ca..226072a779a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1161,12 +1161,16 @@ name = "poetry-core" version = "2.1.3" description = "Poetry PEP 517 Build Backend" optional = false -python-versions = "<4.0,>=3.9" +python-versions = ">=3.9, <4.0" groups = ["main"] -files = [ - {file = "poetry_core-2.1.3-py3-none-any.whl", hash = "sha256:2c704f05016698a54ca1d327f46ce2426d72eaca6ff614132c8477c292266771"}, - {file = "poetry_core-2.1.3.tar.gz", hash = "sha256:0522a015477ed622c89aad56a477a57813cace0c8e7ff2a2906b7ef4a2e296a4"}, -] +files = [] +develop = false + +[package.source] +type = "git" +url = "https://github.com/python-poetry/poetry-core.git" +reference = "HEAD" +resolved_reference = "12f0e00b34f97461709d8d65f9c5ec12d6f71da8" [[package]] name = "pre-commit" @@ -1990,4 +1994,4 @@ cffi = ["cffi (>=1.11)"] [metadata] lock-version = "2.1" python-versions = ">=3.9,<4.0" -content-hash = "f2793aa20e4a10c4d908f759fb731f32a563497fe0799ba44ef431ff8679dce8" +content-hash = "0e8181aa29e95d0c347dd3536f5cff519d5b4f0431f4f9ab421f52015e117c75" diff --git a/pyproject.toml b/pyproject.toml index 97c82eb9956..6012f62b3d8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ version = "2.1.3" description = "Python dependency management and packaging made easy." requires-python = ">=3.9,<4.0" dependencies = [ - "poetry-core (==2.1.3)", + "poetry-core @ git+https://github.com/python-poetry/poetry-core.git", "build (>=1.2.1,<2.0.0)", "cachecontrol[filecache] (>=0.14.0,<0.15.0)", "cleo (>=2.1.0,<3.0.0)", diff --git a/src/poetry/console/commands/group_command.py b/src/poetry/console/commands/group_command.py index 06dea92cc78..d876884fe55 100644 --- a/src/poetry/console/commands/group_command.py +++ b/src/poetry/console/commands/group_command.py @@ -4,6 +4,8 @@ from typing import TYPE_CHECKING from cleo.helpers import option +from packaging.utils import NormalizedName +from packaging.utils import canonicalize_name from poetry.console.commands.command import Command from poetry.console.exceptions import GroupNotFoundError @@ -70,7 +72,7 @@ def default_groups(self) -> set[str]: return self.non_optional_groups @property - def activated_groups(self) -> set[str]: + def activated_groups(self) -> set[NormalizedName]: groups = {} for key in {"with", "without", "only"}: @@ -95,9 +97,17 @@ def activated_groups(self) -> set[str]: "" ) - return groups["only"] or self.default_groups.union(groups["with"]).difference( - groups["without"] - ) + # Normalize after validating so that original names are printed + # in case of an error. + norm_groups = { + key: {canonicalize_name(group) for group in key_groups} + for key, key_groups in groups.items() + } + norm_default_groups = {canonicalize_name(name) for name in self.default_groups} + + return norm_groups["only"] or norm_default_groups.union( + norm_groups["with"] + ).difference(norm_groups["without"]) def project_with_activated_groups_only(self) -> ProjectPackage: return self.poetry.package.with_dependency_groups( diff --git a/src/poetry/console/commands/install.py b/src/poetry/console/commands/install.py index b797c24ada8..4e31d9d1a78 100644 --- a/src/poetry/console/commands/install.py +++ b/src/poetry/console/commands/install.py @@ -11,6 +11,7 @@ if TYPE_CHECKING: from cleo.io.inputs.option import Option + from packaging.utils import NormalizedName class InstallCommand(InstallerCommand): @@ -83,7 +84,7 @@ class InstallCommand(InstallerCommand): ] @property - def activated_groups(self) -> set[str]: + def activated_groups(self) -> set[NormalizedName]: if self.option("only-root"): return set() else: diff --git a/src/poetry/console/commands/self/install.py b/src/poetry/console/commands/self/install.py index 6f0399b2ae2..b4c9a1e2644 100644 --- a/src/poetry/console/commands/self/install.py +++ b/src/poetry/console/commands/self/install.py @@ -3,6 +3,8 @@ from typing import TYPE_CHECKING from typing import ClassVar +from packaging.utils import NormalizedName +from packaging.utils import canonicalize_name from poetry.core.packages.dependency_group import MAIN_GROUP from poetry.console.commands.install import InstallCommand @@ -33,8 +35,8 @@ class SelfInstallCommand(SelfCommand, InstallCommand): """ @property - def activated_groups(self) -> set[str]: - return {MAIN_GROUP, self.default_group} + def activated_groups(self) -> set[NormalizedName]: + return {MAIN_GROUP, canonicalize_name(self.default_group)} @property def _alternative_sync_command(self) -> str: diff --git a/src/poetry/console/commands/self/self_command.py b/src/poetry/console/commands/self/self_command.py index 6b049d3b459..316fd3ec5f9 100644 --- a/src/poetry/console/commands/self/self_command.py +++ b/src/poetry/console/commands/self/self_command.py @@ -3,6 +3,7 @@ from pathlib import Path from typing import TYPE_CHECKING +from packaging.utils import canonicalize_name from poetry.core.packages.dependency import Dependency from poetry.core.packages.project_package import ProjectPackage @@ -16,12 +17,14 @@ if TYPE_CHECKING: + from packaging.utils import NormalizedName + from poetry.poetry import Poetry from poetry.utils.env import Env class SelfCommand(InstallerCommand): - ADDITIONAL_PACKAGE_GROUP = "additional" + ADDITIONAL_PACKAGE_GROUP = canonicalize_name("additional") @staticmethod def get_default_system_pyproject_file() -> Path: @@ -54,8 +57,8 @@ def default_group(self) -> str: return self.ADDITIONAL_PACKAGE_GROUP @property - def activated_groups(self) -> set[str]: - return {self.default_group} + def activated_groups(self) -> set[NormalizedName]: + return {canonicalize_name(self.default_group)} def generate_system_pyproject(self) -> None: preserved = {} diff --git a/src/poetry/console/commands/self/show/__init__.py b/src/poetry/console/commands/self/show/__init__.py index 8f4060ad2a3..e0e5fcc32cb 100644 --- a/src/poetry/console/commands/self/show/__init__.py +++ b/src/poetry/console/commands/self/show/__init__.py @@ -11,6 +11,7 @@ if TYPE_CHECKING: from cleo.io.inputs.option import Option + from packaging.utils import NormalizedName class SelfShowCommand(SelfCommand, ShowCommand): @@ -33,9 +34,8 @@ class SelfShowCommand(SelfCommand, ShowCommand): """ @property - def activated_groups(self) -> set[str]: + def activated_groups(self) -> set[NormalizedName]: if self.option("addons", False): return {SelfCommand.ADDITIONAL_PACKAGE_GROUP} - groups: set[str] = super(ShowCommand, self).activated_groups - return groups + return super(ShowCommand, self).activated_groups diff --git a/src/poetry/installation/installer.py b/src/poetry/installation/installer.py index e86fb540a0a..b4e9eaaaafd 100644 --- a/src/poetry/installation/installer.py +++ b/src/poetry/installation/installer.py @@ -54,7 +54,7 @@ def __init__( self._requires_synchronization = False self._update = False self._verbose = False - self._groups: Iterable[str] | None = None + self._groups: Iterable[NormalizedName] | None = None self._skip_directory = False self._lock = False @@ -127,7 +127,7 @@ def verbose(self, verbose: bool = True) -> Installer: def is_verbose(self) -> bool: return self._verbose - def only_groups(self, groups: Iterable[str]) -> Installer: + def only_groups(self, groups: Iterable[NormalizedName]) -> Installer: self._groups = groups return self diff --git a/src/poetry/packages/locker.py b/src/poetry/packages/locker.py index 20645c7fec6..ff23bc2918c 100644 --- a/src/poetry/packages/locker.py +++ b/src/poetry/packages/locker.py @@ -162,13 +162,20 @@ def locked_packages(self) -> dict[Package, TransitivePackageInfo]: groups = set(info["groups"]) locked_marker = info.get("markers", "*") if isinstance(locked_marker, str): - markers = {group: parse_marker(locked_marker) for group in groups} + markers = { + canonicalize_name(group): parse_marker(locked_marker) + for group in groups + } else: markers = { - group: parse_marker(locked_marker.get(group, "*")) + canonicalize_name(group): parse_marker( + locked_marker.get(group, "*") + ) for group in groups } - locked_packages[package] = TransitivePackageInfo(0, groups, markers) + locked_packages[package] = TransitivePackageInfo( + 0, {canonicalize_name(g) for g in groups}, markers + ) return locked_packages @@ -553,23 +560,23 @@ def _dump_package( data["markers"] = str(marker) else: data["markers"] = inline_table() - for k, v in sorted( + for group, marker in sorted( transitive_info.markers.items(), key=lambda x: (x[0] != "main", x[0]), ): - if not v.is_any(): - data["markers"][k] = str(v) + if not marker.is_any(): + data["markers"][group] = str(marker) data["files"] = sorted(package.files, key=lambda x: x["file"]) if dependencies: data["dependencies"] = table() - for k, constraints in dependencies.items(): + for dep_name, constraints in dependencies.items(): if len(constraints) == 1: - data["dependencies"][k] = constraints[0] + data["dependencies"][dep_name] = constraints[0] else: - data["dependencies"][k] = array().multiline(True) + data["dependencies"][dep_name] = array().multiline(True) for constraint in constraints: - data["dependencies"][k].append(constraint) + data["dependencies"][dep_name].append(constraint) if package.extras: extras = {} diff --git a/src/poetry/packages/transitive_package_info.py b/src/poetry/packages/transitive_package_info.py index 82960ec08d3..89c28a25a45 100644 --- a/src/poetry/packages/transitive_package_info.py +++ b/src/poetry/packages/transitive_package_info.py @@ -10,14 +10,16 @@ if TYPE_CHECKING: from collections.abc import Iterable + from packaging.utils import NormalizedName + @dataclass class TransitivePackageInfo: depth: int # max depth in the dependency tree - groups: set[str] - markers: dict[str, BaseMarker] # group -> marker + groups: set[NormalizedName] + markers: dict[NormalizedName, BaseMarker] # group -> marker - def get_marker(self, groups: Iterable[str]) -> BaseMarker: + def get_marker(self, groups: Iterable[NormalizedName]) -> BaseMarker: marker: BaseMarker = EmptyMarker() for group in groups: if group_marker := self.markers.get(group): diff --git a/src/poetry/puzzle/solver.py b/src/poetry/puzzle/solver.py index b2b4912d30b..26810cc2aeb 100644 --- a/src/poetry/puzzle/solver.py +++ b/src/poetry/puzzle/solver.py @@ -299,7 +299,7 @@ def __init__( self.depth = -1 if not previous: - self.groups: frozenset[str] = frozenset() + self.groups: frozenset[NormalizedName] = frozenset() self.optional = True elif dep: self.groups = dep.groups @@ -361,7 +361,7 @@ def aggregate_package_nodes( ) -> tuple[Package, TransitivePackageInfo]: package = nodes[0].package depth = max(node.depth for node in nodes) - groups: set[str] = set() + groups: set[NormalizedName] = set() for node in nodes: groups.update(node.groups) @@ -395,7 +395,7 @@ def calculate_markers( for depth in range(max_depth + 1): for package in packages_by_depth[depth]: transitive_info = packages[package] - transitive_marker: dict[str, BaseMarker] = { + transitive_marker: dict[NormalizedName, BaseMarker] = { group: EmptyMarker() for group in transitive_info.groups } for parent, m in markers[package].items(): diff --git a/src/poetry/puzzle/transaction.py b/src/poetry/puzzle/transaction.py index 3c76bda3876..ecd78fc2457 100644 --- a/src/poetry/puzzle/transaction.py +++ b/src/poetry/puzzle/transaction.py @@ -23,7 +23,7 @@ def __init__( installed_packages: list[Package] | None = None, root_package: Package | None = None, marker_env: dict[str, Any] | None = None, - groups: set[str] | None = None, + groups: set[NormalizedName] | None = None, ) -> None: self._current_packages = current_packages self._result_packages = result_packages diff --git a/tests/installation/test_installer.py b/tests/installation/test_installer.py index c4560f31907..851c9594b80 100644 --- a/tests/installation/test_installer.py +++ b/tests/installation/test_installer.py @@ -437,7 +437,7 @@ def test_run_install_with_dependency_groups( ) if groups is not None: - installer.only_groups(groups) + installer.only_groups({canonicalize_name(g) for g in groups}) installer.update(update) installer.requires_synchronization(requires_synchronization) diff --git a/tests/packages/test_locker.py b/tests/packages/test_locker.py index 7dce9bfeebf..8fa05d9f672 100644 --- a/tests/packages/test_locker.py +++ b/tests/packages/test_locker.py @@ -35,6 +35,9 @@ from pytest_mock import MockerFixture +DEV_GROUP = canonicalize_name("dev") + + @pytest.fixture def locker() -> Locker: with tempfile.NamedTemporaryFile() as f: @@ -466,17 +469,21 @@ def test_locker_properly_loads_subdir(locker: Locker) -> None: @pytest.mark.parametrize( ("groups", "marker", "expected"), [ + # only main - without marker (["main"], None, {"main": "*"}), + # only main - with marker ( ["main"], repr('python_version == "3.9"'), {"main": 'python_version == "3.9"'}, ), + # two groups - common marker ( ["main", "dev"], repr('python_version == "3.9"'), {"main": 'python_version == "3.9"', "dev": 'python_version == "3.9"'}, ), + # two groups - separate marker ( ["main", "dev"], ( @@ -485,11 +492,27 @@ def test_locker_properly_loads_subdir(locker: Locker) -> None: ), {"main": 'python_version == "3.9"', "dev": 'sys_platform == "linux"'}, ), + # two groups - one without marker ( ["main", "dev"], '{"main" = \'python_version == "3.9"\'}', {"main": 'python_version == "3.9"', "dev": "*"}, ), + ( + # unnormalized group - common marker + ["main", "DEV"], + repr('python_version == "3.9"'), + {"main": 'python_version == "3.9"', "dev": 'python_version == "3.9"'}, + ), + ( + # unnormalized group - separate marker + ["main", "DEV"], + ( + '{"main" = \'python_version == "3.9"\',' + ' "DEV" = \'sys_platform == "linux"\'}' + ), + {"main": 'python_version == "3.9"', "dev": 'sys_platform == "linux"'}, + ), ], ) def test_locker_properly_loads_groups_and_markers( @@ -517,7 +540,7 @@ def test_locker_properly_loads_groups_and_markers( a = get_package("a", "1.0") assert len(packages) == 1 - assert packages[a].groups == set(groups) + assert packages[a].groups == {canonicalize_name(g) for g in groups} assert packages[a].markers == {g: parse_marker(m) for g, m in expected.items()} @@ -997,36 +1020,38 @@ def test_locker_dumps_groups_and_markers( ) -> None: packages = { get_package("A", "1.0"): TransitivePackageInfo( - 0, {"main"}, {"main": AnyMarker()} + 0, {MAIN_GROUP}, {MAIN_GROUP: AnyMarker()} ), get_package("B", "1.0"): TransitivePackageInfo( - 0, {"main"}, {"main": parse_marker('sys_platform == "win32"')} + 0, {MAIN_GROUP}, {MAIN_GROUP: parse_marker('sys_platform == "win32"')} ), get_package("C", "1.0"): TransitivePackageInfo( - 0, {"main", "dev"}, {"main": AnyMarker(), "dev": AnyMarker()} + 0, + {MAIN_GROUP, DEV_GROUP}, + {MAIN_GROUP: AnyMarker(), DEV_GROUP: AnyMarker()}, ), get_package("D", "1.0"): TransitivePackageInfo( 0, - {"main", "dev"}, + {MAIN_GROUP, DEV_GROUP}, { - "main": parse_marker('sys_platform == "win32"'), - "dev": parse_marker('sys_platform == "win32"'), + MAIN_GROUP: parse_marker('sys_platform == "win32"'), + DEV_GROUP: parse_marker('sys_platform == "win32"'), }, ), get_package("E", "1.0"): TransitivePackageInfo( 0, - {"main", "dev"}, + {MAIN_GROUP, DEV_GROUP}, { - "main": parse_marker('sys_platform == "win32"'), - "dev": parse_marker('sys_platform == "linux"'), + MAIN_GROUP: parse_marker('sys_platform == "win32"'), + DEV_GROUP: parse_marker('sys_platform == "linux"'), }, ), get_package("F", "1.0"): TransitivePackageInfo( 0, - {"main", "dev"}, + {MAIN_GROUP, DEV_GROUP}, { - "main": parse_marker('sys_platform == "win32"'), - "dev": AnyMarker(), + MAIN_GROUP: parse_marker('sys_platform == "win32"'), + DEV_GROUP: AnyMarker(), }, ), } diff --git a/tests/packages/test_transitive_package_info.py b/tests/packages/test_transitive_package_info.py index 8532555ba98..89809b65afa 100644 --- a/tests/packages/test_transitive_package_info.py +++ b/tests/packages/test_transitive_package_info.py @@ -2,11 +2,16 @@ import pytest +from packaging.utils import canonicalize_name +from poetry.core.packages.dependency_group import MAIN_GROUP from poetry.core.version.markers import parse_marker from poetry.packages.transitive_package_info import TransitivePackageInfo +DEV_GROUP = canonicalize_name("dev") + + @pytest.mark.parametrize( "groups, expected", [ @@ -21,10 +26,10 @@ def test_get_marker(groups: list[str], expected: str) -> None: info = TransitivePackageInfo( depth=0, - groups={"main", "dev"}, + groups={MAIN_GROUP, DEV_GROUP}, markers={ - "main": parse_marker('sys_platform =="linux"'), - "dev": parse_marker('python_version < "3.9"'), + MAIN_GROUP: parse_marker('sys_platform =="linux"'), + DEV_GROUP: parse_marker('python_version < "3.9"'), }, ) - assert str(info.get_marker(groups)) == expected + assert str(info.get_marker([canonicalize_name(g) for g in groups])) == expected diff --git a/tests/puzzle/test_solver.py b/tests/puzzle/test_solver.py index cc4f7708f7b..a13a1a2fd4a 100644 --- a/tests/puzzle/test_solver.py +++ b/tests/puzzle/test_solver.py @@ -5090,8 +5090,12 @@ def test_solver_resolves_conflicting_dependency_in_root_extra( ), ) solved_packages = transaction.get_solved_packages() - assert solved_packages[package_a1].markers["main"] == parse_marker("extra != 'foo'") - assert solved_packages[package_a2].markers["main"] == parse_marker("extra == 'foo'") + assert solved_packages[package_a1].markers[MAIN_GROUP] == parse_marker( + "extra != 'foo'" + ) + assert solved_packages[package_a2].markers[MAIN_GROUP] == parse_marker( + "extra == 'foo'" + ) def test_solver_resolves_conflicting_dependency_in_root_extras( @@ -5136,10 +5140,10 @@ def test_solver_resolves_conflicting_dependency_in_root_extras( ), ) solved_packages = transaction.get_solved_packages() - assert solved_packages[package_a1].markers["main"] == parse_marker( + assert solved_packages[package_a1].markers[MAIN_GROUP] == parse_marker( "extra != 'bar' and extra == 'foo'" ) - assert solved_packages[package_a2].markers["main"] == parse_marker( + assert solved_packages[package_a2].markers[MAIN_GROUP] == parse_marker( "extra != 'foo' and extra == 'bar'" ) diff --git a/tests/puzzle/test_solver_internals.py b/tests/puzzle/test_solver_internals.py index 3ca8cdc21d6..807a9a32b62 100644 --- a/tests/puzzle/test_solver_internals.py +++ b/tests/puzzle/test_solver_internals.py @@ -7,6 +7,7 @@ from packaging.utils import canonicalize_name from poetry.core.constraints.version import parse_constraint from poetry.core.packages.dependency import Dependency +from poetry.core.packages.dependency_group import MAIN_GROUP from poetry.core.packages.package import Package from poetry.core.version.markers import AnyMarker from poetry.core.version.markers import parse_marker @@ -26,6 +27,9 @@ from poetry.core.packages.project_package import ProjectPackage +DEV_GROUP = canonicalize_name("dev") + + def dep( name: str, marker: str = "", @@ -369,7 +373,9 @@ def test_merge_override_packages_restricted(package: ProjectPackage) -> None: {package: {"a": dep("b", 'python_version < "3.9"')}}, { a: TransitivePackageInfo( - 0, {"main"}, {"main": parse_marker("sys_platform == 'win32'")} + 0, + {MAIN_GROUP}, + {MAIN_GROUP: parse_marker("sys_platform == 'win32'")}, ) }, ), @@ -377,7 +383,9 @@ def test_merge_override_packages_restricted(package: ProjectPackage) -> None: {package: {"a": dep("b", 'python_version >= "3.9"')}}, { a: TransitivePackageInfo( - 0, {"main"}, {"main": parse_marker("sys_platform == 'linux'")} + 0, + {MAIN_GROUP}, + {MAIN_GROUP: parse_marker("sys_platform == 'linux'")}, ) }, ), @@ -404,7 +412,9 @@ def test_merge_override_packages_extras(package: ProjectPackage) -> None: {package: {"a": dep("b", 'python_version < "3.9" and extra == "foo"')}}, { a: TransitivePackageInfo( - 0, {"main"}, {"main": parse_marker("sys_platform == 'win32'")} + 0, + {MAIN_GROUP}, + {MAIN_GROUP: parse_marker("sys_platform == 'win32'")}, ) }, ), @@ -416,7 +426,9 @@ def test_merge_override_packages_extras(package: ProjectPackage) -> None: }, { a: TransitivePackageInfo( - 0, {"main"}, {"main": parse_marker("sys_platform == 'linux'")} + 0, + {MAIN_GROUP}, + {MAIN_GROUP: parse_marker("sys_platform == 'linux'")}, ) }, ), @@ -456,11 +468,11 @@ def test_merge_override_packages_python_constraint( ) } }, - {a: TransitivePackageInfo(0, {"main"}, {"main": AnyMarker()})}, + {a: TransitivePackageInfo(0, {MAIN_GROUP}, {MAIN_GROUP: AnyMarker()})}, ), ( {package: {"a": dep("b", "sys_platform != 'linux'")}}, - {a: TransitivePackageInfo(0, {"main"}, {"main": AnyMarker()})}, + {a: TransitivePackageInfo(0, {MAIN_GROUP}, {MAIN_GROUP: AnyMarker()})}, ), ], parse_constraint(python_constraint), @@ -484,7 +496,7 @@ def test_merge_override_packages_multiple_deps(package: ProjectPackage) -> None: }, a: {"e": dep("f", 'python_version >= "3.8"')}, }, - {a: TransitivePackageInfo(0, {"main"}, {"main": AnyMarker()})}, + {a: TransitivePackageInfo(0, {MAIN_GROUP}, {MAIN_GROUP: AnyMarker()})}, ), ], parse_constraint("*"), @@ -507,14 +519,16 @@ def test_merge_override_packages_groups(package: ProjectPackage) -> None: {package: {"a": dep("b", 'python_version < "3.9"')}}, { a: TransitivePackageInfo( - 0, {"main"}, {"main": parse_marker("sys_platform == 'win32'")} + 0, + {MAIN_GROUP}, + {MAIN_GROUP: parse_marker("sys_platform == 'win32'")}, ), b: TransitivePackageInfo( 0, - {"main", "dev"}, + {MAIN_GROUP, DEV_GROUP}, { - "main": parse_marker("sys_platform == 'win32'"), - "dev": parse_marker("sys_platform == 'linux'"), + MAIN_GROUP: parse_marker("sys_platform == 'win32'"), + DEV_GROUP: parse_marker("sys_platform == 'linux'"), }, ), }, @@ -523,14 +537,16 @@ def test_merge_override_packages_groups(package: ProjectPackage) -> None: {package: {"a": dep("b", 'python_version >= "3.9"')}}, { a: TransitivePackageInfo( - 0, {"dev"}, {"dev": parse_marker("sys_platform == 'linux'")} + 0, + {DEV_GROUP}, + {DEV_GROUP: parse_marker("sys_platform == 'linux'")}, ), b: TransitivePackageInfo( 0, - {"main", "dev"}, + {MAIN_GROUP, DEV_GROUP}, { - "main": parse_marker("platform_machine == 'amd64'"), - "dev": parse_marker("platform_machine == 'aarch64'"), + MAIN_GROUP: parse_marker("platform_machine == 'amd64'"), + DEV_GROUP: parse_marker("platform_machine == 'aarch64'"), }, ), }, @@ -573,9 +589,9 @@ def test_merge_override_packages_shortcut(package: ProjectPackage) -> None: { a: TransitivePackageInfo( 0, - {"main"}, + {MAIN_GROUP}, { - "main": parse_marker( + MAIN_GROUP: parse_marker( f"{override_marker1} and ({common_marker})" ) }, @@ -587,9 +603,9 @@ def test_merge_override_packages_shortcut(package: ProjectPackage) -> None: { a: TransitivePackageInfo( 0, - {"main"}, + {MAIN_GROUP}, { - "main": parse_marker( + MAIN_GROUP: parse_marker( f"{override_marker2} and ({common_marker})" ) }, diff --git a/tests/puzzle/test_transaction.py b/tests/puzzle/test_transaction.py index 1a31deb5369..3f940c6b7bf 100644 --- a/tests/puzzle/test_transaction.py +++ b/tests/puzzle/test_transaction.py @@ -7,6 +7,7 @@ from packaging.utils import canonicalize_name from poetry.core.packages.dependency import Dependency +from poetry.core.packages.dependency_group import MAIN_GROUP from poetry.core.packages.package import Package from poetry.core.packages.project_package import ProjectPackage from poetry.core.version.markers import AnyMarker @@ -21,6 +22,9 @@ from poetry.installation.operations.operation import Operation +DEV_GROUP = canonicalize_name("dev") + + def get_transitive_info(depth: int) -> TransitivePackageInfo: return TransitivePackageInfo(depth, set(), {}) @@ -271,11 +275,15 @@ def test_calculate_operations_with_groups( [Package("a", "1"), Package("b", "1"), Package("c", "1"), Package("d", "1")], { Package("a", "1"): TransitivePackageInfo( - 0, {"main"}, {"main": AnyMarker()} + 0, {MAIN_GROUP}, {MAIN_GROUP: AnyMarker()} + ), + Package("b", "1"): TransitivePackageInfo( + 0, {DEV_GROUP}, {DEV_GROUP: AnyMarker()} ), - Package("b", "1"): TransitivePackageInfo(0, {"dev"}, {"dev": AnyMarker()}), Package("c", "1"): TransitivePackageInfo( - 0, {"main", "dev"}, {"main": AnyMarker(), "dev": AnyMarker()} + 0, + {MAIN_GROUP, DEV_GROUP}, + {MAIN_GROUP: AnyMarker(), DEV_GROUP: AnyMarker()}, ), }, ( @@ -285,7 +293,7 @@ def test_calculate_operations_with_groups( ), None, {"python_version": "3.8"}, - groups, + {canonicalize_name(g) for g in groups}, ) expected_ops = [ @@ -322,16 +330,16 @@ def test_calculate_operations_with_markers( [Package("a", "1"), Package("b", "1")], { Package("a", "1"): TransitivePackageInfo( - 0, {"main"}, {"main": parse_marker("python_version < '3.9'")} + 0, {MAIN_GROUP}, {MAIN_GROUP: parse_marker("python_version < '3.9'")} ), Package("b", "1"): TransitivePackageInfo( - 0, {"main"}, {"main": parse_marker("python_version >= '3.9'")} + 0, {MAIN_GROUP}, {MAIN_GROUP: parse_marker("python_version >= '3.9'")} ), }, [Package("a", "1"), Package("b", "1")] if installed else [], None, {"python_version": python_version}, - {"main"}, + {MAIN_GROUP}, ) expected_ops = [ @@ -374,17 +382,17 @@ def test_calculate_operations_with_groups_and_markers( { Package("a", "1"): TransitivePackageInfo( 0, - {"main", "dev"}, + {MAIN_GROUP, DEV_GROUP}, { - "main": parse_marker("python_version < '3.9'"), - "dev": parse_marker("sys_platform == 'linux'"), + MAIN_GROUP: parse_marker("python_version < '3.9'"), + DEV_GROUP: parse_marker("sys_platform == 'linux'"), }, ), }, [], None, {"python_version": python_version, "sys_platform": sys_platform}, - groups, + {canonicalize_name(g) for g in groups}, ) expected_ops = ( @@ -420,14 +428,14 @@ def test_calculate_operations_extras( { opt_a: TransitivePackageInfo( 0, - {"main"} if marker_env else set(), - {"main": parse_marker("extra == 'foo'")} if marker_env else {}, + {MAIN_GROUP} if marker_env else set(), + {MAIN_GROUP: parse_marker("extra == 'foo'")} if marker_env else {}, ) }, [Package("a", "1")] if installed else [], package, {"python_version": "3.8"} if marker_env else None, - {"main"} if marker_env else None, + {MAIN_GROUP} if marker_env else None, ) if extras: @@ -473,16 +481,20 @@ def test_calculate_operations_extras_no_redundant_uninstall(extra: str) -> None: [Package("a", "1")], { opt_a1: TransitivePackageInfo( - 0, {"main"}, {"main": parse_marker("extra == 'foo' and extra != 'bar'")} + 0, + {MAIN_GROUP}, + {MAIN_GROUP: parse_marker("extra == 'foo' and extra != 'bar'")}, ), opt_a2: TransitivePackageInfo( - 0, {"main"}, {"main": parse_marker("extra == 'bar' and extra != 'foo'")} + 0, + {MAIN_GROUP}, + {MAIN_GROUP: parse_marker("extra == 'bar' and extra != 'foo'")}, ), }, [Package("a", "1")], package, {"python_version": "3.9"}, - {"main"}, + {MAIN_GROUP}, ) if not extra: