[Implementation] (first attempt) Re: A decorator syntax not yet mentioned (I think!)

Michael Sparks michaels at rd.bbc.co.uk
Thu Aug 12 09:46:13 EDT 2004


Michael Sparks wrote:
>> 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...

I've implemented this now, and I have this (kinda*) working. I've
patched the 2.4a2 release from python.org and made the following
changes.
   * Kinda - there's something wrong with my implementation due to
     scoping, and since I only first looked at the python source for the
     first time 4-5 hours ago, I think this is progress :)

I changed the grammar to allow syntax J2:

--- Python-2.4a2/Grammar/Grammar        2004-08-02 07:09:53.000000000 +0100
+++ Python-2.4a2-MS/Grammar/Grammar     2004-08-12 13:21:16.577978408 +0100
@@ -30,5 +30,5 @@

-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] ')'

I then modified comple.c to make this syntax usable:

--- Python-2.4a2/Python/compile.c       2004-08-04 11:26:08.000000000 +0100
+++ Python-2.4a2-MS/Python/compile.c    2004-08-12 14:24:50.537168480 +0100
@@ -4045,12 +4045,12 @@
        int nch = NCH(n);
-       assert(nch >= 2);
-       REQ(CHILD(n, 0), AT);
-       com_decorator_name(c, CHILD(n, 1));
+       assert(nch >= 1);
+       com_decorator_name(c, CHILD(n, 0));

        if (nch > 2) {
-               assert(nch == 4 || nch == 5);
-               REQ(CHILD(n, 2), LPAR);
+               assert(nch == 3 || nch == 4);
+               REQ(CHILD(n, 1), LPAR);
                REQ(CHILD(n, nch - 1), RPAR);
-               com_call_function(c, CHILD(n, 3));
+               com_call_function(c, CHILD(n, 2));
        }
+
 }
@@ -4085,7 +4085,7 @@
        REQ(n, funcdef);
-       /*          -6            -5   -4   -3         -2  -1
-          funcdef: [decorators] 'def' NAME parameters ':' suite */
-
-       if (NCH(n) == 6)
-               ndecorators = com_decorators(c, CHILD(n, 0));
+       /*                                        -7         -6        -5   -4   -3         -2  -1
+          funcdef: ['decorate' ':' NEWLINE INDENT decorators DEDENT ] 'def' NAME parameters ':' suite */
+
+       if (NCH(n) == 11)
+               ndecorators = com_decorators(c, CHILD(n, 4));
        else
@@ -5825,5 +5825,5 @@
                if (TYPE(n) == decorator) {
-                       /* decorator: '@' dotted_name [ '(' [arglist] ')' ] */
+                       /* decorator: dotted_name [ '(' [arglist] ')' ] */
                        node *name, *varname;
-                       name = CHILD(n, 1);
+                       name = CHILD(n, 0);
                        REQ(name, dotted_name);

====================================
The one sting in this, which I haven't figured out is that the decorate
keyword and indentation appear to knock the scoping for six (which I
suspect/hope would be simple to solve) so for *this* implementation you
need to do something like:

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

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

Foo.hello("HOO")
=========================

If you miss out the cruft above, python can't (with the above small
change) find the right scope for "staticmethod".

I suspect that someone with more experience with the source tree would
be able to remove the cruft line above and allow the scope to be searched
correctly.

Either way, the argument on http://www.python.org/moin/PythonDecorators
regarding J2 not having an implementation just (80%) disappeared :)

Should I forward this to the dev list?


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