Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add: Add additional comparison for Version classes (ge, lt and le) #923

Merged
merged 2 commits into from
Nov 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
2 changes: 0 additions & 2 deletions tests/cpe/test_cpe.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,6 @@ def test_formatted_string_binding(self):
"cpe:2.3:a:qrokes:qr_twitter_widget:*:*:*:*:*:wordpress:*:*"
)
cpe = CPE.from_string(cpe_string)
print(repr(cpe))

self.assertEqual(
str(cpe),
Expand Down Expand Up @@ -403,7 +402,6 @@ def test_uri_unbind_examples(self):
cpe = CPE.from_string(
"cpe:/a:hp:insight_diagnostics:7.4.0.1570::~~online~win2003~x64~"
)
print(repr(cpe))
self.assertTrue(cpe.is_uri_binding())
self.assertFalse(cpe.is_formatted_string_binding())
self.assertEqual(cpe.part, Part.APPLICATION)
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