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:
parent
12aab4eec9
commit
a6a75d1f75
@ -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]
|
||||||
|
@ -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.
|
||||||
|
Loading…
Reference in New Issue
Block a user