Skip to content

Unable to pass values from TypedDict into dict #9117

Closed
@PeterJCLaw

Description

@PeterJCLaw

Not sure if this is strictly a bug, however it's not a behaviour I expected and I can't see anything in mypy's docs either way.

If you have a TypedDict such as:

Foo = TypedDict('Foo', {
    'bar': int,
})
foo = Foo({'bar': 42})

and you want to combine that mapping with another using either spray or .update() forms then this is considered an error:

d = {
    'other': 2,
    **foo,  # Argument 1 to "update" of "dict" has incompatible type "Foo"; expected "Mapping[str, int]"
    **dict(foo),  # Argument 1 to "dict" has incompatible type "Foo"; expected "Mapping[str, int]"
}
d.update(foo)  # Argument 1 to "update" of "dict" has incompatible type "Foo"; expected "Mapping[str, int]"

note however that passing only into a dict works:

x = dict(foo)  # Revealed type is 'builtins.dict[builtins.str*, builtins.object*]'

Given the type of x here I can see why the d.update(..) form doesn't work, though I would have expected that mypy would be able to merge the types when using spray notation.

Is this expected behaviour? If so, what is the expected way to combine a TypedDict with additional keys like this?

Aside: I would also expect that the signature of x be Dict[str, int] rather than Dict[str, object] since the type details of the TypedDict are essentially that. (I would expect a Union in the value type of more complicated TypedDicts).

My use-case is preparing a dict for conversion to JSON for a web API, so I'm currently working around this by annotating d as being Dict[str, Any] which I end up doing anyway for JSON and which sidesteps the inference of the dict members to find the type for d.

I'm using mypy 0.782 on Python 3.6.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions