diff options
Diffstat (limited to 'Python/symtable.c')
-rw-r--r-- | Python/symtable.c | 155 |
1 files changed, 96 insertions, 59 deletions
diff --git a/Python/symtable.c b/Python/symtable.c index 1591a20..bf30ecc 100644 --- a/Python/symtable.c +++ b/Python/symtable.c @@ -6,16 +6,22 @@ /* error strings used for warnings */ #define GLOBAL_AFTER_ASSIGN \ -"name '%.400s' is assigned to before global declaration" +"name '%U' is assigned to before global declaration" #define NONLOCAL_AFTER_ASSIGN \ -"name '%.400s' is assigned to before nonlocal declaration" +"name '%U' is assigned to before nonlocal declaration" #define GLOBAL_AFTER_USE \ -"name '%.400s' is used prior to global declaration" +"name '%U' is used prior to global declaration" #define NONLOCAL_AFTER_USE \ -"name '%.400s' is used prior to nonlocal declaration" +"name '%U' is used prior to nonlocal declaration" + +#define GLOBAL_ANNOT \ +"annotated name '%U' can't be global" + +#define NONLOCAL_ANNOT \ +"annotated name '%U' can't be nonlocal" #define IMPORT_STAR_WARNING "import * only allowed at module level" @@ -63,6 +69,7 @@ ste_new(struct symtable *st, identifier name, _Py_block_ty block, ste->ste_nested = 1; ste->ste_child_free = 0; ste->ste_generator = 0; + ste->ste_coroutine = 0; ste->ste_returns_value = 0; ste->ste_needs_class_closure = 0; @@ -160,7 +167,6 @@ PyTypeObject PySTEntry_Type = { }; static int symtable_analyze(struct symtable *st); -static int symtable_warn(struct symtable *st, char *msg, int lineno); static int symtable_enter_block(struct symtable *st, identifier name, _Py_block_ty block, void *ast, int lineno, int col_offset); @@ -378,7 +384,7 @@ error_at_directive(PySTEntryObject *ste, PyObject *name) PyLong_AsLong(PyTuple_GET_ITEM(data, 2))); return 0; - } + } } PyErr_SetString(PyExc_RuntimeError, "BUG: internal directive bookkeeping broken"); @@ -652,7 +658,7 @@ update_symbols(PyObject *symbols, PyObject *scopes, continue; } /* Handle global symbol */ - if (!PySet_Contains(bound, name)) { + if (bound && !PySet_Contains(bound, name)) { Py_DECREF(name); continue; /* it's a global */ } @@ -906,27 +912,6 @@ symtable_analyze(struct symtable *st) return r; } - -static int -symtable_warn(struct symtable *st, char *msg, int lineno) -{ - PyObject *message = PyUnicode_FromString(msg); - if (message == NULL) - return 0; - if (PyErr_WarnExplicitObject(PyExc_SyntaxWarning, message, st->st_filename, - lineno, NULL, NULL) < 0) { - Py_DECREF(message); - if (PyErr_ExceptionMatches(PyExc_SyntaxWarning)) { - PyErr_SetString(PyExc_SyntaxError, msg); - PyErr_SyntaxLocationObject(st->st_filename, st->st_cur->ste_lineno, - st->st_cur->ste_col_offset); - } - return 0; - } - Py_DECREF(message); - return 1; -} - /* symtable_enter_block() gets a reference via ste_new. This reference is released when the block is exited, via the DECREF in symtable_exit_block(). @@ -1201,6 +1186,43 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) VISIT_SEQ(st, expr, s->v.Assign.targets); VISIT(st, expr, s->v.Assign.value); break; + case AnnAssign_kind: + if (s->v.AnnAssign.target->kind == Name_kind) { + expr_ty e_name = s->v.AnnAssign.target; + long cur = symtable_lookup(st, e_name->v.Name.id); + if (cur < 0) { + VISIT_QUIT(st, 0); + } + if ((cur & (DEF_GLOBAL | DEF_NONLOCAL)) + && 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); + VISIT_QUIT(st, 0); + } + if (s->v.AnnAssign.simple && + !symtable_add_def(st, e_name->v.Name.id, + DEF_ANNOT | DEF_LOCAL)) { + VISIT_QUIT(st, 0); + } + else { + if (s->v.AnnAssign.value + && !symtable_add_def(st, e_name->v.Name.id, DEF_LOCAL)) { + VISIT_QUIT(st, 0); + } + } + } + else { + VISIT(st, expr, s->v.AnnAssign.target); + } + VISIT(st, expr, s->v.AnnAssign.annotation); + if (s->v.AnnAssign.value) { + VISIT(st, expr, s->v.AnnAssign.value); + } + break; case AugAssign_kind: VISIT(st, expr, s->v.AugAssign.target); VISIT(st, expr, s->v.AugAssign.value); @@ -1258,21 +1280,21 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) long cur = symtable_lookup(st, name); if (cur < 0) VISIT_QUIT(st, 0); - if (cur & (DEF_LOCAL | USE)) { - char buf[256]; - char *c_name = _PyUnicode_AsString(name); - if (!c_name) - return 0; - if (cur & DEF_LOCAL) - PyOS_snprintf(buf, sizeof(buf), - GLOBAL_AFTER_ASSIGN, - c_name); - else - PyOS_snprintf(buf, sizeof(buf), - GLOBAL_AFTER_USE, - c_name); - if (!symtable_warn(st, buf, s->lineno)) - VISIT_QUIT(st, 0); + if (cur & (DEF_LOCAL | USE | DEF_ANNOT)) { + char* msg; + if (cur & USE) { + msg = GLOBAL_AFTER_USE; + } else if (cur & DEF_ANNOT) { + msg = GLOBAL_ANNOT; + } else { /* DEF_LOCAL */ + msg = GLOBAL_AFTER_ASSIGN; + } + PyErr_Format(PyExc_SyntaxError, + msg, name); + PyErr_SyntaxLocationObject(st->st_filename, + s->lineno, + s->col_offset); + VISIT_QUIT(st, 0); } if (!symtable_add_def(st, name, DEF_GLOBAL)) VISIT_QUIT(st, 0); @@ -1289,21 +1311,20 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) long cur = symtable_lookup(st, name); if (cur < 0) VISIT_QUIT(st, 0); - if (cur & (DEF_LOCAL | USE)) { - char buf[256]; - char *c_name = _PyUnicode_AsString(name); - if (!c_name) - return 0; - if (cur & DEF_LOCAL) - PyOS_snprintf(buf, sizeof(buf), - NONLOCAL_AFTER_ASSIGN, - c_name); - else - PyOS_snprintf(buf, sizeof(buf), - NONLOCAL_AFTER_USE, - c_name); - if (!symtable_warn(st, buf, s->lineno)) - VISIT_QUIT(st, 0); + if (cur & (DEF_LOCAL | USE | DEF_ANNOT)) { + char* msg; + if (cur & USE) { + msg = NONLOCAL_AFTER_USE; + } else if (cur & DEF_ANNOT) { + msg = NONLOCAL_ANNOT; + } else { /* DEF_LOCAL */ + msg = NONLOCAL_AFTER_ASSIGN; + } + PyErr_Format(PyExc_SyntaxError, msg, name); + PyErr_SyntaxLocationObject(st->st_filename, + s->lineno, + s->col_offset); + VISIT_QUIT(st, 0); } if (!symtable_add_def(st, name, DEF_NONLOCAL)) VISIT_QUIT(st, 0); @@ -1341,6 +1362,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) FunctionBlock, (void *)s, s->lineno, s->col_offset)) VISIT_QUIT(st, 0); + 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, s)) @@ -1436,7 +1458,7 @@ symtable_visit_expr(struct symtable *st, expr_ty e) break; case Await_kind: VISIT(st, expr, e->v.Await.value); - st->st_cur->ste_generator = 1; + st->st_cur->ste_coroutine = 1; break; case Compare_kind: VISIT(st, expr, e->v.Compare.left); @@ -1447,6 +1469,15 @@ symtable_visit_expr(struct symtable *st, expr_ty e) VISIT_SEQ(st, expr, e->v.Call.args); VISIT_SEQ_WITH_NULL(st, keyword, e->v.Call.keywords); break; + case FormattedValue_kind: + VISIT(st, expr, e->v.FormattedValue.value); + if (e->v.FormattedValue.format_spec) + VISIT(st, expr, e->v.FormattedValue.format_spec); + break; + case JoinedStr_kind: + VISIT_SEQ(st, expr, e->v.JoinedStr.values); + break; + case Constant_kind: case Num_kind: case Str_kind: case Bytes_kind: @@ -1647,6 +1678,9 @@ symtable_visit_comprehension(struct symtable *st, comprehension_ty lc) VISIT(st, expr, lc->target); VISIT(st, expr, lc->iter); VISIT_SEQ(st, expr, lc->ifs); + if (lc->is_async) { + st->st_cur->ste_coroutine = 1; + } return 1; } @@ -1699,6 +1733,9 @@ symtable_handle_comprehension(struct symtable *st, expr_ty e, return 0; } st->st_cur->ste_generator = is_generator; + if (outermost->is_async) { + st->st_cur->ste_coroutine = 1; + } /* Outermost iter is received as an argument */ if (!symtable_implicit_arg(st, 0)) { symtable_exit_block(st, (void *)e); |