Skip to content

Commit

Permalink
Single marker union simplifications
Browse files Browse the repository at this point in the history
  • Loading branch information
radoering authored and bostonrwalker committed Aug 29, 2022
1 parent 469c564 commit cd48675
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 26 deletions.
3 changes: 3 additions & 0 deletions src/poetry/core/semver/empty_constraint.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ def is_empty(self) -> bool:
def is_any(self) -> bool:
return False

def is_simple(self) -> bool:
return True

def allows(self, version: "Version") -> bool:
return False

Expand Down
3 changes: 3 additions & 0 deletions src/poetry/core/semver/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ def is_any(self) -> bool:
def is_empty(self) -> bool:
return False

def is_simple(self) -> bool:
return True

def allows(self, version: "Version") -> bool:
if version is None:
return False
Expand Down
4 changes: 4 additions & 0 deletions src/poetry/core/semver/version_constraint.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ def is_empty(self) -> bool:
def is_any(self) -> bool:
raise NotImplementedError()

@abstractmethod
def is_simple(self) -> bool:
raise NotImplementedError()

@abstractmethod
def allows(self, version: "Version") -> bool:
raise NotImplementedError()
Expand Down
3 changes: 3 additions & 0 deletions src/poetry/core/semver/version_range.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ def is_empty(self) -> bool:
def is_any(self) -> bool:
return self._min is None and self._max is None

def is_simple(self) -> bool:
return self._min is None or self._max is None

def allows(self, other: "Version") -> bool:
if self._min is not None:
if other < self._min:
Expand Down
3 changes: 3 additions & 0 deletions src/poetry/core/semver/version_union.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ def is_empty(self) -> bool:
def is_any(self) -> bool:
return False

def is_simple(self) -> bool:
return self.excludes_single_version()

def allows(self, version: "Version") -> bool:
return any([constraint.allows(version) for constraint in self._ranges])

Expand Down
46 changes: 24 additions & 22 deletions src/poetry/core/version/markers.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from typing import Type
from typing import Union

from poetry.core.semver.version_constraint import VersionConstraint
from poetry.core.version.grammars import GRAMMAR_PEP_508_MARKERS
from poetry.core.version.parser import Parser

Expand All @@ -16,7 +17,6 @@
from lark import Tree

from poetry.core.packages.constraints import BaseConstraint
from poetry.core.semver.version_constraint import VersionConstraint


class InvalidMarker(ValueError):
Expand Down Expand Up @@ -183,7 +183,7 @@ class SingleMarker(BaseMarker):
}

def __init__(
self, name: str, constraint: Union[str, "BaseConstraint", "VersionConstraint"]
self, name: str, constraint: Union[str, "BaseConstraint", VersionConstraint]
) -> None:
from poetry.core.packages.constraints import (
parse_constraint as parse_generic_constraint,
Expand Down Expand Up @@ -247,7 +247,7 @@ def constraint_string(self) -> str:
return self._constraint_string

@property
def constraint(self) -> Union["BaseConstraint", "VersionConstraint"]:
def constraint(self) -> Union["BaseConstraint", VersionConstraint]:
return self._constraint

@property
Expand Down Expand Up @@ -552,28 +552,30 @@ def of(cls, *markers: BaseMarker) -> BaseMarker:
if marker in new_markers:
continue

if (
isinstance(marker, SingleMarker)
and marker.name in PYTHON_VERSION_MARKERS
):
if isinstance(marker, SingleMarker):
included = False
for i, mark in enumerate(new_markers):
if (
not isinstance(mark, SingleMarker)
or mark.name not in PYTHON_VERSION_MARKERS
if isinstance(mark, SingleMarker) and (
mark.name == marker.name
or (
mark.name in PYTHON_VERSION_MARKERS
and marker.name in PYTHON_VERSION_MARKERS
)
):
continue

union = mark.constraint.union(marker.constraint)
if union == mark.constraint:
included = True
break
elif union == marker.constraint:
new_markers[i] = marker
included = True
break
elif union.is_any():
return AnyMarker()
union = mark.constraint.union(marker.constraint)
if union == mark.constraint:
included = True
break
elif union == marker.constraint:
new_markers[i] = marker
included = True
break
elif union.is_any():
return AnyMarker()
elif isinstance(union, VersionConstraint) and union.is_simple():
new_markers[i] = SingleMarker(mark.name, union)
included = True
break

if included:
continue
Expand Down
42 changes: 38 additions & 4 deletions tests/version/test_markers.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,17 +173,51 @@ def test_single_marker_union():
union = m.union(parse_marker('implementation_name == "cpython"'))
assert str(union) == 'sys_platform == "darwin" or implementation_name == "cpython"'


def test_single_marker_union_is_any():
m = parse_marker('python_version >= "3.4"')

union = m.union(parse_marker('python_version < "3.6"'))
assert union.is_any()


def test_single_marker_union_compacts_constraints():
m = parse_marker('python_version < "3.6"')
@pytest.mark.parametrize(
("marker1", "marker2", "expected"),
[
(
'python_version < "3.6"',
'python_version < "3.4"',
'python_version < "3.6"',
),
(
'sys_platform == "linux"',
'sys_platform != "win32"',
'sys_platform != "win32"',
),
(
'python_version == "3.6"',
'python_version > "3.6"',
'python_version >= "3.6"',
),
(
'python_version == "3.6"',
'python_version < "3.6"',
'python_version <= "3.6"',
),
(
'python_version < "3.6"',
'python_version > "3.6"',
'python_version != "3.6"',
),
],
)
def test_single_marker_union_is_single_marker(
marker1: str, marker2: str, expected: str
):
m = parse_marker(marker1)

union = m.union(parse_marker('python_version < "3.4"'))
assert str(union) == 'python_version < "3.6"'
union = m.union(parse_marker(marker2))
assert str(union) == expected


def test_single_marker_union_with_multi():
Expand Down

0 comments on commit cd48675

Please sign in to comment.