[Python-3000] PEP 3115: Actual use cases for odd metaclasses? Alternate syntax.

Phillip J. Eby pje at telecommunity.com
Sat Dec 22 15:05:54 CET 2007


At 10:30 PM 12/21/2007 -0800, Charles Merriam wrote:
>Are there any other use cases?

Yes, several.  You haven't been reading the previous discussion 
threads, in which I've repeatedly posted other use cases for PEP 
3115, every time someone else who hasn't read the previous posting of 
those use cases, and tries to "simplify" the PEP.  Other people have 
posted a few as well.

You're also utterly ignoring metaclass runtime use cases in your 
proposal, in a way that suggests you don't really know what a 
metaclass *is*, even pre-PEP 3115.


>Unfortunately, this can't unroll gracefully, as it needs some execution
>after partially compiling the class, but before it has been
>fully finished.  The compilation pseudo-code:
>
>     If there is an @@metaclass:
>         remember the metaclass function ("superswizzle")
>         attributes will go in a list, not a dict during class compilation
>         compile up the class
>         create a new Metaclass object with cls, bases, attrs_list
>         call @@metaclass function
>         take the (changed) Metaclass object, and call 'type' to make it.
>         make sure the class remembers which metaclass function to make
>on creation.
>      else:
>         do the usual.

This description makes me think you don't understand how class 
creation works, either.  In particular, you keep using the phrase 
"compiling the class", but I don't think you know what that phrase means.


>The psudo-code for calling the superclass's @@metaclass is left as 
>an exercise.

What about multiple inheritance?  That doesn't seem like such a 
trivial exercise, and AFAICT, your proposal is more complex to 
implement than that of Python 2.x metaclasses.


>So this has the advantages:
>+ Metaclass becomes far less boilerplate, error-prone, black magic.
>+ Metaclass stops being a subclassing hack, which simplifies things.

And eliminates the ability to have a *meta* *class* in the 
process.  No thanks.  (Plus, you have moved the complexity from a 
well-understood and well-grounded-in-theory model to a handwaving 
"left as an exercise" non-proposal.)


>+ __metaclass__ goes away.  It was a crufty syntax.

And yet it was still better than your @@ proposal, and the keyword 
syntax of PEP 3115 is better still.


>+ lots of future hacking on novel ways to use metaclasses
>     now that they are easier.

Er, huh?  How in blue blazes is what you just described *easier* in 
any way, shape or form?  I can't tell through all the hand-waving in 
the semantics, since you didn't provide any real explanation of what 
your "metaclass info" object does, nor did you provide a definition 
of 'super_swizzle'.

Meanwhile, all of the functionality you implied would exist on the 
"mc" object, could easily be implemented as utility functions taking 
a class object in today's Python, and trivially invoked from a 
metaclass __init__, cleanly supporting multiple inheritance in the 
process (by standard super() calls).

Heck, if you don't like defining new metaclasses, the DecoratorTools 
package includes a class that allows its subclasses to define a 
'__class_init__' method that is called in lieu of a metaclass 
__init__, allowing every class to almost be its own metaclass (in the 
limited sense of getting to define certain nominally-metaclassy 
methods like new, init, and call).

I use this class in a lot of libraries because it eliminates the need 
to define custom metaclasses in all but the most demanding metaclass 
use cases, and thus avoids most of the problems involved in mixing 
metaclasses via multiple inheritance.  It lets you define a base 
class that does your "super_swizzle" magic, and then simply inherit 
from it to use it.

In any case, my point is that AFAICT here, there isn't anything 
you've proposed here that can't already be done within the status 
quo, without implementing a new way of "compiling the class" (which 
doesn't mean what you seem to think it means).


>+ Moving the metaclass specialness to a single function simplifies
>     diamond inheritence from classes with multiple metaclasses.

Uh, no, it doesn't.


>I would love to see use cases for which this solution
>does not work.

How about all of the use cases that actually need a *metaclass*, 
rather than merely inherited class decoration?




More information about the Python-3000 mailing list