diff --git a/src/poetry/core/version/markers.py b/src/poetry/core/version/markers.py index 5108598e2..5dfb33fd8 100644 --- a/src/poetry/core/version/markers.py +++ b/src/poetry/core/version/markers.py @@ -49,6 +49,7 @@ class UndefinedEnvironmentName(ValueError): "python_implementation": "platform_python_implementation", } +PYTHON_VERSION_MARKERS = ["python_version", "python_full_version"] # Parser: PEP 508 Environment Markers _parser = Parser(GRAMMAR_PEP_508_MARKERS, "lalr") @@ -259,22 +260,6 @@ def value(self) -> str: def intersect(self, other: MarkerTypes) -> MarkerTypes: if isinstance(other, SingleMarker): - if other.name != self.name: - return MultiMarker(self, other) - - if self == other: - return self - - if self._operator in {"in", "not in"} or other.operator in {"in", "not in"}: - return MultiMarker.of(self, other) - - new_constraint = self._constraint.intersect(other.constraint) - if new_constraint.is_empty(): - return EmptyMarker() - - if new_constraint == self._constraint or new_constraint == other.constraint: - return SingleMarker(self._name, new_constraint) - return MultiMarker.of(self, other) return other.intersect(self) @@ -416,7 +401,13 @@ def of(cls, *markers: MarkerTypes) -> MarkerTypes: if isinstance(marker, SingleMarker): intersected = False for i, mark in enumerate(new_markers): - if isinstance(mark, SingleMarker) and mark.name == marker.name: + if isinstance(mark, SingleMarker) and ( + mark.name == marker.name + or ( + mark.name in PYTHON_VERSION_MARKERS + and marker.name in PYTHON_VERSION_MARKERS + ) + ): intersection = mark.constraint.intersect(marker.constraint) if intersection == mark.constraint: intersected = True @@ -560,13 +551,15 @@ def of(cls, *markers: BaseMarker) -> MarkerTypes: if marker in markers: continue - if isinstance(marker, SingleMarker) and marker.name == "python_version": + if ( + isinstance(marker, SingleMarker) + and marker.name in PYTHON_VERSION_MARKERS + ): included = False for i, mark in enumerate(markers): if ( not isinstance(mark, SingleMarker) - or isinstance(mark, SingleMarker) - and mark.name != marker.name + or mark.name not in PYTHON_VERSION_MARKERS ): continue diff --git a/tests/version/test_markers.py b/tests/version/test_markers.py index d3c8cc99b..be1ef3c2b 100644 --- a/tests/version/test_markers.py +++ b/tests/version/test_markers.py @@ -159,6 +159,14 @@ def test_single_marker_not_in_python_intersection(): assert str(intersection) == 'python_version not in "2.7, 3.0, 3.1, 3.2"' +def test_marker_intersection_of_python_version_and_python_full_version(): + m = parse_marker('python_version >= "3.6"') + m2 = parse_marker('python_full_version >= "3.0.0"') + intersection = m.intersect(m2) + + assert str(intersection) == 'python_version >= "3.6"' + + def test_single_marker_union(): m = parse_marker('sys_platform == "darwin"') @@ -369,6 +377,14 @@ def test_marker_union_deduplicate(): assert str(m) == 'sys_platform == "darwin" or implementation_name == "cpython"' +def test_marker_union_of_python_version_and_python_full_version(): + m = parse_marker('python_version >= "3.6"') + m2 = parse_marker('python_full_version >= "3.0.0"') + union = m.union(m2) + + assert str(union) == 'python_full_version >= "3.0.0"' + + def test_marker_union_intersect_single_marker(): m = parse_marker('sys_platform == "darwin" or python_version < "3.4"')