Skip to content

Commit

Permalink
Merge pull request #125 from snok/unused-imports
Browse files Browse the repository at this point in the history
Stop flagging unused imports
  • Loading branch information
sondrelg authored Aug 4, 2022
2 parents 3dc4eef + e0e22c9 commit 7e8494a
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 27 deletions.
8 changes: 8 additions & 0 deletions flake8_type_checking/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -900,8 +900,16 @@ def unused_imports(self) -> Flake8Generator:
unused_imports = set(self.visitor.imports) - self.visitor.names
used_imports = set(self.visitor.imports) - unused_imports
already_imported_modules = [self.visitor.imports[name].module for name in used_imports]
annotation_names = [i[2] for i in self.visitor.wrapped_annotations] + [
i[2] for i in self.visitor.unwrapped_annotations
]

for name in unused_imports:
if name not in annotation_names:
# The import seems to be completely unused.
# Prevent flagging these, as they're already covered by F401
continue

# Get the ImportName object for this import name
import_name: ImportName = self.visitor.imports[name]
if import_name.module not in already_imported_modules:
Expand Down
10 changes: 8 additions & 2 deletions tests/test_errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@ def test_mixed_errors(self):
import {mod}
import pytest
from x import y
x: {mod} | pytest | y
"""
)
assert _get_error(example) == {
'2:0 ' + TC001.format(module=f'{mod}'),
f"2:0 {TC001.format(module=f'{mod}')}",
'3:0 ' + TC002.format(module='pytest'),
'4:0 ' + TC002.format(module='x.y'),
}
Expand All @@ -35,7 +37,7 @@ def test_type_checking_block_imports_dont_generate_errors(self):
from b import c
def test():
def test(foo: z, bar: x):
pass
"""
)
Expand Down Expand Up @@ -277,3 +279,7 @@ class C:
"""
)
assert _get_error(example) == set()

def test_tc001_false_positive(self):
"""Re https://github.com/snok/flake8-type-checking/issues/116."""
assert _get_error('from x import y') == set()
2 changes: 1 addition & 1 deletion tests/test_exempt_modules.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def test_exempt_modules_option():
from pandas import DataFrame
from a import B
x: Callable[[], List]
x: Callable[[DataFrame, B], List]
'''
)
assert _get_error(example2, error_code_filter='TC002') == {
Expand Down
35 changes: 11 additions & 24 deletions tests/test_tc001_to_tc003.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@ def get_tc_001_to_003_tests(import_: str, ERROR: str) -> L:
# No usage - these should all generate errors.
no_use: L = [
# ast.Import
(f'import {import_}', {f"1:0 {ERROR.format(module=f'{import_}')}"}),
(f'\nimport {import_}', {f"2:0 {ERROR.format(module=f'{import_}')}"}),
(f'import {import_}\nx:{import_}', {f"1:0 {ERROR.format(module=f'{import_}')}"}),
(f'\nimport {import_}\nx:{import_}', {f"2:0 {ERROR.format(module=f'{import_}')}"}),
# ast.ImportFrom
(f'from {import_} import Plugin', {'1:0 ' + ERROR.format(module=f'{import_}.Plugin')}),
(f'\n\nfrom {import_} import constants', {'3:0 ' + ERROR.format(module=f'{import_}.constants')}),
(f'from {import_} import Plugin\nx:Plugin', {'1:0 ' + ERROR.format(module=f'{import_}.Plugin')}),
(f'\n\nfrom {import_} import constants\nx:constants', {'3:0 ' + ERROR.format(module=f'{import_}.constants')}),
# Aliased imports
(f'import {import_} as x', {'1:0 ' + ERROR.format(module='x')}),
(f'from {import_} import constants as x', {'1:0 ' + ERROR.format(module='x')}),
(f'import {import_} as x\ny:x', {'1:0 ' + ERROR.format(module='x')}),
(f'from {import_} import constants as x\ny:x', {'1:0 ' + ERROR.format(module='x')}),
]

# These imports are all used. None should generate errors.
Expand All @@ -60,7 +60,10 @@ def get_tc_001_to_003_tests(import_: str, ERROR: str) -> L:
(f'\nimport {import_}\nx: {import_} = 2', {f"2:0 {ERROR.format(module=f'{import_}')}"}),
# ast.ImportFrom
(f'from {import_} import Plugin\nx: Plugin', {'1:0 ' + ERROR.format(module=f'{import_}.Plugin')}),
(f'\n\nfrom {import_} import constants\nx: Plugin = 2', {'3:0 ' + ERROR.format(module=f'{import_}.constants')}),
(
f'\n\nfrom {import_} import constants\nx: constants = 2',
{'3:0 ' + ERROR.format(module=f'{import_}.constants')},
),
# Aliased imports
(f'import {import_} as x\ny: x', {'1:0 ' + ERROR.format(module='x')}),
(f'from {import_} import constants as x\ny: x = 2', {'1:0 ' + ERROR.format(module='x')}),
Expand All @@ -77,7 +80,7 @@ def get_tc_001_to_003_tests(import_: str, ERROR: str) -> L:
{'1:0 ' + ERROR.format(module=f'{import_}.Plugin')},
),
(
f'\n\nfrom {import_} import constants\ndef example(x: Plugin = 2):\n\tpass',
f'\n\nfrom {import_} import constants\ndef example(x: constants = 2):\n\tpass',
{'3:0 ' + ERROR.format(module=f'{import_}.constants')},
),
# Aliased imports
Expand Down Expand Up @@ -169,22 +172,6 @@ class Migration:
),
set(),
),
(
textwrap.dedent(
f'''
from {import_} import Any, Generator, Union
if TYPE_CHECKING:
ImportType = Union[ast.Import, ast.ImportFrom]
Flake8Generator = Generator[tuple[int, int, str, Any], None, None]
'''
),
{
'2:0 ' + ERROR.format(module=f'{import_}.Any'),
'2:0 ' + ERROR.format(module=f'{import_}.Generator'),
'2:0 ' + ERROR.format(module=f'{import_}.Union'),
},
),
(
textwrap.dedent(
f'''
Expand Down

0 comments on commit 7e8494a

Please sign in to comment.