I want to make sure that the input is the same as output, I tried to use TypeVar to bound the typing but I can't get it to work...
from typing import TypeVar, Union, Any
import pandas as pd
class my_Class():
def __init__(self):
self.days = []
self.count = 0
def __call__(self,
input: Union[dict, list[dict]],
*args,
**kwargs
) -> Union[dict, list[dict]]:
"some code"
what I tried:
from typing import TypeVar, Union, Any
import pandas as pd
T = TypeVar("T", bound=Union[dict, list[dict]])
class my_Class():
def __init__(self):
self.days = []
self.count = 0
def __call__(self, input: T, *args, **kwargs) -> T:
"some code"
It's saying that it's expecting "T" and got either Dict or List but I thought since I bounded it, it will look into that Union that I defined in T? Can someone direct me to what I'm doing wrong here?
You need a constrained type variable, not a bound type variable, in order to require that the same type be bound to T
in both cases.
from typing import TypeVar
T = TypeVar('T', pd.DataFrame, dict, list[dict])
class MyClass:
def __init__(self):
self.days = []
self.count = 0
def __call__(self, input: T, *args, **kwargs) -> T:
...
With a union bound, both the argument and the return type are restricted to one of the three given types, but each use of T
can be bound independently of the other. Further, you have no idea, statically speaking, which of the three will be returned. With a constrained type variable, the same type has to be bound to T
in every occurrence within a single call to __call__
.
Here's a simple example:
from typing import Generic, TypeVar
T = TypeVar('T', int, str)
class Foo:
def __call__(self, x: T) -> T:
return x
x: int = Foo()(9) # OK, 9 makes return value int
y: str = Foo()("foo") # OK, "foo" makes return value str
z: float = Foo()(3.14) # Fails, 3.14 not an int or str
w: str = Foo()(9) # Fails, can' assign an int to w