There are several scenarios, when mypy inference leads to false positives. Namely, if the outer type context (return context) is too wide, mypy uses it and fails immediately. Instead it should try the inner context (argument context) before giving up. For example:
T = TypeVar('T', bound=Dict[str, Any])
def f(arg: T) -> T:
...
def outer(x: Mapping[str, Any]) -> None:
...
d: Dict[str, Any]
m: Mapping[str, Any] = f(d) # Value of type variable "T" of "f" cannot be "Mapping[str, Any]"
outer(f(d)) # Value of type variable "T" of "f" cannot be "Mapping[str, Any]"
There are similar scenarios with union types, for example:
S = TypeVar('S', bound=int)
def g(arg: S) -> Optional[S]:
...
x: Optional[int]
x = g(42) # Value of type variable "S" of "g" cannot be "Optional[int]"
etc. What is interesting, the failure doesn't happen if there are only simple types present in the bound and in the context, to reproduce one needs either generics, union types, or other "complex" types.
There are several scenarios, when mypy inference leads to false positives. Namely, if the outer type context (return context) is too wide, mypy uses it and fails immediately. Instead it should try the inner context (argument context) before giving up. For example:
There are similar scenarios with union types, for example:
etc. What is interesting, the failure doesn't happen if there are only simple types present in the bound and in the context, to reproduce one needs either generics, union types, or other "complex" types.