From de2aea0ff02fa9486365ce9d215bef150fae3a0b Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Sun, 14 Oct 2018 18:01:03 +0100 Subject: [PATCH] bpo-34939: Allow annotated global names in module namespace (GH-9844) Allow annotated global names in the module namespace after the symbol is declared as global. Previously, only symbols annotated before they are declared as global (i.e. inside a function) were allowed. This change allows symbols to be declared as global before the annotation happens in the global scope. --- Lib/test/test_symtable.py | 14 ++++++++++++++ .../2018-10-13-17-40-15.bpo-34939.0gpxlJ.rst | 2 ++ Python/symtable.c | 1 + 3 files changed, 17 insertions(+) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2018-10-13-17-40-15.bpo-34939.0gpxlJ.rst diff --git a/Lib/test/test_symtable.py b/Lib/test/test_symtable.py index 2cd735bdc50..8d76f6fe45f 100644 --- a/Lib/test/test_symtable.py +++ b/Lib/test/test_symtable.py @@ -144,6 +144,20 @@ class SymtableTest(unittest.TestCase): self.assertTrue(st4.lookup('x').is_local()) self.assertFalse(st4.lookup('x').is_annotated()) + # Test that annotations in the global scope are valid after the + # variable is declared as nonlocal. + st5 = symtable.symtable('global x\nx: int', 'test', 'exec') + self.assertTrue(st5.lookup("x").is_global()) + + # Test that annotations for nonlocals are valid after the + # variable is declared as nonlocal. + st6 = symtable.symtable('def g():\n' + ' x = 2\n' + ' def f():\n' + ' nonlocal x\n' + ' x: int', + 'test', 'exec') + def test_imported(self): self.assertTrue(self.top.lookup("sys").is_imported()) diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-10-13-17-40-15.bpo-34939.0gpxlJ.rst b/Misc/NEWS.d/next/Core and Builtins/2018-10-13-17-40-15.bpo-34939.0gpxlJ.rst new file mode 100644 index 00000000000..b588f72d903 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-10-13-17-40-15.bpo-34939.0gpxlJ.rst @@ -0,0 +1,2 @@ +Allow annotated names in module namespace that are declared global before +the annotation happens. Patch by Pablo Galindo. diff --git a/Python/symtable.c b/Python/symtable.c index d74f26fbe35..dc934a556da 100644 --- a/Python/symtable.c +++ b/Python/symtable.c @@ -1175,6 +1175,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) VISIT_QUIT(st, 0); } if ((cur & (DEF_GLOBAL | DEF_NONLOCAL)) + && (st->st_cur->ste_symbols != st->st_global) && s->v.AnnAssign.simple) { PyErr_Format(PyExc_SyntaxError, cur & DEF_GLOBAL ? GLOBAL_ANNOT : NONLOCAL_ANNOT,