@@ -23,6 +23,8 @@ def __init__(self, name, prefix, itselftype):
2323 self .argref = "" # set to "*" if arg to <type>_New should be pointer
2424 self .static = "static " # set to "" to make <type>_New and <type>_Convert public
2525 self .modulename = None
26+ if hasattr (self , "assertions" ):
27+ self .assertions ()
2628
2729 def add (self , g , dupcheck = 0 ):
2830 g .setselftype (self .objecttype , self .itselftype )
@@ -62,8 +64,7 @@ def generate(self):
6264 GeneratorGroup .generate (self )
6365
6466 Output ()
65- Output ("%sPyMethodChain %s_chain = { %s_methods, %s };" ,
66- self .static , self .prefix , self .prefix , self .basechain )
67+ self .outputMethodChain ()
6768
6869 self .outputGetattr ()
6970
@@ -78,6 +79,10 @@ def generate(self):
7879 self .outputTypeObject ()
7980
8081 OutHeader2 ("End object type " + self .name )
82+
83+ def outputMethodChain (self ):
84+ Output ("%sPyMethodChain %s_chain = { %s_methods, %s };" ,
85+ self .static , self .prefix , self .prefix , self .basechain )
8186
8287 def outputStructMembers (self ):
8388 Output ("%s ob_itself;" , self .itselftype )
@@ -200,7 +205,127 @@ def outputTypeObjectInitializer(self):
200205 self .name )
201206 DedentLevel ()
202207
208+ class PEP252Mixin :
209+ getsetlist = []
210+
211+ def assertions (self ):
212+ # Check that various things aren't overridden. If they are it could
213+ # signify a bgen-client that has been partially converted to PEP252.
214+ assert self .outputGetattr .im_func == PEP252Mixin .outputGetattr .im_func
215+ assert self .outputSetattr .im_func == PEP252Mixin .outputSetattr .im_func
216+ assert self .outputGetattrBody == None
217+ assert self .outputGetattrHook == None
218+
219+ def outputGetattr (self ):
220+ pass
221+
222+ outputGetattrBody = None
223+
224+ outputGetattrHook = None
203225
226+ def outputSetattr (self ):
227+ pass
228+
229+ def outputMethodChain (self ):
230+ # This is a good place to output the getters and setters
231+ self .outputGetSetList ()
232+
233+ def outputHook (self , name ):
234+ methodname = "outputHook_" + name
235+ if hasattr (self , methodname ):
236+ func = getattr (self , methodname )
237+ func ()
238+ else :
239+ Output ("0, /*%s*/" , methodname )
240+
241+ def outputTypeObject (self ):
242+ sf = self .static and "static "
243+ Output ()
244+ Output ("%sPyTypeObject %s = {" , sf , self .typename )
245+ IndentLevel ()
246+ Output ("PyObject_HEAD_INIT(NULL)" )
247+ Output ("0, /*ob_size*/" )
248+ if self .modulename :
249+ Output ("\" %s.%s\" , /*tp_name*/" , self .modulename , self .name )
250+ else :
251+ Output ("\" %s\" , /*tp_name*/" , self .name )
252+ Output ("sizeof(%s), /*tp_basicsize*/" , self .objecttype )
253+ Output ("0, /*tp_itemsize*/" )
254+
255+ Output ("/* methods */" )
256+ Output ("(destructor) %s_dealloc, /*tp_dealloc*/" , self .prefix )
257+ Output ("0, /*tp_print*/" )
258+ Output ("(getattrfunc)0, /*tp_getattr*/" )
259+ Output ("(setattrfunc)0, /*tp_setattr*/" )
260+ Output ("(cmpfunc) %s_compare, /*tp_compare*/" , self .prefix )
261+ Output ("(reprfunc) %s_repr, /*tp_repr*/" , self .prefix )
262+
263+ Output ("(PyNumberMethods *)0, /* tp_as_number */" )
264+ Output ("(PySequenceMethods *)0, /* tp_as_sequence */" )
265+ Output ("(PyMappingMethods *)0, /* tp_as_mapping */" )
266+
267+ Output ("(hashfunc) %s_hash, /*tp_hash*/" , self .prefix )
268+ Output ("0, /*tp_call*/" )
269+ Output ("0, /*tp_str*/" )
270+ Output ("PyObject_GenericGetAttr, /*tp_getattro*/" )
271+ Output ("PyObject_GenericSetAttr, /*tp_setattro */" )
272+
273+ self .outputHook ("tp_as_buffer" )
274+ self .outputHook ("tp_flags" )
275+ self .outputHook ("tp_doc" )
276+ self .outputHook ("tp_traverse" )
277+ self .outputHook ("tp_clear" )
278+ self .outputHook ("tp_richcompare" )
279+ self .outputHook ("tp_weaklistoffset" )
280+ self .outputHook ("tp_iter" )
281+ self .outputHook ("tp_iternext" )
282+ Output ("%s_methods, /* tp_methods */" , self .prefix )
283+ self .outputHook ("tp_members" )
284+ Output ("%s_getsetlist, /*tp_getset*/" , self .prefix )
285+ self .outputHook ("tp_base" )
286+ DedentLevel ()
287+ Output ("};" )
288+
289+ def outputGetSetList (self ):
290+ if self .getsetlist :
291+ for name , get , set , doc in self .getsetlist :
292+ if get :
293+ self .outputGetter (name , get )
294+ else :
295+ Output ("#define %s_get_%s NULL" , self .prefix , name )
296+ if set :
297+ self .outputSetter (name , set )
298+ else :
299+ Output ("#define %s_set_%s NULL" , self .prefix , name )
300+
301+ Output ("static PyGetSetDef %s_getsetlist[] = {" , self .prefix )
302+ IndentLevel ()
303+ for name , get , set , doc in self .getsetlist :
304+ if doc :
305+ doc = `doc`
306+ else :
307+ doc = "NULL"
308+ Output ("{\" %s\" , (getter)%s_get_%s, (setter)%s_set_%s, %s}" ,
309+ name , self .prefix , name , self .prefix , name , doc )
310+ DedentLevel ()
311+ Output ("};" )
312+ else :
313+ Output ("#define %s_getsetlist NULL" , self .prefix )
314+
315+ def outputGetter (self , name , code ):
316+ Output ("static PyObject *%s_get_%s(%s *self, void *closure)" ,
317+ self .prefix , name , self .objecttype )
318+ OutLbrace ()
319+ Output (code )
320+ OutRbrace ()
321+
322+ def outputSetter (self , name , code ):
323+ Output ("static int %s_get_%s(%s *self, PyObject *v, void *closure)" ,
324+ self .prefix , name , self .objecttype )
325+ OutLbrace ()
326+ Output (code )
327+ Output ("return 0;" )
328+ OutRbrace ()
204329
205330class GlobalObjectDefinition (ObjectDefinition ):
206331 """Like ObjectDefinition but exports some parts.
0 commit comments