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)
This commit is contained in:
Michael W. Hudson 2004-08-17 17:29:16 +00:00
parent b51b23405b
commit 0ccff074cd
8 changed files with 142 additions and 96 deletions

View file

@ -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);
assert(nch >= 1);
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) {
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);

View file

@ -51,41 +51,40 @@ static arc arcs_3_1[1] = {
};
static arc arcs_3_2[2] = {
{13, 3},
{0, 2},
{2, 4},
};
static arc arcs_3_3[2] = {
{14, 4},
{15, 5},
{14, 5},
{15, 6},
};
static arc arcs_3_4[1] = {
{15, 5},
{0, 4},
};
static arc arcs_3_5[1] = {
{0, 5},
{15, 6},
};
static state states_3[6] = {
static arc arcs_3_6[1] = {
{2, 4},
};
static state states_3[7] = {
{1, arcs_3_0},
{1, arcs_3_1},
{2, arcs_3_2},
{2, arcs_3_3},
{1, arcs_3_4},
{1, arcs_3_5},
{1, arcs_3_6},
};
static arc arcs_4_0[1] = {
{10, 1},
};
static arc arcs_4_1[2] = {
{2, 2},
{10, 1},
{0, 1},
};
static arc arcs_4_2[2] = {
{10, 1},
{0, 2},
};
static state states_4[3] = {
static state states_4[2] = {
{1, arcs_4_0},
{2, arcs_4_1},
{2, arcs_4_2},
};
static arc arcs_5_0[2] = {
{16, 1},
@ -1618,9 +1617,9 @@ static dfa dfas[74] = {
"\204\050\014\000\000\000\200\012\176\231\040\007\040\000\000\206\220\064\041\000"},
{258, "eval_input", 0, 3, states_2,
"\000\040\010\000\000\000\000\000\000\000\000\000\040\000\000\206\220\064\001\000"},
{259, "decorator", 0, 6, states_3,
{259, "decorator", 0, 7, states_3,
"\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
{260, "decorators", 0, 3, states_4,
{260, "decorators", 0, 2, states_4,
"\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
{261, "funcdef", 0, 7, states_5,
"\000\010\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},