diff --git a/autopep8.py b/autopep8.py index 258f30c5..8fc548ad 100755 --- a/autopep8.py +++ b/autopep8.py @@ -57,6 +57,7 @@ class documentation for more information. import textwrap import token import tokenize +import ast import pycodestyle @@ -1402,6 +1403,14 @@ def is_string_literal(line): if line and line[0] in 'rR': line = line[1:] return line and (line[0] == '"' or line[0] == "'") + + def is_future_import(line): + nodes = ast.parse(line) + for n in nodes.body: + if isinstance(n, ast.ImportFrom) and n.module == '__future__': + return True + return False + allowed_try_keywords = ('try', 'except', 'else', 'finally') for cnt, line in enumerate(source): if not line.rstrip(): @@ -1409,7 +1418,7 @@ def is_string_literal(line): elif line.startswith('#'): continue if line.startswith('import ') or line.startswith('from '): - if cnt == import_line_index: + if cnt == import_line_index or is_future_import(line): continue return cnt elif pycodestyle.DUNDER_REGEX.match(line): diff --git a/test/test_autopep8.py b/test/test_autopep8.py index aa502d14..14981e8a 100755 --- a/test/test_autopep8.py +++ b/test/test_autopep8.py @@ -2416,6 +2416,12 @@ def test_e402_duplicate_module(self): with autopep8_context(line) as result: self.assertEqual(fixed, result) + def test_e402_with_future_import(self): + line = 'from __future__ import print_function\na = 1\nimport os\n' + fixed = 'from __future__ import print_function\nimport os\na = 1\n' + with autopep8_context(line) as result: + self.assertEqual(fixed, result) + def test_e402_import_some_modules(self): line = """\ a = 1