Skip to content

Commit

Permalink
Add: Add additional comparison for Version classes (ge, lt and le)
Browse files Browse the repository at this point in the history
Allow to compare versions with greater or equal then, less then and less
or equal then. This is required for comparing CPE versions.
  • Loading branch information
bjoernricks committed Nov 10, 2023
1 parent fe6835f commit 863f54a
Show file tree
Hide file tree
Showing 5 changed files with 526 additions and 14 deletions.
21 changes: 21 additions & 0 deletions pontos/version/schemes/_pep440.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,27 @@ def __gt__(self, other: Any) -> bool:
other = self.from_version(other)
return self._version > other._version

def __ge__(self, other: Any) -> bool:
if not isinstance(other, Version):
raise ValueError(f"Can't compare {type(self)} with {type(other)}")
if not isinstance(other, type(self)):
other = self.from_version(other)
return self._version >= other._version

def __lt__(self, other: Any) -> bool:
if not isinstance(other, Version):
raise ValueError(f"Can't compare {type(self)} with {type(other)}")
if not isinstance(other, type(self)):
other = self.from_version(other)
return self._version < other._version

def __le__(self, other: Any) -> bool:
if not isinstance(other, Version):
raise ValueError(f"Can't compare {type(self)} with {type(other)}")
if not isinstance(other, type(self)):
other = self.from_version(other)
return self._version <= other._version

def __str__(self) -> str:
return str(self._version)

Expand Down
36 changes: 22 additions & 14 deletions pontos/version/schemes/_semantic.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,20 +164,7 @@ def __eq__(self, other: Any) -> bool:
)

def __ne__(self, other: Any) -> bool:
if other is None:
return True
if isinstance(other, str):
# allow to compare against "current" for now
return True
if not isinstance(other, Version):
raise ValueError(f"Can't compare {type(self)} with {type(other)}")
if not isinstance(other, type(self)):
other = self.from_version(other)

return (
self._version_info != other._version_info
or self._version_info.build != other._version_info.build
)
return not self == other

def __gt__(self, other: Any) -> bool:
if not isinstance(other, Version):
Expand Down Expand Up @@ -223,6 +210,27 @@ def __gt__(self, other: Any) -> bool:
# both are equal
return False

def __ge__(self, other: Any) -> bool:
if not isinstance(other, Version):
raise ValueError(f"Can't compare {type(self)} with {type(other)}")
if not isinstance(other, type(self)):
other = self.from_version(other)
return self > other or self == other

def __lt__(self, other: Any) -> bool:
if not isinstance(other, Version):
raise ValueError(f"Can't compare {type(self)} with {type(other)}")
if not isinstance(other, type(self)):
other = self.from_version(other)
return (not self > other) and self != other

def __le__(self, other: Any) -> bool:
if not isinstance(other, Version):
raise ValueError(f"Can't compare {type(self)} with {type(other)}")
if not isinstance(other, type(self)):
other = self.from_version(other)
return not self > other or self == other

def __str__(self) -> str:
"""A string representation of the version"""
return str(self._version_info)
Expand Down
12 changes: 12 additions & 0 deletions pontos/version/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,18 @@ def __ne__(self, other: Any) -> bool:
def __gt__(self, other: Any) -> bool:
pass

@abstractmethod
def __ge__(self, other: Any) -> bool:
pass

@abstractmethod
def __lt__(self, other: Any) -> bool:
pass

@abstractmethod
def __le__(self, other: Any) -> bool:
pass

@abstractmethod
def __str__(self) -> str:
"""A string representation of the version"""
Expand Down
234 changes: 234 additions & 0 deletions tests/version/schemes/test_pep440.py
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,240 @@ def test_greater_then(self):
f"{version1} should not be greater then {version2}",
)

versions = [
("1.0.0", object()),
("1.0.0", 1),
("1.0.0", True),
]
for version1, version2 in versions:
with self.assertRaisesRegex(ValueError, "Can't compare"):
self.assertFalse(Version.from_string(version1) > version2)

def test_greater_or_equal_then(self):
versions = [
("1.0.0", "0.9.9999"),
("1.0.1", "1.0.0"),
("1.0.0", "1.0.0"),
("1.0.0", "1.0.0.dev1"),
("1.0.0", "1.0.0-alpha1"),
("1.0.0", "1.0.0-alpha1"),
("1.0.0", "1.0.0-beta1"),
("1.0.0", "1.0.0-rc1"),
("1.0.0.dev1", "1.0.0.dev1"),
("1.0.0+dev1", "1.0.0+dev1"),
("1.0.0-alpha1", "1.0.0-dev1"),
("1.0.0-alpha1", "1.0.0-alpha1.dev1"),
("1.0.0-alpha1", "1.0.0-alpha1"),
("1.0.0-alpha2", "1.0.0-alpha1"),
("1.0.0-alpha1.dev1", "1.0.0-alpha1.dev1"),
("1.0.0-beta1", "1.0.0-dev1"),
("1.0.0-beta1", "1.0.0-alpha1"),
("1.0.0-beta1", "1.0.0-beta1"),
("1.0.0-beta1", "1.0.0-beta1.dev1"),
("1.0.0-beta2", "1.0.0-beta1"),
("1.0.0-beta1.dev1", "1.0.0-beta1.dev1"),
("1.0.0-rc1", "1.0.0-rc1"),
("1.0.0-rc1", "1.0.0-dev1"),
("1.0.0-rc1", "1.0.0-alpha1"),
("1.0.0-rc1", "1.0.0-beta1"),
("1.0.0-rc1", "1.0.0-rc1.dev1"),
("1.0.0-rc1.dev1", "1.0.0-rc1.dev1"),
("1.0.0-rc2", "1.0.0-rc1"),
]
for version1, version2 in versions:
self.assertTrue(
Version.from_string(version1) >= Version.from_string(version2),
f"{version1} should be greater or equal then {version2}",
)

