diff --git a/Cython/Compiler/CypclassWrapper.py b/Cython/Compiler/CypclassWrapper.py new file mode 100644 index 0000000000000000000000000000000000000000..8eff7d384ccf8c2d10bca8198ae9ba857e6000e4 --- /dev/null +++ b/Cython/Compiler/CypclassWrapper.py @@ -0,0 +1,40 @@ +# +# Code generation for wrapping cypclass as a Python Extension Type +# +# Will be generated: +# - a PyTypeObject definition for each user defined cypclass +# - Python wrappers for cypclass methods +# - Python getters/setters for cypclass attributes +# - Specific 'tp slots' for handling cycplass objects from Python: +# . tp_new +# . tp_init +# . tp_dealloc +# ... +# +# Functions defined here will be called from ModuleNode.py +# +# Reasons for using a separate file: +# - avoid cluttering ModuleNode.py +# - regroup common logic +# - decouple the code generation process from that of 'cdef class' +# +# Code generation for cypclass will be similar to code generation for 'cdef class' in ModuleNode.py, +# but differences are significant enough that it is better to introduce some redundancy than try to +# handle both 'cdef class' and 'cypclass' in ModuleNode.py. +# + + +def generate_cypclass_typeobj_declarations(env, code, definition): + """ + Generate declarations of global pointers to the PyTypeObject for each cypclass + """ + + for entry in env.cypclass_entries: + if definition or entry.defined_in_pxd: + code.putln("static PyTypeObject *%s = 0;" % ( + entry.type.typeptr_cname)) + cyp_scope = entry.type.scope + if cyp_scope: + # generate declarations for nested cycplasses + generate_cypclass_typeobj_declarations(cyp_scope, code, definition) + diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py index c3fcc8b6d1d9e2966e8911de3c6714112629c68d..2244fc4e4fca843f170b51028150f8e01d989af9 100644 --- a/Cython/Compiler/ModuleNode.py +++ b/Cython/Compiler/ModuleNode.py @@ -20,6 +20,7 @@ from .PyrexTypes import CPtrType from . import Future from . import Annotate from . import Code +from . import CypclassWrapper from . import Naming from . import Nodes from . import Options @@ -680,7 +681,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): modulecode.putln("") modulecode.putln("/* Module declarations from %s */" % module.qualified_name.as_c_string_literal()) self.generate_c_class_declarations(module, modulecode, defined_here, globalstate) - self.generate_cypclass_typeobj_declarations(module, modulecode, defined_here) + CypclassWrapper.generate_cypclass_typeobj_declarations(module, modulecode, defined_here) self.generate_cvariable_declarations(module, modulecode, defined_here) self.generate_cfunction_declarations(module, modulecode, defined_here) @@ -1912,16 +1913,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): "Py_VISIT(traverse_module_state->%s);" % ( entry.type.typeobj_cname)) code.putln("#endif") - - def generate_cypclass_typeobj_declarations(self, env, code, definition): - for entry in env.cypclass_entries: - if definition or entry.defined_in_pxd: - code.putln("static PyTypeObject *%s = 0;" % ( - entry.type.typeptr_cname)) - cyp_scope = entry.type.scope - if cyp_scope: - # generate declarations for nested cycplasses - self.generate_cypclass_typeobj_declarations(cyp_scope, code, definition) def generate_cvariable_declarations(self, env, code, definition): if env.is_cython_builtin: