Skip to content

Commit

Permalink
VariableChecker now accounts for attribute lookups in type comments (#…
Browse files Browse the repository at this point in the history
…4604)

* 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
  • Loading branch information
superbobry committed Jun 27, 2021
1 parent 1e55ae6 commit 3d6389b
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CONTRIBUTORS.txt
Expand Up @@ -503,3 +503,5 @@ contributors:
* Markus Siebenhaar: contributor

* Lorena Buciu (lorena-b): contributor

* Sergei Lebedev (superbobry): contributor
5 changes: 5 additions & 0 deletions ChangeLog
Expand Up @@ -186,6 +186,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?
===========================
Expand Down
4 changes: 4 additions & 0 deletions pylint/checkers/variables.py
Expand Up @@ -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

Expand Down
2 changes: 2 additions & 0 deletions pylint/constants.py
@@ -1,6 +1,7 @@
# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
# For details: https://github.com/PyCQA/pylint/blob/master/LICENSE

import platform
import sys

import astroid
Expand All @@ -11,6 +12,7 @@
PY39_PLUS = sys.version_info[:2] >= (3, 9)
PY310_PLUS = sys.version_info[:2] >= (3, 10)

IS_PYPY = platform.python_implementation() == "PyPy"

PY_EXTS = (".py", ".pyc", ".pyo", ".pyw", ".so", ".dll")

Expand Down
20 changes: 20 additions & 0 deletions tests/checkers/unittest_variables.py
Expand Up @@ -21,11 +21,13 @@
import os
import re
import sys
import unittest
from pathlib import Path

import astroid

from pylint.checkers import variables
from pylint.constants import IS_PYPY
from pylint.interfaces import UNDEFINED
from pylint.testutils import CheckerTestCase, Message, linter, set_config

Expand Down Expand Up @@ -191,6 +193,24 @@ def my_method(self) -> MyType:
with self.assertNoMessages():
self.walk(module)

@unittest.skipIf(IS_PYPY, "PyPy does not parse type comments")
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 foo
from foo import Bar, Boo
a = ... # type: foo.Bar
b = ... # type: foo.Bar[Boo]
c = ... # type: Bar.Boo
"""
)
with self.assertNoMessages():
self.walk(module)


class TestVariablesCheckerWithTearDown(CheckerTestCase):

Expand Down

0 comments on commit 3d6389b

Please sign in to comment.