[Python-Dev] Language reference updated for metaclasses

PJ Eby pje at telecommunity.com
Tue Jun 5 00:58:06 CEST 2012


On Mon, Jun 4, 2012 at 6:15 PM, Nick Coghlan <ncoghlan at gmail.com> wrote:

> It's actually the pre-decoration class, since the cell is initialised
> before the class is passed to the first decorator. I agree it's a little
> weird, but I did try to describe it accurately in the new docs.
>
I see that now; it might be helpful to explicitly call that out.

This is adding to my list of Python 3 metaclass gripes, though.  In Python
2, I have in-the-body-of-a-class decorators implemented using metaclasses,
that will no longer work because of PEP 3115...  and if I switch to using
class decorators instead, then they won't work because of PEP 3135.  :-(

Meanwhile, mixing metaclasses is more difficult than ever, due to
__prepare__, and none of these flaws can be worked around officially,
because __build_class__ is an "implementation detail".  I *really* want to
like Python 3, but am still hoping against hope for the restoration of
hooks that __metaclass__ allowed, or some alternative mechanism that would
serve the same use cases.

Specifically, my main use case is method-level decorators and attribute
descriptors that need to interact with a user-defined class, *without*
requiring that user-defined class to either 1) redundantly decorate the
class or 2) inherit from some specific base or inject a specific
metaclass.  I only use __metaclass__ in 2.x for this because it's the only
way for code executed in a class body to gain access to the class at
creation time.

The reason for wanting this to be transparent is that 1) if you forget the
redundant class-decorator, mixin, or metaclass, stuff will silently not
work, and 2) mixing bases or metaclasses has much higher coupling to the
library providing the decorators or descriptors, and greatly increases the
likelihood of mixing metaclasses.

And at the moment, the only workaround I can come up with that *doesn't*
involve replacing __build_class__ is abusing the system trace hook; ISTM
that replacing __build_class__ is the better of those two options.

At this point, with the additions of types.new_class(), ISTM that every
Python implementation will have to *have* a __build_class__ function or its
equivalent; all that remains is the question of whether they allow
*replacing* it.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20120604/db74d65b/attachment.html>


More information about the Python-Dev mailing list