if not self.is_staticmethod and not self.is_classmethod:
rhs.binding = True
- if self.decorators:
- for decorator in self.decorators[::-1]:
- rhs = ExprNodes.SimpleCallNode(
- decorator.pos,
- function = decorator.decorator,
- args = [rhs])
-
self.assmt = SingleAssignmentNode(self.pos,
lhs = ExprNodes.NameNode(self.pos, name = self.name),
rhs = rhs)
# classobj ClassNode Class object
# target NameNode Variable to assign class object to
- child_attrs = ["body", "dict", "metaclass", "mkw", "bases", "class_result", "target"]
+ child_attrs = ["body", "dict", "metaclass", "mkw", "bases", "classobj", "target"]
decorators = None
- class_result = None
py3_style_class = False # Python3 style class (bases+kwargs)
def __init__(self, pos, name, bases, doc, body, decorators = None,
return cenv
def analyse_declarations(self, env):
- class_result = self.classobj
- if self.decorators:
- from ExprNodes import SimpleCallNode
- for decorator in self.decorators[::-1]:
- class_result = SimpleCallNode(
- decorator.pos,
- function = decorator.decorator,
- args = [class_result])
- self.class_result = class_result
- self.class_result.analyse_declarations(env)
self.target.analyse_target_declaration(env)
cenv = self.create_scope(env)
cenv.directives = env.directives
self.metaclass.analyse_expressions(env)
self.mkw.analyse_expressions(env)
self.dict.analyse_expressions(env)
- self.class_result.analyse_expressions(env)
+ self.classobj.analyse_expressions(env)
genv = env.global_scope()
cenv = self.scope
self.body.analyse_expressions(cenv)
self.dict.generate_evaluation_code(code)
cenv.namespace_cname = cenv.class_obj_cname = self.dict.result()
self.body.generate_execution_code(code)
- self.class_result.generate_evaluation_code(code)
+ self.classobj.generate_evaluation_code(code)
cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
- self.target.generate_assignment_code(self.class_result, code)
+ self.target.generate_assignment_code(self.classobj, code)
self.dict.generate_disposal_code(code)
self.dict.free_temps(code)
if self.py3_style_class:
if env.in_cinclude and not self.objstruct_name:
error(self.pos, "Object struct name specification required for "
"C class defined in 'extern from' block")
- if self.decorators:
- error(self.pos,
- "Decorators not allowed on cdef classes (used on type '%s')" % self.class_name)
self.base_type = None
# Now that module imports are cached, we need to
# import the modules for extern classes.
return node
-class DecoratorTransform(ScopeTrackingTransform, SkipDeclarations):
- """Originally, this was the only place where decorators were
- transformed into the corresponding calling code. Now, this is
- done directly in DefNode and PyClassDefNode to avoid reassignments
- to the function/class name - except for cdef class methods. For
- those, the reassignment is required as methods are originally
- defined in the PyMethodDef struct.
- """
+class DecoratorTransform(CythonTransform, 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:
+ self.visitchildren(func_node)
+ if not func_node.decorators:
return func_node
return self._handle_decorators(
func_node, func_node.name)
+ def visit_CClassDefNode(self, class_node):
+ # This doesn't currently work, so it's disabled.
+ #
+ # Problem: assignments to cdef class names do not work. They
+ # would require an additional check anyway, as the extension
+ # type must not change its C type, so decorators cannot
+ # replace an extension type, just alter it and return it.
+
+ self.visitchildren(class_node)
+ if not class_node.decorators:
+ return class_node
+ error(class_node.pos,
+ "Decorators not allowed on cdef classes (used on type '%s')" % class_node.class_name)
+ return class_node
+ #return self._handle_decorators(
+ # class_node, class_node.class_name)
+
+ def visit_ClassDefNode(self, class_node):
+ self.visitchildren(class_node)
+ if not class_node.decorators:
+ return class_node
+ return self._handle_decorators(
+ class_node, class_node.name)
+
def _handle_decorators(self, node, name):
decorator_result = ExprNodes.NameNode(node.pos, name = name)
for decorator in node.decorators[::-1]: