Skip to content

Commit

Permalink
Prevent from * import * to be splitted
Browse files Browse the repository at this point in the history
Closes #7
  • Loading branch information
adhikasp committed Apr 11, 2017
1 parent 1ff40b8 commit fa06eb7
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 13 deletions.
43 changes: 40 additions & 3 deletions autoflake.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

import ast
import difflib
from collections import defaultdict
import io
import os
import re
Expand Down Expand Up @@ -98,6 +99,15 @@ def unused_import_line_numbers(messages):
if isinstance(message, pyflakes.messages.UnusedImport):
yield message.lineno

def unused_import_module_name(messages):
"""Yield line number and module name of unused imports."""
pattern = r'\'(.+?)\''
for message in messages:
if isinstance(message, pyflakes.messages.UnusedImport):
module_name = re.search(pattern, str(message))
module_name = module_name.group()[1:-1]
if (module_name):
yield (message.lineno, module_name)

def unused_variable_line_numbers(messages):
"""Yield line numbers of unused variables."""
Expand Down Expand Up @@ -196,13 +206,33 @@ def multiline_statement(line, previous_line=''):
return True


def filter_from_import(line, unused_module, debug=False):
"""
Parse and filter ``from something import a, b, c``
Return line without unused import
"""
(indentation, imports) = re.split(pattern=r'\bimport \b',
string=line, maxsplit=1)
imports = re.split(pattern=r'[,\s]+', string=imports.rstrip())
unused_module = [x.split('.')[-1] for x in unused_module]
imports = [x for x in imports if x not in unused_module]
if not imports:
return

indentation += 'import '
return indentation + ', '.join(sorted(imports)) + \
get_line_ending(line)


def break_up_import(line):
"""Return line with imports on separate lines."""
assert '\\' not in line
assert '(' not in line
assert ')' not in line
assert ';' not in line
assert '#' not in line
assert 'from' not in line

newline = get_line_ending(line)
if not newline:
Expand Down Expand Up @@ -231,6 +261,9 @@ def filter_code(source, additional_imports=None,

marked_import_line_numbers = frozenset(
unused_import_line_numbers(messages))
marked_unused_module = defaultdict(lambda: [])
for line_number, module_name in unused_import_module_name(messages):
marked_unused_module[line_number].append(module_name)

if remove_unused_variables:
marked_variable_line_numbers = frozenset(
Expand All @@ -246,6 +279,7 @@ def filter_code(source, additional_imports=None,
elif line_number in marked_import_line_numbers:
yield filter_unused_import(
line,
unused_module=marked_unused_module[line_number],
remove_all_unused_imports=remove_all_unused_imports,
imports=imports,
previous_line=previous_line)
Expand All @@ -257,13 +291,16 @@ def filter_code(source, additional_imports=None,
previous_line = line


def filter_unused_import(line, remove_all_unused_imports, imports,
previous_line=''):
def filter_unused_import(line, unused_module, remove_all_unused_imports,
imports, previous_line=''):
"""Return line if used, otherwise return None."""
if multiline_import(line, previous_line):
return line
elif ',' in line:
return break_up_import(line)
if 'from' in line:
return filter_from_import(line, unused_module)
else:
return break_up_import(line)
else:
package = extract_package_name(line)
if not remove_all_unused_imports and package not in imports:
Expand Down
34 changes: 24 additions & 10 deletions test_autoflake.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,21 +293,35 @@ def test_break_up_import_with_indentation(self):
' import abc\n import math\n import subprocess\n',
autoflake.break_up_import(' import abc, subprocess, math\n'))

def test_break_up_import_with_from(self):
self.assertEqual(
"""\
from foo import abc
from foo import math
from foo import subprocess
""",
autoflake.break_up_import(
' from foo import abc, subprocess, math\n'))

def test_break_up_import_should_do_nothing_on_no_line_ending(self):
self.assertEqual(
'import abc, subprocess, math',
autoflake.break_up_import('import abc, subprocess, math'))

def test_filter_from_import_no_remove(self):
self.assertEqual(
"""\
from foo import abc, math, subprocess\n""",
autoflake.filter_from_import(
' from foo import abc, subprocess, math\n',
unused_module=[]))

def test_filter_from_import_remove_module(self):
self.assertEqual(
"""\
from foo import math, subprocess\n""",
autoflake.filter_from_import(
' from foo import abc, subprocess, math\n',
unused_module=['foo.abc']))

def test_filter_from_import_remove_all(self):
self.assertEqual(
None,
autoflake.filter_from_import(
' from foo import abc, subprocess, math\n',
unused_module=['foo.abc', 'foo.subprocess',
'foo.math']))

def test_filter_code_should_ignore_multiline_imports(self):
self.assertEqual(
r"""\
Expand Down

0 comments on commit fa06eb7

Please sign in to comment.