Skip to content

Commit

Permalink
perf: return least complex marker when building intersection
Browse files Browse the repository at this point in the history
This is analogous to what we do when building the union. Although this means extra work, it pays off if the resulting marker is used in another marker operation.
  • Loading branch information
radoering committed Jan 19, 2025
1 parent ed9ac8c commit cd5c538
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 15 deletions.
19 changes: 18 additions & 1 deletion src/poetry/core/version/markers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1076,7 +1076,24 @@ def dnf(marker: BaseMarker) -> BaseMarker:


def intersection(*markers: BaseMarker) -> BaseMarker:
return dnf(MultiMarker(*markers))
# Sometimes normalization makes it more complicate instead of simple
# -> choose candidate with the least complexity
unnormalized: BaseMarker = MultiMarker(*markers)
while (
isinstance(unnormalized, (MultiMarker, MarkerUnion))
and len(unnormalized.markers) == 1
):
unnormalized = unnormalized.markers[0]

disjunction = dnf(MultiMarker(*markers))
if not isinstance(disjunction, MarkerUnion):
return disjunction

conjunction = cnf(disjunction)
if not isinstance(conjunction, MultiMarker):
return conjunction

return min(disjunction, conjunction, unnormalized, key=lambda x: x.complexity)


def union(*markers: BaseMarker) -> BaseMarker:
Expand Down
22 changes: 8 additions & 14 deletions tests/version/test_markers.py
Original file line number Diff line number Diff line change
Expand Up @@ -940,9 +940,8 @@ def test_marker_union_intersect_single_marker() -> None:

intersection = m.intersect(parse_marker('implementation_name == "cpython"'))
assert (
str(intersection)
== 'sys_platform == "darwin" and implementation_name == "cpython" '
'or python_version < "3.4" and implementation_name == "cpython"'
str(intersection) == '(sys_platform == "darwin" or python_version < "3.4")'
' and implementation_name == "cpython"'
)


Expand All @@ -968,11 +967,8 @@ def test_marker_union_intersect_marker_union() -> None:
parse_marker('implementation_name == "cpython" or os_name == "Windows"')
)
assert (
str(intersection)
== 'sys_platform == "darwin" and implementation_name == "cpython" '
'or sys_platform == "darwin" and os_name == "Windows" or '
'python_version < "3.4" and implementation_name == "cpython" or '
'python_version < "3.4" and os_name == "Windows"'
str(intersection) == '(sys_platform == "darwin" or python_version < "3.4") and '
'(implementation_name == "cpython" or os_name == "Windows")'
)


Expand Down Expand Up @@ -1000,18 +996,16 @@ def test_marker_union_intersect_multi_marker() -> None:

# Intersection isn't _quite_ symmetrical.
expected1 = (
'sys_platform == "darwin" and implementation_name == "cpython" and os_name =='
' "Windows" or python_version < "3.4" and implementation_name == "cpython" and'
' os_name == "Windows"'
'(sys_platform == "darwin" or python_version < "3.4")'
' and implementation_name == "cpython" and os_name == "Windows"'
)

intersection = m1.intersect(m2)
assert str(intersection) == expected1

expected2 = (
'implementation_name == "cpython" and os_name == "Windows" and sys_platform'
' == "darwin" or implementation_name == "cpython" and os_name == "Windows"'
' and python_version < "3.4"'
'implementation_name == "cpython" and os_name == "Windows"'
' and (sys_platform == "darwin" or python_version < "3.4")'
)

intersection = m2.intersect(m1)
Expand Down

0 comments on commit cd5c538

Please sign in to comment.