Description
Python version: 3.8.2
mypy version: 0.782
mypy flags: --strict (same result without this flag)
I've encountered what looks like a false positive when calling .update()
on TypedDicts that have some required and some optional fields. I have a hierarchy of TypedDicts with some required fields in the base class and some optional fields in the derived class. Here is a minimal snippet that reproduces the error:
from typing import TypedDict
class Base(TypedDict):
id: int
class Derived(Base, total=False):
description: str
update_me: Derived = {
'id': 1,
'description': 'norsetanrst'
}
new_data: Derived = {
'id': 2
}
# "incompatible type" error from mypy
update_me.update(new_data)
I expected this to type check with no errors. However, mypy emits the following about the last line:
$ mypy --strict
demo.py:21: error: Argument 1 to "update" of "TypedDict" has incompatible type "Derived"; expected "TypedDict({'content'?: Dict[str, int], 'description'?: str})"
Found 1 error in 1 file (checked 1 source file)
It seems like mypy is expecting a TypedDict with the same fields (but all optional) as Derived. If I change the last line to update_me.update(update_me)
, the same error occurs. If I add total=False
to Base
's signature, the error goes away, but then I no longer have any required fields.
Also interesting to note: reveal_type(update_me.update)
prints the signature I would expect:
note: Revealed type is 'def (TypedDict('wee.Derived', {'id': builtins.int, 'description'?: builtins.str}))'
And if I inline the argument, i.e. update_me.update({'id': 2})
, the error goes away. However, my use case is
such that doing so is not a viable solution.
Thank you! Please let me know if there's anything I've missed.