Description
This is probably intended behavior, and if so it be good to have the motivation documented somewhere alongside TypedDict's current docs. Apologies if I'm missing something in the docs.
I would expect to be able to pass a TypedDict to any function that expects a plain old dict:
import mypy_extensions as mt
FancyDict = mt.TypedDict('FancyDict', {'a': str})
fancy = FancyDict(a='1')
def use_any_dict(arg: dict) -> None:
print(arg)
use_any_dict(fancy)
However the above snippet fails:
error: Argument 1 to "use_any_dict" has incompatible type "FancyDict"; expected "Dict[Any, Any]"
TypedDict is a plain dictionary at runtime, which is what the signature of use_any_dict
says it accepts. So why doesn't MyPy allow it?
Going the other direction- passing a Dict[Any,Any] to something expecting a certain TypedDict- also fails, which makes sense to me. But it leaves me wondering how code using normal dicts is supposed to interop with newer code using TypedDict aside from using casts or # type: ignore
.
I've tested this with mypy 0.590 from PyPi as well as commit d6a22cf13a5a44d7db181ae5e1a3faf2c55c02b4
from trunk. I'm invoking MyPy as follows:
mypy \
--ignore-missing-imports \
--strict-optional \
--check-untyped-defs \
--disallow-untyped-calls \
--disallow-incomplete-defs \
--disallow-untyped-defs \
my_module