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

Nick Coghlan ncoghlan at gmail.com
Sun Feb 22 15:25:43 CET 2015


On 22 Feb 2015 21:36, "Martin Teichmann" <lkb.teichmann at gmail.com> wrote:
>
>
> > Backportability is at best a nice-to-have when it comes to designing
> > changes to core semantics, and it certainly doesn't justify additional
> > design complexity.
>
> Speaking of which, I just checked out Daniel's code which was
> proposed as an implementation of PEP 422. To my astonishment,
> it does not do what I (and others) had expected, it does not add
> new functionality to type.__new__ or type.__init__, instead the new
> machinery is in __builtins__.__build_class__.

There are some specific details that can't be implemented properly in
Python 3 using a metaclass, that's one of the core points of the PEP.

Specifically, the __class__ cell can only be populated *after* the object
has already been created, so the new hook has to be introduced later in the
class initialisation process, or it will suffer from the same limitation
metaclasses do (i.e. zero-argument super() and any other references to
__class__ won't work).

>This has weird consequences, e.g. if you create a new class by writing
> type("Spam", (SpamBase,) {}), __class_init__ will not be called.

This code is inherently broken in Python 3, as it bypasses __prepare__
methods.

> I consider this a really unexpected and not desirable behavior.

That ship already sailed years ago when __prepare__ was introduced.

> Sure, types.new_class has been modified accordingly, but
> still.
>
> So I think that the current version of PEP 422 unnecessarily adds
> some unexpected complexity, all of which could be easily avoided
> with my __init_subclass__ (or __subclass_init__? whatever)
> approach.

I don't currently believe you're correct about this, but a PEP and
reference implementation may persuade me that you've found a different way
of achieving the various objectives of PEP 422.

> Another detail: I think it could be useful if the additional
> **kwargs to the class statement were forwarded to
> __(sub)class_init__.

No, that kind of variable signature makes cooperative multiple inheritance
a nightmare to implement. The PEP 422 hook is deliberately designed to act
like an inheritable class decorator that gets set from within the body of
the class definition.

It's *not* intended to provide the full power and flexibility offered by a
metaclass - it's designed to let folks that understand class decorators and
class methods combine the two concepts to define a class decorator that
gets called implicitly for both the current class and all subclasses.

Regards,
Nick.

>
> Greetings
>
> Martin
>
> PS there has been some discussion about politeness on this list.
> I apologize for having been harsh. I hope we can all get
> back to discussing python and how to improve it!
>
>
> _______________________________________________
> 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/20150223/b5b360a8/attachment.html>


More information about the Python-ideas mailing list