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

Petr Viktorin encukou at gmail.com
Mon Feb 16 22:49:07 CET 2015


On Mon, Feb 16, 2015 at 5:16 PM, Martin Teichmann
<martin.teichmann at gmail.com> wrote:
> Hi list,
>
>> Again, Python already has a metaclass that everyone is supposed to
>> use, namely `type`.
>
> well, there is a problem out here: people are indeed using other
> metaclasses. Even the standard library, like ABC or enums.
>
> And there is a problem here in python: once you do multiple inheritance,
> and two classes have different metaclasses, there is no way of
> programmatically determining an appropriate metaclass.
>
> Sure, one can be of Thomas' opinion that doing so is a bad idea
> anyways, but there are other people who think that writing and
> combining metaclasses actually is thing one can do.
>
> Especially for simple cases I do think that metaclasses are a good
> idea and there should be a way to tell python how to combine two
> metaclasses.
>
> I am trying to solve this problem. What I posted was just one simple
> idea how to solve it. Another one is the idea I posted earlier, the
> idea was to add metaclasses using __add__. People didn't like the
> __add__, so I implemented that with a new method called merge,
> it's here: https://github.com/tecki/cpython/commits/metaclass-merge
>
> Instead of yelling at me that my solutions are too complicated,

Hello,
I am very sorry that my post came across as yelling. I had no
intention of that, though on re-reading it is rather harsh.
I will try to be less confrontational in the future.

The meta-metaclass approach is no doubt ingenious, but most people
struggle with the concept of metaclasses, so building a more complex
thing on top is quite tricky. And while I'd like to be proven wrong, I
think fleshing out the details would complicate things even further.

> it would be very helpful and constructive to answer the following
> questions:
>
> - is it desirable to have a programmatic way to combine metaclasses?

That's not a simple yes/no answer.
If you are asking if there should be a generic way to merge any two
metaclasses, then the answer is "no": metaclasses are too powerful to
merge two of them safely without knowing details about both.
If you are asking about merging two metaclasses when knowing all the
details, then the answer is "yes" – but there is already a way to do
this, namely a new metaclass deriving from both.
The discussion is about whether it's desirable to do this subclassing
automatically, so that one of the metaclasses describes how it is to
be combined with the other.
And my answer to that is: no, I don't think it's worth the extra complexity.
If you truly need the full power of metaclasses, then to combine any
two of them you need to know all the details; it is better to create
the subclass explicitly.
For simple cases – and here we seem to disagree – I think metaclasses
*are* a bad idea. This is why I like PEP 422: taking the features that
*can* be safely automatically combined, and letting you combine them
through super()-style cooperative inheritance – which, while still far
from trivial, is far more approachable than metaclasses.
More generally, I think simple things should be built on simple
things, not on complex things with more code added on top.

> - if yes, how should that be done?
>
> My idea is that yes, it is desirable to have a programmatic way of
> combining metaclasses, and I have now proposed two ways how to
> do that.

I still think your other effort – https://github.com/tecki/metaclasses
– is a good solution, provided PEP 422 makes it into Python itself so
that this code is used as a backwards compatibility shim.
Forgive my lack of comments on that: I think that at this point, it's
time to look for and iron out subtle issues in the
idea/implementation, and I've not had time to study them in enough
detail yet. I should have expressed more enthusiasm, rather than
waiting until I was sure I couldn't find obvious flaws. So here it is:
I think PEP 422, and your Github repo, are definitely headed in the
right direction.

Meanwhile I shouted it down the meta-metaclass idea as soon as I saw
it's heading the wrong direction – towards complicating things. I am
too biased towards negativity. Please accept my apology.

Also, a disclaimer: I'm not a Python core developer. Pay much more
attention to Nick's words than mine.


More information about the Python-ideas mailing list