From 40b6b9b151aecdf9e9c821ed852be0415d4823eb Mon Sep 17 00:00:00 2001 From: Seth Yastrov Date: Fri, 26 Nov 2021 16:17:07 +0100 Subject: [PATCH] Fix function containing PEP 593 Annotated with a string literal second arg causing 'Name "x" is not defined" error (#10777) Fixes #9868 When analyzing function definitions, mypy attempts to infer type variables. The code which did that also tried to look into the second type arg to `Annotated`, which, if a string literal, resulted in a lookup which may cause a 'Name "x" is not defined" error. Co-authored-by: 97littleleaf11 <97littleleaf11@users.noreply.github.com> Co-authored-by: Jingchen Ye <97littleleaf11@gmail.com> --- mypy/typeanal.py | 3 +++ test-data/unit/check-annotated.test | 22 ++++++++++++++++++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/mypy/typeanal.py b/mypy/typeanal.py index a1db26c810f3..90f8911b1af5 100644 --- a/mypy/typeanal.py +++ b/mypy/typeanal.py @@ -1269,6 +1269,9 @@ def visit_unbound_type(self, t: UnboundType) -> TypeVarLikeList: return [] elif node and node.fullname in ('typing_extensions.Literal', 'typing.Literal'): return [] + elif node and node.fullname in ('typing_extensions.Annotated', 'typing.Annotated'): + # Don't query the second argument to Annotated for TypeVars + return self.query_types([t.args[0]]) else: return super().visit_unbound_type(t) diff --git a/test-data/unit/check-annotated.test b/test-data/unit/check-annotated.test index 9b65adb377a5..68862087d13d 100644 --- a/test-data/unit/check-annotated.test +++ b/test-data/unit/check-annotated.test @@ -127,19 +127,33 @@ x = Annotated[int, Meta()] reveal_type(x) # N: Revealed type is "def () -> builtins.int" [builtins fixtures/tuple.pyi] +[case testAnnotatedStringLiteralInFunc] +from typing import TypeVar +from typing_extensions import Annotated +def f1(a: Annotated[str, "metadata"]): + pass +reveal_type(f1) # N: Revealed type is "def (a: builtins.str) -> Any" +def f2(a: Annotated["str", "metadata"]): + pass +reveal_type(f2) # N: Revealed type is "def (a: builtins.str) -> Any" +def f3(a: Annotated["notdefined", "metadata"]): # E: Name "notdefined" is not defined + pass +T = TypeVar('T') +def f4(a: Annotated[T, "metatdata"]): + pass +reveal_type(f4) # N: Revealed type is "def [T] (a: T`-1) -> Any" +[builtins fixtures/tuple.pyi] + [case testSliceAnnotated39] # flags: --python-version 3.9 from typing_extensions import Annotated - a: Annotated[int, 1:2] reveal_type(a) # N: Revealed type is "builtins.int" - [builtins fixtures/tuple.pyi] + [case testSliceAnnotated38] # flags: --python-version 3.8 from typing_extensions import Annotated - a: Annotated[int, 1:2] reveal_type(a) # N: Revealed type is "builtins.int" - [builtins fixtures/tuple.pyi]