versions = [
("1.0.0", "1.0.0+dev1"),
("1.0.0.dev1", "1.0.0.dev2"),
("1.0.0", "1.0.1"),
("1.0.0-dev1", "1.0.0"),
("1.0.0-dev1", "1.0.0-alpha1"),
("1.0.0-dev1", "1.0.0-beta1"),
("1.0.0-dev1", "1.0.0-rc1"),
("1.0.0+dev1", "1.0.0+dev2"),
("1.0.0-alpha1", "1.0.0-beta1"),
("1.0.0-alpha1", "1.0.0-rc1"),
("1.0.0-alpha1", "1.0.0-alpha1+dev1"),
("1.0.0-alpha1.dev1", "1.0.0-alpha1.dev2"),
("1.0.0-alpha1+dev1", "1.0.0-alpha1+dev2"),
("1.0.0-beta1", "1.0.0-rc1"),
("1.0.0-beta1", "1.0.0-beta1+dev1"),
("1.0.0-beta1.dev1", "1.0.0-beta1.dev2"),
("1.0.0-beta1+dev1", "1.0.0-beta1+dev2"),
("1.0.0-rc1", "1.0.0"),
("1.0.0-rc1", "1.0.0-rc1+dev1"),
("1.0.0-rc1.dev1", "1.0.0-rc1.dev2"),
("1.0.0-rc1+dev1", "1.0.0-rc1+dev2"),
]
for version1, version2 in versions:
self.assertFalse(
Version.from_string(version1) >= Version.from_string(version2),
f"{version1} should not be greater or equal then {version2}",
)

versions = [
("1.0.0", object()),
("1.0.0", 1),
("1.0.0", True),
]
for version1, version2 in versions:
with self.assertRaisesRegex(ValueError, "Can't compare"):
self.assertFalse(Version.from_string(version1) >= version2)

def test_less_then(self):
versions = [
("1.0.0", "0.9.9999"),
("1.0.1", "1.0.0"),
("1.0.0", "1.0.0.dev1"),
("1.0.0", "1.0.0-alpha1"),
("1.0.0", "1.0.0-alpha1"),
("1.0.0", "1.0.0-beta1"),
("1.0.0", "1.0.0-rc1"),
("1.0.0-alpha1", "1.0.0-dev1"),
("1.0.0-alpha1", "1.0.0-alpha1.dev1"),
("1.0.0-alpha2", "1.0.0-alpha1"),
("1.0.0-beta1", "1.0.0-dev1"),
("1.0.0-beta1", "1.0.0-alpha1"),
("1.0.0-beta1", "1.0.0-beta1.dev1"),
("1.0.0-beta2", "1.0.0-beta1"),
("1.0.0-rc1", "1.0.0-dev1"),
("1.0.0-rc1", "1.0.0-alpha1"),
("1.0.0-rc1", "1.0.0-beta1"),
("1.0.0-rc1", "1.0.0-rc1.dev1"),
("1.0.0-rc2", "1.0.0-rc1"),
]
for version2, version1 in versions:
self.assertTrue(
Version.from_string(version1) < Version.from_string(version2),
f"{version1} should be less then {version2}",
)

versions = [
("1.0.0", "1.0.0"),
("1.0.0", "1.0.0+dev1"),
("1.0.0.dev1", "1.0.0.dev1"),
("1.0.0.dev1", "1.0.0.dev2"),
("1.0.0", "1.0.1"),
("1.0.0-dev1", "1.0.0"),
("1.0.0-dev1", "1.0.0-alpha1"),
("1.0.0-dev1", "1.0.0-beta1"),
("1.0.0-dev1", "1.0.0-rc1"),
("1.0.0+dev1", "1.0.0+dev1"),
("1.0.0+dev1", "1.0.0+dev2"),
("1.0.0-alpha1", "1.0.0-alpha1"),
("1.0.0-alpha1", "1.0.0-beta1"),
("1.0.0-alpha1", "1.0.0-rc1"),
("1.0.0-alpha1", "1.0.0-alpha1+dev1"),
("1.0.0-alpha1.dev1", "1.0.0-alpha1.dev1"),
("1.0.0-alpha1.dev1", "1.0.0-alpha1.dev2"),
("1.0.0-alpha1+dev1", "1.0.0-alpha1+dev2"),
("1.0.0-beta1", "1.0.0-rc1"),
("1.0.0-beta1", "1.0.0-beta1"),
("1.0.0-beta1", "1.0.0-beta1+dev1"),
("1.0.0-beta1.dev1", "1.0.0-beta1.dev1"),
("1.0.0-beta1.dev1", "1.0.0-beta1.dev2"),
("1.0.0-beta1+dev1", "1.0.0-beta1+dev2"),
("1.0.0-rc1", "1.0.0"),
("1.0.0-rc1", "1.0.0-rc1"),
("1.0.0-rc1", "1.0.0-rc1+dev1"),
("1.0.0-rc1.dev1", "1.0.0-rc1.dev1"),
("1.0.0-rc1.dev1", "1.0.0-rc1.dev2"),
("1.0.0-rc1+dev1", "1.0.0-rc1+dev2"),
]
for version2, version1 in versions:
self.assertFalse(
Version.from_string(version1) < Version.from_string(version2),
f"{version1} should not be less then {version2}",
)

