I've encountered a type hinting issue in Python 3.11 using Pylance in Visual Studio Code, and I'm looking for insights into why this error is occurring and how to resolve it. Here's my code:
from typing import TypeAlias, TypeVar
Data: TypeAlias = int | str
DataVar = TypeVar("DataVar", int, str)
class A:
def __init__(self):
pass
def do_something(self, X: Data) -> Data:
return self._foo(X) # <---- Pylance raises an error here!!
def _foo(self, X: DataVar) -> DataVar:
return X
However, Pylance raises the following error:
Argument of type "Data" cannot be assigned to parameter "X" of type "DataVar@_foo" in function "_foo"
Type "Data" is incompatible with constrained type variable "DataVar"
I'm struggling to understand why this error is occurring. As far as I can tell, Data
is a flexible type that can be either an int
or a str
, and _foo
should be able to accept it as an argument. If I had provided the types in the reverse order, i.e. do_something
expects a DataVar
and _foo
gets Data
, I would expect an error (which is indeed raised)
Any insights or suggestions on how to address this issue would be greatly appreciated.
What is the type of Data
?
from typing import reveal_type
Data: TypeAlias = int | str
reveal_type(Data) # Runtime type is 'UnionType'
It's a Union Type.
On the other hand the TypeVar
documentation says:
Using a constrained type variable(like what you defined), however, means that the TypeVar can only ever be solved as being exactly one of the constraints given.
So X
can only be either int
or str
(or their subclasses). Union
type is not a subclass of any of the constraints.
This is how the typing system works. Mypy also complains:
error: Value of type variable "DataVar" of "_foo" of "A" cannot be "int | str" [type-var]
A simple fix to this is to bound DataVar
to Data
:
DataVar = TypeVar("DataVar", bound=Data)