[Python-ideas] A way out of Meta-hell (was: A (meta)class algebra) (original) (raw)

Petr Viktorin encukou at gmail.com
Mon Feb 16 13:39:40 CET 2015


On Sun, Feb 15, 2015 at 11:30 PM, Martin Teichmann <lkb.teichmann at gmail.com> wrote:

Hi again,

staring at the code for hours, I just realized that there is a very simple yet powerful solution to the metaclass merging problem. The changes to be made are so simple there isn't even a need to change the documentation! The current algorithm to find a proper metaclass looks for a class all other metaclasses are a subtype of. For that it uses PyTypeIsSubtype. We could simply change that to PyObjectIsSubclass. This would give a great hook into the system: we just need to intercept the subclasshook, and we have a hook into the metaclass algorithm! Backwards compatibility should not be a problem: how many metaclasses are out there whose metaclass (so the meta-meta-class) overwrites the subclasshook?

Well, none, hopefully.

I changed the code appropriately, and also added a library that uses this hook. It defines a class (called Dominant for technical reasons, I'm waiting for suggestions for a better name), which acts as a baseclass for metaclasses. All metaclasses inheriting from this baseclass are combined automatically (the algorithm doing that could still be improved, but it works).

So, let me get this right: You defined a meta-metaclass that automatically creates a metaclass subclassing all metaclasses of a newly defined class. Except subclassing doesn't really work that way, so you also need to hook into subclass checking. Sounds to me that the implementation is hard to explain.

You're taking a complex thing and layering another complex thing on top, with the goal of preserving full generality (or at least with the goal of making it possible to preserve full generality). You've run into a point where some hand-waving seems necessary:

On the other hand, PEP 422 is not a replacement for metaclasses. It is a simpler way to do some subset of what metaclasses do. I still believe that is the way to go, even if the subset is initially smaller than ideal.

While I was already at it, I also added my variant of PEP 422, which fits already into this metaclass scheme.

The code is at https://github.com/tecki/cpython/commits/metaclass-issubclass

Again, Python already has a metaclass that everyone is supposed to use, namely type. Adding another one can work for a backwards-compatibility shim on PyPI, not for Python itself or its standard library.



More information about the Python-ideas mailing list