From a6a75d1f75ade37ea0c0d449d5f36c085ef6cb41 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Fri, 13 Dec 2019 16:12:47 +0000 Subject: [PATCH] Allow projects to drop 'python_version>=3.x' version specifier For projects that have gone Python 3, having to keep the 'python_version' specifiers can add otherwise unnecessary noise. Special case these until such a time as Python 2.7 is history and we can drop all these Python version specifiers. Change-Id: Ie6dba8bc78dcd5fa95c7ac15b0a3770cdef8ad95 Signed-off-by: Stephen Finucane Co-Authored-By: Zane Bitter --- openstack_requirements/check.py | 13 ++++++-- openstack_requirements/tests/test_check.py | 39 ++++++++++++++++++++++ 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/openstack_requirements/check.py b/openstack_requirements/check.py index cc89cd0f33..31c9a009f0 100644 --- a/openstack_requirements/check.py +++ b/openstack_requirements/check.py @@ -15,6 +15,7 @@ # under the License. import collections +import re from packaging import markers from packaging import specifiers @@ -23,6 +24,7 @@ from openstack_requirements import project from openstack_requirements import requirement MIN_PY_VERSION = '3.5' +PY3_SPECIFIER_RE = re.compile(r'python_version(==|>=|>)[\'"]3\.\d+[\'"]') class RequirementsList(object): @@ -85,7 +87,7 @@ def _get_exclusions(req): ) -def _is_requirement_in_global_reqs(local_req, global_reqs): +def _is_requirement_in_global_reqs(local_req, global_reqs, allow_3_only=False): req_exclusions = _get_exclusions(local_req) for global_req in global_reqs: @@ -94,6 +96,13 @@ def _is_requirement_in_global_reqs(local_req, global_reqs): local_req_val = getattr(local_req, aname) global_req_val = getattr(global_req, aname) if local_req_val != global_req_val: + # if global requirements specifies a python 3 version specifier + # but a project doesn't, allow it since python 3-only is okay + if (allow_3_only and matching and + aname == 'markers' and not local_req_val): + if PY3_SPECIFIER_RE.match(global_req_val): + continue + print('WARNING: possible mismatch found for package ' '"{}"'.format(local_req.package)) print(' Attribute "{}" does not match'.format(aname)) @@ -183,7 +192,7 @@ def _validate_one(name, reqs, blacklist, global_reqs, allow_3_only=False): else: counts[''] = counts.get('', 0) + 1 if not _is_requirement_in_global_reqs( - req, global_reqs[name]): + req, global_reqs[name], allow_3_only): return True # check for minimum being defined min = [s for s in req.specifiers.split(',') if '>' in s] diff --git a/openstack_requirements/tests/test_check.py b/openstack_requirements/tests/test_check.py index 876221c195..694f42a28b 100644 --- a/openstack_requirements/tests/test_check.py +++ b/openstack_requirements/tests/test_check.py @@ -55,6 +55,18 @@ class TestIsReqInGlobalReqs(testtools.TestCase): ) ) + def test_match_without_python3_markers(self): + req = requirement.parse(textwrap.dedent(""" + withmarker>=1.5' + """))['withmarker'][0][0] + self.assertTrue( + check._is_requirement_in_global_reqs( + req, + self.global_reqs['withmarker'], + allow_3_only=True + ) + ) + def test_name_mismatch(self): req = requirement.parse('wrongname>=1.2,!=1.4')['wrongname'][0][0] self.assertFalse( @@ -358,6 +370,33 @@ class TestValidateOne(testtools.TestCase): ) ) + def test_new_item_matches_py3_allowed(self): + # If the global list has multiple entries for an item but the branch + # allows python 3 only, then only the py3 entries need to match. + # Requirements without a python_version marker should always be used. + r_content = textwrap.dedent(""" + name>=1.5 + other-name + """) + reqs = [ + r + for r, line in requirement.parse(r_content)['name'] + ] + global_reqs = check.get_global_reqs(textwrap.dedent(""" + name>=1.5;python_version>='3.5' + name>=1.2,!=1.4;python_version=='2.6' + other-name + """)) + self.assertFalse( + check._validate_one( + 'name', + reqs=reqs, + blacklist=requirement.parse(''), + global_reqs=global_reqs, + allow_3_only=True, + ) + ) + def test_new_item_matches_py3_allowed_with_py2(self): # If the global list has multiple entries for an item but the branch # allows python 3 only, then only the py3 entries need to match.