summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaura M?dioni <laura.medioni@logilab.fr>2015-12-02 09:58:20 +0100
committerLaura M?dioni <laura.medioni@logilab.fr>2015-12-02 09:58:20 +0100
commit9e0620833d014a0c8d34b6bf8c908e01b3ac7e70 (patch)
tree9983214ea81a00244f60ac1277dcd43c037cadf4
parentee042d11d8aa453fc8b2febf10cd979dd26f2941 (diff)
downloadpylint-9e0620833d014a0c8d34b6bf8c908e01b3ac7e70.tar.gz
Allow statements in if or try blocks containing imports.
Closes issue #714
-rw-r--r--ChangeLog4
-rw-r--r--pylint/checkers/imports.py21
-rw-r--r--pylint/test/functional/wrong_import_position.py16
-rw-r--r--pylint/test/functional/wrong_import_position.txt6
4 files changed, 39 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index c9410a9..f8129cc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -16,6 +16,10 @@ ChangeLog for Pylint
* Don't emit super-on-old-class on classes with unknown bases.
Closes issue #721.
+ * Allow statements in `if` or `try` blocks containing imports.
+
+ Closes issue #714.
+
* Added a new warning, 'unsupported-assignment-operation', which is
emitted when item assignment is tried on an object which doesn't
have this ability. Closes issue #591.
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
diff --git a/pylint/test/functional/wrong_import_position.py b/pylint/test/functional/wrong_import_position.py
index 1547ff2..269d757 100644
--- a/pylint/test/functional/wrong_import_position.py
+++ b/pylint/test/functional/wrong_import_position.py
@@ -1,13 +1,25 @@
"""Checks import order rule"""
# pylint: disable=unused-import,relative-import,ungrouped-imports,wrong-import-order,using-constant-test
-# pylint: disable=import-error
+# pylint: disable=import-error, too-few-public-methods, missing-docstring
import os.path
+
if True:
from astroid import are_exclusive
try:
import sys
except ImportError:
- import datetime
+ class Myclass(object):
+ """docstring"""
+
+if sys.version_info[0] == 3:
+ from collections import OrderedDict
+else:
+ class OrderedDict(object):
+ """Nothing to see here."""
+ def some_func(self):
+ pass
+
+import six
CONSTANT = True
diff --git a/pylint/test/functional/wrong_import_position.txt b/pylint/test/functional/wrong_import_position.txt
index 2f417e4..5cde17d 100644
--- a/pylint/test/functional/wrong_import_position.txt
+++ b/pylint/test/functional/wrong_import_position.txt
@@ -1,3 +1,3 @@
-wrong-import-position:14::Import "import datetime" should be placed at the top of the module
-wrong-import-position:20::Import "import scipy" should be placed at the top of the module
-wrong-import-position:21::Import "import astroid" should be placed at the top of the module
+wrong-import-position:26::Import "import datetime" should be placed at the top of the module
+wrong-import-position:32::Import "import scipy" should be placed at the top of the module
+wrong-import-position:33::Import "import astroid" should be placed at the top of the module