Move the definition of BACKPORTS out of code

Move the library names that we are flexible with - backports from the
std.lib - from a hard coded list in code into a txt file

Change-Id: I414f7c386b838248f45fbce003a64d0c83a9919c
This commit is contained in:
Tony Breeds 2022-08-02 19:04:52 +10:00
parent d79553627d
commit 5d31764c15
4 changed files with 98 additions and 8 deletions

1
backports.txt Normal file
View File

@ -0,0 +1 @@
importlib-metadata

View File

@ -25,9 +25,6 @@ from openstack_requirements import requirement
MIN_PY_VERSION = '3.5' MIN_PY_VERSION = '3.5'
PY3_SPECIFIER_RE = re.compile(r'python_version(==|>=|>)[\'"]3\.\d+[\'"]') PY3_SPECIFIER_RE = re.compile(r'python_version(==|>=|>)[\'"]3\.\d+[\'"]')
BACKPORTS = {
'importlib-metadata',
}
class RequirementsList(object): class RequirementsList(object):
@ -90,7 +87,12 @@ def _get_exclusions(req):
) )
def _is_requirement_in_global_reqs(local_req, global_reqs, allow_3_only=False): def _is_requirement_in_global_reqs(
local_req,
global_reqs,
backports,
allow_3_only=False,
):
req_exclusions = _get_exclusions(local_req) req_exclusions = _get_exclusions(local_req)
for global_req in global_reqs: for global_req in global_reqs:
@ -118,7 +120,7 @@ def _is_requirement_in_global_reqs(local_req, global_reqs, allow_3_only=False):
allow_3_only and allow_3_only and
matching and matching and
aname == 'markers' and aname == 'markers' and
local_req.package in BACKPORTS local_req.package in backports
): ):
if ( if (
PY3_SPECIFIER_RE.match(global_req_val) or PY3_SPECIFIER_RE.match(global_req_val) or
@ -195,8 +197,16 @@ def _get_python3_reqs(reqs):
return results return results
def _validate_one(name, reqs, blacklist, global_reqs, allow_3_only=False): def _validate_one(
name,
reqs,
blacklist,
global_reqs,
backports,
allow_3_only=False,
):
"""Returns True if there is a failure.""" """Returns True if there is a failure."""
if name in blacklist: if name in blacklist:
# Blacklisted items are not synced and are managed # Blacklisted items are not synced and are managed
# by project teams as they see fit, so no further # by project teams as they see fit, so no further
@ -213,7 +223,8 @@ def _validate_one(name, reqs, blacklist, global_reqs, allow_3_only=False):
else: else:
counts[''] = counts.get('', 0) + 1 counts[''] = counts.get('', 0) + 1
if not _is_requirement_in_global_reqs( if not _is_requirement_in_global_reqs(
req, global_reqs[name], allow_3_only): req, global_reqs[name], backports, allow_3_only,
):
return True return True
# check for minimum being defined # check for minimum being defined
min = [s for s in req.specifiers.split(',') if '>' in s] min = [s for s in req.specifiers.split(',') if '>' in s]
@ -245,7 +256,13 @@ def _validate_one(name, reqs, blacklist, global_reqs, allow_3_only=False):
return False return False
def validate(head_reqs, blacklist, global_reqs, allow_3_only=False): def validate(
head_reqs,
blacklist,
global_reqs,
backports,
allow_3_only=False,
):
failed = False failed = False
# iterate through the changing entries and see if they match the global # iterate through the changing entries and see if they match the global
# equivalents we want enforced # equivalents we want enforced
@ -258,6 +275,7 @@ def validate(head_reqs, blacklist, global_reqs, allow_3_only=False):
reqs, reqs,
blacklist, blacklist,
global_reqs, global_reqs,
backports,
allow_3_only, allow_3_only,
) )
or failed or failed

View File

