Skip to content

Commit ee2f92b

Browse files
committed
markers: avoid combinatorial explosion by replacing compatible MultiMarker/MarkerUnion with AtomicMultiMarker/AtomicMarkerUnion
1 parent eb0f2a3 commit ee2f92b

File tree

6 files changed

+386
-133
lines changed

6 files changed

+386
-133
lines changed

src/poetry/core/constraints/generic/union_constraint.py

+17-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from __future__ import annotations
22

3+
import itertools
4+
35
from poetry.core.constraints.generic import AnyConstraint
46
from poetry.core.constraints.generic.base_constraint import BaseConstraint
57
from poetry.core.constraints.generic.constraint import Constraint
@@ -132,19 +134,28 @@ def union(self, other: BaseConstraint) -> BaseConstraint:
132134
new_constraints: list[BaseConstraint] = []
133135
if isinstance(other, UnionConstraint):
134136
# (A or B) or (C or D) => A or B or C or D
137+
our_new_constraints: list[BaseConstraint] = []
138+
their_new_constraints: list[BaseConstraint] = []
139+
merged_new_constraints: list[BaseConstraint] = []
135140
for our_constraint in self._constraints:
136141
for their_constraint in other.constraints:
137142
union = our_constraint.union(their_constraint)
138143
if union.is_any():
139144
return AnyConstraint()
140145
if isinstance(union, Constraint):
141-
if union not in new_constraints:
142-
new_constraints.append(union)
146+
if union not in merged_new_constraints:
147+
merged_new_constraints.append(union)
143148
else:
144-
if our_constraint not in new_constraints:
145-
new_constraints.append(our_constraint)
146-
if their_constraint not in new_constraints:
147-
new_constraints.append(their_constraint)
149+
if our_constraint not in our_new_constraints:
150+
our_new_constraints.append(our_constraint)
151+
if their_constraint not in their_new_constraints:
152+
their_new_constraints.append(their_constraint)
153+
new_constraints = our_new_constraints
154+
for constraint in itertools.chain(
155+
their_new_constraints, merged_new_constraints
156+
):
157+
if constraint not in new_constraints:
158+
new_constraints.append(constraint)
148159

149160
else:
150161
assert isinstance(other, MultiConstraint)

src/poetry/core/packages/dependency.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,12 @@ def marker(self, marker: str | BaseMarker) -> None:
176176
self.deactivate()
177177

178178
for or_ in markers["extra"]:
179-
for _, extra in or_:
180-
self.in_extras.append(canonicalize_name(extra))
179+
for op, extra in or_:
180+
if op == "==":
181+
self.in_extras.append(canonicalize_name(extra))
182+
elif op == "" and "||" in extra:
183+
for _extra in extra.split(" || "):
184+
self.in_extras.append(canonicalize_name(_extra))
181185

182186
# Recalculate python versions.
183187
self._python_versions = "*"

src/poetry/core/packages/utils/utils.py

+13-4
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from poetry.core.constraints.version import VersionRange
1919
from poetry.core.constraints.version import parse_constraint
2020
from poetry.core.pyproject.toml import PyProjectTOML
21+
from poetry.core.version.markers import SingleMarkerLike
2122
from poetry.core.version.markers import dnf
2223

2324

@@ -179,10 +180,18 @@ def add_constraint(
179180
for i, sub_marker in enumerate(conjunctions):
180181
if isinstance(sub_marker, MultiMarker):
181182
for m in sub_marker.markers:
182-
assert isinstance(m, SingleMarker)
183-
add_constraint(m.name, (m.operator, m.value), i)
184-
elif isinstance(sub_marker, SingleMarker):
185-
add_constraint(sub_marker.name, (sub_marker.operator, sub_marker.value), i)
183+
assert isinstance(m, SingleMarkerLike)
184+
if isinstance(m, SingleMarker):
185+
add_constraint(m.name, (m.operator, m.value), i)
186+
else:
187+
add_constraint(m.name, ("", str(m.constraint)), i)
188+
elif isinstance(sub_marker, SingleMarkerLike):
189+
if isinstance(sub_marker, SingleMarker):
190+
add_constraint(
191+
sub_marker.name, (sub_marker.operator, sub_marker.value), i
192+
)
193+
else:
194+
add_constraint(sub_marker.name, ("", str(sub_marker.constraint)), i)
186195

187196
for group_name in requirements:
188197
# remove duplicates

0 commit comments

Comments
 (0)