diff options
Diffstat (limited to 'Python/symtable.c')
-rw-r--r-- | Python/symtable.c | 70 |
1 files changed, 56 insertions, 14 deletions
diff --git a/Python/symtable.c b/Python/symtable.c index 55898f99bf..b9ca615721 100644 --- a/Python/symtable.c +++ b/Python/symtable.c @@ -56,6 +56,8 @@ ste_new(struct symtable *st, identifier name, _Py_block_ty block, if (ste->ste_children == NULL) goto fail; + ste->ste_directives = NULL; + ste->ste_type = block; ste->ste_unoptimized = 0; ste->ste_nested = 0; @@ -102,6 +104,7 @@ ste_dealloc(PySTEntryObject *ste) Py_XDECREF(ste->ste_symbols); Py_XDECREF(ste->ste_varnames); Py_XDECREF(ste->ste_children); + Py_XDECREF(ste->ste_directives); PyObject_Del(ste); } @@ -342,6 +345,24 @@ PyST_GetScope(PySTEntryObject *ste, PyObject *name) return (PyLong_AS_LONG(v) >> SCOPE_OFFSET) & SCOPE_MASK; } +static int +error_at_directive(PySTEntryObject *ste, PyObject *name) +{ + Py_ssize_t i; + PyObject *data; + assert(ste->ste_directives); + for (i = 0; ; i++) { + data = PyList_GET_ITEM(ste->ste_directives, i); + assert(PyTuple_CheckExact(data)); + if (PyTuple_GET_ITEM(data, 0) == name) + break; + } + PyErr_SyntaxLocationEx(ste->ste_table->st_filename, + PyLong_AsLong(PyTuple_GET_ITEM(data, 1)), + PyLong_AsLong(PyTuple_GET_ITEM(data, 2))); + return 0; +} + /* Analyze raw symbol information to determine scope of each name. @@ -416,16 +437,13 @@ analyze_name(PySTEntryObject *ste, PyObject *scopes, PyObject *name, long flags, PyErr_Format(PyExc_SyntaxError, "name '%U' is parameter and global", name); - PyErr_SyntaxLocationEx(ste->ste_table->st_filename, - ste->ste_lineno, ste->ste_col_offset); - - return 0; + return error_at_directive(ste, name); } if (flags & DEF_NONLOCAL) { PyErr_Format(PyExc_SyntaxError, "name '%U' is nonlocal and global", name); - return 0; + return error_at_directive(ste, name); } SET_SCOPE(scopes, name, GLOBAL_EXPLICIT); if (PySet_Add(global, name) < 0) @@ -439,19 +457,19 @@ analyze_name(PySTEntryObject *ste, PyObject *scopes, PyObject *name, long flags, PyErr_Format(PyExc_SyntaxError, "name '%U' is parameter and nonlocal", name); - return 0; + return error_at_directive(ste, name); } if (!bound) { PyErr_Format(PyExc_SyntaxError, "nonlocal declaration not allowed at module level"); - return 0; + return error_at_directive(ste, name); } if (!PySet_Contains(bound, name)) { PyErr_Format(PyExc_SyntaxError, "no binding for nonlocal '%U' found", name); - return 0; + return error_at_directive(ste, name); } SET_SCOPE(scopes, name, FREE); ste->ste_free = 1; @@ -1098,6 +1116,25 @@ symtable_new_tmpname(struct symtable *st) static int +symtable_record_directive(struct symtable *st, identifier name, stmt_ty s) +{ + PyObject *data; + int res; + if (!st->st_cur->ste_directives) { + st->st_cur->ste_directives = PyList_New(0); + if (!st->st_cur->ste_directives) + return 0; + } + data = Py_BuildValue("(Oii)", name, s->lineno, s->col_offset); + if (!data) + return 0; + res = PyList_Append(st->st_cur->ste_directives, data); + Py_DECREF(data); + return res == 0; +} + + +static int symtable_visit_stmt(struct symtable *st, stmt_ty s) { if (++st->recursion_depth > st->recursion_limit) { @@ -1257,6 +1294,8 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) } if (!symtable_add_def(st, name, DEF_GLOBAL)) VISIT_QUIT(st, 0); + if (!symtable_record_directive(st, name, s)) + VISIT_QUIT(st, 0); } break; } @@ -1286,6 +1325,8 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) } if (!symtable_add_def(st, name, DEF_NONLOCAL)) VISIT_QUIT(st, 0); + if (!symtable_record_directive(st, name, s)) + VISIT_QUIT(st, 0); } break; } @@ -1396,6 +1437,7 @@ symtable_visit_expr(struct symtable *st, expr_ty e) case Str_kind: case Bytes_kind: case Ellipsis_kind: + case NameConstant_kind: /* Nothing to do here. */ break; /* The following exprs can be assignment targets. */ @@ -1488,10 +1530,10 @@ symtable_visit_annotations(struct symtable *st, stmt_ty s) if (a->args && !symtable_visit_argannotations(st, a->args)) return 0; - if (a->varargannotation) - VISIT(st, expr, a->varargannotation); - if (a->kwargannotation) - VISIT(st, expr, a->kwargannotation); + if (a->vararg && a->vararg->annotation) + VISIT(st, expr, a->vararg->annotation); + if (a->kwarg && a->kwarg->annotation) + VISIT(st, expr, a->kwarg->annotation); if (a->kwonlyargs && !symtable_visit_argannotations(st, a->kwonlyargs)) return 0; if (s->v.FunctionDef.returns) @@ -1510,12 +1552,12 @@ symtable_visit_arguments(struct symtable *st, arguments_ty a) if (a->kwonlyargs && !symtable_visit_params(st, a->kwonlyargs)) return 0; if (a->vararg) { - if (!symtable_add_def(st, a->vararg, DEF_PARAM)) + if (!symtable_add_def(st, a->vararg->arg, DEF_PARAM)) return 0; st->st_cur->ste_varargs = 1; } if (a->kwarg) { - if (!symtable_add_def(st, a->kwarg, DEF_PARAM)) + if (!symtable_add_def(st, a->kwarg->arg, DEF_PARAM)) return 0; st->st_cur->ste_varkeywords = 1; } |