summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudiu Popa <pcmanticore@gmail.com>2015-12-01 14:58:59 +0200
committerClaudiu Popa <pcmanticore@gmail.com>2015-12-01 14:58:59 +0200
commit60dc4441f52dcf9d3ffd78b37be304bdce84b87e (patch)
treede4b4e93c506b9edceb23d24695c6f0a7b353c3b
parent0b5ab33c81a753ad732bfa5cdcf933bb2167a12c (diff)
downloadpylint-60dc4441f52dcf9d3ffd78b37be304bdce84b87e.tar.gz
Don't emit import-self and cyclic-import for relative imports of modules with the same name as the package itself.
The problem was partially the fault of astroid.modutils.get_module_part, in combination with a given context file. The function returned 'dummy' as the module part for the string `dummy.dummy.Dummy`, which is in fact true, since the first dummy is the package and the second dummy is the module from where Dummy gets loaded. But get_module_part has no way to know this semantic inference, that the second dummy is a relative import inside the first one. As such, it's better to just skip the check if the condition of being relative inside a __init__.py file is found, since there's no way to load itself in that case. Closes issues #708 and #706.
-rw-r--r--ChangeLog10
-rw-r--r--pylint/checkers/imports.py18
-rw-r--r--pylint/test/regrtest_data/dummy/__init__.py3
-rw-r--r--pylint/test/regrtest_data/dummy/another.py4
-rw-r--r--pylint/test/regrtest_data/dummy/dummy.py2
-rw-r--r--pylint/test/test_self.py7
6 files changed, 40 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index 1500699..5e7b4b3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -22,6 +22,16 @@ ChangeLog for Pylint
from other files might leak into the current file,
leading to wrong-import-position being emitted by pylint.
+ * Fix a crash which occurred when old visit methods are encountered
+ in plugin modules. Closes issue #711.
+
+ * Don't emit import-self and cyclic-import for relative imports
+ of modules with the same name as the package itself.
+ Closes issues #708 and #706.
+
+
+2015-11-29 -- 1.5.0
+
* Added multiple warnings related to imports. 'wrong-import-order'
is emitted when PEP 8 recommendations regarding imports are not
respected (that is, standard imports should be followed by third-party
diff --git a/pylint/checkers/imports.py b/pylint/checkers/imports.py
index a2f381c..0e16d18 100644
--- a/pylint/checkers/imports.py
+++ b/pylint/checkers/imports.py
@@ -496,14 +496,26 @@ given file (report RP0402 must not be disabled)'}
def _add_imported_module(self, node, importedmodname):
"""notify an imported module, used to analyze dependencies"""
+ module_file = node.root().file
+ context_name = node.root().name
+ base = os.path.splitext(os.path.basename(module_file))[0]
+
+ # Determine if we have a `from .something import` in a package's
+ # __init__. This means the module will never be able to import
+ # itself using this condition (the level will be bigger or
+ # if the same module is named as the package, it will be different
+ # anyway).
+ if isinstance(node, astroid.ImportFrom):
+ if node.level and node.level > 0 and base == '__init__':
+ return
+
try:
importedmodname = get_module_part(importedmodname,
- node.root().file)
+ module_file)
except ImportError:
pass
- context_name = node.root().name
+
if context_name == importedmodname:
- # module importing itself !
self.add_message('import-self', node=node)
elif not is_standard_module(importedmodname):
# handle dependencies
diff --git a/pylint/test/regrtest_data/dummy/__init__.py b/pylint/test/regrtest_data/dummy/__init__.py
new file mode 100644
index 0000000..0b43a70
--- /dev/null
+++ b/pylint/test/regrtest_data/dummy/__init__.py
@@ -0,0 +1,3 @@
+# pylint: disable=missing-docstring
+from .dummy import DUMMY
+from .another import ANOTHER
diff --git a/pylint/test/regrtest_data/dummy/another.py b/pylint/test/regrtest_data/dummy/another.py
new file mode 100644
index 0000000..046b447
--- /dev/null
+++ b/pylint/test/regrtest_data/dummy/another.py
@@ -0,0 +1,4 @@
+# pylint: disable=missing-docstring
+
+ANOTHER = 42
+
diff --git a/pylint/test/regrtest_data/dummy/dummy.py b/pylint/test/regrtest_data/dummy/dummy.py
new file mode 100644
index 0000000..60345dc
--- /dev/null
+++ b/pylint/test/regrtest_data/dummy/dummy.py
@@ -0,0 +1,2 @@
+# pylint: disable=missing-docstring
+DUMMY = 42
diff --git a/pylint/test/test_self.py b/pylint/test/test_self.py
index 69b739c..fae6403 100644
--- a/pylint/test/test_self.py
+++ b/pylint/test/test_self.py
@@ -288,7 +288,12 @@ class RunTC(unittest.TestCase):
actual_output = out.getvalue()
self.assertEqual(expected_output.strip(), actual_output.strip())
-
+ def test_import_itself_not_accounted_for_relative_imports(self):
+ expected = 'No config file found, using default configuration'
+ package = join(HERE, 'regrtest_data', 'dummy')
+ self._test_output([package, '--disable=locally-disabled', '-rn'],
+ expected_output=expected)
+
if __name__ == '__main__':