@ -26,6 +26,7 @@ class TestIsReqInGlobalReqs(testtools.TestCase):
self._stdout_fixture = fixtures.StringStream('stdout') self._stdout_fixture = fixtures.StringStream('stdout')
self.stdout = self.useFixture(self._stdout_fixture).stream self.stdout = self.useFixture(self._stdout_fixture).stream
self.backports = dict()
self.useFixture(fixtures.MonkeyPatch('sys.stdout', self.stdout)) self.useFixture(fixtures.MonkeyPatch('sys.stdout', self.stdout))
self.global_reqs = check.get_global_reqs(textwrap.dedent(""" self.global_reqs = check.get_global_reqs(textwrap.dedent("""
@ -41,6 +42,7 @@ class TestIsReqInGlobalReqs(testtools.TestCase):
check._is_requirement_in_global_reqs( check._is_requirement_in_global_reqs(
req, req,
self.global_reqs['name'], self.global_reqs['name'],
self.backports,
) )
) )
@ -52,6 +54,7 @@ class TestIsReqInGlobalReqs(testtools.TestCase):
check._is_requirement_in_global_reqs( check._is_requirement_in_global_reqs(
req, req,
self.global_reqs['withmarker'], self.global_reqs['withmarker'],
self.backports,
) )
) )
@ -63,6 +66,7 @@ class TestIsReqInGlobalReqs(testtools.TestCase):
check._is_requirement_in_global_reqs( check._is_requirement_in_global_reqs(
req, req,
self.global_reqs['withmarker'], self.global_reqs['withmarker'],
self.backports,
allow_3_only=True allow_3_only=True
) )
) )
@ -73,6 +77,7 @@ class TestIsReqInGlobalReqs(testtools.TestCase):
check._is_requirement_in_global_reqs( check._is_requirement_in_global_reqs(
req, req,
self.global_reqs['name'], self.global_reqs['name'],
self.backports,
) )
) )
@ -82,6 +87,7 @@ class TestIsReqInGlobalReqs(testtools.TestCase):
check._is_requirement_in_global_reqs( check._is_requirement_in_global_reqs(
req, req,
self.global_reqs['name'], self.global_reqs['name'],
self.backports,
) )
) )
@ -91,6 +97,7 @@ class TestIsReqInGlobalReqs(testtools.TestCase):
check._is_requirement_in_global_reqs( check._is_requirement_in_global_reqs(
req, req,
self.global_reqs['name'], self.global_reqs['name'],
self.backports,
) )
) )
@ -100,6 +107,7 @@ class TestIsReqInGlobalReqs(testtools.TestCase):
check._is_requirement_in_global_reqs( check._is_requirement_in_global_reqs(
req, req,
self.global_reqs['name'], self.global_reqs['name'],
self.backports,
) )
) )
@ -135,6 +143,7 @@ class TestValidateOne(testtools.TestCase):
self._stdout_fixture = fixtures.StringStream('stdout') self._stdout_fixture = fixtures.StringStream('stdout')
self.stdout = self.useFixture(self._stdout_fixture).stream self.stdout = self.useFixture(self._stdout_fixture).stream
self.useFixture(fixtures.MonkeyPatch('sys.stdout', self.stdout)) self.useFixture(fixtures.MonkeyPatch('sys.stdout', self.stdout))
self.backports = dict()
def test_unchanged(self): def test_unchanged(self):
# If the line matches the value in the branch list everything # If the line matches the value in the branch list everything
@ -149,6 +158,7 @@ class TestValidateOne(testtools.TestCase):
'name', 'name',
reqs=reqs, reqs=reqs,
blacklist=requirement.parse(''), blacklist=requirement.parse(''),
backports=self.backports,
global_reqs=global_reqs, global_reqs=global_reqs,
) )
) )
@ -165,6 +175,7 @@ class TestValidateOne(testtools.TestCase):
'name', 'name',
reqs=reqs, reqs=reqs,
blacklist=requirement.parse('name'), blacklist=requirement.parse('name'),
backports=self.backports,
global_reqs=global_reqs, global_reqs=global_reqs,
) )
) )
@ -182,6 +193,7 @@ class TestValidateOne(testtools.TestCase):
'name', 'name',
reqs=reqs, reqs=reqs,
blacklist=requirement.parse('name'), blacklist=requirement.parse('name'),
backports=self.backports,
global_reqs=global_reqs, global_reqs=global_reqs,
) )
) )
@ -198,6 +210,7 @@ class TestValidateOne(testtools.TestCase):
'name', 'name',
reqs=reqs, reqs=reqs,
blacklist=requirement.parse(''), blacklist=requirement.parse(''),
backports=self.backports,
global_reqs=global_reqs, global_reqs=global_reqs,
) )
) )
@ -214,6 +227,7 @@ class TestValidateOne(testtools.TestCase):
'name', 'name',
reqs=reqs, reqs=reqs,
blacklist=requirement.parse(''), blacklist=requirement.parse(''),
backports=self.backports,
global_reqs=global_reqs, global_reqs=global_reqs,
) )
) )
@ -231,6 +245,7 @@ class TestValidateOne(testtools.TestCase):
'name', 'name',
reqs=reqs, reqs=reqs,
blacklist=requirement.parse(''), blacklist=requirement.parse(''),
backports=self.backports,
global_reqs=global_reqs, global_reqs=global_reqs,
) )
) )
@ -248,6 +263,7 @@ class TestValidateOne(testtools.TestCase):
'name', 'name',
reqs=reqs, reqs=reqs,
blacklist=requirement.parse(''), blacklist=requirement.parse(''),
backports=self.backports,
global_reqs=global_reqs, global_reqs=global_reqs,
) )
) )
@ -265,6 +281,7 @@ class TestValidateOne(testtools.TestCase):
'name', 'name',
reqs=reqs, reqs=reqs,
blacklist=requirement.parse(''), blacklist=requirement.parse(''),
backports=self.backports,
global_reqs=global_reqs, global_reqs=global_reqs,
) )
) )
@ -290,6 +307,7 @@ class TestValidateOne(testtools.TestCase):
'name', 'name',
reqs=reqs, reqs=reqs,
blacklist=requirement.parse(''), blacklist=requirement.parse(''),
backports=self.backports,
global_reqs=global_reqs, global_reqs=global_reqs,
) )
) )
@ -314,6 +332,7 @@ class TestValidateOne(testtools.TestCase):
'name', 'name',
reqs=reqs, reqs=reqs,
blacklist=requirement.parse(''), blacklist=requirement.parse(''),
backports=self.backports,
global_reqs=global_reqs, global_reqs=global_reqs,
) )
) )
@ -339,6 +358,7 @@ class TestValidateOne(testtools.TestCase):
'name', 'name',
reqs=reqs, reqs=reqs,
blacklist=requirement.parse(''), blacklist=requirement.parse(''),
backports=self.backports,
global_reqs=global_reqs, global_reqs=global_reqs,
) )
) )
@ -365,6 +385,7 @@ class TestValidateOne(testtools.TestCase):
'name', 'name',
reqs=reqs, reqs=reqs,
blacklist=requirement.parse(''), blacklist=requirement.parse(''),
backports=self.backports,
global_reqs=global_reqs, global_reqs=global_reqs,
allow_3_only=True, allow_3_only=True,
) )
@ -392,6 +413,7 @@ class TestValidateOne(testtools.TestCase):
'name', 'name',
reqs=reqs, reqs=reqs,
blacklist=requirement.parse(''), blacklist=requirement.parse(''),
backports=self.backports,
global_reqs=global_reqs, global_reqs=global_reqs,
allow_3_only=True, allow_3_only=True,
) )
@ -418,6 +440,7 @@ class TestValidateOne(testtools.TestCase):
'name', 'name',
reqs=reqs, reqs=reqs,
blacklist=requirement.parse(''), blacklist=requirement.parse(''),
backports=self.backports,
global_reqs=global_reqs, global_reqs=global_reqs,
allow_3_only=True, allow_3_only=True,
) )
@ -442,6 +465,7 @@ class TestValidateOne(testtools.TestCase):
'name', 'name',
reqs=reqs, reqs=reqs,
blacklist=requirement.parse(''), blacklist=requirement.parse(''),
backports=self.backports,
global_reqs=global_reqs, global_reqs=global_reqs,
allow_3_only=True, allow_3_only=True,
) )
@ -696,3 +720,44 @@ class TestValidateLowerConstraints(testtools.TestCase):
blacklist=requirement.parse(''), blacklist=requirement.parse(''),
) )
) )
class TestBackportPythonMarkers(testtools.TestCase):
def setUp(self):
super(TestBackportPythonMarkers, self).setUp()
self._stdout_fixture = fixtures.StringStream('stdout')
self.stdout = self.useFixture(self._stdout_fixture).stream
self.useFixture(fixtures.MonkeyPatch('sys.stdout', self.stdout))
self.req = requirement.parse(textwrap.dedent("""
name>=1.5;python_version=='3.11'
"""))['name'][0][0]
self.global_reqs = check.get_global_reqs(textwrap.dedent("""
name>=1.5;python_version=='3.10'
"""))
def test_notmatching_no_backport(self):
backports = requirement.parse("")
self.assertFalse(
check._is_requirement_in_global_reqs(
self.req,
self.global_reqs["name"],
list(backports.keys()),
allow_3_only=True,
)
)
def test_notmatching_with_backport(self):
b_content = textwrap.dedent("""
name
""")
backports = requirement.parse(b_content)
self.assertTrue(
check._is_requirement_in_global_reqs(
self.req,
self.global_reqs["name"],
list(backports.keys()),
allow_3_only=True,
)
)

View File

@ -113,6 +113,11 @@ def main():
global_reqs = check.get_global_reqs(f.read()) global_reqs = check.get_global_reqs(f.read())
blacklist = requirement.parse( blacklist = requirement.parse(
open(reqdir + '/blacklist.txt', 'rt').read()) open(reqdir + '/blacklist.txt', 'rt').read())
backports_file = reqdir + '/backports.txt'
if os.path.exists(backports_file):
backports = requirement.parse(open(backports_file, 'rt').read())
else:
backports = {}
cwd = os.getcwd() cwd = os.getcwd()
# build a list of requirements in the proposed change, # build a list of requirements in the proposed change,
# and check them for style violations while doing so # and check them for style violations while doing so
@ -136,6 +141,7 @@ def main():
head_reqs, head_reqs,
blacklist, blacklist,
global_reqs, global_reqs,
list(backports.keys()),
allow_3_only=python_3_branch, allow_3_only=python_3_branch,
) )