I wrote a python code like below
class A:
pass
class B:
pass
class C:
pass
from typing import TypeVar, Union, Type, Optional, List
test = TypeVar("test", bound=A)
def wow(w: Optional[List[Union[Type["test"], Type[C]]]]):
pass
wow([A]);
Pylance highlights the line wow([A])
as an error, so I wonder if I wrote the wrong code or if Pylance worked wrong.
when i remove Union part, then it worked well, so i thought there's no reason that the code should be highlighted just because i added Union. But I may be completely mistaken, so please teach me.
below is the error message that I got
Argument of type "list[Type[A]]" cannot be assigned to parameter "w" of type "List[Type[test@wow] | Type[C]] | None" in function "wow"
Type "list[Type[A]]" cannot be assigned to type "List[Type[test@wow] | Type[C]] | None"
"list[Type[A]]" is incompatible with "List[Type[test@wow] | Type[C]]"
TypeVar "_T@list" is invariant
Type "Type[A]" cannot be assigned to type "Type[test@wow] | Type[C]"
"Type[A]" is incompatible with "Type[C]"
Type "Type[A]" cannot be assigned to type "Type[C]"
Type cannot be assigned to type "None"
This is actually almost exactly an example from pyright's type concepts docs in their section about generic types: https://github.com/microsoft/pyright/blob/main/docs/type-concepts.md#generic-types
Essentially, because lists are mutable types, you can't assign a list[Type[A]]
to be a list[Type[test@wow] | Type[C]]
because if you add a Type[C]
to your list[Type[A]]
, it would no longer be a list[Type[A]]
. If you declare w
to be the immutable Sequence
type instead, thereby promising not to modify w
, you can get rid of your type error.