Search code examples
pythonmetaclass

python metaclasses: editing the namespace after `__set_name__` methods have been called?


Suppose we are defining a class with a metaclass. In the class body, objects are assigned that implement __set_name__ to register themselves in a data structure of the class.

Is it possible to edit the namespace after __set_name__ methods have been run? Like, detach the filled data structure, split it in two, and add the parts under new attributes?

The trouble is that, before calling super().__new__(...) in the metaclass, the data structure is still empty. Afterwards it is filled, but then the class is already created, and its namespace is now a read-only copy of the namespace built up in the metaclass.

Is there any chance of editing the namespace, with __set_name__ methods applied, like via a hook just before it is frozen into the new class?


Solution

  • If you need to change the namespace that will be used for class creation, you're out of luck. __set_name__ fundamentally cannot run before the class is created, because it takes the class as an argument. This would matter for things like __slots__, which have to be set before class creation.

    Of course, if all you need to do is mess with the new class's attributes after the fact, you can just go through attribute assignment. It doesn't matter that the class's __dict__ is read-only for that.