Introduce a TypedMapping (analog to TypedDict but frozen)

I prefer frozen datatypes as they prevent accidental modification of data that isn’t supposed to be modified.

Often I have to move around datas in dicts (i.e. read from a json).
To have this data properly typed I used TypedDict.

But I can’t set the TypedDict to “ReadOnly”.

Currently I do something like this

from typing import TypedDict
import json
import types

class Data(TypedDict):
    foo: str
    bar: int

def read_data() -> Data:
    with open("file.json", "r") as f:
        return cast(Data, types.MappingProxyType(json.load(f))) 

Which works fine to prevent runtime modification of data. But I would like the TypeChecker to understand as well, that setting data is invalid.

Would it make sense to introduce a TypedMapping to Python which is basically a TypedDict but without the __setitem__ method and del methods.

If yes would it also make sense to create a class methods for TypedDict like TypeDict.from_typed_mapping(DataMapping) and TypedMapping.from_typed_dict(Data)?
This would help to only define larger TypedDicts and use them in different contexts.

Also this could help to write the types for types.MappingProxyType. Because as I user I would expect that if I insert a TypedDict inside it, a TypedMapping is detected by the type checker.

I am aware that a Mapping[str, str] is different of dict[str, str] as Mapping[str, str] can contain SubclassOfStr("a") wheras dict[str, str] can’t. That might be worth to consider.

1 Like

Does PEP 705 not address this?

Thanks for the hint.
Yes it goes in the direction. But having a lot of attributes that could be cumbersome.

I am thinkinng more of

from typing import TypedDict, ReadOnly
import json
import types

class Data(TypedDict):
    foo: str
    bar: int
    # super many other arguments

def read_data() -> ReadOnly[Data]:
    with open("file.json", "r") as f:
        data = cast(Data, json.load(f))
        return types.MappingProxyType(data) 

Important here

  • I have runtime safe read only behaviour (the PEP explicitly states it only changes the type behaviour)
  • correct typing of types.MappingProxyType if handed in a TypedDict

Unfortunately that opens up more issues, like, what about nested TypedDicts, should we recurse into them and mark them ReadOnly too? What about lists and other mutable collections?

It’s certainly possible to solve this problem but I think it will be through a more generic type transformation system rather than cherry-picking simple cases.