Checking the following code with mypy, it says 30: error: Argument 1 to "f" has incompatible type "T"; expected "X"
.
But there are decorated declarations of f
so we should be able to pass value of class X
or Y
as the argument a
.
Question 1: Could not we use @overload and TypeVar(bound=Union) at the same time ? Or I misunderstand something ?
from typing import TypeVar, Union, overload
class X:
pass
class Y:
pass
@overload
def f(a: X):
...
@overload
def f(a: Y):
...
def f(a):
return
T = TypeVar("T", bound=Union[X, Y])
def func(a: T) -> T:
f(a)
return a
I tried another example as following and it does not make type errors.
Question 2: What makes the difference between overloaded function and classes having same method ?
from typing import TypeVar, Union
class X:
def method(self) -> float:
return 1.0
class Y:
def method(self) -> float:
return 1.0
T = TypeVar("T", bound=Union[X, Y])
def func(a: T) -> T:
a.method()
return a
Question 1: Could not we use @overload and TypeVar(bound=Union) at the same time ? Or I misunderstand something ?
The problem is with TypeVar
: what you want is T = TypeVar("T", X, Y)
because both X
and Y
should be accepted. See the usage paragraph in the documentation. The bound
parameter is used only if you want to define an upper bound to the types, basically you are specifying the constraining superclass. For more details, see Type variables with an upper bound.
Question 2: What makes the difference between overloaded function and classes having same method ?
The @overload
decorator is useful in case there are two functions/methods sharing the same scope, in fact
The variants and the implementations must be adjacent in the code: think of them as one indivisible unit.