Commit 00c78163 authored by Stefan Behnel's avatar Stefan Behnel

fix closure handling for decorated methods

parent 37d6fac0
...@@ -1881,6 +1881,7 @@ class DefNode(FuncDefNode): ...@@ -1881,6 +1881,7 @@ class DefNode(FuncDefNode):
# when the def statement is inside a Python class definition. # when the def statement is inside a Python class definition.
# #
# assmt AssignmentNode Function construction/assignment # 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"] child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
...@@ -1895,6 +1896,7 @@ class DefNode(FuncDefNode): ...@@ -1895,6 +1896,7 @@ class DefNode(FuncDefNode):
entry = None entry = None
acquire_gil = 0 acquire_gil = 0
self_in_stararg = 0 self_in_stararg = 0
py_cfunc_node = None
def __init__(self, pos, **kwds): def __init__(self, pos, **kwds):
FuncDefNode.__init__(self, pos, **kwds) FuncDefNode.__init__(self, pos, **kwds)
...@@ -2242,16 +2244,17 @@ class DefNode(FuncDefNode): ...@@ -2242,16 +2244,17 @@ class DefNode(FuncDefNode):
genv = genv.outer_scope genv = genv.outer_scope
if genv.is_closure_scope: if genv.is_closure_scope:
rhs = ExprNodes.InnerFunctionNode( self.py_cfunc_node = ExprNodes.InnerFunctionNode(
self.pos, pymethdef_cname = self.entry.pymethdef_cname) self.pos, pymethdef_cname = self.entry.pymethdef_cname)
else: else:
rhs = ExprNodes.PyCFunctionNode( self.py_cfunc_node = ExprNodes.PyCFunctionNode(
self.pos, pymethdef_cname = self.entry.pymethdef_cname, binding = env.directives['binding']) self.pos, pymethdef_cname = self.entry.pymethdef_cname, binding = env.directives['binding'])
if env.is_py_class_scope: if env.is_py_class_scope:
if not self.is_staticmethod and not self.is_classmethod: 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: if self.decorators:
for decorator in self.decorators[::-1]: for decorator in self.decorators[::-1]:
rhs = ExprNodes.SimpleCallNode( rhs = ExprNodes.SimpleCallNode(
......
...@@ -957,7 +957,7 @@ class DecoratorTransform(ScopeTrackingTransform, SkipDeclarations): ...@@ -957,7 +957,7 @@ class DecoratorTransform(ScopeTrackingTransform, SkipDeclarations):
def visit_DefNode(self, func_node): def visit_DefNode(self, func_node):
scope_type = self.scope_type scope_type = self.scope_type
func_node = self.visit_FuncDefNode(func_node) 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 func_node
return self._handle_decorators( return self._handle_decorators(
func_node, func_node.name) func_node, func_node.name)
...@@ -1359,9 +1359,9 @@ class CreateClosureClasses(CythonTransform): ...@@ -1359,9 +1359,9 @@ class CreateClosureClasses(CythonTransform):
if not from_closure and (self.path or inner_node): if not from_closure and (self.path or inner_node):
if not inner_node: if not inner_node:
if not node.assmt: if not node.py_cfunc_node:
raise InternalError, "DefNode does not have assignment 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 inner_node.needs_self_code = False
node.needs_outer_scope = False node.needs_outer_scope = False
# Simple cases # Simple cases
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment