Description
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 TypedDict
s).
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.