summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Pribysh <dmand@yandex.ru>2015-10-01 15:13:12 +0300
committerDmitry Pribysh <dmand@yandex.ru>2015-10-01 15:13:12 +0300
commitd26780d82fe0d6a0304bb17025a5a773cf187808 (patch)
tree8224cc3a8a74bc4e858664f58915dd4265c164da
parent0a4169614daa0708abdfa05bcdd3ad670e3d94a1 (diff)
downloadpylint-d26780d82fe0d6a0304bb17025a5a773cf187808.tar.gz
Add checker to identify multiple imports on one line.
Fixes issue #598. Had to modify some functional tests to ignore new message.
-rw-r--r--ChangeLog5
-rw-r--r--pylint/checkers/imports.py10
-rw-r--r--pylint/test/functional/bad_exception_context.py2
-rw-r--r--pylint/test/functional/invalid_exceptions_caught.py2
-rw-r--r--pylint/test/functional/multiple_imports.py2
-rw-r--r--pylint/test/functional/multiple_imports.txt1
-rw-r--r--pylint/test/unittest_checker_imports.py19
7 files changed, 36 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index 2ed0746..8c9811c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,9 +2,12 @@ ChangeLog for Pylint
--------------------
--
+ * Add checker to identify multiple imports on one line.
+ Closes issue #598.
+
* Fix unused-argument false positive when the "+=" operator is used.
Closes issue #518.
-
+
* Don't emit import-error for ignored modules. PyLint will not emit import
errors for any import which is, or is a subpackage of, a module in
the ignored-modules list. Closes issue #223.
diff --git a/pylint/checkers/imports.py b/pylint/checkers/imports.py
index a5a2f28..ae8df55 100644
--- a/pylint/checkers/imports.py
+++ b/pylint/checkers/imports.py
@@ -173,6 +173,11 @@ MSGS = {
'misplaced-future',
'Python 2.5 and greater require __future__ import to be the \
first non docstring statement in the module.'),
+
+ 'W0411': ('Multiple imports on one line (%s)',
+ 'multiple-imports',
+ 'Used when import statement importing multiple modules is '
+ 'detected.'),
}
class ImportsChecker(BaseChecker):
@@ -254,7 +259,10 @@ given file (report RP0402 must not be disabled)'}
def visit_import(self, node):
"""triggered when an import statement is seen"""
modnode = node.root()
- for name, _ in node.names:
+ names = [name for name, _ in node.names]
+ if len(names) >= 2:
+ self.add_message('multiple-imports', args=', '.join(names), node=node)
+ for name in names:
self._check_deprecated_module(node, name)
importedmodnode = self.get_imported_module(node, name)
if importedmodnode is None:
diff --git a/pylint/test/functional/bad_exception_context.py b/pylint/test/functional/bad_exception_context.py
index f386343..af3e4fb 100644
--- a/pylint/test/functional/bad_exception_context.py
+++ b/pylint/test/functional/bad_exception_context.py
@@ -1,6 +1,6 @@
"""Check that raise ... from .. uses a proper exception context """
-# pylint: disable=unreachable, import-error
+# pylint: disable=unreachable, import-error, multiple-imports
import socket, unknown
diff --git a/pylint/test/functional/invalid_exceptions_caught.py b/pylint/test/functional/invalid_exceptions_caught.py
index 2392ab0..545954d 100644
--- a/pylint/test/functional/invalid_exceptions_caught.py
+++ b/pylint/test/functional/invalid_exceptions_caught.py
@@ -1,5 +1,5 @@
"""Test for catching non-exceptions."""
-# pylint: disable=too-many-ancestors, no-absolute-import, import-error
+# pylint: disable=too-many-ancestors, no-absolute-import, import-error, multiple-imports
from __future__ import print_function
import socket, binascii
diff --git a/pylint/test/functional/multiple_imports.py b/pylint/test/functional/multiple_imports.py
new file mode 100644
index 0000000..9008dcc
--- /dev/null
+++ b/pylint/test/functional/multiple_imports.py
@@ -0,0 +1,2 @@
+# pylint: disable=missing-docstring, unused-import
+import os, socket # [multiple-imports]
diff --git a/pylint/test/functional/multiple_imports.txt b/pylint/test/functional/multiple_imports.txt
new file mode 100644
index 0000000..a5df51e
--- /dev/null
+++ b/pylint/test/functional/multiple_imports.txt
@@ -0,0 +1 @@
+multiple-imports:2::Multiple imports on one line (os, socket)
diff --git a/pylint/test/unittest_checker_imports.py b/pylint/test/unittest_checker_imports.py
index 8832878..f5e6bbb 100644
--- a/pylint/test/unittest_checker_imports.py
+++ b/pylint/test/unittest_checker_imports.py
@@ -10,7 +10,10 @@ class ImportsCheckerTC(CheckerTestCase):
CHECKER_CLASS = imports.ImportsChecker
- @set_config(ignored_modules=('external_module', 'fake_module.submodule'))
+ @set_config(ignored_modules=('external_module',
+ 'fake_module.submodule',
+ 'foo',
+ 'bar'))
def test_import_error_skipped(self):
"""Make sure that imports do not emit a 'import-error' when the
module is configured to be ignored."""
@@ -45,6 +48,20 @@ class ImportsCheckerTC(CheckerTestCase):
with self.assertNoMessages():
self.checker.visit_importfrom(node)
+ node = test_utils.extract_node("""
+ import foo, bar
+ """)
+ msg = Message('multiple-imports', node=node, args='foo, bar')
+ with self.assertAddsMessages(msg):
+ self.checker.visit_import(node)
+
+ node = test_utils.extract_node("""
+ import foo
+ import bar
+ """)
+ with self.assertNoMessages():
+ self.checker.visit_import(node)
+
def test_visit_importfrom(self):
"""
Test that duplicate imports on single line raise 'reimported'.