[Python-Dev] Possible rough edges in Python 3 metaclasses (was Re: Language reference updated for metaclasses)

PJ Eby pje at telecommunity.com
Tue Jun 5 05:36:41 CEST 2012


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

> On Tue, Jun 5, 2012 at 10:10 AM, PJ Eby <pje at telecommunity.com> wrote:
> > On Mon, Jun 4, 2012 at 7:18 PM, Nick Coghlan <ncoghlan at gmail.com> wrote:
> >>
> >> On Tue, Jun 5, 2012 at 8:58 AM, PJ Eby <pje at telecommunity.com> wrote:
> >> > 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...
> >>
> >> I'm not quite following this one - do you mean they won't support
> >> __prepare__, won't play nicely with other metaclasses that implement
> >> __prepare__, or something else?
> >
> >
> > I mean that class-level __metaclass__ is no longer supported as of PEP
> 3115,
> > so I can't use that as a way to non-invasively obtain the enclosing
> class at
> > class creation time.
> >
> > (Unfortunately, I didn't realize until relatively recently that it wasn't
> > supported any more; the PEP itself doesn't say the functionality will be
> > removed.  Otherwise, I'd have lobbied sooner for a better migration
> path.)
>
> As in the "def __metaclass__(name, bases, ns): return type(name,
> bases, ns)" functionality?
>

The part where you can do that *dynamically in the class body* from a
decorator or other code, yes.

You can still pass an ordinary callable as the metaclass parameter and
> it will behave the same as the old class level __metaclass__
> definition.
>

Which runs afoul of the requirement that users of the in-body decorator or
descriptor not have to 1) make the extra declaration and 2) deal with the
problem of needing multiple metaclasses.  (Every framework that wants to do
this sort of thing will end up having to have its own metaclass, and you
won't be able to use them together without first creating a mixed
metaclass.)



> I personally wouldn't be averse to bringing back the old spelling for
> the case where __prepare__ isn't needed - you're right that it's a
> convenient way to do a custom callable that gets inherited by
> subclasses.
>

That was a nice hack, but not one I'd lose any sleep over; the translation
to PEP 3115 syntax is straightforward even if less elegant.  It's the
*dynamic* character that's missing in 3.x.  In any case, I don't use the
__metaclass__ hook to actually *change* the metaclass at all; it's simply
the easiest way to get at the class as soon as its built in 2.x.

If there were a way to register a function to be called as soon as an
enclosing class is created, I would use that instead.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20120604/bd8beb86/attachment.html>


More information about the Python-Dev mailing list