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

Nick Coghlan ncoghlan at gmail.com
Tue Feb 17 23:15:03 CET 2015


On 17 Feb 2015 23:13, "Martin Teichmann" <lkb.teichmann at gmail.com> wrote:
>
> > You're asking us to assume covariant metaclasses in a subset of cases,
> > while retaining the assumption of contravariance otherwise. That isn't
> > going to happen - we expect type designers to declare metaclass
> > covariance by creating an explicit subclass and using it where
> > appropriate..
>
> How do you solve my example with ABCs? That means if a
> QObject (from PyQt) tries to implement an ABC by inheritance,
> then one first has to create a new metaclass inheriting from
> ABCMeta and whatever the PyQt metaclass is.
>
> Sure, one could register the class to the ABC, but then you
> loose the option of inheriting stuff from the ABC. One could
> also write an adaptor - so using composition. But to me that
> defeats the point of the concept of ABCs: that you can make
> anything fit appropriately. In general, that smells to me like
> a lot of boilerplate code.

If you're doing something incredibly hard and incredibly rare, the code you
have to write to tell the interpreter how to handle it is not really
boilerplate - the "boilerplate" appellation is generally reserved for
verbose solutions to *common* problems. This is not a common problem -
using a custom metaclass at all is rare (as it should be), and combining
them even more so.

If you specifically want to write QtABCs, then the appropriate solution is
to either write your own combining metaclass, or else to go to whichever Qt
wrapper project you're using and propose adding it there.

That's a readable and relatively simple approach that will make sense to
anyone that understands Python metaclasses, and will also work in all
existing versions of Python that supports ABCs.

It is *not* a good enough reason to try to teach the interpreter how to
automatically combine metaclasses. Even if you could get it to work
reliably (which seems unlikely), it would be impossible to get it to a
point where a *human* (even one who already understood metaclasses in
general) could look at the code and easily tell you what was going on
behind the scenes.

>
> > PEP 422 bypasses the default assumption of metaclass contravariance by
> > operating directly on type instances, without touching any other part
> > of the metaclass machinery.
>
> So there is a problem with the metaclass machinery, and we
> solve that by making one certain special case work? When is the
> next special case going to show up?

Probably never. We've had the metaclass machinery in place for over a
decade, and the "run code at subclass creation time" pattern is the only
particularly common metaclass idiom I am aware of where we would benefit
from a simpler alternative that people can use without first needing to
understand how metaclasses work.

(I'm aware that "common" is a relative term when we're discussing
metaclasses, but establishing or otherwise ensuring class invariants in
subclasses really is one of their main current use cases)

> Will it also be included
> into type?

Unfortunately, you're making the same mistake the numeric folks did before
finally asking specifically for a matrix multiplication operator: trying to
teach the interpreter to solve a hard general problem (in their case,
defining custom infix operators), rather than doing pattern extraction on
known use cases to create an easier to use  piece of syntactic sugar. When
the scientific & data analysis community realised that the general infix
operator case didn't *need* solving, and that all they really wanted was a
matrix multiplication operator, that's what they asked for and that's what
they got for Python 3.5+.

Changes to the language syntax and semantics should make it clear to
*readers* that a particular idiom is in use, rather than helping to hide it
from them.

PEP 422 achieves that - as soon as you see "__init_class__" you know that
inheriting from that base class will just run code at subclass
initialisation time, rather than potentially making arbitrary changes to
the subclass behaviour the way a custom metaclass can.

By contrast, implicitly combining metaclasses at runtime does nothing to
make the code easier to read - it only makes it (arguably) easier to write
by letting the developer omit the currently explicit combining metaclass.
That means that not only does the interpreter have to be taught how to do
implicit metaclass combination but future maintainers have to learn to do
it in their heads, making the code *harder* to read, rather than easier.

Regards,
Nick.

>
> Greetings
>
> Martin
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20150218/4460683e/attachment.html>


More information about the Python-ideas mailing list