closure cleanup, test
authorRobert Bradshaw <robertwb@math.washington.edu>
Thu, 23 Apr 2009 10:56:04 +0000 (03:56 -0700)
committerRobert Bradshaw <robertwb@math.washington.edu>
Thu, 23 Apr 2009 10:56:04 +0000 (03:56 -0700)
Cython/Compiler/Nodes.py
Cython/Compiler/ParseTreeTransforms.py
Cython/Compiler/Symtab.py
tests/run/closures_T82.pyx [new file with mode: 0644]

index 49bc277baff7ce4e9ea7353359db36a89bb694f0..7f611afc6c68641fff5b4a4a4ee4736f3966efd6 100644 (file)
@@ -1062,13 +1062,17 @@ class FuncDefNode(StatNode, BlockNode):
                             lenv.scope_class.type.typeptr_cname,
                             Naming.empty_tuple))
             # TODO: error handling
-            # The code below assumes the local variables are innitially NULL
+            code.put_gotref(Naming.cur_scope_cname)
+            # The code below is because we assume the local variables are 
+            # innitially NULL.
             # Note that it is unsafe to decref the scope at this point.
             for entry in lenv.arg_entries + lenv.var_entries:
                 if entry.in_closure and entry.type.is_pyobject:
+                    code.put_gotref(entry.cname) # so the refnanny doesn't whine
                     code.put_var_decref_clear(entry)
         if env.is_closure_scope:
             if lenv.is_closure_scope:
+                code.put_gotref(outer_scope_cname)
                 code.put_decref(outer_scope_cname, env.scope_class.type)
             code.putln("%s = (%s)%s;" % (
                             outer_scope_cname,
@@ -1883,7 +1887,7 @@ class DefNode(FuncDefNode):
             if arg.is_generic: # or arg.needs_conversion:
                 if arg.needs_conversion:
                     code.putln("PyObject *%s = 0;" % arg.hdr_cname)
-                elif not entry.in_closure:
+                elif not arg.entry.in_closure:
                     code.put_var_declaration(arg.entry)
 
     def generate_keyword_list(self, code):
index e732eaa0b4ede3d61674360d99f1d3ab5d08ca69..f23568542b721c3102c300abc1427d402dec7d19 100644 (file)
@@ -865,8 +865,6 @@ class CreateClosureClasses(CythonTransform):
 
     def create_class_from_scope(self, node, target_module_scope):
     
-        print node.entry.scope.is_closure_scope
-    
         as_name = "%s%s" % (Naming.closure_class_prefix, node.entry.cname)
         func_scope = node.local_scope
 
@@ -875,7 +873,6 @@ class CreateClosureClasses(CythonTransform):
         func_scope.scope_class = entry
         class_scope = entry.type.scope
         if node.entry.scope.is_closure_scope:
-            print "yes", class_scope
             class_scope.declare_var(pos=node.pos,
                                     name=Naming.outer_scope_cname, # this could conflict?
                                     cname=Naming.outer_scope_cname,
index 681ef4af450953b04fc08b2c9b636dedc0b1bb0e..b1a361eefa40f6ca4c0f361f017998dc7911e3d5 100644 (file)
@@ -1057,7 +1057,6 @@ class LocalScope(Scope):
         entry = Scope.lookup(self, name)
         if entry is not None:
             if entry.scope is not self and entry.scope.is_closure_scope:
-                print "making new entry for", entry.cname, "in", self
                 # The actual c fragment for the different scopes differs 
                 # on the outside and inside, so we make a new entry
                 entry.in_closure = True
@@ -1072,9 +1071,7 @@ class LocalScope(Scope):
         return entry
             
     def mangle_closure_cnames(self, outer_scope_cname):
-        print "mangling", self
         for entry in self.entries.values():
-            print entry.name, entry.in_closure, entry.from_closure
             if entry.from_closure:
                 cname = entry.outer_entry.cname
                 if cname.startswith(Naming.cur_scope_cname):
@@ -1083,8 +1080,7 @@ class LocalScope(Scope):
             elif entry.in_closure:
                 entry.original_cname = entry.cname
                 entry.cname = "%s->%s" % (Naming.cur_scope_cname, entry.cname)
-            print entry.cname                
-
+            
 class ClosureScope(LocalScope):
 
     is_closure_scope = True
diff --git a/tests/run/closures_T82.pyx b/tests/run/closures_T82.pyx
new file mode 100644 (file)
index 0000000..9b89f1a
--- /dev/null
@@ -0,0 +1,20 @@
+__doc__ = u"""
+>>> f = add_n(3)
+>>> f(2)
+5
+
+>>> a(5)()
+8
+"""
+
+def add_n(int n):
+    def f(int x):
+        return x+n
+    return f
+
+def a(int x):
+    def b():
+        def c():
+            return 3+x
+        return c()
+    return b