1 from bgenOutput
import *
2 from bgenGeneratorGroup
import GeneratorGroup
4 class ObjectDefinition(GeneratorGroup
):
5 "Spit out code that together defines a new Python object type"
7 def __init__(self
, name
, prefix
, itselftype
):
8 """ObjectDefinition constructor. May be extended, but do not override.
10 - name: the object's official name, e.g. 'SndChannel'.
11 - prefix: the prefix used for the object's functions and data, e.g. 'SndCh'.
12 - itselftype: the C type actually contained in the object, e.g. 'SndChannelPtr'.
14 XXX For official Python data types, rules for the 'Py' prefix are a problem.
17 GeneratorGroup
.__init
__(self
, prefix
or name
)
19 self
.itselftype
= itselftype
20 self
.objecttype
= name
+ 'Object'
21 self
.typename
= name
+ '_Type'
22 self
.argref
= "" # set to "*" if arg to <type>_New should be pointer
23 self
.static
= "static " # set to "" to make <type>_New and <type>_Convert public
24 self
.basechain
= "NULL" # set to &<basetype>_chain to chain methods
27 g
.setselftype(self
.objecttype
, self
.itselftype
)
28 GeneratorGroup
.add(self
, g
)
31 # In case we are referenced from a module
35 # XXX This should use long strings and %(varname)s substitution!
37 OutHeader2("Object type " + self
.name
)
39 sf
= self
.static
and "staticforward "
40 Output("%sPyTypeObject %s;", sf
, self
.typename
)
42 Output("#define %s_Check(x) ((x)->ob_type == &%s)",
43 self
.prefix
, self
.typename
)
45 Output("typedef struct %s {", self
.objecttype
)
47 Output("PyObject_HEAD")
48 self
.outputStructMembers()
50 Output("} %s;", self
.objecttype
)
58 GeneratorGroup
.generate(self
)
61 Output("%sPyMethodChain %s_chain = { %s_methods, %s };",
62 self
.static
, self
.prefix
, self
.prefix
, self
.basechain
)
68 self
.outputTypeObject()
70 OutHeader2("End object type " + self
.name
)
72 def outputStructMembers(self
):
73 Output("%s ob_itself;", self
.itselftype
)
77 Output("%sPyObject *%s_New(itself)", self
.static
, self
.prefix
)
79 Output("%s %sitself;", self
.itselftype
, self
.argref
)
82 Output("%s *it;", self
.objecttype
)
83 self
.outputCheckNewArg()
84 Output("it = PyObject_NEW(%s, &%s);", self
.objecttype
, self
.typename
)
85 Output("if (it == NULL) return NULL;")
86 self
.outputInitStructMembers()
87 Output("return (PyObject *)it;")
90 def outputInitStructMembers(self
):
91 Output("it->ob_itself = %sitself;", self
.argref
)
93 def outputCheckNewArg(self
):
94 "Override this method to apply additional checks/conversions"
96 def outputConvert(self
):
97 Output("%s%s_Convert(v, p_itself)", self
.static
, self
.prefix
)
99 Output("PyObject *v;")
100 Output("%s *p_itself;", self
.itselftype
)
103 self
.outputCheckConvertArg()
104 Output("if (!%s_Check(v))", self
.prefix
)
106 Output('PyErr_SetString(PyExc_TypeError, "%s required");', self
.name
)
109 Output("*p_itself = ((%s *)v)->ob_itself;", self
.objecttype
)
113 def outputCheckConvertArg(self
):
114 "Override this method to apply additional conversions"
116 def outputDealloc(self
):
118 Output("static void %s_dealloc(self)", self
.prefix
)
120 Output("%s *self;", self
.objecttype
)
123 self
.outputCleanupStructMembers()
124 Output("PyMem_DEL(self);")
127 def outputCleanupStructMembers(self
):
128 self
.outputFreeIt("self->ob_itself")
130 def outputFreeIt(self
, name
):
131 Output("/* Cleanup of %s goes here */", name
)
133 def outputGetattr(self
):
135 Output("static PyObject *%s_getattr(self, name)", self
.prefix
)
137 Output("%s *self;", self
.objecttype
)
138 Output("char *name;")
141 self
.outputGetattrBody()
144 def outputGetattrBody(self
):
145 self
.outputGetattrHook()
146 Output("return Py_FindMethodInChain(&%s_chain, (PyObject *)self, name);",
149 def outputGetattrHook(self
):
152 def outputSetattr(self
):
154 Output("#define %s_setattr NULL", self
.prefix
)
156 def outputTypeObject(self
):
157 sf
= self
.static
and "staticforward "
159 Output("%sPyTypeObject %s = {", sf
, self
.typename
)
161 Output("PyObject_HEAD_INIT(&PyType_Type)")
162 Output("0, /*ob_size*/")
163 Output("\"%s\", /*tp_name*/", self
.name
)
164 Output("sizeof(%s), /*tp_basicsize*/", self
.objecttype
)
165 Output("0, /*tp_itemsize*/")
166 Output("/* methods */")
167 Output("(destructor) %s_dealloc, /*tp_dealloc*/", self
.prefix
)
168 Output("0, /*tp_print*/")
169 Output("(getattrfunc) %s_getattr, /*tp_getattr*/", self
.prefix
)
170 Output("(setattrfunc) %s_setattr, /*tp_setattr*/", self
.prefix
)
175 class GlobalObjectDefinition(ObjectDefinition
):
176 """Like ObjectDefinition but exports some parts.
178 XXX Should also somehow generate a .h file for them.
181 def __init__(self
, name
, prefix
= None, itselftype
= None):
182 ObjectDefinition
.__init
__(self
, name
, prefix
or name
, itselftype
or name
)