diff options
author | Guido van Rossum <guido@dropbox.com> | 2016-09-09 16:36:26 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@dropbox.com> | 2016-09-09 16:36:26 (GMT) |
commit | 6cff8744a0ae58c88728df8bbca4580ffa6c6a86 (patch) | |
tree | 8cd1a3c28fdc74e6f432661661f306e9feb2bc6d /Python | |
parent | 95e502e7a664c588bcd9d895af285a32ce8246fe (diff) | |
download | cpython-6cff8744a0ae58c88728df8bbca4580ffa6c6a86.zip cpython-6cff8744a0ae58c88728df8bbca4580ffa6c6a86.tar.gz cpython-6cff8744a0ae58c88728df8bbca4580ffa6c6a86.tar.bz2 |
Issue #27999: Make "global after use" a SyntaxError, and ditto for nonlocal.
Patch by Ivan Levkivskyi.
Diffstat (limited to 'Python')
-rw-r--r-- | Python/symtable.c | 104 |
1 files changed, 36 insertions, 68 deletions
diff --git a/Python/symtable.c b/Python/symtable.c index e55813f..9325dc1 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" @@ -161,7 +167,6 @@ PyTypeObject PySTEntry_Type = { }; static int symtable_analyze(struct symtable *st); -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); @@ -907,27 +912,6 @@ symtable_analyze(struct symtable *st) return r; } - -static int -symtable_warn(struct symtable *st, const 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(). @@ -1212,9 +1196,8 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) 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"); + cur & DEF_GLOBAL ? GLOBAL_ANNOT : NONLOCAL_ANNOT, + e_name->v.Name.id); PyErr_SyntaxLocationObject(st->st_filename, s->lineno, s->col_offset); @@ -1297,31 +1280,24 @@ 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) { + if (cur & (DEF_LOCAL | USE | DEF_ANNOT)) { + char* msg; + if (cur & DEF_ANNOT) { + msg = GLOBAL_ANNOT; + } + if (cur & DEF_LOCAL) { + msg = GLOBAL_AFTER_ASSIGN; + } + else { + msg = GLOBAL_AFTER_USE; + } PyErr_Format(PyExc_SyntaxError, - "annotated name '%U' can't be global", - name); + msg, 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); - 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 (!symtable_add_def(st, name, DEF_GLOBAL)) VISIT_QUIT(st, 0); if (!symtable_record_directive(st, name, s)) @@ -1337,31 +1313,23 @@ 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); + if (cur & (DEF_LOCAL | USE | DEF_ANNOT)) { + char* msg; + if (cur & DEF_ANNOT) { + msg = NONLOCAL_ANNOT; + } + if (cur & DEF_LOCAL) { + msg = NONLOCAL_AFTER_ASSIGN; + } + else { + msg = NONLOCAL_AFTER_USE; + } + PyErr_Format(PyExc_SyntaxError, msg, 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); - 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 (!symtable_add_def(st, name, DEF_NONLOCAL)) VISIT_QUIT(st, 0); if (!symtable_record_directive(st, name, s)) |