From b5f38fb40a9acf9f8e922e64727cb81c53e6ac7c Mon Sep 17 00:00:00 2001 From: esberglu Date: Tue, 13 Feb 2018 10:29:58 -0600 Subject: [PATCH] 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 --- HACKING.rst | 1 + nova/hacking/checks.py | 17 +++++++++++++++++ nova/service.py | 2 +- nova/tests/unit/image/test_glance.py | 2 +- nova/tests/unit/test_hacking.py | 20 ++++++++++++++++++++ nova/tests/unit/virt/test_virt_drivers.py | 11 ++++------- 6 files changed, 44 insertions(+), 9 deletions(-) diff --git a/HACKING.rst b/HACKING.rst index 8de49a735a78..e06eae73522b 100644 --- a/HACKING.rst +++ b/HACKING.rst @@ -66,6 +66,7 @@ Nova Specific Commandments - [N357] Use oslo_utils.uuidutils or uuidsentinel(in case of test cases) to generate UUID instead of uuid4(). - [N358] Return must always be followed by a space when returning a value. +- [N359] Check for redundant import aliases. Creating Unit Tests ------------------- diff --git a/nova/hacking/checks.py b/nova/hacking/checks.py index b63a100068cd..828ede38c683 100644 --- a/nova/hacking/checks.py +++ b/nova/hacking/checks.py @@ -98,6 +98,7 @@ log_remove_context = re.compile( r"(.)*LOG\.(.*)\(.*(context=[_a-zA-Z0-9].*)+.*\)") return_not_followed_by_space = re.compile(r"^\s*return(?:\(|{|\"|'|#).*$") uuid4_re = re.compile(r"uuid4\(\)($|[^\.]|\.hex)") +redundant_import_alias_re = re.compile(r"import (?:.*\.)?(.+) as \1$") class BaseASTChecker(ast.NodeVisitor): @@ -801,6 +802,21 @@ def return_followed_by_space(logical_line): "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): register(import_no_db_in_virt) register(no_db_session_in_public_api) @@ -842,3 +858,4 @@ def factory(register): register(no_assert_true_false_is_not) register(check_uuid4) register(return_followed_by_space) + register(no_redundant_import_alias) diff --git a/nova/service.py b/nova/service.py index a04a2e96d559..ffab3952bffe 100644 --- a/nova/service.py +++ b/nova/service.py @@ -96,7 +96,7 @@ def setup_profiler(binary, host): def assert_eventlet_uses_monotonic_clock(): - import eventlet.hubs as hubs + from eventlet import hubs import monotonic hub = hubs.get_hub() diff --git a/nova/tests/unit/image/test_glance.py b/nova/tests/unit/image/test_glance.py index d1507827b402..002ba6084a8f 100644 --- a/nova/tests/unit/image/test_glance.py +++ b/nova/tests/unit/image/test_glance.py @@ -22,7 +22,7 @@ from cursive import exception as cursive_exception import ddt import glanceclient.exc from glanceclient.v1 import images -import glanceclient.v2.schemas as schemas +from glanceclient.v2 import schemas from keystoneauth1 import loading as ks_loading import mock import six diff --git a/nova/tests/unit/test_hacking.py b/nova/tests/unit/test_hacking.py index 82b822a7931a..befa0f51f5cc 100644 --- a/nova/tests/unit/test_hacking.py +++ b/nova/tests/unit/test_hacking.py @@ -782,3 +782,23 @@ class HackingTestCase(test.NoDBTestCase): "return ' some string '")))) self.assertEqual(0, len(list(checks.return_followed_by_space( "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) diff --git a/nova/tests/unit/virt/test_virt_drivers.py b/nova/tests/unit/virt/test_virt_drivers.py index 147ca6fae01d..368dcc1aa708 100644 --- a/nova/tests/unit/virt/test_virt_drivers.py +++ b/nova/tests/unit/virt/test_virt_drivers.py @@ -82,14 +82,11 @@ class _FakeDriverBackendTestCase(object): else: self.saved_libvirt = None - import nova.tests.unit.virt.libvirt.fake_imagebackend as \ - fake_imagebackend - import nova.tests.unit.virt.libvirt.fake_libvirt_utils as \ - fake_libvirt_utils - import nova.tests.unit.virt.libvirt.fakelibvirt as fakelibvirt + from nova.tests.unit.virt.libvirt import fake_imagebackend + from nova.tests.unit.virt.libvirt import fake_libvirt_utils + from nova.tests.unit.virt.libvirt import fakelibvirt - import nova.tests.unit.virt.libvirt.fake_os_brick_connector as \ - fake_os_brick_connector + from nova.tests.unit.virt.libvirt import fake_os_brick_connector self.useFixture(fake_imagebackend.ImageBackendFixture()) self.useFixture(fakelibvirt.FakeLibvirtFixture())