Skip to content

Commit

Permalink
markers: avoid combinatorial explosion by replacing compatible MultiM…
Browse files Browse the repository at this point in the history
…arker/MarkerUnion with AtomicMultiMarker/AtomicMarkerUnion
  • Loading branch information
radoering committed Mar 31, 2023
1 parent eb0f2a3 commit ee2f92b
Show file tree
Hide file tree
Showing 6 changed files with 386 additions and 133 deletions.
23 changes: 17 additions & 6 deletions src/poetry/core/constraints/generic/union_constraint.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from __future__ import annotations

import itertools

from poetry.core.constraints.generic import AnyConstraint
from poetry.core.constraints.generic.base_constraint import BaseConstraint
from poetry.core.constraints.generic.constraint import Constraint
Expand Down Expand Up @@ -132,19 +134,28 @@ def union(self, other: BaseConstraint) -> BaseConstraint:
new_constraints: list[BaseConstraint] = []
if isinstance(other, UnionConstraint):
# (A or B) or (C or D) => A or B or C or D
our_new_constraints: list[BaseConstraint] = []
their_new_constraints: list[BaseConstraint] = []
merged_new_constraints: list[BaseConstraint] = []
for our_constraint in self._constraints:
for their_constraint in other.constraints:
union = our_constraint.union(their_constraint)
if union.is_any():
return AnyConstraint()
if isinstance(union, Constraint):
if union not in new_constraints:
new_constraints.append(union)
if union not in merged_new_constraints:
merged_new_constraints.append(union)
else:
if our_constraint not in new_constraints:
new_constraints.append(our_constraint)
if their_constraint not in new_constraints:
new_constraints.append(their_constraint)
if our_constraint not in our_new_constraints:
our_new_constraints.append(our_constraint)
if their_constraint not in their_new_constraints:
their_new_constraints.append(their_constraint)
new_constraints = our_new_constraints
for constraint in itertools.chain(
their_new_constraints, merged_new_constraints
):
if constraint not in new_constraints:
new_constraints.append(constraint)

else:
assert isinstance(other, MultiConstraint)
Expand Down
8 changes: 6 additions & 2 deletions src/poetry/core/packages/dependency.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,12 @@ def marker(self, marker: str | BaseMarker) -> None:
self.deactivate()

for or_ in markers["extra"]:
for _, extra in or_:
self.in_extras.append(canonicalize_name(extra))
for op, extra in or_:
if op == "==":
self.in_extras.append(canonicalize_name(extra))
elif op == "" and "||" in extra:
for _extra in extra.split(" || "):
self.in_extras.append(canonicalize_name(_extra))

# Recalculate python versions.
self._python_versions = "*"
Expand Down
17 changes: 13 additions & 4 deletions src/poetry/core/packages/utils/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from poetry.core.constraints.version import VersionRange
from poetry.core.constraints.version import parse_constraint
from poetry.core.pyproject.toml import PyProjectTOML
from poetry.core.version.markers import SingleMarkerLike
from poetry.core.version.markers import dnf


Expand Down Expand Up @@ -179,10 +180,18 @@ def add_constraint(
for i, sub_marker in enumerate(conjunctions):
if isinstance(sub_marker, MultiMarker):
for m in sub_marker.markers:
assert isinstance(m, SingleMarker)
add_constraint(m.name, (m.operator, m.value), i)
elif isinstance(sub_marker, SingleMarker):
add_constraint(sub_marker.name, (sub_marker.operator, sub_marker.value), i)
assert isinstance(m, SingleMarkerLike)
if isinstance(m, SingleMarker):
add_constraint(m.name, (m.operator, m.value), i)
else:
add_constraint(m.name, ("", str(m.constraint)), i)
elif isinstance(sub_marker, SingleMarkerLike):
if isinstance(sub_marker, SingleMarker):
add_constraint(
sub_marker.name, (sub_marker.operator, sub_marker.value), i
)
else:
add_constraint(sub_marker.name, ("", str(sub_marker.constraint)), i)

for group_name in requirements:
# remove duplicates
Expand Down
Loading

0 comments on commit ee2f92b

Please sign in to comment.