From bdba453920c3bf2efa824ac8aa46c13debc9b604 Mon Sep 17 00:00:00 2001 From: David Hotham Date: Fri, 5 May 2023 13:00:16 +0100 Subject: [PATCH] Fix allows_any() with local versions --- .../core/constraints/version/version.py | 19 +++++++++-------- .../core/constraints/version/version_range.py | 21 +++++++++++++++++-- tests/constraints/version/test_version.py | 17 ++++++++++++++- 3 files changed, 45 insertions(+), 12 deletions(-) diff --git a/src/poetry/core/constraints/version/version.py b/src/poetry/core/constraints/version/version.py index faba17392..2a60d832e 100644 --- a/src/poetry/core/constraints/version/version.py +++ b/src/poetry/core/constraints/version/version.py @@ -93,19 +93,20 @@ def allows_all(self, other: VersionConstraint) -> bool: ) def allows_any(self, other: VersionConstraint) -> bool: - if isinstance(other, Version): - return self.allows(other) + intersection = self.intersect(other) + return not intersection.is_empty() - return other.allows(self) + def intersect(self, other: VersionConstraint) -> VersionConstraint: + if isinstance(other, Version): + if self.allows(other): + return other - def intersect(self, other: VersionConstraint) -> Version | EmptyConstraint: - if other.allows(self): - return self + if other.allows(self): + return self - if isinstance(other, Version) and self.allows(other): - return other + return EmptyConstraint() - return EmptyConstraint() + return other.intersect(self) def union(self, other: VersionConstraint) -> VersionConstraint: from poetry.core.constraints.version.version_range import VersionRange diff --git a/src/poetry/core/constraints/version/version_range.py b/src/poetry/core/constraints/version/version_range.py index 6d02797e6..8eda13b98 100644 --- a/src/poetry/core/constraints/version/version_range.py +++ b/src/poetry/core/constraints/version/version_range.py @@ -124,7 +124,14 @@ def allows_any(self, other: VersionConstraint) -> bool: return False if isinstance(other, Version): - return self.allows(other) + if self.allows(other): + return True + + # Although `>=1.2.3+local` does not allow the exact version `1.2.3`, both of + # those versions do allow `1.2.3+local`. + return ( + self.min is not None and self.min.is_local() and other.allows(self.min) + ) if isinstance(other, VersionUnion): return any(self.allows_any(constraint) for constraint in other.ranges) @@ -143,11 +150,21 @@ def intersect(self, other: VersionConstraint) -> VersionConstraint: if isinstance(other, VersionUnion): return other.intersect(self) - # A range and a Version just yields the version if it's in the range. if isinstance(other, Version): + # A range and a Version just yields the version if it's in the range. if self.allows(other): return other + # `>=1.2.3+local` intersects `1.2.3` to return `>=1.2.3+local,<1.2.4`. + if self.min is not None and self.min.is_local() and other.allows(self.min): + upper = other.stable.next_patch() + return VersionRange( + min=self.min, + max=upper, + include_min=self.include_min, + include_max=False, + ) + return EmptyConstraint() if not isinstance(other, VersionRangeConstraint): diff --git a/tests/constraints/version/test_version.py b/tests/constraints/version/test_version.py index dba08787b..5beb1655e 100644 --- a/tests/constraints/version/test_version.py +++ b/tests/constraints/version/test_version.py @@ -374,10 +374,15 @@ def test_allows_all() -> None: Version.parse("1.2.3+cpu"), True, ), + ( + Version.parse("1.2.3"), + VersionRange(Version.parse("1.2.3+local"), include_min=True), + True, + ), ( Version.parse("1.2.3+cpu"), Version.parse("1.2.3"), - False, + True, ), ( Version.parse("1.2.3"), @@ -438,6 +443,16 @@ def test_allows_any( Version.parse("1.2.3+local"), Version.parse("1.2.3+local"), ), + ( + Version.parse("1.2.3"), + VersionRange(Version.parse("1.2.3+local"), include_min=True), + VersionRange( + Version.parse("1.2.3+local"), + Version.parse("1.2.4"), + include_min=True, + include_max=False, + ), + ), ], ) def test_intersect(