mirror of
https://github.com/python/cpython.git
synced 2025-07-17 08:15:19 +00:00
PEP 448: additional unpacking generalizations (closes #2292)
Patch by Neil Girdhar.
This commit is contained in:
parent
4ccc1514d0
commit
025e9ebd0a
26 changed files with 2664 additions and 2118 deletions
|
@ -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);
|
||||
|
@ -812,7 +806,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;
|
||||
|
@ -884,7 +878,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;
|
||||
|
@ -1207,9 +1201,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) {
|
||||
|
@ -1224,8 +1218,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;
|
||||
|
@ -1885,8 +1877,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) {
|
||||
|
@ -1901,8 +1893,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;
|
||||
|
@ -2276,11 +2266,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");
|
||||
|
@ -2442,16 +2427,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)
|
||||
|
@ -2964,16 +2939,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);
|
||||
|
@ -3875,8 +3840,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;
|
||||
|
||||
|
@ -3939,26 +3902,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;
|
||||
|
@ -4007,8 +3950,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;
|
||||
}
|
||||
|
@ -5506,8 +5449,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;
|
||||
|
@ -5568,28 +5509,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;
|
||||
}
|
||||
|
@ -6737,7 +6657,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;
|
||||
|
@ -6745,8 +6665,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;
|
||||
|
|
338
Python/ast.c
338
Python/ast.c
|
@ -235,9 +235,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) &&
|
||||
|
@ -322,9 +320,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:
|
||||
|
@ -848,7 +844,8 @@ static const char* FORBIDDEN[] = {
|
|||
};
|
||||
|
||||
static int
|
||||
forbidden_name(struct compiling *c, identifier name, const node *n, int full_checks)
|
||||
forbidden_name(struct compiling *c, identifier name, const node *n,
|
||||
int full_checks)
|
||||
{
|
||||
assert(PyUnicode_Check(name));
|
||||
if (PyUnicode_CompareWithASCIIString(name, "__debug__") == 0) {
|
||||
|
@ -1445,7 +1442,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;
|
||||
|
@ -1735,16 +1732,22 @@ ast_for_comprehension(struct compiling *c, const node *n)
|
|||
static expr_ty
|
||||
ast_for_itercomp(struct compiling *c, const node *n, int type)
|
||||
{
|
||||
/* testlist_comp: test ( comp_for | (',' test)* [','] )
|
||||
argument: [test '='] test [comp_for] # Really [keyword '='] test */
|
||||
/* testlist_comp: (test|star_expr)
|
||||
* ( comp_for | (',' (test|star_expr))* [','] ) */
|
||||
expr_ty elt;
|
||||
asdl_seq *comps;
|
||||
node *ch;
|
||||
|
||||
assert(NCH(n) > 1);
|
||||
|
||||
elt = ast_for_expr(c, CHILD(n, 0));
|
||||
ch = CHILD(n, 0);
|
||||
elt = ast_for_expr(c, ch);
|
||||
if (!elt)
|
||||
return NULL;
|
||||
if (elt->kind == Starred_kind) {
|
||||
ast_error(c, ch, "iterable unpacking cannot be used in comprehension");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
comps = ast_for_comprehension(c, CHILD(n, 1));
|
||||
if (!comps)
|
||||
|
@ -1761,29 +1764,98 @@ ast_for_itercomp(struct compiling *c, const node *n, int type)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Fills in the key, value pair corresponding to the dict element. In case
|
||||
* of an unpacking, key is NULL. *i is advanced by the number of ast
|
||||
* elements. Iff successful, nonzero is returned.
|
||||
*/
|
||||
static int
|
||||
ast_for_dictelement(struct compiling *c, const node *n, int *i,
|
||||
expr_ty *key, expr_ty *value)
|
||||
{
|
||||
expr_ty expression;
|
||||
if (TYPE(CHILD(n, *i)) == DOUBLESTAR) {
|
||||
assert(NCH(n) - *i >= 2);
|
||||
|
||||
expression = ast_for_expr(c, CHILD(n, *i + 1));
|
||||
if (!expression)
|
||||
return 0;
|
||||
*key = NULL;
|
||||
*value = expression;
|
||||
|
||||
*i += 2;
|
||||
}
|
||||
else {
|
||||
assert(NCH(n) - *i >= 3);
|
||||
|
||||
expression = ast_for_expr(c, CHILD(n, *i));
|
||||
if (!expression)
|
||||
return 0;
|
||||
*key = expression;
|
||||
|
||||
REQ(CHILD(n, *i + 1), COLON);
|
||||
|
||||
expression = ast_for_expr(c, CHILD(n, *i + 2));
|
||||
if (!expression)
|
||||
return 0;
|
||||
*value = expression;
|
||||
|
||||
*i += 3;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static expr_ty
|
||||
ast_for_dictcomp(struct compiling *c, const node *n)
|
||||
{
|
||||
expr_ty key, value;
|
||||
asdl_seq *comps;
|
||||
int i = 0;
|
||||
|
||||
assert(NCH(n) > 3);
|
||||
REQ(CHILD(n, 1), COLON);
|
||||
|
||||
key = ast_for_expr(c, CHILD(n, 0));
|
||||
if (!key)
|
||||
return NULL;
|
||||
value = ast_for_expr(c, CHILD(n, 2));
|
||||
if (!value)
|
||||
if (!ast_for_dictelement(c, n, &i, &key, &value))
|
||||
return NULL;
|
||||
assert(key);
|
||||
assert(NCH(n) - i >= 1);
|
||||
|
||||
comps = ast_for_comprehension(c, CHILD(n, 3));
|
||||
comps = ast_for_comprehension(c, CHILD(n, i));
|
||||
if (!comps)
|
||||
return NULL;
|
||||
|
||||
return DictComp(key, value, comps, LINENO(n), n->n_col_offset, c->c_arena);
|
||||
}
|
||||
|
||||
static expr_ty
|
||||
ast_for_dictdisplay(struct compiling *c, const node *n)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
int size;
|
||||
asdl_seq *keys, *values;
|
||||
|
||||
size = (NCH(n) + 1) / 3; /* +1 in case no trailing comma */
|
||||
keys = _Py_asdl_seq_new(size, c->c_arena);
|
||||
if (!keys)
|
||||
return NULL;
|
||||
|
||||
values = _Py_asdl_seq_new(size, c->c_arena);
|
||||
if (!values)
|
||||
return NULL;
|
||||
|
||||
j = 0;
|
||||
for (i = 0; i < NCH(n); i++) {
|
||||
expr_ty key, value;
|
||||
|
||||
if (!ast_for_dictelement(c, n, &i, &key, &value))
|
||||
return NULL;
|
||||
asdl_seq_SET(keys, j, key);
|
||||
asdl_seq_SET(values, j, value);
|
||||
|
||||
j++;
|
||||
}
|
||||
keys->size = j;
|
||||
values->size = j;
|
||||
return Dict(keys, values, LINENO(n), n->n_col_offset, c->c_arena);
|
||||
}
|
||||
|
||||
static expr_ty
|
||||
ast_for_genexp(struct compiling *c, const node *n)
|
||||
{
|
||||
|
@ -1805,6 +1877,27 @@ ast_for_setcomp(struct compiling *c, const node *n)
|
|||
return ast_for_itercomp(c, n, COMP_SETCOMP);
|
||||
}
|
||||
|
||||
static expr_ty
|
||||
ast_for_setdisplay(struct compiling *c, const node *n)
|
||||
{
|
||||
int i;
|
||||
int size;
|
||||
asdl_seq *elts;
|
||||
|
||||
assert(TYPE(n) == (dictorsetmaker));
|
||||
size = (NCH(n) + 1) / 2; /* +1 in case no trailing comma */
|
||||
elts = _Py_asdl_seq_new(size, c->c_arena);
|
||||
if (!elts)
|
||||
return NULL;
|
||||
for (i = 0; i < NCH(n); i += 2) {
|
||||
expr_ty expression;
|
||||
expression = ast_for_expr(c, CHILD(n, i));
|
||||
if (!expression)
|
||||
return NULL;
|
||||
asdl_seq_SET(elts, i / 2, expression);
|
||||
}
|
||||
return Set(elts, LINENO(n), n->n_col_offset, c->c_arena);
|
||||
}
|
||||
|
||||
static expr_ty
|
||||
ast_for_atom(struct compiling *c, const node *n)
|
||||
|
@ -1915,62 +2008,42 @@ ast_for_atom(struct compiling *c, const node *n)
|
|||
else
|
||||
return ast_for_listcomp(c, ch);
|
||||
case LBRACE: {
|
||||
/* dictorsetmaker: test ':' test (',' test ':' test)* [','] |
|
||||
* test (gen_for | (',' test)* [',']) */
|
||||
int i, size;
|
||||
asdl_seq *keys, *values;
|
||||
|
||||
/* dictorsetmaker: ( ((test ':' test | '**' test)
|
||||
* (comp_for | (',' (test ':' test | '**' test))* [','])) |
|
||||
* ((test | '*' test)
|
||||
* (comp_for | (',' (test | '*' test))* [','])) ) */
|
||||
ch = CHILD(n, 1);
|
||||
if (TYPE(ch) == RBRACE) {
|
||||
/* it's an empty dict */
|
||||
/* It's an empty dict. */
|
||||
return Dict(NULL, NULL, LINENO(n), n->n_col_offset, c->c_arena);
|
||||
} else if (NCH(ch) == 1 || TYPE(CHILD(ch, 1)) == COMMA) {
|
||||
/* it's a simple set */
|
||||
asdl_seq *elts;
|
||||
size = (NCH(ch) + 1) / 2; /* +1 in case no trailing comma */
|
||||
elts = _Py_asdl_seq_new(size, c->c_arena);
|
||||
if (!elts)
|
||||
return NULL;
|
||||
for (i = 0; i < NCH(ch); i += 2) {
|
||||
expr_ty expression;
|
||||
expression = ast_for_expr(c, CHILD(ch, i));
|
||||
if (!expression)
|
||||
return NULL;
|
||||
asdl_seq_SET(elts, i / 2, expression);
|
||||
}
|
||||
else {
|
||||
int is_dict = (TYPE(CHILD(ch, 0)) == DOUBLESTAR);
|
||||
if (NCH(ch) == 1 ||
|
||||
(NCH(ch) > 1 &&
|
||||
TYPE(CHILD(ch, 1)) == COMMA)) {
|
||||
/* It's a set display. */
|
||||
return ast_for_setdisplay(c, ch);
|
||||
}
|
||||
return Set(elts, LINENO(n), n->n_col_offset, c->c_arena);
|
||||
} else if (TYPE(CHILD(ch, 1)) == comp_for) {
|
||||
/* it's a set comprehension */
|
||||
return ast_for_setcomp(c, ch);
|
||||
} else if (NCH(ch) > 3 && TYPE(CHILD(ch, 3)) == comp_for) {
|
||||
return ast_for_dictcomp(c, ch);
|
||||
} else {
|
||||
/* it's a dict */
|
||||
size = (NCH(ch) + 1) / 4; /* +1 in case no trailing comma */
|
||||
keys = _Py_asdl_seq_new(size, c->c_arena);
|
||||
if (!keys)
|
||||
return NULL;
|
||||
|
||||
values = _Py_asdl_seq_new(size, c->c_arena);
|
||||
if (!values)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < NCH(ch); i += 4) {
|
||||
expr_ty expression;
|
||||
|
||||
expression = ast_for_expr(c, CHILD(ch, i));
|
||||
if (!expression)
|
||||
return NULL;
|
||||
|
||||
asdl_seq_SET(keys, i / 4, expression);
|
||||
|
||||
expression = ast_for_expr(c, CHILD(ch, i + 2));
|
||||
if (!expression)
|
||||
return NULL;
|
||||
|
||||
asdl_seq_SET(values, i / 4, expression);
|
||||
else if (NCH(ch) > 1 &&
|
||||
TYPE(CHILD(ch, 1)) == comp_for) {
|
||||
/* It's a set comprehension. */
|
||||
return ast_for_setcomp(c, ch);
|
||||
}
|
||||
else if (NCH(ch) > 3 - is_dict &&
|
||||
TYPE(CHILD(ch, 3 - is_dict)) == comp_for) {
|
||||
/* It's a dictionary comprehension. */
|
||||
if (is_dict) {
|
||||
ast_error(c, n, "dict unpacking cannot be used in "
|
||||
"dict comprehension");
|
||||
return NULL;
|
||||
}
|
||||
return ast_for_dictcomp(c, ch);
|
||||
}
|
||||
else {
|
||||
/* It's a dictionary display. */
|
||||
return ast_for_dictdisplay(c, ch);
|
||||
}
|
||||
return Dict(keys, values, LINENO(n), n->n_col_offset, c->c_arena);
|
||||
}
|
||||
}
|
||||
default:
|
||||
|
@ -2106,7 +2179,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
|
||||
return ast_for_call(c, CHILD(n, 1), left_expr);
|
||||
|
@ -2415,15 +2488,14 @@ static expr_ty
|
|||
ast_for_call(struct compiling *c, const node *n, expr_ty func)
|
||||
{
|
||||
/*
|
||||
arglist: (argument ',')* (argument [',']| '*' test [',' '**' test]
|
||||
| '**' test)
|
||||
argument: [test '='] (test) [comp_for] # Really [keyword '='] test
|
||||
arglist: argument (',' argument)* [',']
|
||||
argument: ( test [comp_for] | '*' test | test '=' test | '**' test )
|
||||
*/
|
||||
|
||||
int i, nargs, nkeywords, ngens;
|
||||
int ndoublestars;
|
||||
asdl_seq *args;
|
||||
asdl_seq *keywords;
|
||||
expr_ty vararg = NULL, kwarg = NULL;
|
||||
|
||||
REQ(n, arglist);
|
||||
|
||||
|
@ -2437,7 +2509,10 @@ 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
|
||||
/* TYPE(CHILD(ch, 0)) == DOUBLESTAR or keyword argument */
|
||||
nkeywords++;
|
||||
}
|
||||
}
|
||||
|
@ -2458,41 +2533,82 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func)
|
|||
keywords = _Py_asdl_seq_new(nkeywords, c->c_arena);
|
||||
if (!keywords)
|
||||
return NULL;
|
||||
nargs = 0;
|
||||
nkeywords = 0;
|
||||
|
||||
nargs = 0; /* positional arguments + iterable argument unpackings */
|
||||
nkeywords = 0; /* keyword arguments + keyword argument unpackings */
|
||||
ndoublestars = 0; /* just keyword argument unpackings */
|
||||
for (i = 0; i < NCH(n); i++) {
|
||||
node *ch = CHILD(n, i);
|
||||
if (TYPE(ch) == argument) {
|
||||
expr_ty e;
|
||||
node *chch = CHILD(ch, 0);
|
||||
if (NCH(ch) == 1) {
|
||||
if (nkeywords) {
|
||||
ast_error(c, CHILD(ch, 0),
|
||||
"non-keyword arg after keyword arg");
|
||||
return NULL;
|
||||
if (TYPE(chch) == star_expr) {
|
||||
/* an iterable argument unpacking */
|
||||
expr_ty starred;
|
||||
if (ndoublestars) {
|
||||
ast_error(c, chch,
|
||||
"iterable argument unpacking follows "
|
||||
"keyword argument unpacking");
|
||||
return NULL;
|
||||
}
|
||||
e = ast_for_expr(c, CHILD(chch, 1));
|
||||
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);
|
||||
}
|
||||
if (vararg) {
|
||||
ast_error(c, CHILD(ch, 0),
|
||||
"only named arguments may follow *expression");
|
||||
return NULL;
|
||||
else {
|
||||
/* a positional argument */
|
||||
if (nkeywords) {
|
||||
if (ndoublestars) {
|
||||
ast_error(c, chch,
|
||||
"positional argument follows "
|
||||
"keyword argument unpacking");
|
||||
}
|
||||
else {
|
||||
ast_error(c, chch,
|
||||
"positional argument follows "
|
||||
"keyword argument");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
e = ast_for_expr(c, chch);
|
||||
if (!e)
|
||||
return NULL;
|
||||
asdl_seq_SET(args, nargs++, e);
|
||||
}
|
||||
e = ast_for_expr(c, CHILD(ch, 0));
|
||||
}
|
||||
else if (TYPE(chch) == DOUBLESTAR) {
|
||||
/* a keyword argument unpacking */
|
||||
keyword_ty kw;
|
||||
i++;
|
||||
e = ast_for_expr(c, CHILD(ch, 1));
|
||||
if (!e)
|
||||
return NULL;
|
||||
asdl_seq_SET(args, nargs++, e);
|
||||
kw = keyword(NULL, e, c->c_arena);
|
||||
asdl_seq_SET(keywords, nkeywords++, kw);
|
||||
ndoublestars++;
|
||||
}
|
||||
else if (TYPE(CHILD(ch, 1)) == comp_for) {
|
||||
/* the lone generator expression */
|
||||
e = ast_for_genexp(c, ch);
|
||||
if (!e)
|
||||
return NULL;
|
||||
asdl_seq_SET(args, nargs++, e);
|
||||
}
|
||||
else {
|
||||
/* a keyword argument */
|
||||
keyword_ty kw;
|
||||
identifier key, tmp;
|
||||
int k;
|
||||
|
||||
/* CHILD(ch, 0) is test, but must be an identifier? */
|
||||
e = ast_for_expr(c, CHILD(ch, 0));
|
||||
/* chch is test, but must be an identifier? */
|
||||
e = ast_for_expr(c, chch);
|
||||
if (!e)
|
||||
return NULL;
|
||||
/* f(lambda x: x[0] = 3) ends up getting parsed with
|
||||
|
@ -2501,19 +2617,24 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func)
|
|||
* then is very confusing.
|
||||
*/
|
||||
if (e->kind == Lambda_kind) {
|
||||
ast_error(c, CHILD(ch, 0), "lambda cannot contain assignment");
|
||||
ast_error(c, chch,
|
||||
"lambda cannot contain assignment");
|
||||
return NULL;
|
||||
} else if (e->kind != Name_kind) {
|
||||
ast_error(c, CHILD(ch, 0), "keyword can't be an expression");
|
||||
}
|
||||
else if (e->kind != Name_kind) {
|
||||
ast_error(c, chch,
|
||||
"keyword can't be an expression");
|
||||
return NULL;
|
||||
} else if (forbidden_name(c, e->v.Name.id, ch, 1)) {
|
||||
}
|
||||
else if (forbidden_name(c, e->v.Name.id, ch, 1)) {
|
||||
return NULL;
|
||||
}
|
||||
key = e->v.Name.id;
|
||||
for (k = 0; k < nkeywords; k++) {
|
||||
tmp = ((keyword_ty)asdl_seq_GET(keywords, k))->arg;
|
||||
if (!PyUnicode_Compare(tmp, key)) {
|
||||
ast_error(c, CHILD(ch, 0), "keyword argument repeated");
|
||||
if (tmp && !PyUnicode_Compare(tmp, key)) {
|
||||
ast_error(c, chch,
|
||||
"keyword argument repeated");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
@ -2526,21 +2647,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
|
||||
|
@ -3520,8 +3629,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 */
|
||||
|
@ -3533,8 +3642,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 */
|
||||
|
@ -3559,8 +3668,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);
|
||||
}
|
||||
|
||||
|
|
164
Python/ceval.c
164
Python/ceval.c
|
@ -12,8 +12,10 @@
|
|||
#include "Python.h"
|
||||
|
||||
#include "code.h"
|
||||
#include "dictobject.h"
|
||||
#include "frameobject.h"
|
||||
#include "opcode.h"
|
||||
#include "setobject.h"
|
||||
#include "structmember.h"
|
||||
|
||||
#include <ctype.h>
|
||||
|
@ -2379,6 +2381,43 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
|
|||
DISPATCH();
|
||||
}
|
||||
|
||||
TARGET_WITH_IMPL(BUILD_TUPLE_UNPACK, _build_list_unpack)
|
||||
TARGET(BUILD_LIST_UNPACK)
|
||||
_build_list_unpack: {
|
||||
int convert_to_tuple = opcode == BUILD_TUPLE_UNPACK;
|
||||
int i;
|
||||
PyObject *sum = PyList_New(0);
|
||||
PyObject *return_value;
|
||||
if (sum == NULL)
|
||||
goto error;
|
||||
|
||||
for (i = oparg; i > 0; i--) {
|
||||
PyObject *none_val;
|
||||
|
||||
none_val = _PyList_Extend((PyListObject *)sum, PEEK(i));
|
||||
if (none_val == NULL) {
|
||||
Py_DECREF(sum);
|
||||
goto error;
|
||||
}
|
||||
Py_DECREF(none_val);
|
||||
}
|
||||
|
||||
if (convert_to_tuple) {
|
||||
return_value = PyList_AsTuple(sum);
|
||||
Py_DECREF(sum);
|
||||
if (return_value == NULL)
|
||||
goto error;
|
||||
}
|
||||
else {
|
||||
return_value = sum;
|
||||
}
|
||||
|
||||
while (oparg--)
|
||||
Py_DECREF(POP());
|
||||
PUSH(return_value);
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
TARGET(BUILD_SET) {
|
||||
PyObject *set = PySet_New(NULL);
|
||||
int err = 0;
|
||||
|
@ -2398,14 +2437,127 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
|
|||
DISPATCH();
|
||||
}
|
||||
|
||||
TARGET(BUILD_SET_UNPACK) {
|
||||
int i;
|
||||
PyObject *sum = PySet_New(NULL);
|
||||
if (sum == NULL)
|
||||
goto error;
|
||||
|
||||
for (i = oparg; i > 0; i--) {
|
||||
if (_PySet_Update(sum, PEEK(i)) < 0) {
|
||||
Py_DECREF(sum);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
while (oparg--)
|
||||
Py_DECREF(POP());
|
||||
PUSH(sum);
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
TARGET(BUILD_MAP) {
|
||||
PyObject *map = _PyDict_NewPresized((Py_ssize_t)oparg);
|
||||
if (map == NULL)
|
||||
goto error;
|
||||
while (--oparg >= 0) {
|
||||
int err;
|
||||
PyObject *key = TOP();
|
||||
PyObject *value = SECOND();
|
||||
STACKADJ(-2);
|
||||
err = PyDict_SetItem(map, key, value);
|
||||
Py_DECREF(value);
|
||||
Py_DECREF(key);
|
||||
if (err != 0) {
|
||||
Py_DECREF(map);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
PUSH(map);
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
TARGET_WITH_IMPL(BUILD_MAP_UNPACK_WITH_CALL, _build_map_unpack)
|
||||
TARGET(BUILD_MAP_UNPACK)
|
||||
_build_map_unpack: {
|
||||
int with_call = opcode == BUILD_MAP_UNPACK_WITH_CALL;
|
||||
int num_maps;
|
||||
int function_location;
|
||||
int i;
|
||||
PyObject *sum = PyDict_New();
|
||||
if (sum == NULL)
|
||||
goto error;
|
||||
if (with_call) {
|
||||
num_maps = oparg & 0xff;
|
||||
function_location = (oparg>>8) & 0xff;
|
||||
}
|
||||
else {
|
||||
num_maps = oparg;
|
||||
}
|
||||
|
||||
for (i = num_maps; i > 0; i--) {
|
||||
PyObject *arg = PEEK(i);
|
||||
if (with_call) {
|
||||
PyObject *intersection = _PyDictView_Intersect(sum, arg);
|
||||
|
||||
if (intersection == NULL) {
|
||||
if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
|
||||
PyObject *func = (
|
||||
PEEK(function_location + num_maps));
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"%.200s%.200s argument after ** "
|
||||
"must be a mapping, not %.200s",
|
||||
PyEval_GetFuncName(func),
|
||||
PyEval_GetFuncDesc(func),
|
||||
arg->ob_type->tp_name);
|
||||
}
|
||||
Py_DECREF(sum);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (PySet_GET_SIZE(intersection)) {
|
||||
Py_ssize_t idx = 0;
|
||||
PyObject *key;
|
||||
PyObject *func = PEEK(function_location + num_maps);
|
||||
Py_hash_t hash;
|
||||
_PySet_NextEntry(intersection, &idx, &key, &hash);
|
||||
if (!PyUnicode_Check(key)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"%.200s%.200s keywords must be strings",
|
||||
PyEval_GetFuncName(func),
|
||||
PyEval_GetFuncDesc(func));
|
||||
} else {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"%.200s%.200s got multiple "
|
||||
"values for keyword argument '%U'",
|
||||
PyEval_GetFuncName(func),
|
||||
PyEval_GetFuncDesc(func),
|
||||
key);
|
||||
}
|
||||
Py_DECREF(intersection);
|
||||
Py_DECREF(sum);
|
||||
goto error;
|
||||
}
|
||||
Py_DECREF(intersection);
|
||||
}
|
||||
|
||||
if (PyDict_Update(sum, arg) < 0) {
|
||||
if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"'%.200s' object is not a mapping",
|
||||
arg->ob_type->tp_name);
|
||||
}
|
||||
Py_DECREF(sum);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
while (num_maps--)
|
||||
Py_DECREF(POP());
|
||||
PUSH(sum);
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
TARGET(STORE_MAP) {
|
||||
PyObject *key = TOP();
|
||||
PyObject *value = SECOND();
|
||||
|
@ -3050,6 +3202,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
|
|||
goto dispatch_opcode;
|
||||
}
|
||||
|
||||
|
||||
#if USE_COMPUTED_GOTOS
|
||||
_unknown_opcode:
|
||||
#endif
|
||||
|
@ -4557,6 +4710,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)) {
|
||||
|
@ -4578,11 +4737,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;
|
||||
|
|
319
Python/compile.c
319
Python/compile.c
|
@ -195,9 +195,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, Py_ssize_t 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 *);
|
||||
|
||||
|
@ -672,7 +670,8 @@ compiler_set_qualname(struct compiler *c)
|
|||
PyObject *mangled, *capsule;
|
||||
|
||||
capsule = PyList_GET_ITEM(c->c_stack, stack_size - 1);
|
||||
parent = (struct compiler_unit *)PyCapsule_GetPointer(capsule, COMPILER_CAPSULE_NAME_COMPILER_UNIT);
|
||||
parent = (struct compiler_unit *)PyCapsule_GetPointer(
|
||||
capsule, COMPILER_CAPSULE_NAME_COMPILER_UNIT);
|
||||
assert(parent);
|
||||
|
||||
if (u->u_scope_type == COMPILER_SCOPE_FUNCTION || u->u_scope_type == COMPILER_SCOPE_CLASS) {
|
||||
|
@ -973,6 +972,13 @@ PyCompile_OpcodeStackEffect(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_UNPACK_WITH_CALL:
|
||||
return 1 - (oparg & 0xFF);
|
||||
case BUILD_MAP:
|
||||
return 1;
|
||||
case LOAD_ATTR:
|
||||
|
@ -1821,9 +1827,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 */
|
||||
|
@ -2870,68 +2874,146 @@ 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)
|
||||
{
|
||||
Py_ssize_t n = asdl_seq_LEN(elts);
|
||||
Py_ssize_t 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
|
||||
assignment_helper(struct compiler *c, asdl_seq *elts)
|
||||
{
|
||||
Py_ssize_t n = asdl_seq_LEN(elts);
|
||||
Py_ssize_t i;
|
||||
int seen_star = 0;
|
||||
for (i = 0; i < n; i++) {
|
||||
expr_ty elt = asdl_seq_GET(elts, i);
|
||||
if (elt->kind == Starred_kind && !seen_star) {
|
||||
if ((i >= (1 << 8)) ||
|
||||
(n-i-1 >= (INT_MAX >> 8)))
|
||||
return compiler_error(c,
|
||||
"too many expressions in "
|
||||
"star-unpacking assignment");
|
||||
ADDOP_I(c, UNPACK_EX, (i + ((n-i-1) << 8)));
|
||||
seen_star = 1;
|
||||
asdl_seq_SET(elts, i, elt->v.Starred.value);
|
||||
}
|
||||
else if (elt->kind == Starred_kind) {
|
||||
return compiler_error(c,
|
||||
"two starred expressions in assignment");
|
||||
}
|
||||
}
|
||||
if (!seen_star) {
|
||||
ADDOP_I(c, UNPACK_SEQUENCE, n);
|
||||
}
|
||||
VISIT_SEQ(c, expr, elts);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
compiler_list(struct compiler *c, expr_ty e)
|
||||
{
|
||||
Py_ssize_t n = asdl_seq_LEN(e->v.List.elts);
|
||||
asdl_seq *elts = e->v.List.elts;
|
||||
if (e->v.List.ctx == Store) {
|
||||
int i, seen_star = 0;
|
||||
for (i = 0; i < n; i++) {
|
||||
expr_ty elt = asdl_seq_GET(e->v.List.elts, i);
|
||||
if (elt->kind == Starred_kind && !seen_star) {
|
||||
if ((i >= (1 << 8)) ||
|
||||
(n-i-1 >= (INT_MAX >> 8)))
|
||||
return compiler_error(c,
|
||||
"too many expressions in "
|
||||
"star-unpacking assignment");
|
||||
ADDOP_I(c, UNPACK_EX, (i + ((n-i-1) << 8)));
|
||||
seen_star = 1;
|
||||
asdl_seq_SET(e->v.List.elts, i, elt->v.Starred.value);
|
||||
} else if (elt->kind == Starred_kind) {
|
||||
return compiler_error(c,
|
||||
"two starred expressions in assignment");
|
||||
}
|
||||
}
|
||||
if (!seen_star) {
|
||||
ADDOP_I(c, UNPACK_SEQUENCE, n);
|
||||
}
|
||||
return assignment_helper(c, elts);
|
||||
}
|
||||
VISIT_SEQ(c, expr, e->v.List.elts);
|
||||
if (e->v.List.ctx == Load) {
|
||||
ADDOP_I(c, BUILD_LIST, n);
|
||||
else if (e->v.List.ctx == Load) {
|
||||
return starunpack_helper(c, elts,
|
||||
BUILD_LIST, BUILD_TUPLE, BUILD_LIST_UNPACK);
|
||||
}
|
||||
else
|
||||
VISIT_SEQ(c, expr, elts);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
compiler_tuple(struct compiler *c, expr_ty e)
|
||||
{
|
||||
Py_ssize_t n = asdl_seq_LEN(e->v.Tuple.elts);
|
||||
asdl_seq *elts = e->v.Tuple.elts;
|
||||
if (e->v.Tuple.ctx == Store) {
|
||||
int i, seen_star = 0;
|
||||
for (i = 0; i < n; i++) {
|
||||
expr_ty elt = asdl_seq_GET(e->v.Tuple.elts, i);
|
||||
if (elt->kind == Starred_kind && !seen_star) {
|
||||
if ((i >= (1 << 8)) ||
|
||||
(n-i-1 >= (INT_MAX >> 8)))
|
||||
return compiler_error(c,
|
||||
"too many expressions in "
|
||||
"star-unpacking assignment");
|
||||
ADDOP_I(c, UNPACK_EX, (i + ((n-i-1) << 8)));
|
||||
seen_star = 1;
|
||||
asdl_seq_SET(e->v.Tuple.elts, i, elt->v.Starred.value);
|
||||
} else if (elt->kind == Starred_kind) {
|
||||
return compiler_error(c,
|
||||
"two starred expressions in assignment");
|
||||
}
|
||||
return assignment_helper(c, elts);
|
||||
}
|
||||
else if (e->v.Tuple.ctx == Load) {
|
||||
return starunpack_helper(c, elts,
|
||||
BUILD_TUPLE, BUILD_TUPLE, BUILD_TUPLE_UNPACK);
|
||||
}
|
||||
else
|
||||
VISIT_SEQ(c, expr, 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_dict(struct compiler *c, expr_ty e)
|
||||
{
|
||||
Py_ssize_t i, n, containers, elements;
|
||||
int is_unpacking = 0;
|
||||
n = asdl_seq_LEN(e->v.Dict.values);
|
||||
containers = 0;
|
||||
elements = 0;
|
||||
for (i = 0; i < n; i++) {
|
||||
is_unpacking = (expr_ty)asdl_seq_GET(e->v.Dict.keys, i) == NULL;
|
||||
if (elements == 0xFFFF || (elements && is_unpacking)) {
|
||||
ADDOP_I(c, BUILD_MAP, elements);
|
||||
containers++;
|
||||
elements = 0;
|
||||
}
|
||||
if (!seen_star) {
|
||||
ADDOP_I(c, UNPACK_SEQUENCE, n);
|
||||
if (is_unpacking) {
|
||||
VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.values, i));
|
||||
containers++;
|
||||
}
|
||||
else {
|
||||
VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.values, i));
|
||||
VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.keys, i));
|
||||
elements++;
|
||||
}
|
||||
}
|
||||
VISIT_SEQ(c, expr, e->v.Tuple.elts);
|
||||
if (e->v.Tuple.ctx == Load) {
|
||||
ADDOP_I(c, BUILD_TUPLE, n);
|
||||
if (elements || containers == 0) {
|
||||
ADDOP_I(c, BUILD_MAP, elements);
|
||||
containers++;
|
||||
}
|
||||
/* If there is more than one dict, they need to be merged into a new
|
||||
* dict. If there is one dict and it's an unpacking, then it needs
|
||||
* to be copied into a new dict." */
|
||||
while (containers > 1 || is_unpacking) {
|
||||
int oparg = containers < 255 ? containers : 255;
|
||||
ADDOP_I(c, BUILD_MAP_UNPACK, oparg);
|
||||
containers -= (oparg - 1);
|
||||
is_unpacking = 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -2987,9 +3069,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 */
|
||||
|
@ -2997,26 +3077,102 @@ static int
|
|||
compiler_call_helper(struct compiler *c,
|
||||
Py_ssize_t n, /* Args already pushed */
|
||||
asdl_seq *args,
|
||||
asdl_seq *keywords,
|
||||
expr_ty starargs,
|
||||
expr_ty kwargs)
|
||||
asdl_seq *keywords)
|
||||
{
|
||||
int code = 0;
|
||||
Py_ssize_t nelts, i, nseen, nkw;
|
||||
|
||||
n += asdl_seq_LEN(args);
|
||||
VISIT_SEQ(c, expr, args);
|
||||
if (keywords) {
|
||||
VISIT_SEQ(c, keyword, keywords);
|
||||
n |= asdl_seq_LEN(keywords) << 8;
|
||||
/* the number of tuples and dictionaries on the stack */
|
||||
Py_ssize_t nsubargs = 0, nsubkwargs = 0;
|
||||
|
||||
nkw = 0;
|
||||
nseen = 0; /* the number of positional arguments on the stack */
|
||||
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 we've seen positional arguments,
|
||||
pack the positional arguments into a
|
||||
tuple. */
|
||||
if (nseen) {
|
||||
ADDOP_I(c, BUILD_TUPLE, nseen);
|
||||
nseen = 0;
|
||||
nsubargs++;
|
||||
}
|
||||
VISIT(c, expr, elt->v.Starred.value);
|
||||
nsubargs++;
|
||||
}
|
||||
else if (nsubargs) {
|
||||
/* We've seen star-args already, so we
|
||||
count towards items-to-pack-into-tuple. */
|
||||
VISIT(c, expr, elt);
|
||||
nseen++;
|
||||
}
|
||||
else {
|
||||
/* Positional arguments before star-arguments
|
||||
are left on the stack. */
|
||||
VISIT(c, expr, elt);
|
||||
n++;
|
||||
}
|
||||
}
|
||||
if (starargs) {
|
||||
VISIT(c, expr, starargs);
|
||||
if (nseen) {
|
||||
/* Pack up any trailing positional arguments. */
|
||||
ADDOP_I(c, BUILD_TUPLE, nseen);
|
||||
nsubargs++;
|
||||
}
|
||||
if (nsubargs) {
|
||||
code |= 1;
|
||||
if (nsubargs > 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, nsubargs);
|
||||
}
|
||||
}
|
||||
if (kwargs) {
|
||||
VISIT(c, expr, kwargs);
|
||||
|
||||
/* Same dance again for keyword arguments */
|
||||
nseen = 0; /* the number of keyword arguments on the stack following */
|
||||
nelts = asdl_seq_LEN(keywords);
|
||||
for (i = 0; i < nelts; i++) {
|
||||
keyword_ty kw = asdl_seq_GET(keywords, i);
|
||||
if (kw->arg == NULL) {
|
||||
/* A keyword argument unpacking. */
|
||||
if (nseen) {
|
||||
ADDOP_I(c, BUILD_MAP, nseen);
|
||||
nseen = 0;
|
||||
nsubkwargs++;
|
||||
}
|
||||
VISIT(c, expr, kw->value);
|
||||
nsubkwargs++;
|
||||
}
|
||||
else if (nsubkwargs) {
|
||||
/* A keyword argument and we already have a dict. */
|
||||
VISIT(c, expr, kw->value);
|
||||
ADDOP_O(c, LOAD_CONST, kw->arg, consts);
|
||||
nseen++;
|
||||
}
|
||||
else {
|
||||
/* keyword argument */
|
||||
VISIT(c, keyword, kw)
|
||||
nkw++;
|
||||
}
|
||||
}
|
||||
if (nseen) {
|
||||
/* Pack up any trailing keyword arguments. */
|
||||
ADDOP_I(c, BUILD_MAP, nseen);
|
||||
nsubkwargs++;
|
||||
}
|
||||
if (nsubkwargs) {
|
||||
code |= 2;
|
||||
if (nsubkwargs > 1) {
|
||||
/* Pack it all up */
|
||||
int function_pos = n + (code & 1) + nkw + 1;
|
||||
ADDOP_I(c, BUILD_MAP_UNPACK_WITH_CALL, nsubkwargs | (function_pos << 8));
|
||||
}
|
||||
}
|
||||
assert(n < 1<<8);
|
||||
assert(nkw < 1<<24);
|
||||
n |= nkw << 8;
|
||||
|
||||
switch (code) {
|
||||
case 0:
|
||||
ADDOP_I(c, CALL_FUNCTION, n);
|
||||
|
@ -3141,8 +3297,9 @@ compiler_comprehension_generator(struct compiler *c,
|
|||
}
|
||||
|
||||
static int
|
||||
compiler_comprehension(struct compiler *c, expr_ty e, int type, identifier name,
|
||||
asdl_seq *generators, expr_ty elt, expr_ty val)
|
||||
compiler_comprehension(struct compiler *c, expr_ty e, int type,
|
||||
identifier name, asdl_seq *generators, expr_ty elt,
|
||||
expr_ty val)
|
||||
{
|
||||
PyCodeObject *co = NULL;
|
||||
expr_ty outermost_iter;
|
||||
|
@ -3399,8 +3556,6 @@ compiler_with(struct compiler *c, stmt_ty s, int pos)
|
|||
static int
|
||||
compiler_visit_expr(struct compiler *c, expr_ty e)
|
||||
{
|
||||
Py_ssize_t i, n;
|
||||
|
||||
/* If expr e has a different line number than the last expr/stmt,
|
||||
set a new line number for the next instruction.
|
||||
*/
|
||||
|
@ -3427,23 +3582,9 @@ compiler_visit_expr(struct compiler *c, expr_ty e)
|
|||
case IfExp_kind:
|
||||
return compiler_ifexp(c, e);
|
||||
case Dict_kind:
|
||||
n = asdl_seq_LEN(e->v.Dict.values);
|
||||
/* BUILD_MAP parameter is only used to preallocate the dictionary,
|
||||
it doesn't need to be exact */
|
||||
ADDOP_I(c, BUILD_MAP, (n>0xFFFF ? 0xFFFF : n));
|
||||
for (i = 0; i < n; i++) {
|
||||
VISIT(c, expr,
|
||||
(expr_ty)asdl_seq_GET(e->v.Dict.values, i));
|
||||
VISIT(c, expr,
|
||||
(expr_ty)asdl_seq_GET(e->v.Dict.keys, i));
|
||||
ADDOP(c, STORE_MAP);
|
||||
}
|
||||
break;
|
||||
return compiler_dict(c, e);
|
||||
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:
|
||||
|
@ -3554,7 +3695,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:
|
||||
|
|
|
@ -1569,60 +1569,78 @@ static state states_71[3] = {
|
|||
{2, arcs_71_1},
|
||||
{2, arcs_71_2},
|
||||
};
|
||||
static arc arcs_72_0[1] = {
|
||||
static arc arcs_72_0[3] = {
|
||||
{24, 1},
|
||||
{32, 2},
|
||||
{48, 3},
|
||||
};
|
||||
static arc arcs_72_1[4] = {
|
||||
{25, 2},
|
||||
{159, 3},
|
||||
{30, 4},
|
||||
{25, 4},
|
||||
{159, 5},
|
||||
{30, 6},
|
||||
{0, 1},
|
||||
};
|
||||
static arc arcs_72_2[1] = {
|
||||
{24, 5},
|
||||
{104, 7},
|
||||
};
|
||||
static arc arcs_72_3[1] = {
|
||||
static arc arcs_72_3[3] = {
|
||||
{159, 5},
|
||||
{30, 6},
|
||||
{0, 3},
|
||||
};
|
||||
static arc arcs_72_4[2] = {
|
||||
{24, 6},
|
||||
{0, 4},
|
||||
static arc arcs_72_4[1] = {
|
||||
{24, 7},
|
||||
};
|
||||
static arc arcs_72_5[3] = {
|
||||
{159, 3},
|
||||
{30, 7},
|
||||
static arc arcs_72_5[1] = {
|
||||
{0, 5},
|
||||
};
|
||||
static arc arcs_72_6[2] = {
|
||||
{30, 4},
|
||||
static arc arcs_72_6[3] = {
|
||||
{24, 8},
|
||||
{48, 8},
|
||||
{0, 6},
|
||||
};
|
||||
static arc arcs_72_7[2] = {
|
||||
{24, 8},
|
||||
static arc arcs_72_7[3] = {
|
||||
{159, 5},
|
||||
{30, 9},
|
||||
{0, 7},
|
||||
};
|
||||
static arc arcs_72_8[1] = {
|
||||
{25, 9},
|
||||
static arc arcs_72_8[2] = {
|
||||
{30, 6},
|
||||
{0, 8},
|
||||
};
|
||||
static arc arcs_72_9[1] = {
|
||||
static arc arcs_72_9[3] = {
|
||||
{24, 10},
|
||||
{32, 11},
|
||||
{0, 9},
|
||||
};
|
||||
static arc arcs_72_10[2] = {
|
||||
{30, 7},
|
||||
{0, 10},
|
||||
static arc arcs_72_10[1] = {
|
||||
{25, 12},
|
||||
};
|
||||
static state states_72[11] = {
|
||||
{1, arcs_72_0},
|
||||
static arc arcs_72_11[1] = {
|
||||
{104, 13},
|
||||
};
|
||||
static arc arcs_72_12[1] = {
|
||||
{24, 13},
|
||||
};
|
||||
static arc arcs_72_13[2] = {
|
||||
{30, 9},
|
||||
{0, 13},
|
||||
};
|
||||
static state states_72[14] = {
|
||||
{3, arcs_72_0},
|
||||
{4, arcs_72_1},
|
||||
{1, arcs_72_2},
|
||||
{1, arcs_72_3},
|
||||
{2, arcs_72_4},
|
||||
{3, arcs_72_5},
|
||||
{2, arcs_72_6},
|
||||
{2, arcs_72_7},
|
||||
{1, arcs_72_8},
|
||||
{1, arcs_72_9},
|
||||
{2, arcs_72_10},
|
||||
{3, arcs_72_3},
|
||||
{1, arcs_72_4},
|
||||
{1, arcs_72_5},
|
||||
{3, arcs_72_6},
|
||||
{3, arcs_72_7},
|
||||
{2, arcs_72_8},
|
||||
{3, arcs_72_9},
|
||||
{1, arcs_72_10},
|
||||
{1, arcs_72_11},
|
||||
{1, arcs_72_12},
|
||||
{2, arcs_72_13},
|
||||
};
|
||||
static arc arcs_73_0[1] = {
|
||||
{163, 1},
|
||||
|
@ -1660,67 +1678,47 @@ static state states_73[8] = {
|
|||
{1, arcs_73_6},
|
||||
{1, arcs_73_7},
|
||||
};
|
||||
static arc arcs_74_0[3] = {
|
||||
static arc arcs_74_0[1] = {
|
||||
{164, 1},
|
||||
{31, 2},
|
||||
{32, 3},
|
||||
};
|
||||
static arc arcs_74_1[2] = {
|
||||
{30, 4},
|
||||
{30, 2},
|
||||
{0, 1},
|
||||
};
|
||||
static arc arcs_74_2[1] = {
|
||||
{24, 5},
|
||||
};
|
||||
static arc arcs_74_3[1] = {
|
||||
{24, 6},
|
||||
};
|
||||
static arc arcs_74_4[4] = {
|
||||
static arc arcs_74_2[2] = {
|
||||
{164, 1},
|
||||
{31, 2},
|
||||
{32, 3},
|
||||
{0, 4},
|
||||
{0, 2},
|
||||
};
|
||||
static arc arcs_74_5[2] = {
|
||||
{30, 7},
|
||||
{0, 5},
|
||||
};
|
||||
static arc arcs_74_6[1] = {
|
||||
{0, 6},
|
||||
};
|
||||
static arc arcs_74_7[2] = {
|
||||
{164, 5},
|
||||
{32, 3},
|
||||
};
|
||||
static state states_74[8] = {
|
||||
{3, arcs_74_0},
|
||||
static state states_74[3] = {
|
||||
{1, 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},
|
||||
{2, arcs_74_2},
|
||||
};
|
||||
static arc arcs_75_0[1] = {
|
||||
static arc arcs_75_0[3] = {
|
||||
{24, 1},
|
||||
{32, 2},
|
||||
{48, 3},
|
||||
};
|
||||
static arc arcs_75_1[3] = {
|
||||
{159, 2},
|
||||
{29, 3},
|
||||
{159, 3},
|
||||
{29, 4},
|
||||
{0, 1},
|
||||
};
|
||||
static arc arcs_75_2[1] = {
|
||||
{0, 2},
|
||||
{104, 3},
|
||||
};
|
||||
static arc arcs_75_3[1] = {
|
||||
{24, 2},
|
||||
{0, 3},
|
||||
};
|
||||
static state states_75[4] = {
|
||||
{1, arcs_75_0},
|
||||
static arc arcs_75_4[1] = {
|
||||
{24, 3},
|
||||
};
|
||||
static state states_75[5] = {
|
||||
{3, arcs_75_0},
|
||||
{3, arcs_75_1},
|
||||
{1, arcs_75_2},
|
||||
{1, arcs_75_3},
|
||||
{1, arcs_75_4},
|
||||
};
|
||||
static arc arcs_76_0[2] = {
|
||||
{159, 1},
|
||||
|
@ -1964,14 +1962,14 @@ static dfa dfas[82] = {
|
|||
"\000\040\040\200\000\000\000\000\000\000\001\000\000\000\000\000\000\014\241\174\000\000"},
|
||||
{327, "testlist", 0, 3, states_71,
|
||||
"\000\040\040\000\000\000\000\000\000\000\001\000\000\000\041\000\000\014\241\174\000\000"},
|
||||
{328, "dictorsetmaker", 0, 11, states_72,
|
||||
"\000\040\040\000\000\000\000\000\000\000\001\000\000\000\041\000\000\014\241\174\000\000"},
|
||||
{328, "dictorsetmaker", 0, 14, states_72,
|
||||
"\000\040\040\200\001\000\000\000\000\000\001\000\000\000\041\000\000\014\241\174\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\010\000"},
|
||||
{330, "arglist", 0, 8, states_74,
|
||||
{330, "arglist", 0, 3, states_74,
|
||||
"\000\040\040\200\001\000\000\000\000\000\001\000\000\000\041\000\000\014\241\174\000\000"},
|
||||
{331, "argument", 0, 5, states_75,
|
||||
"\000\040\040\200\001\000\000\000\000\000\001\000\000\000\041\000\000\014\241\174\000\000"},
|
||||
{331, "argument", 0, 4, states_75,
|
||||
"\000\040\040\000\000\000\000\000\000\000\001\000\000\000\041\000\000\014\241\174\000\000"},
|
||||
{332, "comp_iter", 0, 2, states_76,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\040\002\000\000\000\000\000\000\000\000\000"},
|
||||
{333, "comp_for", 0, 6, states_77,
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -148,11 +148,11 @@ static void *opcode_targets[256] = {
|
|||
&&TARGET_SET_ADD,
|
||||
&&TARGET_MAP_ADD,
|
||||
&&TARGET_LOAD_CLASSDEREF,
|
||||
&&_unknown_opcode,
|
||||
&&_unknown_opcode,
|
||||
&&_unknown_opcode,
|
||||
&&_unknown_opcode,
|
||||
&&_unknown_opcode,
|
||||
&&TARGET_BUILD_LIST_UNPACK,
|
||||
&&TARGET_BUILD_MAP_UNPACK,
|
||||
&&TARGET_BUILD_MAP_UNPACK_WITH_CALL,
|
||||
&&TARGET_BUILD_TUPLE_UNPACK,
|
||||
&&TARGET_BUILD_SET_UNPACK,
|
||||
&&_unknown_opcode,
|
||||
&&_unknown_opcode,
|
||||
&&_unknown_opcode,
|
||||
|
|
|
@ -1083,13 +1083,13 @@ error:
|
|||
} \
|
||||
}
|
||||
|
||||
#define VISIT_KWONLYDEFAULTS(ST, KW_DEFAULTS) { \
|
||||
#define VISIT_SEQ_WITH_NULL(ST, TYPE, SEQ) { \
|
||||
int i = 0; \
|
||||
asdl_seq *seq = (KW_DEFAULTS); /* avoid variable capture */ \
|
||||
asdl_seq *seq = (SEQ); /* avoid variable capture */ \
|
||||
for (i = 0; i < asdl_seq_LEN(seq); i++) { \
|
||||
expr_ty elt = (expr_ty)asdl_seq_GET(seq, i); \
|
||||
TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \
|
||||
if (!elt) continue; /* can be NULL */ \
|
||||
if (!symtable_visit_expr((ST), elt)) \
|
||||
if (!symtable_visit_ ## TYPE((ST), elt)) \
|
||||
VISIT_QUIT((ST), 0); \
|
||||
} \
|
||||
}
|
||||
|
@ -1146,8 +1146,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
|
|||
if (s->v.FunctionDef.args->defaults)
|
||||
VISIT_SEQ(st, expr, s->v.FunctionDef.args->defaults);
|
||||
if (s->v.FunctionDef.args->kw_defaults)
|
||||
VISIT_KWONLYDEFAULTS(st,
|
||||
s->v.FunctionDef.args->kw_defaults);
|
||||
VISIT_SEQ_WITH_NULL(st, expr, s->v.FunctionDef.args->kw_defaults);
|
||||
if (!symtable_visit_annotations(st, s))
|
||||
VISIT_QUIT(st, 0);
|
||||
if (s->v.FunctionDef.decorator_list)
|
||||
|
@ -1167,10 +1166,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,
|
||||
|
@ -1349,8 +1344,7 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
|
|||
if (e->v.Lambda.args->defaults)
|
||||
VISIT_SEQ(st, expr, e->v.Lambda.args->defaults);
|
||||
if (e->v.Lambda.args->kw_defaults)
|
||||
VISIT_KWONLYDEFAULTS(st,
|
||||
e->v.Lambda.args->kw_defaults);
|
||||
VISIT_SEQ_WITH_NULL(st, expr, e->v.Lambda.args->kw_defaults);
|
||||
if (!symtable_enter_block(st, lambda,
|
||||
FunctionBlock, (void *)e, e->lineno,
|
||||
e->col_offset))
|
||||
|
@ -1367,7 +1361,7 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
|
|||
VISIT(st, expr, e->v.IfExp.orelse);
|
||||
break;
|
||||
case Dict_kind:
|
||||
VISIT_SEQ(st, expr, e->v.Dict.keys);
|
||||
VISIT_SEQ_WITH_NULL(st, expr, e->v.Dict.keys);
|
||||
VISIT_SEQ(st, expr, e->v.Dict.values);
|
||||
break;
|
||||
case Set_kind:
|
||||
|
@ -1405,11 +1399,7 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
|
|||
case Call_kind:
|
||||
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);
|
||||
VISIT_SEQ_WITH_NULL(st, keyword, e->v.Call.keywords);
|
||||
break;
|
||||
case Num_kind:
|
||||
case Str_kind:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue