summaryrefslogtreecommitdiffstats
path: root/Python/symtable.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/symtable.c')
-rw-r--r--Python/symtable.c155
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);