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

Introduce "all" and "none" specifiers #146

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 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
25 changes: 23 additions & 2 deletions src/univers/version_range.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
from univers import versions
from univers.conan.version_range import VersionRange as conan_version_range
from univers.utils import remove_spaces
from univers.versions import AllVersion
from univers.versions import NoneVersion
from univers.version_constraint import VersionConstraint
from univers.version_constraint import contains_version

Expand Down Expand Up @@ -220,6 +222,13 @@ def __contains__(self, version):
object. A version is contained in a VersionRange if it satisfies its
constraints according to ``vers`` rules.
"""

if self.version_class is AllVersion:
return True

if self.version_class is NoneVersion:
return False

if not isinstance(version, self.version_class):
raise TypeError(
f"{version!r} is not of expected type: {self.version_class!r}",
Expand Down Expand Up @@ -712,9 +721,9 @@ class PypiVersionRange(VersionRange):
def from_native(cls, string):
"""
Return a VersionRange built from a PyPI PEP440 version specifiers ``string``.
Raise an a univers.versions.InvalidVersion
Raise a univers.versions.InvalidVersion
"""
# TODO: environment markers are yet supported
# TODO: environment markers are not yet supported
# TODO: handle .* version, ~= and === operators

if ";" in string:
Expand Down Expand Up @@ -1177,6 +1186,16 @@ class MattermostVersionRange(VersionRange):
version_class = versions.SemverVersion


class AllVersionRange(VersionRange):
scheme = "all"
version_class = versions.AllVersion


class NoneVersionRange(VersionRange):
scheme = "none"
version_class = versions.NoneVersion


def from_gitlab_native(gitlab_scheme, string):
purl_scheme = gitlab_scheme
if gitlab_scheme not in PURL_TYPE_BY_GITLAB_SCHEME.values():
Expand Down Expand Up @@ -1419,6 +1438,8 @@ def build_range_from_snyk_advisory_string(scheme: str, string: Union[str, List])
"openssl": OpensslVersionRange,
"mattermost": MattermostVersionRange,
"conan": ConanVersionRange,
"all": AllVersionRange,
"none": NoneVersionRange,
}

PURL_TYPE_BY_GITLAB_SCHEME = {
Expand Down
14 changes: 13 additions & 1 deletion src/univers/versions.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ def build_value(self, string):

def satisfies(self, constraint):
"""
Return True is this Version satisfies the ``constraint``
Return True if this Version satisfies the ``constraint``
VersionConstraint. Satisfying means that this version is "within" the
``constraint``.
"""
Expand All @@ -133,6 +133,18 @@ def __str__(self):
return str(self.value)


class AllVersion(Version):
@classmethod
def is_valid(cls, string):
return string == "vers:all/*"


class NoneVersion(Version):
@classmethod
def is_valid(cls, string):
return string == "vers:none/*"


class GenericVersion(Version):
@classmethod
def is_valid(cls, string):
Expand Down
21 changes: 21 additions & 0 deletions tests/test_version_range.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
from univers.versions import PypiVersion
from univers.versions import RubygemsVersion
from univers.versions import SemverVersion
from univers.versions import Version


class TestVersionRange(TestCase):
Expand Down Expand Up @@ -546,3 +547,23 @@ def test_version_range_normalize_case3():
nvr = vr.normalize(known_versions=known_versions)

assert str(nvr) == "vers:pypi/>=1.0.0|<=1.3.0|3.0.0"

def test_version_range_all():
all_vers = VersionRange.from_string("vers:all/*")
assert all_vers.contains(Version("1.2.3"))
assert PypiVersion("2.0.3") in all_vers
# test for invalid all range specification
with pytest.raises(Exception):
VersionRange.from_string("vers:all/>1.2.3")
with pytest.raises(Exception):
VersionRange.from_string("vers:all/*|>1.2.3")
immqu marked this conversation as resolved.
Show resolved Hide resolved

def test_version_range_none():
none_vers = VersionRange.from_string("vers:none/*")
assert not none_vers.contains(Version("1.2.3"))
assert PypiVersion("2.0.3") not in none_vers
# test for invalid all range specification
with pytest.raises(Exception):
VersionRange.from_string("vers:none/!1.2.3")
with pytest.raises(Exception):
VersionRange.from_string("vers:none/*|>1.2.3")
Loading