diff options
Diffstat (limited to 'Python/symtable.c')
-rw-r--r-- | Python/symtable.c | 77 |
1 files changed, 72 insertions, 5 deletions
diff --git a/Python/symtable.c b/Python/symtable.c index 1591a20..e55813f 100644 --- a/Python/symtable.c +++ b/Python/symtable.c @@ -63,6 +63,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 +161,7 @@ PyTypeObject PySTEntry_Type = { }; static int symtable_analyze(struct symtable *st); -static int symtable_warn(struct symtable *st, char *msg, int lineno); +static int symtable_warn(struct symtable *st, const 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 +379,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 +653,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 */ } @@ -908,7 +909,7 @@ symtable_analyze(struct symtable *st) static int -symtable_warn(struct symtable *st, char *msg, int lineno) +symtable_warn(struct symtable *st, const char *msg, int lineno) { PyObject *message = PyUnicode_FromString(msg); if (message == NULL) @@ -1201,6 +1202,44 @@ 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, + "annotated name '%U' can't be %s", + e_name->v.Name.id, + cur & DEF_GLOBAL ? "global" : "nonlocal"); + 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,6 +1297,15 @@ 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_ANNOT) { + PyErr_Format(PyExc_SyntaxError, + "annotated name '%U' can't be global", + name); + PyErr_SyntaxLocationObject(st->st_filename, + s->lineno, + s->col_offset); + VISIT_QUIT(st, 0); + } if (cur & (DEF_LOCAL | USE)) { char buf[256]; char *c_name = _PyUnicode_AsString(name); @@ -1289,6 +1337,15 @@ 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_ANNOT) { + PyErr_Format(PyExc_SyntaxError, + "annotated name '%U' can't be nonlocal", + name); + PyErr_SyntaxLocationObject(st->st_filename, + s->lineno, + s->col_offset); + VISIT_QUIT(st, 0); + } if (cur & (DEF_LOCAL | USE)) { char buf[256]; char *c_name = _PyUnicode_AsString(name); @@ -1341,6 +1398,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 +1494,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 +1505,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: |