[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