Remove hacking rules for python 2/3 compatibility

The Python 2.7 Support has been dropped since Ussuri.
So remove hacking rules for compatibility between python 2 and 3.

- [N325] str() and unicode() cannot be used on an exception.
         Remove or use six.text_type()
- [N327] Do not use xrange(). xrange() is not compatible with Python 3.
         Use range() or six.moves.range() instead.
- [N344] Python 3: do not use dict.iteritems.
- [N345] Python 3: do not use dict.iterkeys.
- [N346] Python 3: do not use dict.itervalues.

See also line 414 in https://etherpad.opendev.org/p/nova-victoria-ptg

Change-Id: If4335b2e8ef5bbabba37598110c1aa8269635c2f
Implements: blueprint six-removal
Signed-off-by: Takashi Natsume <takanattie@gmail.com>
This commit is contained in:
Takashi Natsume 2020-06-07 11:59:30 +00:00
parent 1490a54fa9
commit 9dca0d186f
4 changed files with 0 additions and 187 deletions

View File

@ -31,9 +31,7 @@ Nova Specific Commandments
- [N322] Method's default argument shouldn't be mutable
- [N323] Ensure that the _() function is explicitly imported to ensure proper translations.
- [N324] Ensure that jsonutils.%(fun)s must be used instead of json.%(fun)s
- [N325] str() and unicode() cannot be used on an exception. Remove use or use six.text_type()
- [N326] Translated messages cannot be concatenated. String should be included in translated message.
- [N327] Do not use xrange(). xrange() is not compatible with Python 3. Use range() or six.moves.range() instead.
- [N332] Check that the api_version decorator is the first decorator on a method
- [N334] Change assertTrue/False(A in/not in B, message) to the more specific
assertIn/NotIn(A, B, message)
@ -48,9 +46,6 @@ Nova Specific Commandments
- [N341] contextlib.nested is deprecated
- [N342] Config options should be in the central location ``nova/conf/``
- [N343] Check for common double word typos
- [N344] Python 3: do not use dict.iteritems.
- [N345] Python 3: do not use dict.iterkeys.
- [N346] Python 3: do not use dict.itervalues.
- [N348] Deprecated library function os.popen()
- [N349] Check for closures in tests which are not used
- [N350] Policy registration should be in the central location ``nova/policies/``

View File

