Search code examples
pythonpython-typingmypy

Is it possible to change string representation of a `typing.TypedDict`?


I can do it while subclassing from a native dict but can't with the typed version. Here's the code:

from typing import TypedDict


class Typed(TypedDict):
    x: int

    def __str__(self):
        return "str-typed"


class Native(dict):
    def __str__(self):
        return "str-native"


typed = Typed(x=1)
print("typed =", typed)

native = Native(x=1)
print("native =", native)

assert typed == native

and its result:

$ python typed_dict.py 
typed = {'x': 1}
native = str-native

$ mypy typed_dict.py 
typed_dict.py:7: error: Invalid statement in TypedDict definition; expected "field_name: field_type"
Found 1 error in 1 file (checked 1 source file)

Any suggestions?


Solution

  • Calling Typed creates a regular dict. Methods you write won't do anything, because typed isn't an instance of Typed and doesn't have any of Typed's methods.

    While it is technically possible to disable that behavior at runtime (in the current 3.8 implementation, del Typed.__new__ would do it), mypy still won't be happy. The intent of TypedDict is that

    class Foo(typing.TypedDict):
        x: int
        y: str
    
    d: Foo = {'x': 1, 'y': 'blah'}
    

    type checks. A TypedDict subclass is intended to represent a static type for regular dicts with specific string keys. It's not supposed to be used as its own separate runtime type.

    Also, del Typed.__new__ would be poking at implementation details, which are subject to change without notice.