A decorator syntax not yet mentioned (I think!)
Michael Sparks
michaels at rd.bbc.co.uk
Thu Aug 12 07:33:04 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...
>
> 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)
Done a bit more work and it certainly *is* caused by the backend
logic not in step with the grammar change I made rather than it not
building/parsing correctly. I've tried changing things to make this
work, but at this exact instant I don't have the time to do this. (I
might take another look this evening, it doesn't look *too* difficult
to do)
I've also changed the grammar rules again to make it a smaller change:
--- Python-2.4a2/Grammar/Grammar 2004-08-02 07:09:53.000000000 +0100
+++ Python-2.4a2-MS/Grammar/Grammar 2004-08-12 12:12:11.567115840 +0100
@@ -28,9 +28,10 @@
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
+funcdef: ['decorate' ':' NEWLINE INDENT decorators DEDENT] 'def' NAME parameters ':' suite
parameters: '(' [varargslist] ')'
varargslist: (fpdef ['=' test] ',')* ('*' NAME [',' '**' NAME] | '**' NAME) | fpdef ['=' test] (',' fpdef ['=' test])* [',']
fpdef: NAME | '(' fplist ')'
This builds, and I've changed some of Python/compile.c to handle this:
--- Python-2.4a2/Python/compile.c 2004-08-04 11:26:08.000000000 +0100
+++ Python-2.4a2-MS/Python/compile.c 2004-08-12 12:19:47.570792744 +0100
@@ -4043,13 +4043,13 @@
{
/* decorator: '@' dotted_name [ '(' [arglist] ')' ] */
int nch = NCH(n);
- assert(nch >= 2);
- REQ(CHILD(n, 0), AT);
- com_decorator_name(c, CHILD(n, 1));
+ assert(nch >= 1);
+ // REQ(CHILD(n, 0), AT);
+ com_decorator_name(c, CHILD(n, 0));
if (nch > 2) {
assert(nch == 4 || nch == 5);
- REQ(CHILD(n, 2), LPAR);
+ REQ(CHILD(n, 1), LPAR);
REQ(CHILD(n, nch - 1), RPAR);
com_call_function(c, CHILD(n, 3));
}
@@ -4083,11 +4083,14 @@
PyObject *co;
int ndefs, ndecorators;
REQ(n, funcdef);
- /* -6 -5 -4 -3 -2 -1
+ /* -6 -5 -4 -3 -2 -1
funcdef: [decorators] 'def' NAME parameters ':' suite */
+ /* -7 -6 -5 -4 -3 -2 -1
+ funcdef: ['decorate' ':' NEWLINE INDENT decorators DEDENT ] 'def' NAME parameters ':' suite */
+
- if (NCH(n) == 6)
- ndecorators = com_decorators(c, CHILD(n, 0));
+ if (NCH(n) == 11)
+ ndecorators = com_decorators(c, CHILD(n, 4));
else
ndecorators = 0;
@@ -5823,9 +5826,9 @@
*/
case decorator:
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);
varname = CHILD(name, 0);
REQ(varname, NAME);
However I'm now getting a new error instead (just before a controlled
core dump):
Fatal Python error: unknown scope for staticmethod in Foo(1) in ./foo.py
symbols: {'hello2': 2, 'hello': 2}
locals: {'hello2': 0, 'hello': 1}
globals: {}
Aborted (core dumped)
Smoke test is this:
---------
class Foo:
decorate:
staticmethod
def hello(who):
print "woo?", who
def hello2(who):
print "woo?", who
Foo.hello("HOO")
---------
I've got to put this aside for the moment, but I'll come back to it
later. (I think this is actually pretty close to working though...)
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