From a54b0c5a110661a37700aa64a0dbae2723973ec2 Mon Sep 17 00:00:00 2001 From: Ivan Levkivskyi Date: Wed, 28 Sep 2022 13:22:28 +0100 Subject: [PATCH] Allow recursive aliases at class scope --- mypy/semanal.py | 6 ++++-- test-data/unit/check-recursive-types.test | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/mypy/semanal.py b/mypy/semanal.py index 81f50b8d75a5..f4df0f7748ab 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -5086,7 +5086,9 @@ class C: X = X # Initializer refers to outer scope Nested classes are an exception, since we want to support - arbitrary forward references in type annotations. + arbitrary forward references in type annotations. Also, we + allow forward references to type aliases to support recursive + types. """ # TODO: Forward reference to name imported in class body is not # caught. @@ -5097,7 +5099,7 @@ class C: node is None or self.is_textually_before_statement(node) or not self.is_defined_in_current_module(node.fullname) - or isinstance(node, TypeInfo) + or isinstance(node, (TypeInfo, TypeAlias)) or (isinstance(node, PlaceholderNode) and node.becomes_typeinfo) ) diff --git a/test-data/unit/check-recursive-types.test b/test-data/unit/check-recursive-types.test index c326246436ba..8a491e208c44 100644 --- a/test-data/unit/check-recursive-types.test +++ b/test-data/unit/check-recursive-types.test @@ -810,3 +810,19 @@ std: STD[str] reveal_type(std) # N: Revealed type is "TypedDict('__main__.STD', {'val': builtins.str, 'other': ..., 'sval': builtins.str, 'one': TypedDict('__main__.TD', {'val': builtins.str, 'other': ...})})" [builtins fixtures/dict.pyi] [typing fixtures/typing-typeddict.pyi] + +[case testRecursiveClassLevelAlias] +# flags: --enable-recursive-aliases +from typing import Union, Sequence + +class A: + Children = Union[Sequence['Children'], 'A', None] +x: A.Children +reveal_type(x) # N: Revealed type is "Union[typing.Sequence[...], __main__.A, None]" + +class B: + Foo = Sequence[Bar] + Bar = Sequence[Foo] +y: B.Foo +reveal_type(y) # N: Revealed type is "typing.Sequence[typing.Sequence[...]]" +[builtins fixtures/tuple.pyi]