mirror of
https://github.com/python/cpython.git
synced 2025-07-19 01:05:26 +00:00
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:
parent
b51b23405b
commit
0ccff074cd
8 changed files with 142 additions and 96 deletions
|
@ -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);
|
||||
|
|
|
@ -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"},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue