From b700c2f8a0e6b8d61c3abea8d41438f66cd55025 Mon Sep 17 00:00:00 2001 From: Claudiu Popa Date: Sun, 6 Dec 2015 17:18:09 +0200 Subject: Make pylint work with new astroid exceptions, AstroidImportError and AstroidSyntaxError. --- pylint/checkers/imports.py | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) (limited to 'pylint/checkers/imports.py') diff --git a/pylint/checkers/imports.py b/pylint/checkers/imports.py index 0e16d18..5863130 100644 --- a/pylint/checkers/imports.py +++ b/pylint/checkers/imports.py @@ -298,7 +298,7 @@ given file (report RP0402 must not be disabled)'} for name in names: self._check_deprecated_module(node, name) - importedmodnode = self.get_imported_module(node, name) + importedmodnode = self._get_imported_module(node, name) if isinstance(node.scope(), astroid.Module): self._check_position(node) self._record_import(node, importedmodnode) @@ -320,7 +320,7 @@ given file (report RP0402 must not be disabled)'} self._check_reimport(node, basename=basename, level=node.level) modnode = node.root() - importedmodnode = self.get_imported_module(node, basename) + importedmodnode = self._get_imported_module(node, basename) if isinstance(node.scope(), astroid.Module): self._check_position(node) self._record_import(node, importedmodnode) @@ -458,22 +458,20 @@ given file (report RP0402 must not be disabled)'} '"%s"' % local_imports[0][0].as_string())) return std_imports, extern_imports, local_imports - def get_imported_module(self, importnode, modname): + def _get_imported_module(self, importnode, modname): try: return importnode.do_import_module(modname) - except astroid.InferenceError as ex: - dotted_modname = _get_import_name(importnode, modname) - if str(ex) != modname: - args = '%r (%s)' % (dotted_modname, ex) - else: - args = repr(dotted_modname) - + except astroid.AstroidBuildingException as exc: for submodule in _qualified_names(modname): if submodule in self._ignored_modules: return None - if not node_ignores_exception(importnode, ImportError): - self.add_message("import-error", args=args, node=importnode) + if node_ignores_exception(importnode, ImportError): + return None + + dotted_modname = _get_import_name(importnode, modname) + self.add_message("import-error", args=repr(dotted_modname), + node=importnode) def _check_relative_import(self, modnode, importnode, importedmodnode, importedasname): -- cgit v1.2.1 From b7f934de0d5ded5a120685d92ae07c2eb54b9ff1 Mon Sep 17 00:00:00 2001 From: Claudiu Popa Date: Sun, 6 Dec 2015 18:41:34 +0200 Subject: 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. --- pylint/checkers/imports.py | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) (limited to 'pylint/checkers/imports.py') 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, -- cgit v1.2.1 From 9e0620833d014a0c8d34b6bf8c908e01b3ac7e70 Mon Sep 17 00:00:00 2001 From: Laura M?dioni Date: Wed, 2 Dec 2015 09:58:20 +0100 Subject: Allow statements in if or try blocks containing imports. Closes issue #714 --- pylint/checkers/imports.py | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'pylint/checkers/imports.py') diff --git a/pylint/checkers/imports.py b/pylint/checkers/imports.py index 2fdcc85..2d37461 100644 --- a/pylint/checkers/imports.py +++ b/pylint/checkers/imports.py @@ -381,9 +381,24 @@ given file (report RP0402 must not be disabled)'} = visit_ifexp = visit_comprehension = visit_if def visit_functiondef(self, node): - # if it is the first non import instruction of the module, record it - if not self._first_non_import_node: - self._first_non_import_node = node + # If it is the first non import instruction of the module, record it. + if self._first_non_import_node: + return + + # Check if the node belongs to an `If` or a `Try` block. If they + # contain imports, skip recording this node. + if not isinstance(node.parent.scope(), astroid.Module): + return + + root = node + while not isinstance(root.parent, astroid.Module): + root = root.parent + + if isinstance(root, (astroid.If, astroid.TryFinally, astroid.TryExcept)): + if any(root.nodes_of_class((astroid.Import, astroid.ImportFrom))): + return + + self._first_non_import_node = node visit_classdef = visit_for = visit_while = visit_functiondef -- cgit v1.2.1