Fix two more closure bugs.
authorRobert Bradshaw <robertwb@math.washington.edu>
Tue, 6 Oct 2009 10:12:11 +0000 (03:12 -0700)
committerRobert Bradshaw <robertwb@math.washington.edu>
Tue, 6 Oct 2009 10:12:11 +0000 (03:12 -0700)
Cython/Compiler/ControlFlow.py
Cython/Compiler/Nodes.py
tests/run/closures_T82.pyx

index 4ed163f9a3fa21a23846cd316921a48cd2fb317d..f63d52caa09cd882c8b435458df6aa4071d7cca9 100644 (file)
@@ -70,7 +70,7 @@ class ControlFlow(object):
         if current is None:
             return (None, None)
         state = current._get_pos_state_local(item, pos)
-        while state is None and current.incoming is not None:
+        while (state is None or state == (None, None)) and current.incoming is not None:
             current = current.incoming
             state = current._get_pos_state_local(item, pos)
         if state is None:
index 71bf63ccf9ef9233d915545663dac52748ab19a4..0e16e029ed0b9ef7a00b11ee75d1d4dd33fb436a 100644 (file)
@@ -1220,8 +1220,6 @@ class FuncDefNode(StatNode, BlockNode):
                 if lenv.control_flow.get_state((entry.name, 'initalized')) is not True:
                     entry.xdecref_cleanup = 1
         
-        if self.needs_closure:
-            code.put_decref(Naming.cur_scope_cname, lenv.scope_class.type)
         for entry in lenv.var_entries:
             if entry.used and not entry.in_closure:
                 code.put_var_decref(entry)
@@ -1234,6 +1232,8 @@ class FuncDefNode(StatNode, BlockNode):
                     code.put_var_giveref(entry)
                 elif not entry.in_closure and src != 'arg':
                     code.put_var_decref(entry)
+        if self.needs_closure:
+            code.put_decref(Naming.cur_scope_cname, lenv.scope_class.type)
                 
         # ----- Return
         # This code is duplicated in ModuleNode.generate_module_init_func
@@ -1861,10 +1861,11 @@ class DefNode(FuncDefNode):
         for arg in self.args:
             if not arg.name:
                 error(arg.pos, "Missing argument name")
-            if arg.needs_conversion:
-                arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
+            else:
                 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
                 env.control_flow.set_state((), (arg.name, 'initalized'), True)
+            if arg.needs_conversion:
+                arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
                 if arg.type.is_pyobject:
                     arg.entry.init = "0"
                 arg.entry.init_to_none = 0
index 37f39532ce3183bc238d392c1549ff8aea2a5956..0bbb7db13cde3543d8a34a35f259b5af3dd2f7b0 100644 (file)
@@ -50,6 +50,15 @@ True
 >>> inner_funcs[0](16), inner_funcs[1](32), inner_funcs[2](64)
 (19, 37, 73)
 
+>>> switch_funcs([1,2,3], [4,5,6], 0)([10])
+[1, 2, 3, 10]
+>>> switch_funcs([1,2,3], [4,5,6], 1)([10])
+[4, 5, 6, 10]
+>>> switch_funcs([1,2,3], [4,5,6], 2) is None
+True
+
+>>> call_ignore_func()
+
 """
 
 def add_n(int n):
@@ -125,6 +134,25 @@ def cy_twofuncs(x):
         return x + b
     return f
 
+def switch_funcs(a, b, int ix):
+    def f(x):
+        return a + x
+    def g(x):
+        return b + x
+    if ix == 0:
+        return f
+    elif ix == 1:
+        return g
+    else:
+        return None
+
+def ignore_func(x):
+    def f():
+        return x
+    return None
+
+def call_ignore_func():
+    ignore_func((1,2,3))
 
 def more_inner_funcs(x):
     # called with x==1