Reputation: 473
I would have expected to see an error after running MyPy targeting a file with these contents:
from typing import TypeVar
T = TypeVar('T')
def do_nothing(one_arg: T, other_arg: T) -> None:
return
do_nothing(1, 2)
do_nothing(1, "abc")
do_nothing(1, None)
do_nothing("abc", None)
do_nothing([1, 2, 3], { "a": "b"})
But I only get Success: no issues found in 1 source file
.
My understanding is that a function having arguments of type T
means that such function can only receive arguments of the same type. In this case, only do_nothing(1, 2)
should have had passed.
What am I missing?
Upvotes: 0
Views: 467
Reputation: 3900
In your example you are allowing T
to be anything. That effectively means that T
is bound to object
meaning that any subtype of object is allowed.
mypy resolves types to the most common type possible. object
is common for any type. Thus, it's ok to pass anything even "different" types.
TypeVar('T')
expresses that your function doesn't require any protocol additional to one provided by object
to be implemented in passed types.
So, unless you are going to call some methods on arguments that require the same protocol but for unrelated types there is no way to force such a restriction with mypy.
Consider a counter example:
import typing
T = typing.TypeVar('T', bound=bytes|str)
In this case mypy will restrict arguments to be either both str
or both bytes
because
>>> issubclass(str, bytes)
False
>>> issubclass(bytes, str)
False
str
and bytes
cannot be resolved to a common type that is above the bytes|str
bound.
See typing.TypeVar
docs.
Upvotes: 1