Add check for redundant import aliases

This adds a pep8 function that will check for redundant import aliases.
Any imports of the forms below will not be allowed.

from x import y as y
import x as x
import x.y as y

Change-Id: Iff90f0172d97bd1d49d54c811a70c8af11776da4
This commit is contained in:
esberglu
2018-02-13 10:29:58 -06:00
committed by Eric Berglund
parent fba4161f71
commit b5f38fb40a
6 changed files with 44 additions and 9 deletions

View File

@@ -66,6 +66,7 @@ Nova Specific Commandments
- [N357] Use oslo_utils.uuidutils or uuidsentinel(in case of test cases) to - [N357] Use oslo_utils.uuidutils or uuidsentinel(in case of test cases) to
generate UUID instead of uuid4(). generate UUID instead of uuid4().
- [N358] Return must always be followed by a space when returning a value. - [N358] Return must always be followed by a space when returning a value.
- [N359] Check for redundant import aliases.
Creating Unit Tests Creating Unit Tests
------------------- -------------------

View File

@@ -98,6 +98,7 @@ log_remove_context = re.compile(
r"(.)*LOG\.(.*)\(.*(context=[_a-zA-Z0-9].*)+.*\)") r"(.)*LOG\.(.*)\(.*(context=[_a-zA-Z0-9].*)+.*\)")
return_not_followed_by_space = re.compile(r"^\s*return(?:\(|{|\"|'|#).*$") return_not_followed_by_space = re.compile(r"^\s*return(?:\(|{|\"|'|#).*$")
uuid4_re = re.compile(r"uuid4\(\)($|[^\.]|\.hex)") uuid4_re = re.compile(r"uuid4\(\)($|[^\.]|\.hex)")
redundant_import_alias_re = re.compile(r"import (?:.*\.)?(.+) as \1$")
class BaseASTChecker(ast.NodeVisitor): class BaseASTChecker(ast.NodeVisitor):
@@ -801,6 +802,21 @@ def return_followed_by_space(logical_line):
"N357: Return keyword should be followed by a space.") "N357: Return keyword should be followed by a space.")
def no_redundant_import_alias(logical_line):
"""Check for redundant import aliases.
Imports should not be in the forms below.
from x import y as y
import x as x
import x.y as y
N359
"""
if re.search(redundant_import_alias_re, logical_line):
yield (0, "N359: Import alias should not be redundant.")
def factory(register): def factory(register):
register(import_no_db_in_virt) register(import_no_db_in_virt)
register(no_db_session_in_public_api) register(no_db_session_in_public_api)
@@ -842,3 +858,4 @@ def factory(register):
register(no_assert_true_false_is_not) register(no_assert_true_false_is_not)
register(check_uuid4) register(check_uuid4)
register(return_followed_by_space) register(return_followed_by_space)
register(no_redundant_import_alias)

View File

@@ -96,7 +96,7 @@ def setup_profiler(binary, host):
def assert_eventlet_uses_monotonic_clock(): def assert_eventlet_uses_monotonic_clock():
import eventlet.hubs as hubs from eventlet import hubs
import monotonic import monotonic
hub = hubs.get_hub() hub = hubs.get_hub()

View File

@@ -22,7 +22,7 @@ from cursive import exception as cursive_exception
import ddt import ddt
import glanceclient.exc import glanceclient.exc
from glanceclient.v1 import images from glanceclient.v1 import images
import glanceclient.v2.schemas as schemas from glanceclient.v2 import schemas
from keystoneauth1 import loading as ks_loading from keystoneauth1 import loading as ks_loading
import mock import mock
import six import six

View File

@@ -782,3 +782,23 @@ class HackingTestCase(test.NoDBTestCase):
"return ' some string '")))) "return ' some string '"))))
self.assertEqual(0, len(list(checks.return_followed_by_space( self.assertEqual(0, len(list(checks.return_followed_by_space(
"return (int('40') + 2)")))) "return (int('40') + 2)"))))
def test_no_redundant_import_alias(self):
code = """
from x import y as y
import x as x
import x.y.z as z
import x.y.z as y.z
"""
errors = [(x + 1, 0, 'N359') for x in range(4)]
self._assert_has_errors(code, checks.no_redundant_import_alias,
expected_errors=errors)
code = """
from x import y
import x
from x.y import z
from a import bcd as cd
import ab.cd.efg as fg
import ab.cd.efg as d.efg
"""
self._assert_has_no_errors(code, checks.no_redundant_import_alias)

View File

@@ -82,14 +82,11 @@ class _FakeDriverBackendTestCase(object):
else: else:
self.saved_libvirt = None self.saved_libvirt = None
import nova.tests.unit.virt.libvirt.fake_imagebackend as \ from nova.tests.unit.virt.libvirt import fake_imagebackend
fake_imagebackend from nova.tests.unit.virt.libvirt import fake_libvirt_utils
import nova.tests.unit.virt.libvirt.fake_libvirt_utils as \ from nova.tests.unit.virt.libvirt import fakelibvirt
fake_libvirt_utils
import nova.tests.unit.virt.libvirt.fakelibvirt as fakelibvirt
import nova.tests.unit.virt.libvirt.fake_os_brick_connector as \ from nova.tests.unit.virt.libvirt import fake_os_brick_connector
fake_os_brick_connector
self.useFixture(fake_imagebackend.ImageBackendFixture()) self.useFixture(fake_imagebackend.ImageBackendFixture())
self.useFixture(fakelibvirt.FakeLibvirtFixture()) self.useFixture(fakelibvirt.FakeLibvirtFixture())