From 27f7cbb871d9ae11b73bccb723b3d17dcecee01e Mon Sep 17 00:00:00 2001 From: David Hotham Date: Sun, 13 Mar 2022 11:38:18 +0000 Subject: [PATCH] Fix a solver case with complex extras --- src/poetry/puzzle/solver.py | 2 +- tests/puzzle/test_solver.py | 47 +++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/poetry/puzzle/solver.py b/src/poetry/puzzle/solver.py index 32bd327a7be..db16cd6b1ac 100644 --- a/src/poetry/puzzle/solver.py +++ b/src/poetry/puzzle/solver.py @@ -339,7 +339,7 @@ def reachable(self) -> list[PackageNode]: and dependency.constraint.allows(pkg.version.stable) ) and not any( - child.package.name == pkg.name + child.package.complete_name == pkg.complete_name and child.groups == dependency.groups for child in children ) diff --git a/tests/puzzle/test_solver.py b/tests/puzzle/test_solver.py index d3242cfb531..0e766ce516d 100644 --- a/tests/puzzle/test_solver.py +++ b/tests/puzzle/test_solver.py @@ -686,6 +686,53 @@ def test_solver_returns_extras_only_requested_nested( assert ops[0].package.marker.is_any() +def test_solver_finds_extras_next_to_non_extras( + solver: Solver, repo: Repository, package: ProjectPackage +): + # Root depends on A[foo] + package.add_dependency( + Factory.create_dependency("A", {"version": "*", "extras": ["foo"]}) + ) + + package_a = get_package("A", "1.0") + package_b = get_package("B", "1.0") + package_c = get_package("C", "1.0") + package_d = get_package("D", "1.0") + + # A depends on B; A[foo] depends on B[bar]. + package_a.add_dependency(Factory.create_dependency("B", "*")) + package_a.add_dependency( + Factory.create_dependency( + "B", {"version": "*", "extras": ["bar"], "markers": "extra == 'foo'"} + ) + ) + package_a.extras = {"foo": [get_dependency("B", "*")]} + + # B depends on C; B[bar] depends on D. + package_b.add_dependency(Factory.create_dependency("C", "*")) + package_b.add_dependency( + Factory.create_dependency("D", {"version": "*", "markers": 'extra == "bar"'}) + ) + package_b.extras = {"bar": [get_dependency("D", "*")]} + + repo.add_package(package_a) + repo.add_package(package_b) + repo.add_package(package_c) + repo.add_package(package_d) + + transaction = solver.solve() + + check_solver_result( + transaction, + [ + {"job": "install", "package": package_c}, + {"job": "install", "package": package_d}, + {"job": "install", "package": package_b}, + {"job": "install", "package": package_a}, + ], + ) + + def test_solver_returns_prereleases_if_requested( solver: Solver, repo: Repository, package: ProjectPackage ):