> There’s a huge difference between functions that might mutate a dictionary you pass in to them and functions that definitely won’t.
Maybe I misunderstood, but it sounds to me like you're hoping for the following code to work:
def will_not_modify_arg(x: frozendict) -> Result:
...
foo = {"a": 1, "b": 2} # type of foo is dict
r = will_not_modify_arg(foo)
But this won't work (as in, type checkers will complain) because dict is not derived from frozendict (or vice-versa). You'd have to create a copy of the dict to pass it to the function. (Aside from presumably not being what you intended, you can already do that with regular dictionaries to guarantee the original won't change.)
Ah, I see. The last sentence in your previous comment makes more sense now ("Mapping is great, but ... you can violate it at run time"). A type checker would normally catch violations but I can still see a frozendict would be useful.
Maybe I misunderstood, but it sounds to me like you're hoping for the following code to work:
But this won't work (as in, type checkers will complain) because dict is not derived from frozendict (or vice-versa). You'd have to create a copy of the dict to pass it to the function. (Aside from presumably not being what you intended, you can already do that with regular dictionaries to guarantee the original won't change.)