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:
parent
1490a54fa9
commit
9dca0d186f
|
@ -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/``
|
||||
|
|
|
@ -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('
|
||||
|
|
|
@ -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",
|
||||
|
|
5
tox.ini
5
tox.ini
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue