PEP-589 inheritance rules and typing.Literal / PEP-586

In PEP-589: “Inheritance”, it is stated:

Changing a field type of a parent TypedDict class in a subclass is not allowed.

However, this restriction seems perhaps too restrictive in the presence of typing.Literal and PEP-586.

Consider a situation like the following, which might describe some polymorphic data returned from a web API:

from typing import Literal, TypedDict

# Assume these all have several other fields

class BaseDatum(TypedDict):
    id: str
    datumType: str

class Thing(BaseDatum):
    datumType: Literal["thing"]

class Widget(BaseDatum):
    datumType: Literal["widget"]

This seems like a reasonable thing that someone might want to do, especially in a context where you can’t use something like Marshmallow for runtime validation & deserialization (don’t want performance overhead, restricted from using 3rd-party dependencies, etc).

However, in the above example, MyPy emits:

tmp1.py:10: error: Overwriting TypedDict field "datumType" while extending
tmp1.py:13: error: Overwriting TypedDict field "datumType" while extending
Found 2 errors in 1 file (checked 1 source file)

Typically, Literal["widget"] is considered a subclass of str, as in:

from typing import Literal
x: Literal["hello"] = "hello"
y: str = x

It appears that the MyPy devs faithfully honored the restriction on changing type that is stated in PEP-589, but I think in this specific case the restriction is excessive.

Should there be a revision to the TypedDict specification to allow this particular case? For that matter, why shouldn’t TypedDict members be covariant in general? Or is there a good reason why the restriction is what it is?

1 Like

Just a heads-up that most of the typing folk are on the typing-SIG mailing list, so you may have a better chance of getting an answer there than here.

Thanks for the tip.

Here is the ensuing mailing list thread, as a follow-up: Mailman 3 PEP-589 TypedDict inheritance rules and typing.Literal / PEP-586 - Typing-sig - python.org