diff --git a/HACKING.rst b/HACKING.rst index 62ff5eb9aa..a203bb1092 100644 --- a/HACKING.rst +++ b/HACKING.rst @@ -25,3 +25,6 @@ glance Specific Commandments - [G327] Prevent use of deprecated contextlib.nested - [G328] Must use a dict comprehension instead of a dict constructor with a sequence of key-value pairs - [G329] Python 3: Do not use xrange. +- [G330] Python 3: do not use dict.iteritems. +- [G331] Python 3: do not use dict.iterkeys. +- [G332] Python 3: do not use dict.itervalues. diff --git a/glance/hacking/checks.py b/glance/hacking/checks.py index 95a4f8c176..66f89490fa 100644 --- a/glance/hacking/checks.py +++ b/glance/hacking/checks.py @@ -162,6 +162,27 @@ def check_python3_xrange(logical_line): "large loops.") +def check_python3_no_iteritems(logical_line): + msg = ("G330: Use six.iteritems() or dict.items() instead of " + "dict.iteritems().") + if re.search(r".*\.iteritems\(\)", logical_line): + yield(0, msg) + + +def check_python3_no_iterkeys(logical_line): + msg = ("G331: Use six.iterkeys() or dict.keys() instead of " + "dict.iterkeys().") + if re.search(r".*\.iterkeys\(\)", logical_line): + yield(0, msg) + + +def check_python3_no_itervalues(logical_line): + msg = ("G332: Use six.itervalues() or dict.values instead of " + "dict.itervalues().") + if re.search(r".*\.itervalues\(\)", logical_line): + yield(0, msg) + + def factory(register): register(assert_true_instance) register(assert_equal_type) @@ -172,3 +193,6 @@ def factory(register): register(check_no_contextlib_nested) register(dict_constructor_with_list_copy) register(check_python3_xrange) + register(check_python3_no_iteritems) + register(check_python3_no_iterkeys) + register(check_python3_no_itervalues) diff --git a/glance/tests/test_hacking.py b/glance/tests/test_hacking.py index 258bf54183..0568014fea 100644 --- a/glance/tests/test_hacking.py +++ b/glance/tests/test_hacking.py @@ -108,3 +108,33 @@ class HackingTestCase(utils.BaseTestCase): self.assertEqual(0, len(list(func('for i in range(10)')))) self.assertEqual(0, len(list(func('for i in six.moves.range(10)')))) self.assertEqual(0, len(list(func('testxrange(10)')))) + + def test_dict_iteritems(self): + self.assertEqual(1, len(list(checks.check_python3_no_iteritems( + "obj.iteritems()")))) + + self.assertEqual(0, len(list(checks.check_python3_no_iteritems( + "six.iteritems(obj)")))) + + self.assertEqual(0, len(list(checks.check_python3_no_iteritems( + "obj.items()")))) + + def test_dict_iterkeys(self): + self.assertEqual(1, len(list(checks.check_python3_no_iterkeys( + "obj.iterkeys()")))) + + self.assertEqual(0, len(list(checks.check_python3_no_iterkeys( + "six.iterkeys(obj)")))) + + self.assertEqual(0, len(list(checks.check_python3_no_iterkeys( + "obj.keys()")))) + + def test_dict_itervalues(self): + self.assertEqual(1, len(list(checks.check_python3_no_itervalues( + "obj.itervalues()")))) + + self.assertEqual(0, len(list(checks.check_python3_no_itervalues( + "six.itervalues(ob)")))) + + self.assertEqual(0, len(list(checks.check_python3_no_itervalues( + "obj.values()"))))