[Python-Dev] new syntax for wrapping (PEP 318)

Phillip J. Eby pje at telecommunity.com
Thu Feb 19 22:33:32 EST 2004


At 12:48 PM 2/20/04 +1000, Nick Coghlan wrote:
>Phillip J. Eby wrote:
>
>>At 06:48 PM 2/19/04 -0500, Jewett, Jim J wrote:
>>
>>>I think this may be one reason this didn't happen before;
>>>wrapping is good, but it isn't entirely obvious how to
>>>write it or exactly what it should mean.  Given that, it
>>>might be premature to use up the [] syntax.
>>
>>Well, I personally prefer the 'as' syntax for both class and function 
>>decorators.
>>As for the semantics of class decorators, I would propose that they be 
>>identical to the semantics for function decorators.  I don't think 
>>there's a point to adding more ways to spell '__metaclass__'.  :)
>
>Do you mean:
>
>   class decorated as decorator: pass
>
>is equivalent to:
>
>   class decorated: pass
>   decorated = decorator(decorated)
>
>?

Yep.


>And to get PJE's example to work would require a 'protocol decorator' 
>method such as 'IFoo_decorator' which took a class as an argument, told 
>PyProtocols about the class and the interface it supports, and then 
>returned either the original class, or a suitably changed version?

Yes.  In the specific cases of Zope and PyProtocols, such functions are 
called "class advisors".  A class advisor takes a class as an argument, and 
returns either the original class (possibly modified in-place), or a 
suitable replacement.

So, these "class advisors" in fact exist.  The "magic" functions used by 
Zope and PyProtocols usually look something like:

def magic(...):

     def advise(klass):
         ...
         return klass

     addClassAdvisor(advise)

and are used like this:


class Something:
     magic(...)


The 'addClassAdvisor' does the magic stack and metaclass manipulation 
(which is a *very* ugly process, btw) to cause 'advise()' to get called on 
the resulting class, after calling the original metaclass to construct the 
class.

If Python 2.4 included class decorators, then "un-magic" versions of these 
functions would look more like:

def unmagic(...):

     def advise(klass):
         ...
         return klass

     return advise

and you would use them like this:

class Something as unmagic(...):
     pass


All in all though, I'm sort of only +0 on class decorators, because the 
"magic" spelling is easier to read when there are complex declarations 
being done.  The decorator syntax has the disadvantage of requiring line 
continuations or parens, and the result is a bit ugly.

However, if class decorators are included, I believe they should follow the 
above semantics, rather than diverge from the function decorator 
semantics.  Not just for consistency, but because metaclass hacks are much 
harder than they need to be.  Many simple things that people would like to 
do with metaclasses can be more easily accomplished with a simple 
decorator.  Decorators also don't have to automatically be reapplied to 
subclasses, while metaclasses do.




More information about the Python-Dev mailing list