Allow statements in if or try blocks containing imports.

Closes issue #714

authorLaura Médioni <laura.medioni@logilab.fr>
changeset9a545cc2e2b6
branchdefault
phasepublic
hiddenno
parent revision#70703f84d72b Move the construction of generated_members into open.
child revision#9b3cbdb52788 pylint/config.py: Add another check of the current working directory for `.pylintrc`.
files modified by this revision
ChangeLog
pylint/checkers/imports.py
pylint/test/functional/wrong_import_position.py
pylint/test/functional/wrong_import_position.txt
# HG changeset patch
# User Laura Médioni <laura.medioni@logilab.fr>
# Date 1449046700 -3600
# Wed Dec 02 09:58:20 2015 +0100
# Node ID 9a545cc2e2b654d7c80228428b8230445184c284
# Parent 70703f84d72b6097b6381e520a797a4fa39db566
Allow statements in if or try blocks containing imports.

Closes issue #714

diff --git a/ChangeLog b/ChangeLog
@@ -8,10 +8,14 @@
1        .qname() method after the inference.
2 
3      * Don't emit super-on-old-class on classes with unknown bases.
4        Closes issue #721.
5 
6 +    * Allow statements in `if` or `try` blocks containing imports.
7 +
8 +      Closes issue #714. 
9 +
10 
11  2015-12-02 -- 1.5.1
12 
13      * Don't emit unsubscriptable-object if the node is found
14        inside an abstract class. Closes issue #685.
diff --git a/pylint/checkers/imports.py b/pylint/checkers/imports.py
@@ -367,13 +367,28 @@
15 
16      visit_tryfinally = visit_tryexcept = visit_assignattr = visit_assign \
17              = visit_ifexp = visit_comprehension = visit_if
18 
19      def visit_functiondef(self, node):
20 -        # if it is the first non import instruction of the module, record it
21 -        if not self._first_non_import_node:
22 -            self._first_non_import_node = node
23 +        # If it is the first non import instruction of the module, record it.
24 +        if self._first_non_import_node:
25 +            return
26 +
27 +        # Check if the node belongs to an `If` or a `Try` block. If they
28 +        # contain imports, skip recording this node.
29 +        if not isinstance(node.parent.scope(), astroid.Module):
30 +            return
31 +
32 +        root = node
33 +        while not isinstance(root.parent, astroid.Module):
34 +            root = root.parent
35 +
36 +        if isinstance(root, (astroid.If, astroid.TryFinally, astroid.TryExcept)):
37 +            if any(root.nodes_of_class((astroid.Import, astroid.ImportFrom))):
38 +                return
39 +
40 +        self._first_non_import_node = node
41 
42      visit_classdef = visit_for = visit_while = visit_functiondef
43 
44      def _check_misplaced_future(self, node):
45          basename = node.modname
diff --git a/pylint/test/functional/wrong_import_position.py b/pylint/test/functional/wrong_import_position.py
@@ -1,15 +1,27 @@
46  """Checks import order rule"""
47  # pylint: disable=unused-import,relative-import,ungrouped-imports,wrong-import-order,using-constant-test
48 -# pylint: disable=import-error
49 +# pylint: disable=import-error, too-few-public-methods, missing-docstring
50  import os.path
51 +
52  if True:
53      from astroid import are_exclusive
54  try:
55      import sys
56  except ImportError:
57 -    import datetime
58 +    class Myclass(object):
59 +        """docstring"""
60 +
61 +if sys.version_info[0] == 3:
62 +    from collections import OrderedDict
63 +else:
64 +    class OrderedDict(object):
65 +        """Nothing to see here."""
66 +        def some_func(self):
67 +            pass
68 +
69 +import six
70 
71  CONSTANT = True
72 
73  import datetime  # [wrong-import-position]
74 
diff --git a/pylint/test/functional/wrong_import_position.txt b/pylint/test/functional/wrong_import_position.txt
@@ -1,3 +1,3 @@
75 -wrong-import-position:14::Import "import datetime" should be placed at the top of the module
76 -wrong-import-position:20::Import "import scipy" should be placed at the top of the module
77 -wrong-import-position:21::Import "import astroid" should be placed at the top of the module
78 +wrong-import-position:26::Import "import datetime" should be placed at the top of the module
79 +wrong-import-position:32::Import "import scipy" should be placed at the top of the module
80 +wrong-import-position:33::Import "import astroid" should be placed at the top of the module