@ -32,7 +32,6 @@ import os
import re
from hacking import core
import six
UNDERSCORE_IMPORT_FILES = []
@ -292,13 +291,6 @@ def assert_equal_type(logical_line):
yield (0, "N317: assertEqual(type(A), B) sentences not allowed")
@core.flake8ext
def check_python3_xrange(logical_line):
if re.search(r"\bxrange\s*\(", logical_line):
yield (0, "N327: Do not use xrange(). 'xrange()' is not compatible "
"with Python 3. Use range() or six.moves.range() instead.")
@core.flake8ext
def no_translate_logs(logical_line, filename):
"""Check for 'LOG.foo(_('
@ -400,58 +392,6 @@ def check_api_version_decorator(logical_line, previous_logical, blank_before,
yield (0, msg)
class CheckForStrUnicodeExc(BaseASTChecker):
"""Checks for the use of str() or unicode() on an exception.
This currently only handles the case where str() or unicode()
is used in the scope of an exception handler. If the exception
is passed into a function, returned from an assertRaises, or
used on an exception created in the same scope, this does not
catch it.
"""
name = 'check_for_string_unicode_exc'
version = '1.0'
CHECK_DESC = ('N325 str() and unicode() cannot be used on an '
'exception. Remove or use six.text_type()')
def __init__(self, tree, filename):
super(CheckForStrUnicodeExc, self).__init__(tree, filename)
self.name = []
self.already_checked = []
# Python 2 produces ast.TryExcept and ast.TryFinally nodes, but Python 3
# only produces ast.Try nodes.
if six.PY2:
def visit_TryExcept(self, node):
for handler in node.handlers:
if handler.name:
self.name.append(handler.name.id)
super(CheckForStrUnicodeExc, self).generic_visit(node)
self.name = self.name[:-1]
else:
super(CheckForStrUnicodeExc, self).generic_visit(node)
else:
def visit_Try(self, node):
for handler in node.handlers:
if handler.name:
self.name.append(handler.name)
super(CheckForStrUnicodeExc, self).generic_visit(node)
self.name = self.name[:-1]
else:
super(CheckForStrUnicodeExc, self).generic_visit(node)
def visit_Call(self, node):
if self._check_call_names(node, ['str', 'unicode']):
if node not in self.already_checked:
self.already_checked.append(node)
if isinstance(node.args[0], ast.Name):
if node.args[0].id in self.name:
self.add_error(node.args[0])
super(CheckForStrUnicodeExc, self).generic_visit(node)
class CheckForTransAdd(BaseASTChecker):
"""Checks for the use of concatenation on a translated string.
@ -723,30 +663,6 @@ def check_doubled_words(physical_line, filename):
return (0, msg % {'word': match.group(1)})
@core.flake8ext
def check_python3_no_iteritems(logical_line):
msg = ("N344: Use items() instead of dict.iteritems().")
if re.search(r".*\.iteritems\(\)", logical_line):
yield (0, msg)
@core.flake8ext
def check_python3_no_iterkeys(logical_line):
msg = ("N345: Use six.iterkeys() instead of dict.iterkeys().")
if re.search(r".*\.iterkeys\(\)", logical_line):
yield (0, msg)
@core.flake8ext
def check_python3_no_itervalues(logical_line):
msg = ("N346: Use six.itervalues() instead of dict.itervalues().")
if re.search(r".*\.itervalues\(\)", logical_line):
yield (0, msg)
@core.flake8ext
def no_os_popen(logical_line):
"""Disallow 'os.popen('

View File

@ -285,71 +285,6 @@ class HackingTestCase(test.NoDBTestCase):
def _assert_has_no_errors(self, code, checker, filename=None):
self._assert_has_errors(code, checker, filename=filename)
def test_str_unicode_exception(self):
checker = checks.CheckForStrUnicodeExc
code = """
def f(a, b):
try:
p = str(a) + str(b)
except ValueError as e:
p = str(e)
return p
"""
errors = [(5, 16, 'N325')]
self._assert_has_errors(code, checker, expected_errors=errors)
code = """
def f(a, b):
try:
p = unicode(a) + str(b)
except ValueError as e:
p = e
return p
"""
self._assert_has_no_errors(code, checker)
code = """
def f(a, b):
try:
p = str(a) + str(b)
except ValueError as e:
p = unicode(e)
return p
"""
errors = [(5, 20, 'N325')]
self._assert_has_errors(code, checker, expected_errors=errors)
code = """
def f(a, b):
try:
p = str(a) + str(b)
except ValueError as e:
try:
p = unicode(a) + unicode(b)
except ValueError as ve:
p = str(e) + str(ve)
p = e
return p
"""
errors = [(8, 20, 'N325'), (8, 29, 'N325')]
self._assert_has_errors(code, checker, expected_errors=errors)
code = """
def f(a, b):
try:
p = str(a) + str(b)
except ValueError as e:
try:
p = unicode(a) + unicode(b)
except ValueError as ve:
p = str(e) + unicode(ve)
p = str(e)
return p
"""
errors = [(8, 20, 'N325'), (8, 33, 'N325'), (9, 16, 'N325')]
self._assert_has_errors(code, checker, expected_errors=errors)
def test_api_version_decorator_check(self):
code = """
@some_other_decorator
@ -571,27 +506,6 @@ class HackingTestCase(test.NoDBTestCase):
code = "'This is the then best comment'\n"
self._assert_has_no_errors(code, checks.check_doubled_words)
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(ob))"))))
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(ob))"))))
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))"))))
def test_no_os_popen(self):
code = """
import os
@ -685,13 +599,6 @@ class HackingTestCase(test.NoDBTestCase):
"""
self._assert_has_no_errors(code, checks.check_policy_enforce)
def test_check_python3_xrange(self):
func = checks.check_python3_xrange
self.assertEqual(1, len(list(func('for i in xrange(10)'))))
self.assertEqual(1, len(list(func('for i in xrange (10)'))))
self.assertEqual(0, len(list(func('for i in range(10)'))))
self.assertEqual(0, len(list(func('for i in six.moves.range(10)'))))
def test_log_context(self):
code = """
LOG.info("Rebooting instance",

View File

@ -288,7 +288,6 @@ extension =
N323 = checks:check_explicit_underscore_import
N324 = checks:use_jsonutils
N332 = checks:check_api_version_decorator
N325 = checks:CheckForStrUnicodeExc
N326 = checks:CheckForTransAdd
N334 = checks:assert_true_or_false_with_in
N336 = checks:dict_constructor_with_list_copy
@ -300,10 +299,6 @@ extension =
N350 = checks:check_policy_registration_in_central_place
N351 = checks:check_policy_enforce
N343 = checks:check_doubled_words
N344 = checks:check_python3_no_iteritems
N345 = checks:check_python3_no_iterkeys
N346 = checks:check_python3_no_itervalues
N327 = checks:check_python3_xrange
N348 = checks:no_os_popen
N352 = checks:no_log_warn
N349 = checks:CheckForUncalledTestClosure