Skip to content

Commit bd9c5c8

Browse files
radoeringneersighted
authored andcommitted
solver: fix special case where a direct origin dependency without extras is requested by the project and the same dependency with extras is requested by another dependency
1 parent 92dde5b commit bd9c5c8

File tree

2 files changed

+62
-1
lines changed

2 files changed

+62
-1
lines changed

Diff for: src/poetry/mixology/partial_solution.py

+10-1
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@
44

55
from poetry.mixology.assignment import Assignment
66
from poetry.mixology.set_relation import SetRelation
7+
from poetry.mixology.term import Term
78

89

910
if TYPE_CHECKING:
1011
from poetry.core.packages.dependency import Dependency
1112
from poetry.core.packages.package import Package
1213

1314
from poetry.mixology.incompatibility import Incompatibility
14-
from poetry.mixology.term import Term
1515

1616

1717
class PartialSolution:
@@ -146,6 +146,15 @@ def _register(self, assignment: Assignment) -> None:
146146
"""
147147
name = assignment.dependency.complete_name
148148
old_positive = self._positive.get(name)
149+
if old_positive is None and assignment.dependency.features:
150+
old_positive_without_features = self._positive.get(
151+
assignment.dependency.name
152+
)
153+
if old_positive_without_features is not None:
154+
dep = old_positive_without_features.dependency.with_features(
155+
assignment.dependency.features
156+
)
157+
old_positive = Term(dep, is_positive=True)
149158
if old_positive is not None:
150159
value = old_positive.intersect(assignment)
151160
assert value is not None

Diff for: tests/puzzle/test_solver.py

+52
Original file line numberDiff line numberDiff line change
@@ -3539,3 +3539,55 @@ def test_solver_keeps_multiple_locked_dependencies_for_same_package(
35393539
{"job": "install", "package": a12},
35403540
],
35413541
)
3542+
3543+
3544+
def test_solver_direct_origin_dependency_with_extras_requested_by_other_package(
3545+
solver: Solver, repo: Repository, package: ProjectPackage
3546+
):
3547+
"""
3548+
Another package requires the same dependency with extras that is required
3549+
by the project as direct origin dependency without any extras.
3550+
"""
3551+
pendulum = get_package("pendulum", "2.0.3") # required by demo
3552+
cleo = get_package("cleo", "1.0.0") # required by demo[foo]
3553+
demo_foo = get_package("demo-foo", "1.2.3")
3554+
demo_foo.add_dependency(
3555+
Factory.create_dependency("demo", {"version": ">=0.1", "extras": ["foo"]})
3556+
)
3557+
repo.add_package(demo_foo)
3558+
repo.add_package(pendulum)
3559+
repo.add_package(cleo)
3560+
3561+
path = (
3562+
Path(__file__).parent.parent
3563+
/ "fixtures"
3564+
/ "git"
3565+
/ "github.com"
3566+
/ "demo"
3567+
/ "demo"
3568+
).as_posix()
3569+
3570+
# project requires path dependency of demo while demo-foo requires demo[foo]
3571+
package.add_dependency(Factory.create_dependency("demo", {"path": path}))
3572+
package.add_dependency(Factory.create_dependency("demo-foo", "^1.2.3"))
3573+
3574+
transaction = solver.solve()
3575+
3576+
demo = Package("demo", "0.1.2", source_type="directory", source_url=path)
3577+
3578+
ops = check_solver_result(
3579+
transaction,
3580+
[
3581+
{"job": "install", "package": cleo},
3582+
{"job": "install", "package": pendulum},
3583+
{"job": "install", "package": demo},
3584+
{"job": "install", "package": demo_foo},
3585+
],
3586+
)
3587+
3588+
op = ops[2]
3589+
3590+
assert op.package.name == "demo"
3591+
assert op.package.version.text == "0.1.2"
3592+
assert op.package.source_type == "directory"
3593+
assert op.package.source_url == path

0 commit comments

Comments
 (0)