Prevent use filter(lambda obj: test(obj), data)
In Python3 [1], if we need filter on python3, replace filter(lambda obj: test(obj), data) with: [obj for obj in data if test(obj)]. This patch replaces filter function and introduces a hacking rule to prevent using filter in future. [1] https://wiki.openstack.org/wiki/Python3 Change-Id: I83d22108c02f8da007a7233e71a4a7fb833170ec
This commit is contained in:
parent
9a2e0b7669
commit
9afb9ca598
@ -29,6 +29,8 @@ Neutron Specific Commandments
|
||||
- [N340] Check usage of <module>.i18n (and neutron.i18n)
|
||||
- [N341] Check usage of _ from python builtins
|
||||
- [N342] String interpolation should be delayed at logging calls.
|
||||
- [N344] Python 3: Do not use filter(lambda obj: test(obj), data). Replace it
|
||||
with [obj for obj in data if test(obj)].
|
||||
|
||||
Creating Unit Tests
|
||||
-------------------
|
||||
|
@ -75,6 +75,7 @@ log_warn = re.compile(
|
||||
r"(.)*LOG\.(warn)\(\s*('|\"|_)")
|
||||
unittest_imports_dot = re.compile(r"\bimport[\s]+unittest\b")
|
||||
unittest_imports_from = re.compile(r"\bfrom[\s]+unittest\b")
|
||||
filter_match = re.compile(r".*filter\(lambda ")
|
||||
|
||||
|
||||
@flake8ext
|
||||
@ -381,6 +382,17 @@ def check_delayed_string_interpolation(logical_line, filename, noqa):
|
||||
yield(0, msg)
|
||||
|
||||
|
||||
@flake8ext
|
||||
def check_python3_no_filter(logical_line):
|
||||
"""N344 - Use list comprehension instead of filter(lambda)."""
|
||||
|
||||
msg = ("N343: Use list comprehension instead of "
|
||||
"filter(lambda obj: test(obj), data) on python3.")
|
||||
|
||||
if filter_match.match(logical_line):
|
||||
yield(0, msg)
|
||||
|
||||
|
||||
def factory(register):
|
||||
register(validate_log_translations)
|
||||
register(use_jsonutils)
|
||||
@ -400,3 +412,4 @@ def factory(register):
|
||||
register(check_builtins_gettext)
|
||||
register(check_unittest_imports)
|
||||
register(check_delayed_string_interpolation)
|
||||
register(check_python3_no_filter)
|
||||
|
@ -212,8 +212,8 @@ class QosPolicy(rbac_db.NeutronRbacObject):
|
||||
|
||||
def obj_make_compatible(self, primitive, target_version):
|
||||
def filter_rules(obj_names, rules):
|
||||
return filter(lambda rule:
|
||||
(rule['versioned_object.name'] in obj_names), rules)
|
||||
return [rule for rule in rules if
|
||||
rule['versioned_object.name'] in obj_names]
|
||||
|
||||
_target_version = versionutils.convert_version_to_tuple(target_version)
|
||||
names = []
|
||||
|
@ -112,7 +112,7 @@ def _build_subattr_match_rule(attr_name, attr, action, target):
|
||||
# typing for API attributes
|
||||
# Expect a dict as type descriptor
|
||||
validate = attr['validate']
|
||||
key = list(filter(lambda k: k.startswith('type:dict'), validate.keys()))
|
||||
key = [k for k in validate.keys() if k.startswith('type:dict')]
|
||||
if not key:
|
||||
LOG.warning(_LW("Unable to find data type descriptor "
|
||||
"for attribute %s"),
|
||||
|
@ -110,13 +110,15 @@ class SubnetPoolsTest(SubnetPoolsTestBase):
|
||||
body = self._create_subnetpool(description='d1')
|
||||
self.assertEqual('d1', body['description'])
|
||||
sub_id = body['id']
|
||||
body = filter(lambda x: x['id'] == sub_id,
|
||||
self.client.list_subnetpools()['subnetpools'])[0]
|
||||
subnet_pools = [x for x in
|
||||
self.client.list_subnetpools()['subnetpools'] if x['id'] == sub_id]
|
||||
body = subnet_pools[0]
|
||||
self.assertEqual('d1', body['description'])
|
||||
body = self.client.update_subnetpool(sub_id, description='d2')
|
||||
self.assertEqual('d2', body['subnetpool']['description'])
|
||||
body = filter(lambda x: x['id'] == sub_id,
|
||||
self.client.list_subnetpools()['subnetpools'])[0]
|
||||
subnet_pools = [x for x in
|
||||
self.client.list_subnetpools()['subnetpools'] if x['id'] == sub_id]
|
||||
body = subnet_pools[0]
|
||||
self.assertEqual('d2', body['description'])
|
||||
|
||||
@test.idempotent_id('741d08c2-1e3f-42be-99c7-0ea93c5b728c')
|
||||
|
@ -339,6 +339,13 @@ class HackingTestCase(base.BaseTestCase):
|
||||
self.assertEqual(
|
||||
1, len(list(checks.check_log_warn_deprecated(bad, 'f'))))
|
||||
|
||||
def test_check_python3_filter(self):
|
||||
f = checks.check_python3_no_filter
|
||||
self.assertLineFails(f, "filter(lambda obj: test(obj), data)")
|
||||
self.assertLinePasses(f, "[obj for obj in data if test(obj)]")
|
||||
self.assertLinePasses(f, "filter(function, range(0,10))")
|
||||
self.assertLinePasses(f, "lambda x, y: x+y")
|
||||
|
||||
# The following is borrowed from hacking/tests/test_doctest.py.
|
||||
# Tests defined in docstring is easier to understand
|
||||
# in some cases, for example, hacking rules which take tokens as argument.
|
||||
|
Loading…
x
Reference in New Issue
Block a user