Description
At first glance, the following code should not pass type verification because f
and g
return or yield T
instead of Node[T]
:
from typing import TypeVar, Generic, Iterator
T = TypeVar('T')
class Node(Generic[T]):
def __init__(self, value: T) -> None:
self.value = value
def f(v: Node) -> Node:
return v.value
def g(v: Node) -> Iterator[Node]:
yield v.value
However, mypy --strict --python-version 3.6
doesn't report any errors. It does produce a warning:
Returning
Any
from function with declared return typenode.Node[Any]
but even the warning is only reported for f()
, not for g()
.
To be fair, there are ways to call these functions that doesn't violate type expectations, for example f(Node(Node(1)))
would return Node(1)
which fits its promised return type. But I was hoping mypy
might notice that the only way this code would be correct is if the argument to f()
is a Node[Node]
rather than just arbitrary Node
. And so I was expecting mypy
to force me to write:
def f(v: Node[Node]) -> Node:
return v.value
def g(v: Node[Node]) -> Node:
yield v.value
if that's what I meant of course. (Although it's much more likely that it's actually a bug, and that I meant to return v
rather than return v.value
; in that case, mypy
would help me catch that bug.)
Furthermore, if I add the following code at the end of the original code snippet:
v = Node(1)
f(v)
for x in g(v):
pass
mypy
should be able to see that something is definitely wrong; at this point it's completely clear that f(v)
won't return the promised Node
, and g(v)
won't yield one. But adding those lines does not add any new error or warning messages.