diff --git a/tests/hacking/README.rst b/tests/hacking/README.rst index fc6cf806..48ad3bb6 100644 --- a/tests/hacking/README.rst +++ b/tests/hacking/README.rst @@ -29,4 +29,5 @@ Rally Specific Commandments * [N334] - Ensure that ``itertools.imap`` is not used * [N335] - Ensure that ``xrange`` is not used * [N336] - Ensure that ``string.lowercase`` and ``string.uppercase`` are not used + * [N337] - Ensure that ``next()`` method on iterator objects is not used * [N340] - Ensure that we are importing always ``from rally import objects`` diff --git a/tests/hacking/checks.py b/tests/hacking/checks.py index e88a70d7..a2234916 100644 --- a/tests/hacking/checks.py +++ b/tests/hacking/checks.py @@ -53,6 +53,7 @@ re_itertools_imap_method = re.compile(r"(^|[\s=])itertools\.imap\(") re_xrange_method = re.compile(r"(^|[\s=])xrange\(") re_string_lower_upper_case_method = re.compile( r"(^|[(,\s=])string\.(lower|upper)case([)\[,\s]|$)") +re_next_on_iterator_method = re.compile(r"\.next\(\)") def _parse_assert_mock_str(line): @@ -322,6 +323,21 @@ def check_string_lower_upper_case_method(logical_line): "rather than string.lowercase or string.uppercase.") +def check_next_on_iterator_method(logical_line): + """Check if next() method on iterator objects are properly called + + Python 3 introduced a next() function to replace the next() method on + iterator objects. Rather than calling the method on the iterator, + the next() function is called with the iterable object as it's sole + parameter, which calls the underlying __next__() method. + + N337 + """ + res = re_next_on_iterator_method.search(logical_line) + if res: + yield (0, "N337: Use next(iterator) rather than iterator.next().") + + def check_no_direct_rally_objects_import(logical_line, filename): """Check if rally.objects are properly imported. @@ -356,4 +372,5 @@ def factory(register): register(check_itertools_imap_method) register(check_xrange_method) register(check_string_lower_upper_case_method) + register(check_next_on_iterator_method) register(check_no_direct_rally_objects_import) diff --git a/tests/unit/test_hacking.py b/tests/unit/test_hacking.py index 82855906..8442ac0e 100644 --- a/tests/unit/test_hacking.py +++ b/tests/unit/test_hacking.py @@ -176,6 +176,13 @@ class HackingTestCase(test.TestCase): self.assertEqual(len(list(checks.check_string_lower_upper_case_method( "string.ascii_uppercase[:16]"))), 0) + def test_check_next_on_iterator_method(self): + self.assertEqual(len(list(checks.check_next_on_iterator_method( + "iterator.next()"))), 1) + + self.assertEqual(len(list(checks.check_next_on_iterator_method( + "next(iterator)"))), 0) + def test_assert_equal_none(self): self.assertEqual(len(list(checks.assert_equal_none( "self.assertEqual(A, None)"))), 1)