versions = [
("1.0.0", object()),
("1.0.0", 1),
("1.0.0", True),
]
for version1, version2 in versions:
with self.assertRaisesRegex(ValueError, "Can't compare"):
self.assertFalse(Version.from_string(version1) < version2)

def test_less_or_equal_then(self):
versions = [
("1.0.0", "0.9.9999"),
("1.0.1", "1.0.0"),
("1.0.0", "1.0.0"),
("1.0.0", "1.0.0.dev1"),
("1.0.0", "1.0.0-alpha1"),
("1.0.0", "1.0.0-alpha1"),
("1.0.0", "1.0.0-beta1"),
("1.0.0", "1.0.0-rc1"),
("1.0.0.dev1", "1.0.0.dev1"),
("1.0.0+dev1", "1.0.0+dev1"),
("1.0.0-alpha1", "1.0.0-dev1"),
("1.0.0-alpha1", "1.0.0-alpha1.dev1"),
("1.0.0-alpha1", "1.0.0-alpha1"),
("1.0.0-alpha2", "1.0.0-alpha1"),
("1.0.0-alpha1.dev1", "1.0.0-alpha1.dev1"),
("1.0.0-beta1", "1.0.0-dev1"),
("1.0.0-beta1", "1.0.0-alpha1"),
("1.0.0-beta1", "1.0.0-beta1"),
("1.0.0-beta1", "1.0.0-beta1.dev1"),
("1.0.0-beta2", "1.0.0-beta1"),
("1.0.0-beta1.dev1", "1.0.0-beta1.dev1"),
("1.0.0-rc1", "1.0.0-rc1"),
("1.0.0-rc1", "1.0.0-dev1"),
("1.0.0-rc1", "1.0.0-alpha1"),
("1.0.0-rc1", "1.0.0-beta1"),
("1.0.0-rc1", "1.0.0-rc1.dev1"),
("1.0.0-rc1.dev1", "1.0.0-rc1.dev1"),
("1.0.0-rc2", "1.0.0-rc1"),
]
for version2, version1 in versions:
self.assertTrue(
Version.from_string(version1) <= Version.from_string(version2),
f"{version1} should be less or equal then {version2}",
)

versions = [
("1.0.0", "1.0.0+dev1"),
("1.0.0.dev1", "1.0.0.dev2"),
("1.0.0", "1.0.1"),
("1.0.0-dev1", "1.0.0"),
("1.0.0-dev1", "1.0.0-alpha1"),
("1.0.0-dev1", "1.0.0-beta1"),
("1.0.0-dev1", "1.0.0-rc1"),
("1.0.0+dev1", "1.0.0+dev2"),
("1.0.0-alpha1", "1.0.0-beta1"),
("1.0.0-alpha1", "1.0.0-rc1"),
("1.0.0-alpha1", "1.0.0-alpha1+dev1"),
("1.0.0-alpha1.dev1", "1.0.0-alpha1.dev2"),
("1.0.0-alpha1+dev1", "1.0.0-alpha1+dev2"),
("1.0.0-beta1", "1.0.0-rc1"),
("1.0.0-beta1", "1.0.0-beta1+dev1"),
("1.0.0-beta1.dev1", "1.0.0-beta1.dev2"),
("1.0.0-beta1+dev1", "1.0.0-beta1+dev2"),
("1.0.0-rc1", "1.0.0"),
("1.0.0-rc1", "1.0.0-rc1+dev1"),
("1.0.0-rc1.dev1", "1.0.0-rc1.dev2"),
("1.0.0-rc1+dev1", "1.0.0-rc1+dev2"),
]
for version2, version1 in versions:
self.assertFalse(
Version.from_string(version1) <= Version.from_string(version2),
f"{version1} should not be less or equal then {version2}",
)

versions = [
("1.0.0", object()),
("1.0.0", 1),
("1.0.0", True),
]
for version1, version2 in versions:
with self.assertRaisesRegex(ValueError, "Can't compare"):
self.assertFalse(Version.from_string(version1) <= version2)

def test_is_dev_release(self):
versions = [
"1.0.0.dev1",
Expand Down
Loading

0 comments on commit 863f54a

Please sign in to comment.