From aec98bed49907d4a2b494f1e6a66f8d14c6dfb7d Mon Sep 17 00:00:00 2001 From: David Hotham Date: Tue, 7 Jun 2022 11:53:19 +0100 Subject: [PATCH] make intersection of two Versions symmetrical --- src/poetry/core/semver/empty_constraint.py | 6 +++ src/poetry/core/semver/version.py | 3 ++ tests/semver/test_version.py | 49 ++++++++++++++++------ 3 files changed, 45 insertions(+), 13 deletions(-) diff --git a/src/poetry/core/semver/empty_constraint.py b/src/poetry/core/semver/empty_constraint.py index 56d1f2108..5cd7ea73b 100644 --- a/src/poetry/core/semver/empty_constraint.py +++ b/src/poetry/core/semver/empty_constraint.py @@ -43,3 +43,9 @@ def flatten(self) -> list[VersionRangeConstraint]: def __str__(self) -> str: return "" + + def __eq__(self, other: object) -> bool: + if not isinstance(other, VersionConstraint): + return False + + return other.is_empty() diff --git a/src/poetry/core/semver/version.py b/src/poetry/core/semver/version.py index 417d23a1d..356ac9e09 100644 --- a/src/poetry/core/semver/version.py +++ b/src/poetry/core/semver/version.py @@ -107,6 +107,9 @@ def intersect(self, other: VersionConstraint) -> Version | EmptyConstraint: if other.allows(self): return self + if isinstance(other, Version) and self.allows(other): + return other + return EmptyConstraint() def union(self, other: VersionConstraint) -> VersionConstraint: diff --git a/tests/semver/test_version.py b/tests/semver/test_version.py index 90d3c503c..787dad2af 100644 --- a/tests/semver/test_version.py +++ b/tests/semver/test_version.py @@ -1,5 +1,7 @@ from __future__ import annotations +from typing import TYPE_CHECKING + import pytest from poetry.core.semver.empty_constraint import EmptyConstraint @@ -9,6 +11,10 @@ from poetry.core.version.pep440 import ReleaseTag +if TYPE_CHECKING: + from poetry.core.semver.version_constraint import VersionConstraint + + @pytest.mark.parametrize( "text,version", [ @@ -163,19 +169,36 @@ def test_allows_any() -> None: assert not v.allows_any(EmptyConstraint()) -def test_intersect() -> None: - v = Version.parse("1.2.3") - - assert v.intersect(v) == v - assert v.intersect(Version.parse("1.1.4")).is_empty() - assert ( - v.intersect(VersionRange(Version.parse("1.1.4"), Version.parse("1.2.4"))) == v - ) - assert ( - Version.parse("1.1.4") - .intersect(VersionRange(v, Version.parse("1.2.4"))) - .is_empty() - ) +@pytest.mark.parametrize( + ("version1", "version2", "expected"), + [ + ( + Version.parse("1.2.3"), + Version.parse("1.1.4"), + EmptyConstraint(), + ), + ( + Version.parse("1.2.3"), + VersionRange(Version.parse("1.1.4"), Version.parse("1.2.4")), + Version.parse("1.2.3"), + ), + ( + Version.parse("1.1.4"), + VersionRange(Version.parse("1.2.3"), Version.parse("1.2.4")), + EmptyConstraint(), + ), + ( + Version.parse("1.2.3"), + Version.parse("1.2.3.post0"), + Version.parse("1.2.3.post0"), + ), + ], +) +def test_intersect( + version1: Version, version2: Version, expected: VersionConstraint +) -> None: + assert version1.intersect(version2) == expected + assert version2.intersect(version1) == expected def test_union() -> None: