I am using Python 3.11 and Pylance for this.
class Dog:
pass
Example A:
DogType: type[Dog] = Dog # type[Dog]
AnotherDogType: type[DogType] = Dog # Error
# ^^^^^^^ variable not allowed in type expression
Example B:
DogType = Dog # type[Dog]
AnotherDogType: type[DogType] = Dog # Ok
I am wondering why I get the error for ExampleA.AnotherDogType
. DogType
is type[Dog]
when I hover over both variables in vscode.
In the case of:
DogType = Dog
That is being recognized as a type alias by pylance. You can even see this when you hover over it:
Python's type annotation system is relatively new, and still currently evolving. This was the original way to create a type alias. From my recollection, this was never adequatly specified, and different type checkers have treated assigning types to a bare variable differently when it occurs in different context (e.g. in a class definition).
Later, the typing.TypeAlias
type hint was added to make this less ambiguous, and even more recently in Python 3.12, a type
statement was added. Type statemens should be preferred over the bare variable assignment way of doing things, and typing.TypeAlias
should only be used for backwards compatibilty. Code written for Python 3.12+ should use type statements to create type aliases.
When you explicitly annotate it with DogType: type[Dog] = Dog
, then it is no longer a type alias, it is treated as just a regular variable that will hold type objects.
As an aside, I just want to reiterate something that was stated in the comments, but nesting classes like this almost never makes any sense.