A decorator syntax not yet mentioned (I think!)

Michael Sparks michaels at rd.bbc.co.uk
Thu Aug 12 06:25:27 EDT 2004


Regarding J2 on http://www.python.org/moin/PythonDecorators ...
...
>    5 Technical problems with the current grammar parser if a suite
>      *starts* with an optional part. (Ending with an optional part,
>      such as "else:" is OK, but starting with one is not.)
...
> Item 6 is always the case for any new feature, so I doubt that's the
> real problem - the real problem here strikes me as item 5.
> 
> I do wonder how difficult it would be to add though...

It doesn't actually seem that difficult to modify the grammar to handle
this if the decorator block handles *only* decorators. I've just tried
modifying the Grammar/Grammar file to see how plausible this is, and I
can get python to build and parse it. (It bombs out because I've not
done any backend work, and this is the first time I've touched the python
compiler source)

The change I made was this:

--- Python-2.4a2/Grammar/Grammar        2004-08-02 07:09:53.000000000 +0100
+++ Python-2.4a2-MS/Grammar/Grammar     2004-08-12 11:05:04.085386128 +0100
@@ -27,10 +27,13 @@
 single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE
 file_input: (NEWLINE | stmt)* ENDMARKER
 eval_input: testlist NEWLINE* ENDMARKER
-
-decorator: '@' dotted_name [ '(' [arglist] ')' ]
+# decorator: '@' dotted_name [ '(' [arglist] ')' ]
+# decorators: decorator ([NEWLINE] decorator)* NEWLINE
+# funcdef: [decorators] 'def' NAME parameters ':' suite
+decorator: dotted_name [ '(' [arglist] ')' ]
 decorators: decorator ([NEWLINE] decorator)* NEWLINE
-funcdef: [decorators] 'def' NAME parameters ':' suite
+decoratedfuncdef: 'decorate' ':' NEWLINE INDENT decorators DEDENT funcdef
+funcdef: 'def' NAME parameters ':' suite
 parameters: '(' [varargslist] ')'
 varargslist: (fpdef ['=' test] ',')* ('*' NAME [',' '**' NAME] | '**' NAME) | fpdef ['=' test] (',' fpdef ['=' test])* [',']
 fpdef: NAME | '(' fplist ')'
@@ -59,7 +62,7 @@
 exec_stmt: 'exec' expr ['in' test [',' test]]
 assert_stmt: 'assert' test [',' test]

-compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef
+compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | funcdef| decoratedfuncdef | classdef
 if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
 while_stmt: 'while' test ':' suite ['else' ':' suite]
 for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite]

This change seems to allow the following code to be parsed happily:

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

   def hello2(who):
      print "woo?", who

I say *seems* because I'm getting seg faults when I try and *run* the
above, but the following produces an expected syntax error - _implying_
that the code above is parsed correctly...

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

   def hello2(who):
      print "woo?", who

   def crashandburnhere(who)
      print "woo?", who

(Backtrace from the seg faults seem to point at other stuff as well,
but I don't know the python source well enough to say for certain!
I suspect the reason is because I've yanked the leading "@" more than
anything else)

There is a restriction here - the contents of the decorate block must
be limited to what you would get after an "@" - ie just declarations -
it's not a "suite" (bunch of statements).


Michael.
-- 
Michael.Sparks at rd.bbc.co.uk    
British Broadcasting Corporation, Research and Development
Kingswood Warren, Surrey KT20 6NP

This message (and any attachments) may contain personal views
which are not the views of the BBC unless specifically stated.





More information about the Python-list mailing list