Merge "Vendor VersionPredicate"
This commit is contained in:
commit
2acc162e21
@ -93,3 +93,51 @@ class IsCompatibleTestCase(test_base.BaseTestCase):
|
|||||||
versionutils.convert_version_to_tuple('6.7.0beta1'))
|
versionutils.convert_version_to_tuple('6.7.0beta1'))
|
||||||
self.assertEqual((6, 7, 0),
|
self.assertEqual((6, 7, 0),
|
||||||
versionutils.convert_version_to_tuple('6.7.0rc1'))
|
versionutils.convert_version_to_tuple('6.7.0rc1'))
|
||||||
|
|
||||||
|
|
||||||
|
class VersionPredicateTest(test_base.BaseTestCase):
|
||||||
|
def test_version_predicate_valid(self):
|
||||||
|
pred = versionutils.VersionPredicate('<2.0.0')
|
||||||
|
self.assertTrue(pred.satisfied_by('1.10.0'))
|
||||||
|
self.assertFalse(pred.satisfied_by('2.0.0'))
|
||||||
|
|
||||||
|
pred = versionutils.VersionPredicate('<=2.0.0')
|
||||||
|
self.assertTrue(pred.satisfied_by('2.0.0'))
|
||||||
|
self.assertFalse(pred.satisfied_by('2.1.0'))
|
||||||
|
|
||||||
|
pred = versionutils.VersionPredicate('>2.0.0')
|
||||||
|
self.assertFalse(pred.satisfied_by('1.10.0'))
|
||||||
|
self.assertTrue(pred.satisfied_by('2.1.0'))
|
||||||
|
|
||||||
|
pred = versionutils.VersionPredicate('>=2.0.0')
|
||||||
|
self.assertFalse(pred.satisfied_by('1.9.0'))
|
||||||
|
self.assertTrue(pred.satisfied_by('2.0.0'))
|
||||||
|
|
||||||
|
pred = versionutils.VersionPredicate('== 2.0.0')
|
||||||
|
self.assertFalse(pred.satisfied_by('1.9.9'))
|
||||||
|
self.assertTrue(pred.satisfied_by('2.0.0'))
|
||||||
|
self.assertFalse(pred.satisfied_by('2.0.1'))
|
||||||
|
|
||||||
|
pred = versionutils.VersionPredicate('!= 2.0.0')
|
||||||
|
self.assertTrue(pred.satisfied_by('1.9.9'))
|
||||||
|
self.assertFalse(pred.satisfied_by('2.0.0'))
|
||||||
|
self.assertTrue(pred.satisfied_by('2.0.1'))
|
||||||
|
|
||||||
|
def test_version_predicate_valid_multi(self):
|
||||||
|
pred = versionutils.VersionPredicate('<3.0.0,>=2.1.0')
|
||||||
|
self.assertTrue(pred.satisfied_by('2.1.0'))
|
||||||
|
self.assertTrue(pred.satisfied_by('2.11.0'))
|
||||||
|
self.assertFalse(pred.satisfied_by('2.0.0'))
|
||||||
|
self.assertFalse(pred.satisfied_by('3.0.0'))
|
||||||
|
|
||||||
|
pred = versionutils.VersionPredicate(' < 2.0.0, >= 1.0.0 ')
|
||||||
|
self.assertTrue(pred.satisfied_by('1.0.0'))
|
||||||
|
self.assertTrue(pred.satisfied_by('1.10.0'))
|
||||||
|
self.assertFalse(pred.satisfied_by('0.9.0'))
|
||||||
|
self.assertFalse(pred.satisfied_by('2.0.0'))
|
||||||
|
|
||||||
|
def test_version_predicate_valid_invalid(self):
|
||||||
|
for invalid_str in ['3.0.0', 'foo', '<> 3.0.0', '>=1.0.0;<2.0.0',
|
||||||
|
'>abc', '>=1.0.0,', '>=1.0.0,2.0.0']:
|
||||||
|
self.assertRaises(
|
||||||
|
ValueError, versionutils.VersionPredicate, invalid_str)
|
||||||
|
@ -20,6 +20,7 @@ Helpers for comparing version strings.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import functools
|
import functools
|
||||||
|
import operator
|
||||||
import re
|
import re
|
||||||
|
|
||||||
import packaging.version
|
import packaging.version
|
||||||
@ -90,3 +91,35 @@ def convert_version_to_tuple(version_str):
|
|||||||
"""
|
"""
|
||||||
version_str = re.sub(r'(\d+)(a|alpha|b|beta|rc)\d+$', '\\1', version_str)
|
version_str = re.sub(r'(\d+)(a|alpha|b|beta|rc)\d+$', '\\1', version_str)
|
||||||
return tuple(int(part) for part in version_str.split('.'))
|
return tuple(int(part) for part in version_str.split('.'))
|
||||||
|
|
||||||
|
|
||||||
|
class VersionPredicate:
|
||||||
|
"""Parse version predicate and check version requirements
|
||||||
|
|
||||||
|
This is based on the implementation of distutils.VersionPredicate
|
||||||
|
|
||||||
|
.. versionadded:: 7.4
|
||||||
|
"""
|
||||||
|
_PREDICATE_MATCH = re.compile(r"^\s*(<=|>=|<|>|!=|==)\s*([^\s]+)\s*$")
|
||||||
|
_COMP_MAP = {
|
||||||
|
"<": operator.lt, "<=": operator.le, "==": operator.eq,
|
||||||
|
">": operator.gt, ">=": operator.ge, "!=": operator.ne
|
||||||
|
}
|
||||||
|
|
||||||
|
def __init__(self, predicate_str):
|
||||||
|
self.pred = [self._parse_predicate(pred) for pred
|
||||||
|
in predicate_str.split(',')]
|
||||||
|
|
||||||
|
def _parse_predicate(self, pred):
|
||||||
|
res = self._PREDICATE_MATCH.match(pred)
|
||||||
|
if not res:
|
||||||
|
raise ValueError("bad package restriction syntax: %s" % pred)
|
||||||
|
cond, ver_str = res.groups()
|
||||||
|
return (cond, packaging.version.Version(ver_str))
|
||||||
|
|
||||||
|
def satisfied_by(self, version_str):
|
||||||
|
version = packaging.version.Version(version_str)
|
||||||
|
for cond, ver in self.pred:
|
||||||
|
if not self._COMP_MAP[cond](version, ver):
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
The new ``VersionPredicate`` class has been added to the ``versionutils``
|
||||||
|
module, which parses version predicate and check if the given version meets
|
||||||
|
the described requirements.
|
Loading…
Reference in New Issue
Block a user