diff options
author | shadchin <shadchin@yandex-team.ru> | 2022-02-10 16:44:30 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:44:30 +0300 |
commit | 2598ef1d0aee359b4b6d5fdd1758916d5907d04f (patch) | |
tree | 012bb94d777798f1f56ac1cec429509766d05181 /contrib/tools/python3/src/Python/symtable.c | |
parent | 6751af0b0c1b952fede40b19b71da8025b5d8bcf (diff) | |
download | ydb-2598ef1d0aee359b4b6d5fdd1758916d5907d04f.tar.gz |
Restoring authorship annotation for <shadchin@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/tools/python3/src/Python/symtable.c')
-rw-r--r-- | contrib/tools/python3/src/Python/symtable.c | 494 |
1 files changed, 247 insertions, 247 deletions
diff --git a/contrib/tools/python3/src/Python/symtable.c b/contrib/tools/python3/src/Python/symtable.c index d192f31dee..11bf28d873 100644 --- a/contrib/tools/python3/src/Python/symtable.c +++ b/contrib/tools/python3/src/Python/symtable.c @@ -1,8 +1,8 @@ #include "Python.h" -#include "pycore_pystate.h" // _PyThreadState_GET() +#include "pycore_pystate.h" // _PyThreadState_GET() #include "symtable.h" -#undef Yield /* undefine macro conflicting with <winbase.h> */ -#include "structmember.h" // PyMemberDef +#undef Yield /* undefine macro conflicting with <winbase.h> */ +#include "structmember.h" // PyMemberDef /* error strings used for warnings */ #define GLOBAL_PARAM \ @@ -31,18 +31,18 @@ #define IMPORT_STAR_WARNING "import * only allowed at module level" -#define NAMED_EXPR_COMP_IN_CLASS \ -"assignment expression within a comprehension cannot be used in a class body" - -#define NAMED_EXPR_COMP_CONFLICT \ -"assignment expression cannot rebind comprehension iteration variable '%U'" - -#define NAMED_EXPR_COMP_INNER_LOOP_CONFLICT \ -"comprehension inner loop cannot rebind assignment expression target '%U'" - -#define NAMED_EXPR_COMP_ITER_EXPR \ -"assignment expression cannot be used in a comprehension iterable expression" - +#define NAMED_EXPR_COMP_IN_CLASS \ +"assignment expression within a comprehension cannot be used in a class body" + +#define NAMED_EXPR_COMP_CONFLICT \ +"assignment expression cannot rebind comprehension iteration variable '%U'" + +#define NAMED_EXPR_COMP_INNER_LOOP_CONFLICT \ +"comprehension inner loop cannot rebind assignment expression target '%U'" + +#define NAMED_EXPR_COMP_ITER_EXPR \ +"assignment expression cannot be used in a comprehension iterable expression" + static PySTEntryObject * ste_new(struct symtable *st, identifier name, _Py_block_ty block, void *key, int lineno, int col_offset) @@ -87,11 +87,11 @@ ste_new(struct symtable *st, identifier name, _Py_block_ty block, ste->ste_child_free = 0; ste->ste_generator = 0; ste->ste_coroutine = 0; - ste->ste_comprehension = 0; + ste->ste_comprehension = 0; ste->ste_returns_value = 0; ste->ste_needs_class_closure = 0; - ste->ste_comp_iter_target = 0; - ste->ste_comp_iter_expr = 0; + ste->ste_comp_iter_target = 0; + ste->ste_comp_iter_expr = 0; ste->ste_symbols = PyDict_New(); ste->ste_varnames = PyList_New(0); @@ -151,10 +151,10 @@ PyTypeObject PySTEntry_Type = { sizeof(PySTEntryObject), 0, (destructor)ste_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_as_async */ + 0, /* tp_as_async */ (reprfunc)ste_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -190,7 +190,7 @@ static int symtable_analyze(struct symtable *st); static int symtable_enter_block(struct symtable *st, identifier name, _Py_block_ty block, void *ast, int lineno, int col_offset); -static int symtable_exit_block(struct symtable *st); +static int symtable_exit_block(struct symtable *st); static int symtable_visit_stmt(struct symtable *st, stmt_ty s); static int symtable_visit_expr(struct symtable *st, expr_ty s); static int symtable_visit_genexp(struct symtable *st, expr_ty s); @@ -205,7 +205,7 @@ static int symtable_visit_keyword(struct symtable *st, keyword_ty); static int symtable_visit_params(struct symtable *st, asdl_seq *args); static int symtable_visit_argannotations(struct symtable *st, asdl_seq *args); static int symtable_implicit_arg(struct symtable *st, int pos); -static int symtable_visit_annotations(struct symtable *st, arguments_ty, expr_ty); +static int symtable_visit_annotations(struct symtable *st, arguments_ty, expr_ty); static int symtable_visit_withitem(struct symtable *st, withitem_ty item); @@ -265,7 +265,7 @@ PySymtable_BuildObject(mod_ty mod, PyObject *filename, PyFutureFeatures *future) int i; PyThreadState *tstate; int recursion_limit = Py_GetRecursionLimit(); - int starting_recursion_depth; + int starting_recursion_depth; if (st == NULL) return NULL; @@ -278,15 +278,15 @@ PySymtable_BuildObject(mod_ty mod, PyObject *filename, PyFutureFeatures *future) st->st_future = future; /* Setup recursion depth check counters */ - tstate = _PyThreadState_GET(); + tstate = _PyThreadState_GET(); if (!tstate) { PySymtable_Free(st); return NULL; } /* Be careful here to prevent overflow. */ - starting_recursion_depth = (tstate->recursion_depth < INT_MAX / COMPILER_STACK_FRAME_SCALE) ? + starting_recursion_depth = (tstate->recursion_depth < INT_MAX / COMPILER_STACK_FRAME_SCALE) ? tstate->recursion_depth * COMPILER_STACK_FRAME_SCALE : tstate->recursion_depth; - st->recursion_depth = starting_recursion_depth; + st->recursion_depth = starting_recursion_depth; st->recursion_limit = (recursion_limit < INT_MAX / COMPILER_STACK_FRAME_SCALE) ? recursion_limit * COMPILER_STACK_FRAME_SCALE : recursion_limit; @@ -317,30 +317,30 @@ PySymtable_BuildObject(mod_ty mod, PyObject *filename, PyFutureFeatures *future) (stmt_ty)asdl_seq_GET(seq, i))) goto error; break; - case FunctionType_kind: - PyErr_SetString(PyExc_RuntimeError, - "this compiler does not handle FunctionTypes"); - goto error; + case FunctionType_kind: + PyErr_SetString(PyExc_RuntimeError, + "this compiler does not handle FunctionTypes"); + goto error; } - if (!symtable_exit_block(st)) { - PySymtable_Free(st); - return NULL; - } - /* Check that the recursion depth counting balanced correctly */ - if (st->recursion_depth != starting_recursion_depth) { - PyErr_Format(PyExc_SystemError, - "symtable analysis recursion depth mismatch (before=%d, after=%d)", - starting_recursion_depth, st->recursion_depth); + if (!symtable_exit_block(st)) { PySymtable_Free(st); return NULL; } + /* Check that the recursion depth counting balanced correctly */ + if (st->recursion_depth != starting_recursion_depth) { + PyErr_Format(PyExc_SystemError, + "symtable analysis recursion depth mismatch (before=%d, after=%d)", + starting_recursion_depth, st->recursion_depth); + PySymtable_Free(st); + return NULL; + } /* Make the second symbol analysis pass */ if (symtable_analyze(st)) return st; PySymtable_Free(st); return NULL; error: - (void) symtable_exit_block(st); + (void) symtable_exit_block(st); PySymtable_Free(st); return NULL; } @@ -375,12 +375,12 @@ PySymtable_Lookup(struct symtable *st, void *key) k = PyLong_FromVoidPtr(key); if (k == NULL) return NULL; - v = PyDict_GetItemWithError(st->st_blocks, k); + v = PyDict_GetItemWithError(st->st_blocks, k); if (v) { assert(PySTEntry_Check(v)); Py_INCREF(v); } - else if (!PyErr_Occurred()) { + else if (!PyErr_Occurred()) { PyErr_SetString(PyExc_KeyError, "unknown symbol table entry"); } @@ -389,23 +389,23 @@ PySymtable_Lookup(struct symtable *st, void *key) return (PySTEntryObject *)v; } -static long -_PyST_GetSymbol(PySTEntryObject *ste, PyObject *name) +static long +_PyST_GetSymbol(PySTEntryObject *ste, PyObject *name) { PyObject *v = PyDict_GetItem(ste->ste_symbols, name); if (!v) return 0; assert(PyLong_Check(v)); - return PyLong_AS_LONG(v); -} - -int -PyST_GetScope(PySTEntryObject *ste, PyObject *name) -{ - long symbol = _PyST_GetSymbol(ste, name); - return (symbol >> SCOPE_OFFSET) & SCOPE_MASK; + return PyLong_AS_LONG(v); } +int +PyST_GetScope(PySTEntryObject *ste, PyObject *name) +{ + long symbol = _PyST_GetSymbol(ste, name); + return (symbol >> SCOPE_OFFSET) & SCOPE_MASK; +} + static int error_at_directive(PySTEntryObject *ste, PyObject *name) { @@ -419,7 +419,7 @@ error_at_directive(PySTEntryObject *ste, PyObject *name) if (PyUnicode_Compare(PyTuple_GET_ITEM(data, 0), name) == 0) { PyErr_SyntaxLocationObject(ste->ste_table->st_filename, PyLong_AsLong(PyTuple_GET_ITEM(data, 1)), - PyLong_AsLong(PyTuple_GET_ITEM(data, 2)) + 1); + PyLong_AsLong(PyTuple_GET_ITEM(data, 2)) + 1); return 0; } @@ -660,7 +660,7 @@ update_symbols(PyObject *symbols, PyObject *scopes, } while ((name = PyIter_Next(itr))) { - v = PyDict_GetItemWithError(symbols, name); + v = PyDict_GetItemWithError(symbols, name); /* Handle symbol that already exists in this scope */ if (v) { @@ -685,9 +685,9 @@ update_symbols(PyObject *symbols, PyObject *scopes, Py_DECREF(name); continue; } - else if (PyErr_Occurred()) { - goto error; - } + else if (PyErr_Occurred()) { + goto error; + } /* Handle global symbol */ if (bound && !PySet_Contains(bound, name)) { Py_DECREF(name); @@ -949,7 +949,7 @@ symtable_analyze(struct symtable *st) */ static int -symtable_exit_block(struct symtable *st) +symtable_exit_block(struct symtable *st) { Py_ssize_t size; @@ -978,13 +978,13 @@ symtable_enter_block(struct symtable *st, identifier name, _Py_block_ty block, return 0; } prev = st->st_cur; - /* bpo-37757: For now, disallow *all* assignment expressions in the - * outermost iterator expression of a comprehension, even those inside - * a nested comprehension or a lambda expression. - */ - if (prev) { - ste->ste_comp_iter_expr = prev->ste_comp_iter_expr; - } + /* bpo-37757: For now, disallow *all* assignment expressions in the + * outermost iterator expression of a comprehension, even those inside + * a nested comprehension or a lambda expression. + */ + if (prev) { + ste->ste_comp_iter_expr = prev->ste_comp_iter_expr; + } /* The entry is owned by the stack. Borrow it for st_cur. */ Py_DECREF(ste); st->st_cur = ste; @@ -1004,13 +1004,13 @@ symtable_lookup(struct symtable *st, PyObject *name) PyObject *mangled = _Py_Mangle(st->st_private, name); if (!mangled) return 0; - long ret = _PyST_GetSymbol(st->st_cur, mangled); + long ret = _PyST_GetSymbol(st->st_cur, mangled); Py_DECREF(mangled); - return ret; + return ret; } static int -symtable_add_def_helper(struct symtable *st, PyObject *name, int flag, struct _symtable_entry *ste) +symtable_add_def_helper(struct symtable *st, PyObject *name, int flag, struct _symtable_entry *ste) { PyObject *o; PyObject *dict; @@ -1020,41 +1020,41 @@ symtable_add_def_helper(struct symtable *st, PyObject *name, int flag, struct _s if (!mangled) return 0; - dict = ste->ste_symbols; - if ((o = PyDict_GetItemWithError(dict, mangled))) { + dict = ste->ste_symbols; + if ((o = PyDict_GetItemWithError(dict, mangled))) { val = PyLong_AS_LONG(o); if ((flag & DEF_PARAM) && (val & DEF_PARAM)) { /* Is it better to use 'mangled' or 'name' here? */ PyErr_Format(PyExc_SyntaxError, DUPLICATE_ARGUMENT, name); PyErr_SyntaxLocationObject(st->st_filename, - ste->ste_lineno, - ste->ste_col_offset + 1); + ste->ste_lineno, + ste->ste_col_offset + 1); goto error; } val |= flag; - } - else if (PyErr_Occurred()) { - goto error; - } - else { + } + else if (PyErr_Occurred()) { + goto error; + } + else { val = flag; - } - if (ste->ste_comp_iter_target) { - /* This name is an iteration variable in a comprehension, - * so check for a binding conflict with any named expressions. - * Otherwise, mark it as an iteration variable so subsequent - * named expressions can check for conflicts. - */ - if (val & (DEF_GLOBAL | DEF_NONLOCAL)) { - PyErr_Format(PyExc_SyntaxError, - NAMED_EXPR_COMP_INNER_LOOP_CONFLICT, name); - PyErr_SyntaxLocationObject(st->st_filename, - ste->ste_lineno, - ste->ste_col_offset + 1); - goto error; - } - val |= DEF_COMP_ITER; - } + } + if (ste->ste_comp_iter_target) { + /* This name is an iteration variable in a comprehension, + * so check for a binding conflict with any named expressions. + * Otherwise, mark it as an iteration variable so subsequent + * named expressions can check for conflicts. + */ + if (val & (DEF_GLOBAL | DEF_NONLOCAL)) { + PyErr_Format(PyExc_SyntaxError, + NAMED_EXPR_COMP_INNER_LOOP_CONFLICT, name); + PyErr_SyntaxLocationObject(st->st_filename, + ste->ste_lineno, + ste->ste_col_offset + 1); + goto error; + } + val |= DEF_COMP_ITER; + } o = PyLong_FromLong(val); if (o == NULL) goto error; @@ -1065,7 +1065,7 @@ symtable_add_def_helper(struct symtable *st, PyObject *name, int flag, struct _s Py_DECREF(o); if (flag & DEF_PARAM) { - if (PyList_Append(ste->ste_varnames, mangled) < 0) + if (PyList_Append(ste->ste_varnames, mangled) < 0) goto error; } else if (flag & DEF_GLOBAL) { /* XXX need to update DEF_GLOBAL for other flags too; @@ -1091,11 +1091,11 @@ error: return 0; } -static int -symtable_add_def(struct symtable *st, PyObject *name, int flag) { - return symtable_add_def_helper(st, name, flag, st->st_cur); -} - +static int +symtable_add_def(struct symtable *st, PyObject *name, int flag) { + return symtable_add_def_helper(st, name, flag, st->st_cur); +} + /* VISIT, VISIT_SEQ and VIST_SEQ_TAIL take an ASDL type as their second argument. They use the ASDL name to synthesize the name of the C type and the visit function. @@ -1146,7 +1146,7 @@ symtable_add_def(struct symtable *st, PyObject *name, int flag) { } static int -symtable_record_directive(struct symtable *st, identifier name, int lineno, int col_offset) +symtable_record_directive(struct symtable *st, identifier name, int lineno, int col_offset) { PyObject *data, *mangled; int res; @@ -1158,7 +1158,7 @@ symtable_record_directive(struct symtable *st, identifier name, int lineno, int mangled = _Py_Mangle(st->st_private, name); if (!mangled) return 0; - data = Py_BuildValue("(Nii)", mangled, lineno, col_offset); + data = Py_BuildValue("(Nii)", mangled, lineno, col_offset); if (!data) return 0; res = PyList_Append(st->st_cur->ste_directives, data); @@ -1183,7 +1183,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) VISIT_SEQ(st, expr, s->v.FunctionDef.args->defaults); if (s->v.FunctionDef.args->kw_defaults) VISIT_SEQ_WITH_NULL(st, expr, s->v.FunctionDef.args->kw_defaults); - if (!symtable_visit_annotations(st, s->v.FunctionDef.args, + if (!symtable_visit_annotations(st, s->v.FunctionDef.args, s->v.FunctionDef.returns)) VISIT_QUIT(st, 0); if (s->v.FunctionDef.decorator_list) @@ -1194,7 +1194,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) VISIT_QUIT(st, 0); VISIT(st, arguments, s->v.FunctionDef.args); VISIT_SEQ(st, stmt, s->v.FunctionDef.body); - if (!symtable_exit_block(st)) + if (!symtable_exit_block(st)) VISIT_QUIT(st, 0); break; case ClassDef_kind: { @@ -1212,7 +1212,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) st->st_private = s->v.ClassDef.name; VISIT_SEQ(st, stmt, s->v.ClassDef.body); st->st_private = tmp; - if (!symtable_exit_block(st)) + if (!symtable_exit_block(st)) VISIT_QUIT(st, 0); break; } @@ -1237,14 +1237,14 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) VISIT_QUIT(st, 0); } if ((cur & (DEF_GLOBAL | DEF_NONLOCAL)) - && (st->st_cur->ste_symbols != st->st_global) + && (st->st_cur->ste_symbols != st->st_global) && s->v.AnnAssign.simple) { PyErr_Format(PyExc_SyntaxError, cur & DEF_GLOBAL ? GLOBAL_ANNOT : NONLOCAL_ANNOT, e_name->v.Name.id); PyErr_SyntaxLocationObject(st->st_filename, s->lineno, - s->col_offset + 1); + s->col_offset + 1); VISIT_QUIT(st, 0); } if (s->v.AnnAssign.simple && @@ -1339,12 +1339,12 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) msg, name); PyErr_SyntaxLocationObject(st->st_filename, s->lineno, - s->col_offset + 1); + s->col_offset + 1); VISIT_QUIT(st, 0); } if (!symtable_add_def(st, name, DEF_GLOBAL)) VISIT_QUIT(st, 0); - if (!symtable_record_directive(st, name, s->lineno, s->col_offset)) + if (!symtable_record_directive(st, name, s->lineno, s->col_offset)) VISIT_QUIT(st, 0); } break; @@ -1371,12 +1371,12 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) PyErr_Format(PyExc_SyntaxError, msg, name); PyErr_SyntaxLocationObject(st->st_filename, s->lineno, - s->col_offset + 1); + s->col_offset + 1); VISIT_QUIT(st, 0); } if (!symtable_add_def(st, name, DEF_NONLOCAL)) VISIT_QUIT(st, 0); - if (!symtable_record_directive(st, name, s->lineno, s->col_offset)) + if (!symtable_record_directive(st, name, s->lineno, s->col_offset)) VISIT_QUIT(st, 0); } break; @@ -1401,7 +1401,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) if (s->v.AsyncFunctionDef.args->kw_defaults) VISIT_SEQ_WITH_NULL(st, expr, s->v.AsyncFunctionDef.args->kw_defaults); - if (!symtable_visit_annotations(st, s->v.AsyncFunctionDef.args, + if (!symtable_visit_annotations(st, s->v.AsyncFunctionDef.args, s->v.AsyncFunctionDef.returns)) VISIT_QUIT(st, 0); if (s->v.AsyncFunctionDef.decorator_list) @@ -1413,7 +1413,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) st->st_cur->ste_coroutine = 1; VISIT(st, arguments, s->v.AsyncFunctionDef.args); VISIT_SEQ(st, stmt, s->v.AsyncFunctionDef.body); - if (!symtable_exit_block(st)) + if (!symtable_exit_block(st)) VISIT_QUIT(st, 0); break; case AsyncWith_kind: @@ -1432,99 +1432,99 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) } static int -symtable_extend_namedexpr_scope(struct symtable *st, expr_ty e) -{ - assert(st->st_stack); - assert(e->kind == Name_kind); - - PyObject *target_name = e->v.Name.id; - Py_ssize_t i, size; - struct _symtable_entry *ste; - size = PyList_GET_SIZE(st->st_stack); - assert(size); - - /* Iterate over the stack in reverse and add to the nearest adequate scope */ - for (i = size - 1; i >= 0; i--) { - ste = (struct _symtable_entry *) PyList_GET_ITEM(st->st_stack, i); - - /* If we find a comprehension scope, check for a target - * binding conflict with iteration variables, otherwise skip it - */ - if (ste->ste_comprehension) { - long target_in_scope = _PyST_GetSymbol(ste, target_name); - if (target_in_scope & DEF_COMP_ITER) { - PyErr_Format(PyExc_SyntaxError, NAMED_EXPR_COMP_CONFLICT, target_name); - PyErr_SyntaxLocationObject(st->st_filename, - e->lineno, - e->col_offset); - VISIT_QUIT(st, 0); - } - continue; - } - - /* If we find a FunctionBlock entry, add as GLOBAL/LOCAL or NONLOCAL/LOCAL */ - if (ste->ste_type == FunctionBlock) { - long target_in_scope = _PyST_GetSymbol(ste, target_name); - if (target_in_scope & DEF_GLOBAL) { - if (!symtable_add_def(st, target_name, DEF_GLOBAL)) - VISIT_QUIT(st, 0); - } else { - if (!symtable_add_def(st, target_name, DEF_NONLOCAL)) - VISIT_QUIT(st, 0); - } - if (!symtable_record_directive(st, target_name, e->lineno, e->col_offset)) - VISIT_QUIT(st, 0); - - return symtable_add_def_helper(st, target_name, DEF_LOCAL, ste); - } - /* If we find a ModuleBlock entry, add as GLOBAL */ - if (ste->ste_type == ModuleBlock) { - if (!symtable_add_def(st, target_name, DEF_GLOBAL)) - VISIT_QUIT(st, 0); - if (!symtable_record_directive(st, target_name, e->lineno, e->col_offset)) - VISIT_QUIT(st, 0); - - return symtable_add_def_helper(st, target_name, DEF_GLOBAL, ste); - } - /* Disallow usage in ClassBlock */ - if (ste->ste_type == ClassBlock) { - PyErr_Format(PyExc_SyntaxError, NAMED_EXPR_COMP_IN_CLASS); - PyErr_SyntaxLocationObject(st->st_filename, - e->lineno, - e->col_offset); - VISIT_QUIT(st, 0); - } - } - - /* We should always find either a FunctionBlock, ModuleBlock or ClassBlock - and should never fall to this case - */ - assert(0); - return 0; -} - -static int -symtable_handle_namedexpr(struct symtable *st, expr_ty e) -{ - if (st->st_cur->ste_comp_iter_expr > 0) { - /* Assignment isn't allowed in a comprehension iterable expression */ - PyErr_Format(PyExc_SyntaxError, NAMED_EXPR_COMP_ITER_EXPR); - PyErr_SyntaxLocationObject(st->st_filename, - e->lineno, - e->col_offset); - return 0; - } - if (st->st_cur->ste_comprehension) { - /* Inside a comprehension body, so find the right target scope */ - if (!symtable_extend_namedexpr_scope(st, e->v.NamedExpr.target)) - return 0; - } - VISIT(st, expr, e->v.NamedExpr.value); - VISIT(st, expr, e->v.NamedExpr.target); - return 1; -} - -static int +symtable_extend_namedexpr_scope(struct symtable *st, expr_ty e) +{ + assert(st->st_stack); + assert(e->kind == Name_kind); + + PyObject *target_name = e->v.Name.id; + Py_ssize_t i, size; + struct _symtable_entry *ste; + size = PyList_GET_SIZE(st->st_stack); + assert(size); + + /* Iterate over the stack in reverse and add to the nearest adequate scope */ + for (i = size - 1; i >= 0; i--) { + ste = (struct _symtable_entry *) PyList_GET_ITEM(st->st_stack, i); + + /* If we find a comprehension scope, check for a target + * binding conflict with iteration variables, otherwise skip it + */ + if (ste->ste_comprehension) { + long target_in_scope = _PyST_GetSymbol(ste, target_name); + if (target_in_scope & DEF_COMP_ITER) { + PyErr_Format(PyExc_SyntaxError, NAMED_EXPR_COMP_CONFLICT, target_name); + PyErr_SyntaxLocationObject(st->st_filename, + e->lineno, + e->col_offset); + VISIT_QUIT(st, 0); + } + continue; + } + + /* If we find a FunctionBlock entry, add as GLOBAL/LOCAL or NONLOCAL/LOCAL */ + if (ste->ste_type == FunctionBlock) { + long target_in_scope = _PyST_GetSymbol(ste, target_name); + if (target_in_scope & DEF_GLOBAL) { + if (!symtable_add_def(st, target_name, DEF_GLOBAL)) + VISIT_QUIT(st, 0); + } else { + if (!symtable_add_def(st, target_name, DEF_NONLOCAL)) + VISIT_QUIT(st, 0); + } + if (!symtable_record_directive(st, target_name, e->lineno, e->col_offset)) + VISIT_QUIT(st, 0); + + return symtable_add_def_helper(st, target_name, DEF_LOCAL, ste); + } + /* If we find a ModuleBlock entry, add as GLOBAL */ + if (ste->ste_type == ModuleBlock) { + if (!symtable_add_def(st, target_name, DEF_GLOBAL)) + VISIT_QUIT(st, 0); + if (!symtable_record_directive(st, target_name, e->lineno, e->col_offset)) + VISIT_QUIT(st, 0); + + return symtable_add_def_helper(st, target_name, DEF_GLOBAL, ste); + } + /* Disallow usage in ClassBlock */ + if (ste->ste_type == ClassBlock) { + PyErr_Format(PyExc_SyntaxError, NAMED_EXPR_COMP_IN_CLASS); + PyErr_SyntaxLocationObject(st->st_filename, + e->lineno, + e->col_offset); + VISIT_QUIT(st, 0); + } + } + + /* We should always find either a FunctionBlock, ModuleBlock or ClassBlock + and should never fall to this case + */ + assert(0); + return 0; +} + +static int +symtable_handle_namedexpr(struct symtable *st, expr_ty e) +{ + if (st->st_cur->ste_comp_iter_expr > 0) { + /* Assignment isn't allowed in a comprehension iterable expression */ + PyErr_Format(PyExc_SyntaxError, NAMED_EXPR_COMP_ITER_EXPR); + PyErr_SyntaxLocationObject(st->st_filename, + e->lineno, + e->col_offset); + return 0; + } + if (st->st_cur->ste_comprehension) { + /* Inside a comprehension body, so find the right target scope */ + if (!symtable_extend_namedexpr_scope(st, e->v.NamedExpr.target)) + return 0; + } + VISIT(st, expr, e->v.NamedExpr.value); + VISIT(st, expr, e->v.NamedExpr.target); + return 1; +} + +static int symtable_visit_expr(struct symtable *st, expr_ty e) { if (++st->recursion_depth > st->recursion_limit) { @@ -1533,10 +1533,10 @@ symtable_visit_expr(struct symtable *st, expr_ty e) VISIT_QUIT(st, 0); } switch (e->kind) { - case NamedExpr_kind: - if(!symtable_handle_namedexpr(st, e)) - VISIT_QUIT(st, 0); - break; + case NamedExpr_kind: + if(!symtable_handle_namedexpr(st, e)) + VISIT_QUIT(st, 0); + break; case BoolOp_kind: VISIT_SEQ(st, expr, e->v.BoolOp.values); break; @@ -1560,7 +1560,7 @@ symtable_visit_expr(struct symtable *st, expr_ty e) VISIT_QUIT(st, 0); VISIT(st, arguments, e->v.Lambda.args); VISIT(st, expr, e->v.Lambda.body); - if (!symtable_exit_block(st)) + if (!symtable_exit_block(st)) VISIT_QUIT(st, 0); break; } @@ -1631,19 +1631,19 @@ symtable_visit_expr(struct symtable *st, expr_ty e) break; case Subscript_kind: VISIT(st, expr, e->v.Subscript.value); - VISIT(st, expr, e->v.Subscript.slice); + VISIT(st, expr, e->v.Subscript.slice); break; case Starred_kind: VISIT(st, expr, e->v.Starred.value); break; - case Slice_kind: - if (e->v.Slice.lower) - VISIT(st, expr, e->v.Slice.lower) - if (e->v.Slice.upper) - VISIT(st, expr, e->v.Slice.upper) - if (e->v.Slice.step) - VISIT(st, expr, e->v.Slice.step) - break; + case Slice_kind: + if (e->v.Slice.lower) + VISIT(st, expr, e->v.Slice.lower) + if (e->v.Slice.upper) + VISIT(st, expr, e->v.Slice.upper) + if (e->v.Slice.step) + VISIT(st, expr, e->v.Slice.step) + break; case Name_kind: if (!symtable_add_def(st, e->v.Name.id, e->v.Name.ctx == Load ? USE : DEF_LOCAL)) @@ -1717,10 +1717,10 @@ symtable_visit_argannotations(struct symtable *st, asdl_seq *args) } static int -symtable_visit_annotations(struct symtable *st, arguments_ty a, expr_ty returns) +symtable_visit_annotations(struct symtable *st, arguments_ty a, expr_ty returns) { - if (a->posonlyargs && !symtable_visit_argannotations(st, a->posonlyargs)) - return 0; + if (a->posonlyargs && !symtable_visit_argannotations(st, a->posonlyargs)) + return 0; if (a->args && !symtable_visit_argannotations(st, a->args)) return 0; if (a->vararg && a->vararg->annotation) @@ -1740,8 +1740,8 @@ symtable_visit_arguments(struct symtable *st, arguments_ty a) /* skip default arguments inside function block XXX should ast be different? */ - if (a->posonlyargs && !symtable_visit_params(st, a->posonlyargs)) - return 0; + if (a->posonlyargs && !symtable_visit_params(st, a->posonlyargs)) + return 0; if (a->args && !symtable_visit_params(st, a->args)) return 0; if (a->kwonlyargs && !symtable_visit_params(st, a->kwonlyargs)) @@ -1813,7 +1813,7 @@ symtable_visit_alias(struct symtable *st, alias_ty a) int lineno = st->st_cur->ste_lineno; int col_offset = st->st_cur->ste_col_offset; PyErr_SetString(PyExc_SyntaxError, IMPORT_STAR_WARNING); - PyErr_SyntaxLocationObject(st->st_filename, lineno, col_offset + 1); + PyErr_SyntaxLocationObject(st->st_filename, lineno, col_offset + 1); Py_DECREF(store_name); return 0; } @@ -1826,12 +1826,12 @@ symtable_visit_alias(struct symtable *st, alias_ty a) static int symtable_visit_comprehension(struct symtable *st, comprehension_ty lc) { - st->st_cur->ste_comp_iter_target = 1; + st->st_cur->ste_comp_iter_target = 1; VISIT(st, expr, lc->target); - st->st_cur->ste_comp_iter_target = 0; - st->st_cur->ste_comp_iter_expr++; + st->st_cur->ste_comp_iter_target = 0; + st->st_cur->ste_comp_iter_expr++; VISIT(st, expr, lc->iter); - st->st_cur->ste_comp_iter_expr--; + st->st_cur->ste_comp_iter_expr--; VISIT_SEQ(st, expr, lc->ifs); if (lc->is_async) { st->st_cur->ste_coroutine = 1; @@ -1857,9 +1857,9 @@ symtable_handle_comprehension(struct symtable *st, expr_ty e, comprehension_ty outermost = ((comprehension_ty) asdl_seq_GET(generators, 0)); /* Outermost iterator is evaluated in current scope */ - st->st_cur->ste_comp_iter_expr++; + st->st_cur->ste_comp_iter_expr++; VISIT(st, expr, outermost->iter); - st->st_cur->ste_comp_iter_expr--; + st->st_cur->ste_comp_iter_expr--; /* Create comprehension scope for the rest */ if (!scope_name || !symtable_enter_block(st, scope_name, FunctionBlock, (void *)e, @@ -1869,37 +1869,37 @@ symtable_handle_comprehension(struct symtable *st, expr_ty e, if (outermost->is_async) { st->st_cur->ste_coroutine = 1; } - st->st_cur->ste_comprehension = 1; - + st->st_cur->ste_comprehension = 1; + /* Outermost iter is received as an argument */ if (!symtable_implicit_arg(st, 0)) { - symtable_exit_block(st); + symtable_exit_block(st); return 0; } - /* Visit iteration variable target, and mark them as such */ - st->st_cur->ste_comp_iter_target = 1; + /* Visit iteration variable target, and mark them as such */ + st->st_cur->ste_comp_iter_target = 1; VISIT(st, expr, outermost->target); - st->st_cur->ste_comp_iter_target = 0; - /* Visit the rest of the comprehension body */ + st->st_cur->ste_comp_iter_target = 0; + /* Visit the rest of the comprehension body */ VISIT_SEQ(st, expr, outermost->ifs); VISIT_SEQ_TAIL(st, comprehension, generators, 1); if (value) VISIT(st, expr, value); VISIT(st, expr, elt); if (st->st_cur->ste_generator) { - PyErr_SetString(PyExc_SyntaxError, + PyErr_SetString(PyExc_SyntaxError, (e->kind == ListComp_kind) ? "'yield' inside list comprehension" : (e->kind == SetComp_kind) ? "'yield' inside set comprehension" : (e->kind == DictComp_kind) ? "'yield' inside dict comprehension" : "'yield' inside generator expression"); - PyErr_SyntaxLocationObject(st->st_filename, - st->st_cur->ste_lineno, - st->st_cur->ste_col_offset + 1); - symtable_exit_block(st); - return 0; + PyErr_SyntaxLocationObject(st->st_filename, + st->st_cur->ste_lineno, + st->st_cur->ste_col_offset + 1); + symtable_exit_block(st); + return 0; } - st->st_cur->ste_generator = is_generator; - return symtable_exit_block(st); + st->st_cur->ste_generator = is_generator; + return symtable_exit_block(st); } static int |