Skip to content

TypedDict cannot be used where a normal dict is expected #4976

Closed
@TimSimpsonR

Description

@TimSimpsonR

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

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions