[Python-Dev] Decorator syntax J2 (decorate..def), with implementation

Michael Sparks zathras at thwackety.com
Sat Aug 14 01:31:24 CEST 2004


Hi,


I suspect people are getting sick of the decorator discussion by now, so
I'll try to be brief, and useful.

Syntax option J2 from the wiki seems to have provoked an interesting
discussion[1] at least by a small subset of c.l.p, so I wondered how
difficult it would be to implement - this turned out to be relatively
simple [2].
   [1] http://mail.python.org/pipermail/python-list/2004-August/233413.html
   [2] http://mail.python.org/pipermail/python-list/2004-August/233591.html
       (implementation)

Example of the syntax... (I'm sure it's familiar...)

#Syntax J2 from http://www.python.org/moin/PythonDecorators
#Some random comment
#More random comment
decorate:
     staticmethod
     grammarrule('statement : expression')
     versioninfo("Added in 2.4")
     deprecated
     typeinfo(None)
def p_statement_expr(self, p):
     print p[1]

For comparison, this is intended as equivalent to:

#Current syntax in 2.4a2
#Some random comment
#More random comment
@staticmethod
@grammarrule('statement : expression')
@versioninfo("Added in 2.4")
@deprecated
@typeinfo(None)
def p_statement_expr(self, p):
     print p[1]

With the exact semantics and restrictions remaining the same - this is
just syntactic sugar.


This was my first time looking at the python source to see how easy it
would be to implement - so it's not perfect, and probably far from ideal.
My reasons I looking and giving it a go though were:

   * To me it looks much clearer - you can instantly see where the method
     (and decorator block) starts.
   * Lack of repetition of the decoration hint
   * It hints to a non-python programmer very clearly that this is
     something different. If they're aware of the decorator patterm,
     they will realise (perhaps) what it means, and if they don't they
     have something to google for.

I have read most of the arguments against this syntax, and if the decision
ends up to stay with @ or take a different syntax, I'm sure it'll work out
fine :) (This isn't my favourite syntax, my favourite has a keyword inside
the function suite, which I'm well aware is dead in the water!)

The post I made to c.l.p with a first attempt at an implementation (has
minor issues regarding scopes, but does work) can be found here:

   * http://mail.python.org/pipermail/python-list/2004-August/233591.html

If there is interest in this syntax, then I suspect/hope making it
suitable for a "proper" patch would be relatively simple.

In case people are wondering what the grammar change I made for this is,
I'll include here:

-decorator: '@' dotted_name [ '(' [arglist] ')' ]
+decorator: dotted_name [ '(' [arglist] ')' ]
 decorators: decorator ([NEWLINE] decorator)* NEWLINE
-funcdef: [decorators] 'def' NAME parameters ':' suite
+funcdef: ['decorate' ':' NEWLINE INDENT decorators DEDENT ] 'def' NAME parameters ':' suite
 parameters: '(' [varargslist] ')'

Downsides here:
   * Looks like a suite, implying it allows arbitrary statements, but
     isn't
   * Introduces a new keyword
   * Some people have expressed reservations about the syntax, some of
     which also apply to the @pie syntax, and some which don't.
   * The patch above has scope issues, which means currently it requires
     some cruft to force functions into scope.

Biggest upside from a personal perspective though is this: (aside from
others)
   * Forces things like the common cases of classmethod and staticmethod
     to jump out at a maintainer.

     As the wiki mentions, this two line syntax is relatively heavyweight
     for these cases, and I agree. I disagree about this being  bad -
     static methods and class methods are rare.

     Having a BIG indication they exist when you have (say) 20 methods in
     a class strikes me as a very positive thing, and is surely 90% of
     the reason for moving from the existing mechanism of:

        foo = staticmethod(foo)

Example tested:

class Foo:
   staticmethod # This is cruft to force staticmethod into scope

   decorate:
      staticmethod
   def hello(who):
      print "woo?", who

Anyway, hope this is considered useful, rather than extending the
headache! (However, I am for one very happy  that decorators are now
available in something clearer than we had in pre(2.4) and it certainly
made implementing the syntax/semantics above relatively trivial :)

Regards,


Michael.
--
"The 'nice' thing about decorator syntaxes is there are so many to choose
 from."



More information about the Python-Dev mailing list