# HG changeset patch # User diff --git a/Grammar/Grammar b/Grammar/Grammar index d7aaffd..b0c66fa 100644 --- a/Grammar/Grammar +++ b/Grammar/Grammar @@ -116,12 +116,20 @@ dictorsetmaker: ( (test ':' test (comp_for | (',' test ':' test)* [','])) | classdef: 'class' NAME ['(' [arglist] ')'] ':' suite -arglist: (argument ',')* (argument [','] - |'*' test (',' argument)* [',' '**' test] - |'**' test) +#arglist: (argument ',')* argument [','] + +arglist: ((argument |'*' test |'**' test) ',')* (argument [','] |'*' test |'**' test) # The reason that keywords are test nodes instead of NAME is that using NAME # results in an ambiguity. ast.c makes sure it's a NAME. -argument: test [comp_for] | test '=' test # Really [keyword '='] test +#argument: test [comp_for] | test '=' test # Really [keyword '='] test + +#arglist: argument (',' argument)* [','] +# "test '=' test" is really "keyword '=' test", but we have no such token. +# These need to be in a single rule to avoid grammar that is ambiguous +# to our LL(1) parser. Even though 'test' includes '*expr' in star_expr, +# we explicitly match '*' here, too, to give it proper precedence. +argument: ( test [comp_for] | '*' test | test '=' test | '**' test ) + comp_iter: comp_for | comp_if comp_for: 'for' exprlist 'in' or_test [comp_iter] comp_if: 'if' test_nocond [comp_iter] diff --git a/Include/Python-ast.h b/Include/Python-ast.h index 67d677b..7147f70 100644 --- a/Include/Python-ast.h +++ b/Include/Python-ast.h @@ -84,8 +84,6 @@ struct _stmt { identifier name; asdl_seq *bases; asdl_seq *keywords; - expr_ty starargs; - expr_ty kwargs; asdl_seq *body; asdl_seq *decorator_list; } ClassDef; @@ -263,8 +261,6 @@ struct _expr { expr_ty func; asdl_seq *args; asdl_seq *keywords; - expr_ty starargs; - expr_ty kwargs; } Call; struct { @@ -406,11 +402,10 @@ mod_ty _Py_Suite(asdl_seq * body, PyArena *arena); stmt_ty _Py_FunctionDef(identifier name, arguments_ty args, asdl_seq * body, asdl_seq * decorator_list, expr_ty returns, int lineno, int col_offset, PyArena *arena); -#define ClassDef(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) _Py_ClassDef(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) +#define ClassDef(a0, a1, a2, a3, a4, a5, a6, a7) _Py_ClassDef(a0, a1, a2, a3, a4, a5, a6, a7) stmt_ty _Py_ClassDef(identifier name, asdl_seq * bases, asdl_seq * keywords, - expr_ty starargs, expr_ty kwargs, asdl_seq * body, - asdl_seq * decorator_list, int lineno, int col_offset, - PyArena *arena); + asdl_seq * body, asdl_seq * decorator_list, int lineno, + int col_offset, PyArena *arena); #define Return(a0, a1, a2, a3) _Py_Return(a0, a1, a2, a3) stmt_ty _Py_Return(expr_ty value, int lineno, int col_offset, PyArena *arena); #define Delete(a0, a1, a2, a3) _Py_Delete(a0, a1, a2, a3) @@ -504,10 +499,9 @@ expr_ty _Py_YieldFrom(expr_ty value, int lineno, int col_offset, PyArena #define Compare(a0, a1, a2, a3, a4, a5) _Py_Compare(a0, a1, a2, a3, a4, a5) expr_ty _Py_Compare(expr_ty left, asdl_int_seq * ops, asdl_seq * comparators, int lineno, int col_offset, PyArena *arena); -#define Call(a0, a1, a2, a3, a4, a5, a6, a7) _Py_Call(a0, a1, a2, a3, a4, a5, a6, a7) -expr_ty _Py_Call(expr_ty func, asdl_seq * args, asdl_seq * keywords, expr_ty - starargs, expr_ty kwargs, int lineno, int col_offset, PyArena - *arena); +#define Call(a0, a1, a2, a3, a4, a5) _Py_Call(a0, a1, a2, a3, a4, a5) +expr_ty _Py_Call(expr_ty func, asdl_seq * args, asdl_seq * keywords, int + lineno, int col_offset, PyArena *arena); #define Num(a0, a1, a2, a3) _Py_Num(a0, a1, a2, a3) expr_ty _Py_Num(object n, int lineno, int col_offset, PyArena *arena); #define Str(a0, a1, a2, a3) _Py_Str(a0, a1, a2, a3) diff --git a/Include/opcode.h b/Include/opcode.h index 0936f2d..04a230b 100644 --- a/Include/opcode.h +++ b/Include/opcode.h @@ -141,6 +141,11 @@ extern "C" { #define LOAD_CLASSDEREF 148 +#define BUILD_LIST_UNPACK 149 /* number of iterables to unpack */ +#define BUILD_MAP_UNPACK 150 /* "" */ +#define BUILD_TUPLE_UNPACK 151 /* number of iterables to unpack */ +#define BUILD_SET_UNPACK 152 /* "" */ + /* EXCEPT_HANDLER is a special, implicit block type which is created when entering an except handler. It is not an opcode but we define it here as we want it to be available to both frameobject.c and ceval.c, while diff --git a/Lib/opcode.py b/Lib/opcode.py index 78d1229..631b1f1 100644 --- a/Lib/opcode.py +++ b/Lib/opcode.py @@ -184,4 +184,9 @@ hasfree.append(148) def_op('EXTENDED_ARG', 144) EXTENDED_ARG = 144 +def_op('BUILD_LIST_UNPACK', 149) +def_op('BUILD_MAP_UNPACK', 150) +def_op('BUILD_TUPLE_UNPACK', 151) +def_op('BUILD_SET_UNPACK', 152) + del def_op, name_op, jrel_op, jabs_op diff --git a/Lib/test/test_extcall.py b/Lib/test/test_extcall.py index 6b6c12d..26ec6a3 100644 --- a/Lib/test/test_extcall.py +++ b/Lib/test/test_extcall.py @@ -34,17 +34,31 @@ Argument list examples (1, 2, 3, 4, 5) {} >>> f(1, 2, 3, *[4, 5]) (1, 2, 3, 4, 5) {} + >>> f(*[1, 2, 3], 4, 5) + (1, 2, 3, 4, 5) {} >>> f(1, 2, 3, *UserList([4, 5])) (1, 2, 3, 4, 5) {} + >>> f(1, 2, 3, *[4, 5], *[6, 7]) + (1, 2, 3, 4, 5, 6, 7) {} + >>> f(1, *[2, 3], 4, *[5, 6], 7) + (1, 2, 3, 4, 5, 6, 7) {} + >>> f(*UserList([1, 2]), *UserList([3, 4]), 5, *UserList([6, 7])) + (1, 2, 3, 4, 5, 6, 7) {} Here we add keyword arguments >>> f(1, 2, 3, **{'a':4, 'b':5}) (1, 2, 3) {'a': 4, 'b': 5} + >>> f(1, 2, **{'a': -1, 'b': 5}, **{'a': 4, 'c': 6}) + (1, 2) {'a': 4, 'b': 5, 'c': 6} >>> f(1, 2, 3, *[4, 5], **{'a':6, 'b':7}) (1, 2, 3, 4, 5) {'a': 6, 'b': 7} >>> f(1, 2, 3, x=4, y=5, *(6, 7), **{'a':8, 'b': 9}) (1, 2, 3, 6, 7) {'a': 8, 'b': 9, 'x': 4, 'y': 5} + >>> f(1, 2, 3, *[4, 5], **{'c': 8}, **{'a':6, 'b':7}) + (1, 2, 3, 4, 5) {'a': 6, 'b': 7, 'c': 8} + >>> f(1, 2, 3, *(4, 5), x=6, y=7, **{'a':8, 'b': 9}) + (1, 2, 3, 4, 5) {'a': 8, 'b': 9, 'x': 6, 'y': 7} >>> f(1, 2, 3, **UserDict(a=4, b=5)) (1, 2, 3) {'a': 4, 'b': 5} @@ -52,6 +66,8 @@ Here we add keyword arguments (1, 2, 3, 4, 5) {'a': 6, 'b': 7} >>> f(1, 2, 3, x=4, y=5, *(6, 7), **UserDict(a=8, b=9)) (1, 2, 3, 6, 7) {'a': 8, 'b': 9, 'x': 4, 'y': 5} + >>> f(1, 2, 3, *(4, 5), x=6, y=7, **UserDict(a=8, b=9)) + (1, 2, 3, 4, 5) {'a': 8, 'b': 9, 'x': 6, 'y': 7} Examples with invalid arguments (TypeErrors). We're also testing the function names in the exception messages. diff --git a/Modules/parsermodule.c b/Modules/parsermodule.c index 537a2e9..5b563b9 100644 --- a/Modules/parsermodule.c +++ b/Modules/parsermodule.c @@ -2732,9 +2732,6 @@ validate_arglist(node *tree) } ok = 1; if (nch-i > 0) { - /* - * argument | '*' test [',' '**' test] | '**' test - */ int sym = TYPE(CHILD(tree, i)); if (sym == argument) { @@ -2745,30 +2742,7 @@ validate_arglist(node *tree) ok = 0; } } - else if (sym == STAR) { - ok = validate_star(CHILD(tree, i)); - if (ok && (nch-i == 2)) - ok = validate_test(CHILD(tree, i+1)); - else if (ok && (nch-i == 5)) - ok = (validate_test(CHILD(tree, i+1)) - && validate_comma(CHILD(tree, i+2)) - && validate_doublestar(CHILD(tree, i+3)) - && validate_test(CHILD(tree, i+4))); - else { - err_string("illegal use of '*' in arglist"); - ok = 0; - } - } - else if (sym == DOUBLESTAR) { - if (nch-i == 2) - ok = (validate_doublestar(CHILD(tree, i)) - && validate_test(CHILD(tree, i+1))); - else { - err_string("illegal use of '**' in arglist"); - ok = 0; - } - } - else { + else { err_string("illegal arglist specification"); ok = 0; } @@ -2788,14 +2762,18 @@ validate_argument(node *tree) int nch = NCH(tree); int res = (validate_ntype(tree, argument) && ((nch == 1) || (nch == 2) || (nch == 3))); - if (res) - res = validate_test(CHILD(tree, 0)); - if (res && (nch == 2)) - res = validate_comp_for(CHILD(tree, 1)); - else if (res && (nch == 3)) - res = (validate_equal(CHILD(tree, 1)) - && validate_test(CHILD(tree, 2))); + if (res && (TYPE(CHILD(tree, 0)) == STAR || + TYPE(CHILD(tree, 0)) == DOUBLESTAR)) + res = validate_test(CHILD(tree, 1)); + else if (res) { + res = validate_test(CHILD(tree, 0)); + if (res && (nch == 2)) + res = validate_comp_for(CHILD(tree, 1)); + else if (res && (nch == 3)) + res = (validate_equal(CHILD(tree, 1)) + && validate_test(CHILD(tree, 2))); + } return (res); } diff --git a/Parser/Python.asdl b/Parser/Python.asdl index debd89e..12179e8 100644 --- a/Parser/Python.asdl +++ b/Parser/Python.asdl @@ -14,8 +14,6 @@ module Python | ClassDef(identifier name, expr* bases, keyword* keywords, - expr? starargs, - expr? kwargs, stmt* body, expr* decorator_list) | Return(expr? value) @@ -64,8 +62,7 @@ module Python -- need sequences for compare to distinguish between -- x < 4 < 3 and (x < 4) < 3 | Compare(expr left, cmpop* ops, expr* comparators) - | Call(expr func, expr* args, keyword* keywords, - expr? starargs, expr? kwargs) + | Call(expr func, expr* args, keyword* keywords) | Num(object n) -- a number as a PyObject. | Str(string s) -- need to specify raw, unicode, etc? | Bytes(bytes s) @@ -109,8 +106,8 @@ module Python arg = (identifier arg, expr? annotation) attributes (int lineno, int col_offset) - -- keyword arguments supplied to call - keyword = (identifier arg, expr value) + -- keyword arguments supplied to call (NULL identifier for **kwargs) + keyword = (identifier? arg, expr value) -- import name with optional 'as' alias. alias = (identifier name, identifier? asname) diff --git a/Python/Python-ast.c b/Python/Python-ast.c index e07a93f..cc089ba 100644 --- a/Python/Python-ast.c +++ b/Python/Python-ast.c @@ -48,14 +48,10 @@ static char *FunctionDef_fields[]={ static PyTypeObject *ClassDef_type; _Py_IDENTIFIER(bases); _Py_IDENTIFIER(keywords); -_Py_IDENTIFIER(starargs); -_Py_IDENTIFIER(kwargs); static char *ClassDef_fields[]={ "name", "bases", "keywords", - "starargs", - "kwargs", "body", "decorator_list", }; @@ -254,8 +250,6 @@ static char *Call_fields[]={ "func", "args", "keywords", - "starargs", - "kwargs", }; static PyTypeObject *Num_type; _Py_IDENTIFIER(n); @@ -811,7 +805,7 @@ static int init_types(void) FunctionDef_type = make_type("FunctionDef", stmt_type, FunctionDef_fields, 5); if (!FunctionDef_type) return 0; - ClassDef_type = make_type("ClassDef", stmt_type, ClassDef_fields, 7); + ClassDef_type = make_type("ClassDef", stmt_type, ClassDef_fields, 5); if (!ClassDef_type) return 0; Return_type = make_type("Return", stmt_type, Return_fields, 1); if (!Return_type) return 0; @@ -883,7 +877,7 @@ static int init_types(void) if (!YieldFrom_type) return 0; Compare_type = make_type("Compare", expr_type, Compare_fields, 3); if (!Compare_type) return 0; - Call_type = make_type("Call", expr_type, Call_fields, 5); + Call_type = make_type("Call", expr_type, Call_fields, 3); if (!Call_type) return 0; Num_type = make_type("Num", expr_type, Num_fields, 1); if (!Num_type) return 0; @@ -1202,9 +1196,9 @@ FunctionDef(identifier name, arguments_ty args, asdl_seq * body, asdl_seq * } stmt_ty -ClassDef(identifier name, asdl_seq * bases, asdl_seq * keywords, expr_ty - starargs, expr_ty kwargs, asdl_seq * body, asdl_seq * decorator_list, - int lineno, int col_offset, PyArena *arena) +ClassDef(identifier name, asdl_seq * bases, asdl_seq * keywords, asdl_seq * + body, asdl_seq * decorator_list, int lineno, int col_offset, PyArena + *arena) { stmt_ty p; if (!name) { @@ -1219,8 +1213,6 @@ ClassDef(identifier name, asdl_seq * bases, asdl_seq * keywords, expr_ty p->v.ClassDef.name = name; p->v.ClassDef.bases = bases; p->v.ClassDef.keywords = keywords; - p->v.ClassDef.starargs = starargs; - p->v.ClassDef.kwargs = kwargs; p->v.ClassDef.body = body; p->v.ClassDef.decorator_list = decorator_list; p->lineno = lineno; @@ -1880,8 +1872,8 @@ Compare(expr_ty left, asdl_int_seq * ops, asdl_seq * comparators, int lineno, } expr_ty -Call(expr_ty func, asdl_seq * args, asdl_seq * keywords, expr_ty starargs, - expr_ty kwargs, int lineno, int col_offset, PyArena *arena) +Call(expr_ty func, asdl_seq * args, asdl_seq * keywords, int lineno, int + col_offset, PyArena *arena) { expr_ty p; if (!func) { @@ -1896,8 +1888,6 @@ Call(expr_ty func, asdl_seq * args, asdl_seq * keywords, expr_ty starargs, p->v.Call.func = func; p->v.Call.args = args; p->v.Call.keywords = keywords; - p->v.Call.starargs = starargs; - p->v.Call.kwargs = kwargs; p->lineno = lineno; p->col_offset = col_offset; return p; @@ -2271,11 +2261,6 @@ keyword_ty keyword(identifier arg, expr_ty value, PyArena *arena) { keyword_ty p; - if (!arg) { - PyErr_SetString(PyExc_ValueError, - "field arg is required for keyword"); - return NULL; - } if (!value) { PyErr_SetString(PyExc_ValueError, "field value is required for keyword"); @@ -2437,16 +2422,6 @@ ast2obj_stmt(void* _o) if (_PyObject_SetAttrId(result, &PyId_keywords, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(o->v.ClassDef.starargs); - if (!value) goto failed; - if (_PyObject_SetAttrId(result, &PyId_starargs, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_expr(o->v.ClassDef.kwargs); - if (!value) goto failed; - if (_PyObject_SetAttrId(result, &PyId_kwargs, value) == -1) - goto failed; - Py_DECREF(value); value = ast2obj_list(o->v.ClassDef.body, ast2obj_stmt); if (!value) goto failed; if (_PyObject_SetAttrId(result, &PyId_body, value) == -1) @@ -2959,16 +2934,6 @@ ast2obj_expr(void* _o) if (_PyObject_SetAttrId(result, &PyId_keywords, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(o->v.Call.starargs); - if (!value) goto failed; - if (_PyObject_SetAttrId(result, &PyId_starargs, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_expr(o->v.Call.kwargs); - if (!value) goto failed; - if (_PyObject_SetAttrId(result, &PyId_kwargs, value) == -1) - goto failed; - Py_DECREF(value); break; case Num_kind: result = PyType_GenericNew(Num_type, NULL, NULL); @@ -3867,8 +3832,6 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena) identifier name; asdl_seq* bases; asdl_seq* keywords; - expr_ty starargs; - expr_ty kwargs; asdl_seq* body; asdl_seq* decorator_list; @@ -3931,26 +3894,6 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena) PyErr_SetString(PyExc_TypeError, "required field \"keywords\" missing from ClassDef"); return 1; } - if (exists_not_none(obj, &PyId_starargs)) { - int res; - tmp = _PyObject_GetAttrId(obj, &PyId_starargs); - if (tmp == NULL) goto failed; - res = obj2ast_expr(tmp, &starargs, arena); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } else { - starargs = NULL; - } - if (exists_not_none(obj, &PyId_kwargs)) { - int res; - tmp = _PyObject_GetAttrId(obj, &PyId_kwargs); - if (tmp == NULL) goto failed; - res = obj2ast_expr(tmp, &kwargs, arena); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } else { - kwargs = NULL; - } if (_PyObject_HasAttrId(obj, &PyId_body)) { int res; Py_ssize_t len; @@ -3999,8 +3942,8 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena) PyErr_SetString(PyExc_TypeError, "required field \"decorator_list\" missing from ClassDef"); return 1; } - *out = ClassDef(name, bases, keywords, starargs, kwargs, body, - decorator_list, lineno, col_offset, arena); + *out = ClassDef(name, bases, keywords, body, decorator_list, lineno, + col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -5498,8 +5441,6 @@ obj2ast_expr(PyObject* obj, expr_ty* out, PyArena* arena) expr_ty func; asdl_seq* args; asdl_seq* keywords; - expr_ty starargs; - expr_ty kwargs; if (_PyObject_HasAttrId(obj, &PyId_func)) { int res; @@ -5560,28 +5501,7 @@ obj2ast_expr(PyObject* obj, expr_ty* out, PyArena* arena) PyErr_SetString(PyExc_TypeError, "required field \"keywords\" missing from Call"); return 1; } - if (exists_not_none(obj, &PyId_starargs)) { - int res; - tmp = _PyObject_GetAttrId(obj, &PyId_starargs); - if (tmp == NULL) goto failed; - res = obj2ast_expr(tmp, &starargs, arena); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } else { - starargs = NULL; - } - if (exists_not_none(obj, &PyId_kwargs)) { - int res; - tmp = _PyObject_GetAttrId(obj, &PyId_kwargs); - if (tmp == NULL) goto failed; - res = obj2ast_expr(tmp, &kwargs, arena); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } else { - kwargs = NULL; - } - *out = Call(func, args, keywords, starargs, kwargs, lineno, col_offset, - arena); + *out = Call(func, args, keywords, lineno, col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -6721,7 +6641,7 @@ obj2ast_keyword(PyObject* obj, keyword_ty* out, PyArena* arena) identifier arg; expr_ty value; - if (_PyObject_HasAttrId(obj, &PyId_arg)) { + if (exists_not_none(obj, &PyId_arg)) { int res; tmp = _PyObject_GetAttrId(obj, &PyId_arg); if (tmp == NULL) goto failed; @@ -6729,8 +6649,7 @@ obj2ast_keyword(PyObject* obj, keyword_ty* out, PyArena* arena) if (res != 0) goto failed; Py_CLEAR(tmp); } else { - PyErr_SetString(PyExc_TypeError, "required field \"arg\" missing from keyword"); - return 1; + arg = NULL; } if (_PyObject_HasAttrId(obj, &PyId_value)) { int res; diff --git a/Python/ast.c b/Python/ast.c index 3bd24fd..3753828 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -233,9 +233,7 @@ validate_expr(expr_ty exp, expr_context_ty ctx) case Call_kind: return validate_expr(exp->v.Call.func, Load) && validate_exprs(exp->v.Call.args, Load, 0) && - validate_keywords(exp->v.Call.keywords) && - (!exp->v.Call.starargs || validate_expr(exp->v.Call.starargs, Load)) && - (!exp->v.Call.kwargs || validate_expr(exp->v.Call.kwargs, Load)); + validate_keywords(exp->v.Call.keywords); case Num_kind: { PyObject *n = exp->v.Num.n; if (!PyLong_CheckExact(n) && !PyFloat_CheckExact(n) && @@ -320,9 +318,7 @@ validate_stmt(stmt_ty stmt) return validate_body(stmt->v.ClassDef.body, "ClassDef") && validate_exprs(stmt->v.ClassDef.bases, Load, 0) && validate_keywords(stmt->v.ClassDef.keywords) && - validate_exprs(stmt->v.ClassDef.decorator_list, Load, 0) && - (!stmt->v.ClassDef.starargs || validate_expr(stmt->v.ClassDef.starargs, Load)) && - (!stmt->v.ClassDef.kwargs || validate_expr(stmt->v.ClassDef.kwargs, Load)); + validate_exprs(stmt->v.ClassDef.decorator_list, Load, 0); case Return_kind: return !stmt->v.Return.value || validate_expr(stmt->v.Return.value, Load); case Delete_kind: @@ -1438,7 +1434,7 @@ ast_for_decorator(struct compiling *c, const node *n) name_expr = NULL; } else if (NCH(n) == 5) { /* Call with no arguments */ - d = Call(name_expr, NULL, NULL, NULL, NULL, LINENO(n), + d = Call(name_expr, NULL, NULL, LINENO(n), n->n_col_offset, c->c_arena); if (!d) return NULL; @@ -2099,7 +2095,7 @@ ast_for_trailer(struct compiling *c, const node *n, expr_ty left_expr) REQ(n, trailer); if (TYPE(CHILD(n, 0)) == LPAR) { if (NCH(n) == 2) - return Call(left_expr, NULL, NULL, NULL, NULL, LINENO(n), + return Call(left_expr, NULL, NULL, LINENO(n), n->n_col_offset, c->c_arena); else { expr_ty tmp = ast_for_call(c, CHILD(n, 1), left_expr); @@ -2424,7 +2420,6 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func) int i, nargs, nkeywords, ngens; asdl_seq *args; asdl_seq *keywords; - expr_ty vararg = NULL, kwarg = NULL; REQ(n, arglist); @@ -2438,6 +2433,8 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func) nargs++; else if (TYPE(CHILD(ch, 1)) == comp_for) ngens++; + else if (TYPE(CHILD(ch, 0)) == STAR) + nargs++; else nkeywords++; } @@ -2471,16 +2468,36 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func) "non-keyword arg after keyword arg"); return NULL; } - if (vararg) { - ast_error(c, CHILD(ch, 0), - "only named arguments may follow *expression"); - return NULL; - } e = ast_for_expr(c, CHILD(ch, 0)); if (!e) return NULL; asdl_seq_SET(args, nargs++, e); } + else if (TYPE(CHILD(ch, 0)) == STAR) { + node *chch = CHILD(ch, 1); + expr_ty starred; + if (nkeywords) { + ast_error(c, chch, "non-keyword arg after keyword arg"); + return NULL; + } + e = ast_for_expr(c, chch); + if (!e) + return NULL; + starred = Starred(e, Load, LINENO(chch), chch->n_col_offset, + c->c_arena); + if (!starred) + return NULL; + asdl_seq_SET(args, nargs++, starred); + } + else if (TYPE(CHILD(ch, 0)) == DOUBLESTAR) { + keyword_ty kw; + i++; + e = ast_for_expr(c, CHILD(ch, 1)); + if (!e) + return NULL; + kw = keyword(NULL, e, c->c_arena); + asdl_seq_SET(keywords, nkeywords++, kw); + } else if (TYPE(CHILD(ch, 1)) == comp_for) { e = ast_for_genexp(c, ch); if (!e) @@ -2527,21 +2544,9 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func) asdl_seq_SET(keywords, nkeywords++, kw); } } - else if (TYPE(ch) == STAR) { - vararg = ast_for_expr(c, CHILD(n, i+1)); - if (!vararg) - return NULL; - i++; - } - else if (TYPE(ch) == DOUBLESTAR) { - kwarg = ast_for_expr(c, CHILD(n, i+1)); - if (!kwarg) - return NULL; - i++; - } } - return Call(func, args, keywords, vararg, kwarg, func->lineno, func->col_offset, c->c_arena); + return Call(func, args, keywords, func->lineno, func->col_offset, c->c_arena); } static expr_ty @@ -3521,8 +3526,8 @@ ast_for_classdef(struct compiling *c, const node *n, asdl_seq *decorator_seq) return NULL; if (forbidden_name(c, classname, CHILD(n, 3), 0)) return NULL; - return ClassDef(classname, NULL, NULL, NULL, NULL, s, decorator_seq, - LINENO(n), n->n_col_offset, c->c_arena); + return ClassDef(classname, NULL, NULL, s, decorator_seq, LINENO(n), + n->n_col_offset, c->c_arena); } if (TYPE(CHILD(n, 3)) == RPAR) { /* class NAME '(' ')' ':' suite */ @@ -3534,8 +3539,8 @@ ast_for_classdef(struct compiling *c, const node *n, asdl_seq *decorator_seq) return NULL; if (forbidden_name(c, classname, CHILD(n, 3), 0)) return NULL; - return ClassDef(classname, NULL, NULL, NULL, NULL, s, decorator_seq, - LINENO(n), n->n_col_offset, c->c_arena); + return ClassDef(classname, NULL, NULL, s, decorator_seq, LINENO(n), + n->n_col_offset, c->c_arena); } /* class NAME '(' arglist ')' ':' suite */ @@ -3560,8 +3565,7 @@ ast_for_classdef(struct compiling *c, const node *n, asdl_seq *decorator_seq) if (forbidden_name(c, classname, CHILD(n, 1), 0)) return NULL; - return ClassDef(classname, call->v.Call.args, call->v.Call.keywords, - call->v.Call.starargs, call->v.Call.kwargs, s, + return ClassDef(classname, call->v.Call.args, call->v.Call.keywords, s, decorator_seq, LINENO(n), n->n_col_offset, c->c_arena); } diff --git a/Python/ceval.c b/Python/ceval.c index e2e882b..c3ffe4b 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -2340,6 +2340,72 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) DISPATCH(); } + TARGET(BUILD_TUPLE_UNPACK) { + PyObject *x = PyList_New(0); + PyObject *w, *v; + if (x != NULL) { + int i; + for ( i = oparg; i > 0; i--) { + w = stack_pointer[-i]; + v = _PyList_Extend((PyListObject *)x, + w); + if (!v) { + Py_DECREF(x); + x = NULL; + break; + } + Py_DECREF(v); + } + if (x == NULL) + break; + STACKADJ(-oparg); + if (opcode == BUILD_TUPLE_UNPACK) { + v = PyObject_CallFunctionObjArgs( + (PyObject *)&PyTuple_Type, + x, NULL); + Py_DECREF(x); + if (v) + PUSH(v); + x = v; + } else + PUSH(x); + } + DISPATCH(); + } + + TARGET(BUILD_LIST_UNPACK) { + PyObject *x = PyList_New(0); + PyObject *w, *v; + if (x != NULL) { + int i; + for ( i = oparg; i > 0; i--) { + w = stack_pointer[-i]; + v = _PyList_Extend((PyListObject *)x, + w); + if (!v) { + Py_DECREF(x); + x = NULL; + break; + } + Py_DECREF(v); + } + if (x == NULL) + break; + STACKADJ(-oparg); + if (opcode == BUILD_TUPLE_UNPACK) { + v = PyObject_CallFunctionObjArgs( + (PyObject *)&PyTuple_Type, + x, NULL); + Py_DECREF(x); + if (v) + PUSH(v); + x = v; + } else + PUSH(x); + } + DISPATCH(); + } + TARGET(BUILD_SET) { PyObject *set = PySet_New(NULL); int err = 0; @@ -2359,6 +2425,27 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) DISPATCH(); } + TARGET(BUILD_SET_UNPACK) { + PyObject *w; + PyObject *x = PySet_New(NULL); + if (x != NULL) { + int i; + for ( i = oparg; i > 0; i--) { + w = stack_pointer[-i]; + if (_PySet_Update(x, w) < 0) { + Py_DECREF(x); + x = NULL; + break; + } + } + if (x == NULL) + break; + STACKADJ(-oparg); + PUSH(x); + } + DISPATCH(); + } + TARGET(BUILD_MAP) { PyObject *map = _PyDict_NewPresized((Py_ssize_t)oparg); if (map == NULL) @@ -2367,6 +2454,27 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) DISPATCH(); } + TARGET(BUILD_MAP_UNPACK) { + PyObject *w; + PyObject *x = PyDict_New(); + if (x != NULL) { + int i; + for ( i = oparg; i > 0; i--) { + w = stack_pointer[-i]; + if (PyDict_Update(x, w) < 0) { + Py_DECREF(x); + x = NULL; + break; + } + } + if (x == NULL) + break; + STACKADJ(-oparg+1); + SET_TOP(x); + } + DISPATCH(); + } + TARGET(STORE_MAP) { PyObject *key = TOP(); PyObject *value = SECOND(); @@ -3009,6 +3117,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) goto dispatch_opcode; } + #if USE_COMPUTED_GOTOS _unknown_opcode: #endif @@ -4495,6 +4604,12 @@ ext_do_call(PyObject *func, PyObject ***pp_stack, int flags, int na, int nk) kwdict = d; } } + if (nk > 0) { + kwdict = update_keyword_args(kwdict, nk, pp_stack, func); + if (kwdict == NULL) + goto ext_call_fail; + } + if (flags & CALL_FLAG_VAR) { stararg = EXT_POP(*pp_stack); if (!PyTuple_Check(stararg)) { @@ -4516,11 +4631,6 @@ ext_do_call(PyObject *func, PyObject ***pp_stack, int flags, int na, int nk) } nstar = PyTuple_GET_SIZE(stararg); } - if (nk > 0) { - kwdict = update_keyword_args(kwdict, nk, pp_stack, func); - if (kwdict == NULL) - goto ext_call_fail; - } callargs = update_star_args(na, nstar, stararg, pp_stack); if (callargs == NULL) goto ext_call_fail; diff --git a/Python/compile.c b/Python/compile.c index 8b00211..7577841 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -197,9 +197,7 @@ static int expr_constant(struct compiler *, expr_ty); static int compiler_with(struct compiler *, stmt_ty, int); static int compiler_call_helper(struct compiler *c, int n, asdl_seq *args, - asdl_seq *keywords, - expr_ty starargs, - expr_ty kwargs); + asdl_seq *keywords); static int compiler_try_except(struct compiler *, stmt_ty); static int compiler_set_qualname(struct compiler *); @@ -973,6 +971,11 @@ opcode_stack_effect(int opcode, int oparg) case BUILD_LIST: case BUILD_SET: return 1-oparg; + case BUILD_LIST_UNPACK: + case BUILD_TUPLE_UNPACK: + case BUILD_SET_UNPACK: + case BUILD_MAP_UNPACK: + return 1-oparg; case BUILD_MAP: return 1; case LOAD_ATTR: @@ -1807,9 +1810,7 @@ compiler_class(struct compiler *c, stmt_ty s) /* 5. generate the rest of the code for the call */ if (!compiler_call_helper(c, 2, s->v.ClassDef.bases, - s->v.ClassDef.keywords, - s->v.ClassDef.starargs, - s->v.ClassDef.kwargs)) + s->v.ClassDef.keywords)) return 0; /* 6. apply decorators */ @@ -2851,6 +2852,40 @@ compiler_boolop(struct compiler *c, expr_ty e) return 1; } + static int +starunpack_helper(struct compiler *c, asdl_seq *elts, int single_op, + int inner_op, int outer_op) +{ + int n = asdl_seq_LEN(elts); + int i, nsubitems = 0, nseen = 0; + for (i = 0; i < n; i++) { + expr_ty elt = asdl_seq_GET(elts, i); + if (elt->kind == Starred_kind) { + if (nseen) { + ADDOP_I(c, inner_op, nseen); + nseen = 0; + nsubitems++; + } + VISIT(c, expr, elt->v.Starred.value); + nsubitems++; + } + else { + VISIT(c, expr, elt); + nseen++; + } + } + if (nsubitems) { + if (nseen) { + ADDOP_I(c, inner_op, nseen); + nsubitems++; + } + ADDOP_I(c, outer_op, nsubitems); + } + else + ADDOP_I(c, single_op, nseen); + return 1; +} + static int compiler_list(struct compiler *c, expr_ty e) { @@ -2877,10 +2912,11 @@ compiler_list(struct compiler *c, expr_ty e) ADDOP_I(c, UNPACK_SEQUENCE, n); } } - VISIT_SEQ(c, expr, e->v.List.elts); - if (e->v.List.ctx == Load) { - ADDOP_I(c, BUILD_LIST, n); - } + if (e->v.List.ctx == Load) + return starunpack_helper(c, e->v.List.elts, BUILD_LIST, + BUILD_TUPLE, BUILD_LIST_UNPACK); + else + VISIT_SEQ(c, expr, e->v.List.elts); return 1; } @@ -2910,14 +2946,22 @@ compiler_tuple(struct compiler *c, expr_ty e) ADDOP_I(c, UNPACK_SEQUENCE, n); } } - VISIT_SEQ(c, expr, e->v.Tuple.elts); - if (e->v.Tuple.ctx == Load) { - ADDOP_I(c, BUILD_TUPLE, n); - } + if (e->v.Tuple.ctx == Load) + return starunpack_helper(c, e->v.Tuple.elts, BUILD_TUPLE, + BUILD_TUPLE, BUILD_TUPLE_UNPACK); + else + VISIT_SEQ(c, expr, e->v.Tuple.elts); return 1; } static int +compiler_set(struct compiler *c, expr_ty e) +{ + return starunpack_helper(c, e->v.Set.elts, BUILD_SET, + BUILD_SET, BUILD_SET_UNPACK); +} + +static int compiler_compare(struct compiler *c, expr_ty e) { int i, n; @@ -2968,9 +3012,7 @@ compiler_call(struct compiler *c, expr_ty e) VISIT(c, expr, e->v.Call.func); return compiler_call_helper(c, 0, e->v.Call.args, - e->v.Call.keywords, - e->v.Call.starargs, - e->v.Call.kwargs); + e->v.Call.keywords); } /* shared code between compiler_call and compiler_class */ @@ -2978,26 +3020,118 @@ static int compiler_call_helper(struct compiler *c, int n, /* Args already pushed */ asdl_seq *args, - asdl_seq *keywords, - expr_ty starargs, - expr_ty kwargs) + asdl_seq *keywords) { int code = 0; - n += asdl_seq_LEN(args); - VISIT_SEQ(c, expr, args); - if (keywords) { - VISIT_SEQ(c, keyword, keywords); - n |= asdl_seq_LEN(keywords) << 8; + int nelts; + int i, nsubitems, nseen, nkw = 0; + nsubitems = 0; + nseen = 0; + nelts = asdl_seq_LEN(args); + for (i = 0; i < nelts; i++) { + expr_ty elt = asdl_seq_GET(args, i); + if (elt->kind == Starred_kind) { + /* A star-arg. If this isn't the first, + and we've seen normal positional arguments + since, pack the positional arguments into a + tuple. */ + if (nseen) { + ADDOP_I(c, BUILD_TUPLE, nseen); + nseen = 0; + nsubitems++; + } + VISIT(c, expr, elt->v.Starred.value); + nsubitems++; + } + else if (nsubitems) { + /* We've seen star-args already, so we + count towards items-to-pack-into-tuple. */ + VISIT(c, expr, elt); + nseen++; + } + else { + /* positional argument before any star-arg + hanky-panky, we just leave it on the stack. */ + VISIT(c, expr, elt); + n++; + } + } + if (nseen) { + /* Pack up any trailing positional arguments */ + ADDOP_I(c, BUILD_TUPLE, nseen); + nsubitems++; + } + if (nsubitems > 1) { + /* If we ended up with more than one stararg, we need + to concatenate them into a single sequence. */ + ADDOP_I(c, BUILD_LIST_UNPACK, nsubitems); + code |= 1; } - if (starargs) { - VISIT(c, expr, starargs); + else if (nsubitems) { code |= 1; +} + /* Same dance again for keyword arguments */ + nseen = 0; + nsubitems = 0; + nelts = asdl_seq_LEN(keywords); + for (i = 0; i < nelts; i++) { + keyword_ty kw = asdl_seq_GET(keywords, i); + if (kw->arg == NULL) { + /* A starstar-kwarg. Because we need to use + BUILD_MAP and STORE_SUBSCR to store + keyword arguments as we visit them, + we just need to flag that subsequent + keyword arguments should be stored in a new + dict, and count the previous dict. */ + if (nseen) { + nseen = 0; + nsubitems++; + } + VISIT(c, expr, kw->value); + nsubitems++; + } + else if (nsubitems) { + /* This code would be a lot simpler if we had + a BUILD_MAP opcode that acted like BUILD_LIST */ + if (!nseen) + ADDOP(c, BUILD_MAP); + /* Odd dance because of STORE_SUBSCR's odd-ish + stack order: , + and it eats the dict. In normal dict building, + the value is evaluated before the key, but + for keyword arguments this doesn't matter, + since the keyword is always a constant. */ + ADDOP(c, DUP_TOP); + VISIT(c, expr, kw->value); + ADDOP(c, ROT_TWO); + ADDOP_O(c, LOAD_CONST, kw->arg, consts); + ADDOP(c, STORE_SUBSCR); + } + else { + VISIT(c, keyword, kw) + nkw++; + } + } + if (nseen) { + /* Count the last built map */ + nsubitems++; + } + if (nsubitems > 1) { + /* Pack it all up */ + ADDOP_I(c, BUILD_MAP_UNPACK, nsubitems); + code |= 2; } - if (kwargs) { - VISIT(c, expr, kwargs); + else if (nsubitems) { code |= 2; } + assert(n < 1<<8); + assert(nkw < 1<<24); + n |= nkw << 8; + + if (code != 0) { + printf("Code %d\n", code); + } switch (code) { case 0: ADDOP_I(c, CALL_FUNCTION, n); @@ -3041,7 +3175,8 @@ compiler_comprehension_generator(struct compiler *c, comprehension_ty gen; basicblock *start, *anchor, *skip, *if_cleanup; - int i, n; + basicblock *innerstart, *inneranchor; + int i, n, is_star = 0; start = compiler_new_block(c); skip = compiler_new_block(c); @@ -3084,21 +3219,41 @@ compiler_comprehension_generator(struct compiler *c, elt, val, type)) return 0; + if (elt->kind == Starred_kind && + type != COMP_DICTCOMP) { + elt = elt->v.Starred.value; + is_star = 1; + innerstart = compiler_new_block(c); + inneranchor = compiler_new_block(c); + if (innerstart == NULL || inneranchor == NULL) + return 0; + } + /* only append after the last for generator */ if (gen_index >= asdl_seq_LEN(generators)) { + /* Dictcomps can't be using unpacking-*, and need + elements visited in a different order. */ + if (type != COMP_DICTCOMP) + VISIT(c, expr, elt); + if (is_star) { + ADDOP(c, GET_ITER); + compiler_use_next_block(c, innerstart); + ADDOP_JREL(c, FOR_ITER, inneranchor); + NEXT_BLOCK(c); + } + /* comprehension specific code */ switch (type) { case COMP_GENEXP: - VISIT(c, expr, elt); ADDOP(c, YIELD_VALUE); ADDOP(c, POP_TOP); break; case COMP_LISTCOMP: - VISIT(c, expr, elt); + //ADDOP(c, ROT_TWO); ADDOP_I(c, LIST_APPEND, gen_index + 1); break; case COMP_SETCOMP: - VISIT(c, expr, elt); + //ADDOP(c, ROT_TWO); ADDOP_I(c, SET_ADD, gen_index + 1); break; case COMP_DICTCOMP: @@ -3111,7 +3266,11 @@ compiler_comprehension_generator(struct compiler *c, default: return 0; } - + if (is_star) { + ADDOP_JABS(c, JUMP_ABSOLUTE, innerstart); + compiler_use_next_block(c, inneranchor); + } + compiler_use_next_block(c, skip); } compiler_use_next_block(c, if_cleanup); @@ -3250,6 +3409,45 @@ compiler_dictcomp(struct compiler *c, expr_ty e) e->v.DictComp.key, e->v.DictComp.value); } +static int +compiler_yield(struct compiler *c, expr_ty e) +{ + int is_star = 0; + expr_ty elt = e->v.Yield.value; + + if (c->u->u_ste->ste_type != FunctionBlock) + return compiler_error(c, "'yield' outside function"); + if (elt && elt->kind == Starred_kind) { + is_star = 1; + elt = elt->v.Starred.value; + } + if (elt) { + VISIT(c, expr, elt); + } + else { + ADDOP_O(c, LOAD_CONST, Py_None, consts); + } + if (is_star) { + basicblock *start, *anchor; + + start = compiler_new_block(c); + anchor = compiler_new_block(c); + if (start == NULL || anchor == NULL) + return 0; + ADDOP(c, GET_ITER); + compiler_use_next_block(c, start); + ADDOP_JREL(c, FOR_ITER, anchor); + NEXT_BLOCK(c); + ADDOP(c, YIELD_VALUE); + ADDOP(c, POP_TOP); + ADDOP_JABS(c, JUMP_ABSOLUTE, start); + compiler_use_next_block(c, anchor); + ADDOP_O(c, LOAD_CONST, Py_None, consts); + } + else + ADDOP(c, YIELD_VALUE); + return 1; +} static int compiler_visit_keyword(struct compiler *c, keyword_ty k) @@ -3419,10 +3617,7 @@ compiler_visit_expr(struct compiler *c, expr_ty e) } break; case Set_kind: - n = asdl_seq_LEN(e->v.Set.elts); - VISIT_SEQ(c, expr, e->v.Set.elts); - ADDOP_I(c, BUILD_SET, n); - break; + return compiler_set(c, e); case GeneratorExp_kind: return compiler_genexp(c, e); case ListComp_kind: @@ -3432,16 +3627,7 @@ compiler_visit_expr(struct compiler *c, expr_ty e) case DictComp_kind: return compiler_dictcomp(c, e); case Yield_kind: - if (c->u->u_ste->ste_type != FunctionBlock) - return compiler_error(c, "'yield' outside function"); - if (e->v.Yield.value) { - VISIT(c, expr, e->v.Yield.value); - } - else { - ADDOP_O(c, LOAD_CONST, Py_None, consts); - } - ADDOP(c, YIELD_VALUE); - break; + return compiler_yield(c, e); case YieldFrom_kind: if (c->u->u_ste->ste_type != FunctionBlock) return compiler_error(c, "'yield' outside function"); @@ -3533,7 +3719,7 @@ compiler_visit_expr(struct compiler *c, expr_ty e) "starred assignment target must be in a list or tuple"); default: return compiler_error(c, - "can use starred expression only as assignment target"); + "can't use starred expression here"); } break; case Name_kind: diff --git a/Python/graminit.c b/Python/graminit.c index e04999b..eec0c69 100644 --- a/Python/graminit.c +++ b/Python/graminit.c @@ -1661,61 +1661,50 @@ static state states_73[8] = { static arc arcs_74_0[3] = { {163, 1}, {31, 2}, - {32, 3}, + {32, 2}, }; static arc arcs_74_1[2] = { - {30, 4}, + {30, 3}, {0, 1}, }; static arc arcs_74_2[1] = { - {24, 5}, -}; -static arc arcs_74_3[1] = { - {24, 6}, + {24, 4}, }; -static arc arcs_74_4[4] = { +static arc arcs_74_3[4] = { {163, 1}, {31, 2}, - {32, 3}, - {0, 4}, -}; -static arc arcs_74_5[2] = { - {30, 7}, - {0, 5}, -}; -static arc arcs_74_6[1] = { - {0, 6}, + {32, 2}, + {0, 3}, }; -static arc arcs_74_7[2] = { - {163, 5}, - {32, 3}, +static arc arcs_74_4[2] = { + {30, 0}, + {0, 4}, }; -static state states_74[8] = { +static state states_74[5] = { {3, arcs_74_0}, {2, arcs_74_1}, {1, arcs_74_2}, - {1, arcs_74_3}, - {4, arcs_74_4}, - {2, arcs_74_5}, - {1, arcs_74_6}, - {2, arcs_74_7}, + {4, arcs_74_3}, + {2, arcs_74_4}, }; -static arc arcs_75_0[1] = { +static arc arcs_75_0[3] = { {24, 1}, + {31, 2}, + {32, 2}, }; static arc arcs_75_1[3] = { - {158, 2}, - {29, 3}, + {158, 3}, + {29, 2}, {0, 1}, }; static arc arcs_75_2[1] = { - {0, 2}, + {24, 3}, }; static arc arcs_75_3[1] = { - {24, 2}, + {0, 3}, }; static state states_75[4] = { - {1, arcs_75_0}, + {3, arcs_75_0}, {3, arcs_75_1}, {1, arcs_75_2}, {1, arcs_75_3}, @@ -1966,10 +1955,10 @@ static dfa dfas[82] = { "\000\040\040\000\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000\000"}, {329, "classdef", 0, 8, states_73, "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000"}, - {330, "arglist", 0, 8, states_74, + {330, "arglist", 0, 5, states_74, "\000\040\040\200\001\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000\000"}, {331, "argument", 0, 4, states_75, - "\000\040\040\000\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000\000"}, + "\000\040\040\200\001\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000\000"}, {332, "comp_iter", 0, 2, states_76, "\000\000\000\000\000\000\000\000\000\000\000\020\001\000\000\000\000\000\000\000\000\000"}, {333, "comp_for", 0, 6, states_77, diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h index f90a17a..86888b2 100644 --- a/Python/opcode_targets.h +++ b/Python/opcode_targets.h @@ -148,10 +148,10 @@ static void *opcode_targets[256] = { &&TARGET_SET_ADD, &&TARGET_MAP_ADD, &&TARGET_LOAD_CLASSDEREF, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, + &&TARGET_BUILD_LIST_UNPACK, + &&TARGET_BUILD_MAP_UNPACK, + &&TARGET_BUILD_TUPLE_UNPACK, + &&TARGET_BUILD_SET_UNPACK, &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, diff --git a/Python/symtable.c b/Python/symtable.c index da164aa..4d159aa 100644 --- a/Python/symtable.c +++ b/Python/symtable.c @@ -1201,10 +1201,6 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) VISIT_QUIT(st, 0); VISIT_SEQ(st, expr, s->v.ClassDef.bases); VISIT_SEQ(st, keyword, s->v.ClassDef.keywords); - if (s->v.ClassDef.starargs) - VISIT(st, expr, s->v.ClassDef.starargs); - if (s->v.ClassDef.kwargs) - VISIT(st, expr, s->v.ClassDef.kwargs); if (s->v.ClassDef.decorator_list) VISIT_SEQ(st, expr, s->v.ClassDef.decorator_list); if (!symtable_enter_block(st, s->v.ClassDef.name, ClassBlock, @@ -1452,10 +1448,6 @@ symtable_visit_expr(struct symtable *st, expr_ty e) VISIT(st, expr, e->v.Call.func); VISIT_SEQ(st, expr, e->v.Call.args); VISIT_SEQ(st, keyword, e->v.Call.keywords); - if (e->v.Call.starargs) - VISIT(st, expr, e->v.Call.starargs); - if (e->v.Call.kwargs) - VISIT(st, expr, e->v.Call.kwargs); break; case Num_kind: case Str_kind: