Manuel
Manuel

Reputation: 473

MyPy doesn't complain when calling a function with distinct types which are declared as TypeVar

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

Answers (1)

lig
lig

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

Related Questions