Interesting example. I don't think disallowing type aliases in functions would break that code. However, it limits the ability to use type aliases to give new names to types (eg for renaming a class defined within a function). Take a look at this: from typing_extensions import TypeAlias def foo() -> None: class Hello: pass foo = Hello bar: TypeAlias = Hello foo1 = foo() foo2: foo = foo() bar1 = bar() bar2: bar = bar() Today, foo gets inferred to either a TypeAlias or Type[Hello] - depending on the typechecker's inference heuristic. bar's legality is also up for debate - again depending on typechecker. I think it's a pretty reasonable use case to consider wanting to rename `Hello` in a backward compatible manner, even within function scope - given python's willingness to allow classes defined within functions. Supporting a type alias in this scenario would be least surprising to me. With the heuristics that Eric Traut outlined, both `foo` and `bar` would be inferred as a TypeAlias matching my expectation. Eric's heuristics try to infer a TypeAlias whenever possible and fallback to a Type[_] - a behavior I think would be nice to standardize in the PEP613/PEP484. Shannon mentioned Type Aliases defined as instance variables - which seems non-useful, since you couldn't use it in a type context. self.baz: TypeAlias = Hello baz1: self.baz = self.baz() # self probably shouldn't resolve in type context I propose clarifying in PEP484 that the LHS must be an identifier in order to be a type alias - so that self.baz = Hello is not a type alias (and self.baz: TypeAlias = Hello is invalid) In favor of both - allowing explicit type alias at any scope (in PEP 613) - standardizing the implicit type-var vs alias inference heuristic to the one Eric described (in PEP 484) Would be interested in hearing Shannon's thoughts about function scope type alias implementation difficulties. --Nipunn
The line between classes and functions is blurry. For example, disallowing type aliases in functions would break code like: ``` def foo(x): bar = map return bar(lambda y: y+1, x) ``` because map is actually a class (and is typed as such in typeshed).
``` def foo(x): bar = map return bar(x) ```