That’s fair, though _
as a key is still probably quite rare. Your proposal seems pretty reasonable.
The issue with key conflicts got me thinking about a more general solution to work around key naming limitations. We already don’t support all possible keys when using the class-based syntax, and thus we probably can’t deprecate the functional syntax. What if we’d add a new way of specifying arbitrary string keys using the class-based-syntax? Here’s one idea:
class Foo(TypedDict):
name: str # Regular item
_: bool # Type of extra items
__items__ = {
"_": int, # Literal "_" as a key
"class": str, # Keyword as a key
"tricky.name?": float, # Arbitrary str key
}
(The name __items__
is just the first thing that came to my mind – the specifics of the name aren’t important.)
This may go beyond the original goals of the PEP, but this would have some nice properties:
- Arbitrary key names can be supported using the class-based syntax.
- We can hopefully deprecate the functional TypedDict syntax.
- We can support forward references in the extra item type without escaping.
- All TypedDict items (including the extra ones) are defined using a similar syntax in the common case where
__items__
is not needed. - We have the option of adding arbitrary magic key names such as
_
, since name conflicts can be worked around easily.
This would make the proposal a bit bigger, but on the other hand, we could deprecate the functional syntax, so arguably this would simplify the overall non-deprecated TypedDict functionality.