error tests for nonlocal, fixes to properly detect these errors (Python gives warning...
authorStefan Behnel <scoder@users.berlios.de>
Fri, 17 Dec 2010 07:43:42 +0000 (08:43 +0100)
committerStefan Behnel <scoder@users.berlios.de>
Fri, 17 Dec 2010 07:43:42 +0000 (08:43 +0100)
Cython/Compiler/Symtab.py
tests/errors/e_nonlocal_T490.pyx [new file with mode: 0644]

index 40fb6d48aee92703089f9c54d67d4eecab39df95..34b2d0d0ede410662e22e0e11538460b0cca5f74 100644 (file)
@@ -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 (file)
index 0000000..0fa7804
--- /dev/null
@@ -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
+"""