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 <sfinucan@redhat.com>
Co-Authored-By: Zane Bitter <zbitter@redhat.com>
This commit is contained in:
Stephen Finucane 2019-12-13 16:12:47 +00:00 committed by Matthew Thode
parent 12aab4eec9
commit a6a75d1f75
No known key found for this signature in database
GPG Key ID: 64A37BEAAE19A4E8
2 changed files with 50 additions and 2 deletions

View File

@ -15,6 +15,7 @@
# under the License. # under the License.
import collections import collections
import re
from packaging import markers from packaging import markers
from packaging import specifiers from packaging import specifiers
@ -23,6 +24,7 @@ from openstack_requirements import project
from openstack_requirements import requirement 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+[\'"]')
class RequirementsList(object): 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) req_exclusions = _get_exclusions(local_req)
for global_req in global_reqs: 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) local_req_val = getattr(local_req, aname)
global_req_val = getattr(global_req, aname) global_req_val = getattr(global_req, aname)
if local_req_val != global_req_val: 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 ' print('WARNING: possible mismatch found for package '
'"{}"'.format(local_req.package)) '"{}"'.format(local_req.package))
print(' Attribute "{}" does not match'.format(aname)) print(' Attribute "{}" does not match'.format(aname))
@ -183,7 +192,7 @@ 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]): req, global_reqs[name], 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]

View File

@ -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): def test_name_mismatch(self):
req = requirement.parse('wrongname>=1.2,!=1.4')['wrongname'][0][0] req = requirement.parse('wrongname>=1.2,!=1.4')['wrongname'][0][0]
self.assertFalse( 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): def test_new_item_matches_py3_allowed_with_py2(self):
# If the global list has multiple entries for an item but the branch # 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. # allows python 3 only, then only the py3 entries need to match.