diff options
author | Michael W. Hudson <mwh@python.net> | 2004-08-17 17:29:16 (GMT) |
---|---|---|
committer | Michael W. Hudson <mwh@python.net> | 2004-08-17 17:29:16 (GMT) |
commit | 0ccff074cd806bc7e963a1e0ff6ce25e0d11cce9 (patch) | |
tree | c8e7be65d3051aa878fe53169b9bdeb4d3b4227e /Python/compile.c | |
parent | b51b23405b6cf82ab4ec20f3d5ef4b895bd0786f (diff) | |
download | cpython-0ccff074cd806bc7e963a1e0ff6ce25e0d11cce9.zip cpython-0ccff074cd806bc7e963a1e0ff6ce25e0d11cce9.tar.gz cpython-0ccff074cd806bc7e963a1e0ff6ce25e0d11cce9.tar.bz2 |
This is Mark Russell's patch:
[ 1009560 ] Fix @decorator evaluation order
From the description:
Changes in this patch:
- Change Grammar/Grammar to require
newlines between adjacent decorators.
- Fix order of evaluation of decorators
in the C (compile.c) and python
(Lib/compiler/pycodegen.py) compilers
- Add better order of evaluation check
to test_decorators.py (test_eval_order)
- Update the decorator documentation in
the reference manual (improve description
of evaluation order and update syntax
description)
and the comment:
Used Brett's evaluation order (see
http://mail.python.org/pipermail/python-dev/2004-August/047835.html)
(I'm checking this in for Anthony who was having problems getting SF to
talk to him)
Diffstat (limited to 'Python/compile.c')
-rw-r--r-- | Python/compile.c | 42 |
1 files changed, 20 insertions, 22 deletions
diff --git a/Python/compile.c b/Python/compile.c index 79620c2..fbb91f7 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -4107,16 +4107,17 @@ com_decorator_name(struct compiling *c, node *n) static void com_decorator(struct compiling *c, node *n) { - /* decorator: '@' dotted_name [ '(' [arglist] ')' ] */ + /* decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE */ int nch = NCH(n); - assert(nch >= 2); + assert(nch >= 3); REQ(CHILD(n, 0), AT); + REQ(RCHILD(n, -1), NEWLINE); com_decorator_name(c, CHILD(n, 1)); - if (nch > 2) { - assert(nch == 4 || nch == 5); + if (nch > 3) { + assert(nch == 5 || nch == 6); REQ(CHILD(n, 2), LPAR); - REQ(CHILD(n, nch - 1), RPAR); + REQ(RCHILD(n, -2), RPAR); com_call_function(c, CHILD(n, 3)); } } @@ -4124,26 +4125,20 @@ com_decorator(struct compiling *c, node *n) static int com_decorators(struct compiling *c, node *n) { - int i, nch, ndecorators; + int i, nch; - /* decorator ([NEWLINE] decorator)* NEWLINE */ + /* decorator+ */ nch = NCH(n); - assert(nch >= 2); - REQ(CHILD(n, nch - 1), NEWLINE); - - ndecorators = 0; - /* the application order for decorators is the reverse of how they are - listed; bottom-up */ - nch -= 1; - for (i = 0; i < nch; i+=1) { + assert(nch >= 1); + + for (i = 0; i < nch; ++i) { node *ch = CHILD(n, i); - if (TYPE(ch) != NEWLINE) { - com_decorator(c, ch); - ++ndecorators; - } + REQ(ch, decorator); + + com_decorator(c, ch); } - return ndecorators; + return nch; } static void @@ -4151,6 +4146,7 @@ com_funcdef(struct compiling *c, node *n) { PyObject *co; int ndefs, ndecorators; + REQ(n, funcdef); /* -6 -5 -4 -3 -2 -1 funcdef: [decorators] 'def' NAME parameters ':' suite */ @@ -4159,7 +4155,7 @@ com_funcdef(struct compiling *c, node *n) ndecorators = com_decorators(c, CHILD(n, 0)); else ndecorators = 0; - + ndefs = com_argdefs(c, n); if (ndefs < 0) return; @@ -4179,11 +4175,13 @@ com_funcdef(struct compiling *c, node *n) else com_addoparg(c, MAKE_FUNCTION, ndefs); com_pop(c, ndefs); + while (ndecorators > 0) { com_addoparg(c, CALL_FUNCTION, 1); com_pop(c, 1); - ndecorators--; + --ndecorators; } + com_addop_varname(c, VAR_STORE, STR(RCHILD(n, -4))); com_pop(c, 1); Py_DECREF(co); |