There were some issues that came up with the aforementioned previous attempt at making it possible to convert module and class dicts into frozendicts that caused the idea to be abandoned that would need to be resolved. This isn’t intended to be a comprehensive list, but these were the big ones in that case.
- PEP-810 lazy imports rely on replacing a
lazy_importobject in the module dict when accessed. Under that implementation this causedTypeErrors if alazy_importobject was accessed after a module was frozen.- Under
-X lazy_imports=allthis is (almost) every import - A caveat was that the implementation from that attempt didn’t manage to replace the reference to the original unfrozen dict held by functions so lazy imports did work inside functions, though not intentionally and not correctly.
- Both lazy and regular imports can also add attributes to a module dict that aren’t there when the module is created
- Under
__annotations__is lazily created and added to class and module dicts only when first successfully accessed under PEP-649/749 annotations.- Using
freeze(__module__)inside a module prevents monkey patching, which is not uncommon (thinkunittest.mock.patchor what gevent does to the stdlib).
Note that this is specific to modules and to a lesser extent, classes. I’d love a proper way to make instances frozen - frozen dataclasses are slow[1].
I’ll also note that the PEP asserts:
Almost all objects in Python have a
__dict__attribute. Freezing an object will convert its__dict__into afrozendict.
There’s now the fairly common case via @dataclass(slots=True) or @attrs.define of objects with slots and potentially without a __dict__. I do think it’s probably necessary to explain how such objects will (or won’t) be handled.
compared to non-frozen classes, about twice as slow to make the class and 3.5x as slow to make each instance ↩︎