summaryrefslogtreecommitdiffstats
path: root/Python/compile.c
diff options
context:
space:
mode:
authorMichael W. Hudson <mwh@python.net>2004-08-17 17:29:16 (GMT)
committerMichael W. Hudson <mwh@python.net>2004-08-17 17:29:16 (GMT)
commit0ccff074cd806bc7e963a1e0ff6ce25e0d11cce9 (patch)
treec8e7be65d3051aa878fe53169b9bdeb4d3b4227e /Python/compile.c
parentb51b23405b6cf82ab4ec20f3d5ef4b895bd0786f (diff)
downloadcpython-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.c42
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);