From 748f27fe99c1f4816afeba2249ccb8c788fd258c Mon Sep 17 00:00:00 2001 From: Stefan Behnel Date: Fri, 17 Dec 2010 08:43:42 +0100 Subject: [PATCH] error tests for nonlocal, fixes to properly detect these errors (Python gives warnings for redefs, but I find errors more appropriate) --- Cython/Compiler/Symtab.py | 10 +++++---- tests/errors/e_nonlocal_T490.pyx | 35 ++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 4 deletions(-) create mode 100644 tests/errors/e_nonlocal_T490.pyx diff --git a/Cython/Compiler/Symtab.py b/Cython/Compiler/Symtab.py index 40fb6d48..34b2d0d0 100644 --- a/Cython/Compiler/Symtab.py +++ b/Cython/Compiler/Symtab.py @@ -1274,8 +1274,9 @@ class LocalScope(Scope): def declare_nonlocal(self, name, pos): # Pull entry from outer scope into local scope - if self.lookup_here(name): - warning(pos, "'%s' redeclared" % name, 0) + orig_entry = self.lookup_here(name) + if orig_entry and orig_entry.scope is self and not orig_entry.from_closure: + error(pos, "'%s' redeclared as nonlocal" % name) else: entry = self.lookup(name) if entry is None or not entry.from_closure: @@ -1452,8 +1453,9 @@ class PyClassScope(ClassScope): def declare_nonlocal(self, name, pos): # Pull entry from outer scope into local scope - if self.lookup_here(name): - warning(pos, "'%s' redeclared" % name, 0) + orig_entry = self.lookup_here(name) + if orig_entry and orig_entry.scope is self and not orig_entry.from_closure: + error(pos, "'%s' redeclared as nonlocal" % name) else: entry = self.lookup(name) if entry is None: diff --git a/tests/errors/e_nonlocal_T490.pyx b/tests/errors/e_nonlocal_T490.pyx new file mode 100644 index 00000000..0fa7804c --- /dev/null +++ b/tests/errors/e_nonlocal_T490.pyx @@ -0,0 +1,35 @@ + +def test_non_existant(): + nonlocal no_such_name + no_such_name = 1 + +def redef(): + x = 1 + def f(): + x = 2 + nonlocal x + +global_name = 5 + +def ref_to_global(): + nonlocal global_name + global_name = 6 + +def global_in_class_scope(): + class Test(): + nonlocal global_name + global_name = 6 + +def redef_in_class_scope(): + x = 1 + class Test(): + x = 2 + nonlocal x + + +_ERRORS = u""" +3:4: no binding for nonlocal 'no_such_name' found +10:8: 'x' redeclared as nonlocal +15:4: no binding for nonlocal 'global_name' found +27:8: 'x' redeclared as nonlocal +""" -- 2.26.2