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

Some extensions to acceptable specs #8

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
36 changes: 19 additions & 17 deletions semantic_version/base.py
Expand Up @@ -361,17 +361,13 @@ class SpecItem(object):
KIND_GTE = '>='
KIND_GT = '>'
KIND_NEQ = '!='
# this kind is slightly different, because it isn't followed by a version
KIND_ANY = '*'

STRICT_KINDS = (
KIND_LT,
KIND_LTE,
KIND_EQUAL,
KIND_GTE,
KIND_GT,
KIND_NEQ,
)
MATCH_EQUAL = re.compile('^={0,2}$')

re_spec = re.compile(r'^(<|<=|==|>=|>|!=)(\d.*)$')
re_any = re.compile(r'^(\*)$')
re_spec = re.compile(r'^(<|<=|={0,2}|>=|>|!=)(\d.*)$')

def __init__(self, requirement_string):
kind, spec = self.parse(requirement_string)
Expand All @@ -382,33 +378,39 @@ def __init__(self, requirement_string):
def parse(cls, requirement_string):
if not requirement_string:
raise ValueError("Invalid empty requirement specification: %r" % requirement_string)

match = cls.re_any.match(requirement_string)
if match:
kind, version = match.groups() + (None,)
else:
match = cls.re_spec.match(requirement_string)
if not match:
raise ValueError("Invalid requirement specification: %r" % requirement_string)
kind, version = match.groups()

match = cls.re_spec.match(requirement_string)
if not match:
raise ValueError("Invalid requirement specification: %r" % requirement_string)

kind, version = match.groups()
spec = Version(version, partial=True)
spec = Version(version, partial=True) if version else None
return (kind, spec)

def match(self, version):
if self.kind == self.KIND_LT:
return version < self.spec
elif self.kind == self.KIND_LTE:
return version <= self.spec
elif self.kind == self.KIND_EQUAL:
elif self.MATCH_EQUAL.match(self.kind):
return version == self.spec
elif self.kind == self.KIND_GTE:
return version >= self.spec
elif self.kind == self.KIND_GT:
return version > self.spec
elif self.kind == self.KIND_NEQ:
return version != self.spec
elif self.kind == self.KIND_ANY:
return True
else: # pragma: no cover
raise ValueError('Unexpected match kind: %r' % self.kind)

def __str__(self):
return '%s%s' % (self.kind, self.spec)
return '%s%s' % (self.kind, self.spec or '')

def __repr__(self):
return '<SpecItem: %s %r>' % (self.kind, self.spec)
Expand Down
12 changes: 12 additions & 0 deletions tests/test_base.py
Expand Up @@ -279,6 +279,14 @@ def test_components(self):
['0.1.0', '0.1.0-rc1', '0.1.0+build1', '0.1.0-rc1+build2'],
['0.0.1', '0.2.0', '0.1.1'],
),
'=0.1.0': (
['0.1.0', '0.1.0-rc1', '0.1.0+build1', '0.1.0-rc1+build2'],
['0.0.1', '0.2.0', '0.1.1'],
),
'0.1.0': (
['0.1.0', '0.1.0-rc1', '0.1.0+build1', '0.1.0-rc1+build2'],
['0.0.1', '0.2.0', '0.1.1'],
),
'==0.1.2-rc3': (
['0.1.2-rc3+build1', '0.1.2-rc3+build4.5'],
['0.1.2-rc4', '0.1.2', '0.1.3'],
Expand Down Expand Up @@ -323,6 +331,10 @@ def test_components(self):
['0.4.0', '1.3.0', '0.3.4-alpha', '0.3.4-alpha+b1'],
['0.3.4', '0.3.4+b1'],
),
'*': (
['0.1.0', '0.1.0-rc1', '0.1.0+build1', '0.1.0-rc1+build2', '0.0.1', '0.2.0', '0.1.1'],
[]
),
}

def test_matches(self):
Expand Down
3 changes: 3 additions & 0 deletions tests/test_match.py
Expand Up @@ -18,6 +18,9 @@ class MatchTestCase(unittest.TestCase):
]

valid_specs = [
'*',
'0.1.0',
'=0.1.0',
'==0.1.0',
'<=0.1.1',
'<0.1',
Expand Down