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

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 PyType_IsSubtype. We could simply change that
> to PyObject_IsSubclass. 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:
- This is a suitable baseclass for all simple metaclasses – Can you
actually define "simple"?
- "the algorithm doing that could still be improved, but it works" –
Works for what? What exactly does it do – solve the problem of merging
any two metaclasses?
If you want to take this further (not that I recommend it), you'll at
least need some more precise wording here.


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