Closed

Description
Lets consider this source code:
from typing import Tuple, TypeVar
import collections
N = collections.namedtuple("N", "name")
T = TypeVar("T", N, Tuple[N, N])
# T = TypeVar("T", N, Tuple[N, ...])
def get_name_bad(item: T) -> str:
return item.name if isinstance(item, N) else item[0].name
def get_name_good(item: T) -> str:
if isinstance(item, N):
return item.name
return item[0].name
foo = N("1")
bar = N("2")
both = (foo, bar)
get_name_good(foo)
get_name_good(bar)
get_name_good(both)
get_name_bad(foo)
get_name_bad(bar)
get_name_bad(both)
I am using Python 3.8.3 and mypy 0.782. Depending on TypeVar
definition I get following results:
$ grep "^T = TypeVar" snippet.py
T = TypeVar("T", N, Tuple[N, N])
$ mypy-3.8 snippet.py
snippet.py:12: error: "Tuple[N, N]" has no attribute "name"
Found 1 error in 1 file (checked 1 source file)
$ grep "^T = TypeVar" snippet.py
T = TypeVar("T", N, Tuple[N, ...])
$ mypy-3.8 snippet.py
Success: no issues found in 1 source file
This means the conditional expression containing isinstance()
in function get_name_bad()
does trigger error while normal if-block with isinstance()
from get_name_good()
doesnt. All of this is happening only with fixed-length tuple in TypeVar
and not with variable length tuple.
I would expect there is no difference between Tuple[N, N]
and Tuple[N, ...]
when checking the type via isinstance()
in conditional expression.