diff --git a/tests/hacking/README.rst b/tests/hacking/README.rst index 8671aa00..fc6cf806 100644 --- a/tests/hacking/README.rst +++ b/tests/hacking/README.rst @@ -28,4 +28,5 @@ Rally Specific Commandments * [N333] - Ensure that ``urlparse`` is not used * [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 * [N340] - Ensure that we are importing always ``from rally import objects`` diff --git a/tests/hacking/checks.py b/tests/hacking/checks.py index 6618751d..e88a70d7 100644 --- a/tests/hacking/checks.py +++ b/tests/hacking/checks.py @@ -51,6 +51,8 @@ re_StringIO_method = re.compile(r"StringIO\.StringIO\(") re_urlparse_method = re.compile(r"(^|[\s=])urlparse\.") 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]|$)") def _parse_assert_mock_str(line): @@ -306,6 +308,20 @@ def check_xrange_method(logical_line): yield (0, "N335: Use six.moves.range rather than xrange.") +def check_string_lower_upper_case_method(logical_line): + """Check if string.lowercase and string.uppercase are properly called + + In Python 3, string.lowercase and string.uppercase are gone. + The correct form is "string.ascii_lowercase" and "string.ascii_uppercase". + + N336 + """ + res = re_string_lower_upper_case_method.search(logical_line) + if res: + yield (0, "N336: Use string.ascii_lowercase or string.ascii_uppercase " + "rather than string.lowercase or string.uppercase.") + + def check_no_direct_rally_objects_import(logical_line, filename): """Check if rally.objects are properly imported. @@ -339,4 +355,5 @@ def factory(register): register(check_urlparse_method) register(check_itertools_imap_method) register(check_xrange_method) + register(check_string_lower_upper_case_method) register(check_no_direct_rally_objects_import) diff --git a/tests/unit/fakes.py b/tests/unit/fakes.py index 200b73e7..2c4beebf 100644 --- a/tests/unit/fakes.py +++ b/tests/unit/fakes.py @@ -36,7 +36,7 @@ def generate_uuid(): return str(uuid.uuid4()) -def generate_name(prefix="", length=12, choices=string.lowercase): +def generate_name(prefix="", length=12, choices=string.ascii_lowercase): """Generate pseudo-random name. :param prefix: str, custom prefix for genertated name diff --git a/tests/unit/test_hacking.py b/tests/unit/test_hacking.py index 96b576e8..82855906 100644 --- a/tests/unit/test_hacking.py +++ b/tests/unit/test_hacking.py @@ -163,6 +163,19 @@ class HackingTestCase(test.TestCase): self.assertEqual(len(list(checks.check_xrange_method( "six.moves.range()"))), 0) + def test_check_string_lower_upper_case_method(self): + self.assertEqual(len(list(checks.check_string_lower_upper_case_method( + "string.lowercase[:16]"))), 1) + + self.assertEqual(len(list(checks.check_string_lower_upper_case_method( + "string.uppercase[:16]"))), 1) + + self.assertEqual(len(list(checks.check_string_lower_upper_case_method( + "string.ascii_lowercase[:16]"))), 0) + + self.assertEqual(len(list(checks.check_string_lower_upper_case_method( + "string.ascii_uppercase[:16]"))), 0) + def test_assert_equal_none(self): self.assertEqual(len(list(checks.assert_equal_none( "self.assertEqual(A, None)"))), 1)