diff -r 98a57845c8cc Doc/reference/simple_stmts.rst --- a/Doc/reference/simple_stmts.rst Fri Sep 09 07:38:50 2016 +0000 +++ b/Doc/reference/simple_stmts.rst Fri Sep 09 16:17:38 2016 +0200 @@ -907,7 +907,7 @@ .. impl-detail:: - The current implementation does not enforce the two restrictions, but + The current implementation does not enforce the latter restriction, but programs should not abuse this freedom, as future implementations may enforce them or silently change the meaning of the program. diff -r 98a57845c8cc Lib/test/test_syntax.py --- a/Lib/test/test_syntax.py Fri Sep 09 07:38:50 2016 +0000 +++ b/Lib/test/test_syntax.py Fri Sep 09 16:17:38 2016 +0200 @@ -366,7 +366,23 @@ ... SyntaxError: too many statically nested blocks -Misuse of the nonlocal statement can lead to a few unique syntax errors. +Misuse of the nonlocal and global statement can lead to a few unique syntax errors. + + >>> def f(): + ... x = 1 + ... global x + Traceback (most recent call last): + ... + SyntaxError: name 'x' is assigned to before global declaration + + >>> def f(): + ... x = 1 + ... def g(): + ... print(x) + ... nonlocal x + Traceback (most recent call last): + ... + SyntaxError: name 'x' is used prior to nonlocal declaration >>> def f(x): ... nonlocal x diff -r 98a57845c8cc Python/symtable.c --- a/Python/symtable.c Fri Sep 09 07:38:50 2016 +0000 +++ b/Python/symtable.c Fri Sep 09 16:17:38 2016 +0200 @@ -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" @@ -1212,9 +1218,8 @@ 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 +1302,24 @@ 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 +1335,24 @@ 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 = NONLOCAL_ANNOT; + } + if (cur & DEF_LOCAL) { + msg = NONLOCAL_AFTER_ASSIGN; + } + else { + msg = NONLOCAL_AFTER_USE; + } PyErr_Format(PyExc_SyntaxError, - "annotated name '%U' can't be nonlocal", - 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), - 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))