fix closure handling for decorated methods
authorStefan Behnel <scoder@users.berlios.de>
Wed, 29 Dec 2010 22:34:13 +0000 (23:34 +0100)
committerStefan Behnel <scoder@users.berlios.de>
Wed, 29 Dec 2010 22:34:13 +0000 (23:34 +0100)
Cython/Compiler/Nodes.py
Cython/Compiler/ParseTreeTransforms.py

index 0e7af2d449b1c594aa774f6e0fe4776a13b3c8b5..00db41513d7a2f24f1eec3bb99ca56f4626ff4da 100644 (file)
@@ -1881,6 +1881,7 @@ class DefNode(FuncDefNode):
     #  when the def statement is inside a Python class definition.
     #
     #  assmt   AssignmentNode   Function construction/assignment
+    #  py_cfunc_node  PyCFunctionNode/InnerFunctionNode   The PyCFunction to create and assign
 
     child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
 
@@ -1895,6 +1896,7 @@ class DefNode(FuncDefNode):
     entry = None
     acquire_gil = 0
     self_in_stararg = 0
+    py_cfunc_node = None
 
     def __init__(self, pos, **kwds):
         FuncDefNode.__init__(self, pos, **kwds)
@@ -2242,16 +2244,17 @@ class DefNode(FuncDefNode):
             genv = genv.outer_scope
 
         if genv.is_closure_scope:
-            rhs = ExprNodes.InnerFunctionNode(
+            self.py_cfunc_node = ExprNodes.InnerFunctionNode(
                 self.pos, pymethdef_cname = self.entry.pymethdef_cname)
         else:
-            rhs = ExprNodes.PyCFunctionNode(
+            self.py_cfunc_node = ExprNodes.PyCFunctionNode(
                 self.pos, pymethdef_cname = self.entry.pymethdef_cname, binding = env.directives['binding'])
 
         if env.is_py_class_scope:
             if not self.is_staticmethod and not self.is_classmethod:
-                rhs.binding = True
+                self.py_cfunc_node.binding = True
 
+        rhs = self.py_cfunc_node
         if self.decorators:
             for decorator in self.decorators[::-1]:
                 rhs = ExprNodes.SimpleCallNode(
index 166ceec766bedd87b4996e034ee2451320229a6b..6ea7cc02a257b033088355eddccc0cf354649c8a 100644 (file)
@@ -957,7 +957,7 @@ class DecoratorTransform(ScopeTrackingTransform, SkipDeclarations):
     def visit_DefNode(self, func_node):
         scope_type = self.scope_type
         func_node = self.visit_FuncDefNode(func_node)
-        if scope_type is not 'cclass' or not func_node.decorators:
+        if scope_type != 'cclass' or not func_node.decorators:
             return func_node
         return self._handle_decorators(
             func_node, func_node.name)
@@ -1359,9 +1359,9 @@ class CreateClosureClasses(CythonTransform):
 
         if not from_closure and (self.path or inner_node):
             if not inner_node:
-                if not node.assmt:
+                if not node.py_cfunc_node:
                     raise InternalError, "DefNode does not have assignment node"
-                inner_node = node.assmt.rhs
+                inner_node = node.py_cfunc_node
             inner_node.needs_self_code = False
             node.needs_outer_scope = False
         # Simple cases