From 37dac96e7980217bd0e6cd6f736af73a741e4ac8 Mon Sep 17 00:00:00 2001 From: Sergei Lebedev Date: Tue, 22 Jun 2021 11:36:58 +0100 Subject: [PATCH] VariableChecker now accounts for attribute lookups in type comments Prior to this commit VariableChecker did not recurse into attribute lookups in type comments. This lead to false positive unused-import messages in e.g. import collections d = ... # type: collections.OrderedDict Fixes #4603. --- CONTRIBUTORS.txt | 2 ++ ChangeLog | 5 +++++ pylint/checkers/variables.py | 4 ++++ tests/checkers/unittest_variables.py | 13 +++++++++++++ 4 files changed, 24 insertions(+) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index b1de7ff30e3..05e4a31e18e 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -503,3 +503,5 @@ contributors: * Markus Siebenhaar: contributor * Lorena Buciu (lorena-b): contributor + +* Sergei Lebedev (superbobry): contributor diff --git a/ChangeLog b/ChangeLog index c2b1382d7a8..4ffa5a84144 100644 --- a/ChangeLog +++ b/ChangeLog @@ -171,6 +171,11 @@ Closes #4555 Closes #4023 +* Fix ``unused-import`` false positive for imported modules referenced in + attribute lookups in type comments. + + Closes #4603 + What's New in Pylint 2.8.3? =========================== diff --git a/pylint/checkers/variables.py b/pylint/checkers/variables.py index 3ddafd59942..8a46375097a 100644 --- a/pylint/checkers/variables.py +++ b/pylint/checkers/variables.py @@ -1826,6 +1826,10 @@ def _store_type_annotation_node(self, type_annotation): self._type_annotation_names.append(type_annotation.name) return + if isinstance(type_annotation, astroid.Attribute): + self._store_type_annotation_node(type_annotation.expr) + return + if not isinstance(type_annotation, astroid.Subscript): return diff --git a/tests/checkers/unittest_variables.py b/tests/checkers/unittest_variables.py index 90daa8d5d10..83321994532 100644 --- a/tests/checkers/unittest_variables.py +++ b/tests/checkers/unittest_variables.py @@ -191,6 +191,19 @@ def my_method(self) -> MyType: with self.assertNoMessages(): self.walk(module) + def test_attribute_in_type_comment(self): + """Ensure attribute lookups in type comments are accounted for. + + https://github.com/PyCQA/pylint/issues/4603 + """ + module = astroid.parse( + """ + import abc + x = ... # type: abc.ABC + """) + with self.assertNoMessages(): + self.walk(module) + class TestVariablesCheckerWithTearDown(CheckerTestCase):