diff options
author | Claudiu Popa <pcmanticore@gmail.com> | 2015-12-06 18:41:34 +0200 |
---|---|---|
committer | Claudiu Popa <pcmanticore@gmail.com> | 2015-12-06 18:41:34 +0200 |
commit | b7f934de0d5ded5a120685d92ae07c2eb54b9ff1 (patch) | |
tree | d5ae59bdcf3d8099f907fe854c9ee315bdfa9281 /pylint/checkers/imports.py | |
parent | b700c2f8a0e6b8d61c3abea8d41438f66cd55025 (diff) | |
download | pylint-b7f934de0d5ded5a120685d92ae07c2eb54b9ff1.tar.gz |
Added a new error, 'relative-beyond-top-level'.
This is emitted when a relative import was attempted beyond the top level package.
For instance, if a package has X levels, trying to climb X + n levels with a relative
import, as in `from ..stuff import Stuff`, will result in an error.
Closes issue #588.
Diffstat (limited to 'pylint/checkers/imports.py')
-rw-r--r-- | pylint/checkers/imports.py | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/pylint/checkers/imports.py b/pylint/checkers/imports.py index 5863130..2fdcc85 100644 --- a/pylint/checkers/imports.py +++ b/pylint/checkers/imports.py @@ -88,6 +88,14 @@ def _get_first_import(node, context, name, base, level): if found and not are_exclusive(first, node): return first + +def _ignore_import_failure(node, modname, ignored_modules): + for submodule in _qualified_names(modname): + if submodule in ignored_modules: + return True + + return node_ignores_exception(node, ImportError) + # utilities to represents import dependencies as tree and dot graph ########### def _make_tree_defs(mod_files_list): @@ -161,6 +169,10 @@ MSGS = { 'import-error', 'Used when pylint has been unable to import a module.', {'old_names': [('F0401', 'import-error')]}), + 'E0402': ('Attempted relative import beyond top-level package', + 'relative-beyond-top-level', + 'Used when a relative import tries to access too many levels ' + 'in the current package.'), 'R0401': ('Cyclic import (%s)', 'cyclic-import', 'Used when a cyclic import between two or more modules is \ @@ -461,16 +473,18 @@ given file (report RP0402 must not be disabled)'} def _get_imported_module(self, importnode, modname): try: return importnode.do_import_module(modname) - except astroid.AstroidBuildingException as exc: - for submodule in _qualified_names(modname): - if submodule in self._ignored_modules: - return None + except astroid.TooManyLevelsError: + if _ignore_import_failure(importnode, modname, self._ignored_modules): + return None + + self.add_message('relative-beyond-top-level', node=importnode) - if node_ignores_exception(importnode, ImportError): + except astroid.AstroidBuildingException as exc: + if _ignore_import_failure(importnode, modname, self._ignored_modules): return None dotted_modname = _get_import_name(importnode, modname) - self.add_message("import-error", args=repr(dotted_modname), + self.add_message('import-error', args=repr(dotted_modname), node=importnode) def _check_relative_import(self, modnode, importnode, importedmodnode, |