From 84da8cdaad574df7e692dff06ab561acc63d521c Mon Sep 17 00:00:00 2001 From: Laurent Kadian <17257425+lkadian@users.noreply.github.com> Date: Sun, 13 Feb 2022 11:32:09 -0500 Subject: support TypeAlias annotations (#679) For assignments with `TypeAlias` as annotation, handle the value as an annotation also. Avoids incorrectly detecting `Bar` as unused in `x: TypeAlias = 'Bar'`. --- pyflakes/checker.py | 10 ++++++--- pyflakes/test/test_type_annotations.py | 40 ++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/pyflakes/checker.py b/pyflakes/checker.py index 45f2a42..7f33d6a 100644 --- a/pyflakes/checker.py +++ b/pyflakes/checker.py @@ -128,7 +128,7 @@ def _is_const_non_singleton(node): # type: (ast.AST) -> bool return _is_constant(node) and not _is_singleton(node) -def _is_name_or_attr(node, name): # type: (ast.Ast, str) -> bool +def _is_name_or_attr(node, name): # type: (ast.AST, str) -> bool return ( (isinstance(node, ast.Name) and node.id == name) or (isinstance(node, ast.Attribute) and node.attr == name) @@ -2381,9 +2381,13 @@ class Checker(object): def ANNASSIGN(self, node): self.handleNode(node.target, node) self.handleAnnotation(node.annotation, node) + # If the assignment has value, handle the *value* now. if node.value: - # If the assignment has value, handle the *value* now. - self.handleNode(node.value, node) + # If the annotation is `TypeAlias`, handle the *value* as an annotation. + if _is_typing(node.annotation, 'TypeAlias', self.scopeStack): + self.handleAnnotation(node.value, node) + else: + self.handleNode(node.value, node) def COMPARE(self, node): left = node.left diff --git a/pyflakes/test/test_type_annotations.py b/pyflakes/test/test_type_annotations.py index f3b6c24..3b6d5e7 100644 --- a/pyflakes/test/test_type_annotations.py +++ b/pyflakes/test/test_type_annotations.py @@ -300,6 +300,46 @@ class TestTypeAnnotations(TestCase): a: 'a: "A"' ''', m.ForwardAnnotationSyntaxError) + @skipIf(version_info < (3, 6), 'new in Python 3.6') + def test_TypeAlias_annotations(self): + self.flakes(""" + from typing_extensions import TypeAlias + from foo import Bar + + bar: TypeAlias = Bar + """) + self.flakes(""" + from typing_extensions import TypeAlias + from foo import Bar + + bar: TypeAlias = 'Bar' + """) + self.flakes(""" + from typing_extensions import TypeAlias + from foo import Bar + + class A: + bar: TypeAlias = Bar + """) + self.flakes(""" + from typing_extensions import TypeAlias + from foo import Bar + + class A: + bar: TypeAlias = 'Bar' + """) + self.flakes(""" + from typing_extensions import TypeAlias + + bar: TypeAlias + """) + self.flakes(""" + from typing_extensions import TypeAlias + from foo import Bar + + bar: TypeAlias + """, m.UnusedImport) + @skipIf(version_info < (3, 6), 'new in Python 3.6') def test_annotating_an_import(self): self.flakes(''' -- cgit v1.2.1