Is the statement to create a type alias without `type` keyword a type statement or an assignment statement?

With type keyword, a type alias can be created with a type statement as shown below:

type MyType = int | str | list[int]

And, a type alias can also be created without type keyword as shown below:

MyType = int | str | list[int]

Now, is the statement to create a type alias without type keyword a type statement or an assignment statement?

“type statement” refers specifically to the type Name = Expr construct.

Name = TypeExpr is an assignment statement.

type x = y does the same that x: typing.TypeAlias = y used to do. It basically is just syntactic shugar for that, allowing us to define TypeAliases more easily.

For forward references you had to write

    a: typing.TypeAlias = "b"
    class b: pass

With PEP 613, you can write

    type a = b
    class b: pass

For the interpreter these two things are completely different since type aliases are lazily evaluated references to the type, which fits in the PEP 649 world, where annotations are lazily evaluated, unlike strings as under from __future__ import annotations.

Isn’t that part of PEP 649 then, and not related to PEP 613?

In other words, had PEP 649 been implemented before PEP 613 came around, they would actually both have evaluated their type lazily.

Sorry, mixed up the numbers. the type statement was in PEP 695, not in PEP 613.

1 Like

The two mechanisms work similarly, but are largely unrelated. Even if PEP 649 had been implemented first, the assignment version a: TypeAlias = b would not have been evaluated lazily. From the interpreter’s point of view, that really is just a bog standard assignment statement. There’s no kind of code transform, special casing, or really anything like that going on there. It’s the exact same as e.g. writing a = 123 and just assigns b to a. But type a = b doesn’t do that. It creates a TypeAliasType object with a specially synthesized set of methods and assigns that to a.

1 Like

Yeah, I rather talked about the perspective of type checkers though (which seems to not have been as clear as it should be). I suppose type checkers also evaluate types (e.g. forwardrefs) lazily, at least since PEP 649.

At runtime the meaning of a keyword obviously is different to that of a Type-hint (which is ignored anyways).

But to get back to topic, type x is, as far as I know, a type statement in all cases, even though it can be used at runtime like a normal object (although it is of type TypeAliasType).