Merge "Vendor VersionPredicate"

This commit is contained in:
Zuul 2024-10-29 04:37:08 +00:00 committed by Gerrit Code Review
commit 2acc162e21
3 changed files with 87 additions and 0 deletions

View File

@ -93,3 +93,51 @@ class IsCompatibleTestCase(test_base.BaseTestCase):
versionutils.convert_version_to_tuple('6.7.0beta1'))
self.assertEqual((6, 7, 0),
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)

View File

@ -20,6 +20,7 @@ Helpers for comparing version strings.
"""
import functools
import operator
import re
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)
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

View File

@ -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.