44class ObjectDefinition (GeneratorGroup ):
55 "Spit out code that together defines a new Python object type"
66 basechain = "NULL"
7+ tp_flags = "Py_TPFLAGS_DEFAULT"
8+ basetype = None
79
810 def __init__ (self , name , prefix , itselftype ):
911 """ObjectDefinition constructor. May be extended, but do not override.
@@ -45,7 +47,11 @@ def generate(self):
4547 sf = self .static and "static "
4648 Output ("%sPyTypeObject %s;" , sf , self .typename )
4749 Output ()
48- Output ("#define %s_Check(x) ((x)->ob_type == &%s)" ,
50+ if self .basetype :
51+ Output ("#define %s_Check(x) ((x)->ob_type == &%s || PyObject_TypeCheck((x), %s)" ,
52+ self .prefix , self .typename , self .typename )
53+ else :
54+ Output ("#define %s_Check(x) ((x)->ob_type == &%s)" ,
4955 self .prefix , self .typename )
5056 Output ()
5157 Output ("typedef struct %s {" , self .objecttype )
@@ -76,6 +82,8 @@ def generate(self):
7682
7783 self .outputHash ()
7884
85+ self .outputPEP253Hooks ()
86+
7987 self .outputTypeObject ()
8088
8189 OutHeader2 ("End object type " + self .name )
@@ -96,6 +104,8 @@ def outputNew(self):
96104 self .outputCheckNewArg ()
97105 Output ("it = PyObject_NEW(%s, &%s);" , self .objecttype , self .typename )
98106 Output ("if (it == NULL) return NULL;" )
107+ if self .basetype :
108+ Output ("/* XXXX Should we tp_init or tp_new our basetype? */" )
99109 self .outputInitStructMembers ()
100110 Output ("return (PyObject *)it;" )
101111 OutRbrace ()
@@ -128,7 +138,10 @@ def outputDealloc(self):
128138 Output ("static void %s_dealloc(%s *self)" , self .prefix , self .objecttype )
129139 OutLbrace ()
130140 self .outputCleanupStructMembers ()
131- Output ("PyObject_Del(self);" )
141+ if self .basetype :
142+ Output ("%s.tp_dealloc(self)" , self .basetype )
143+ else :
144+ Output ("PyObject_Del(self);" )
132145 OutRbrace ()
133146
134147 def outputCleanupStructMembers (self ):
@@ -197,14 +210,17 @@ def outputTypeObject(self):
197210
198211 def outputTypeObjectInitializer (self ):
199212 Output ("""%s.ob_type = &PyType_Type;""" , self .typename );
213+ if self .basetype :
214+ Output ("%s.tp_base = %s;" , self .typename , self .basetype )
215+ Output ("""Py_INCREF(&%s);""" , self .typename )
216+ Output ("PyModule_AddObject(m, \" %s\" , (PyObject *)&%s);" , self .name , self .typename );
217+ Output ("/* Backward-compatible name */" )
200218 Output ("""Py_INCREF(&%s);""" , self .typename );
201- Output ("""if (PyDict_SetItemString(d, "%sType", (PyObject *)&%s) != 0)""" ,
202- self .name , self .typename );
203- IndentLevel ()
204- Output ("""Py_FatalError("can\' t initialize %sType");""" ,
205- self .name )
206- DedentLevel ()
219+ Output ("PyModule_AddObject(m, \" %sType\" , (PyObject *)&%s);" , self .name , self .typename );
207220
221+ def outputPEP253Hooks (self ):
222+ pass
223+
208224class PEP252Mixin :
209225 getsetlist = []
210226
@@ -237,7 +253,7 @@ def outputHook(self, name):
237253 func = getattr (self , methodname )
238254 func ()
239255 else :
240- Output ("0, /*%s*/" , methodname )
256+ Output ("0, /*%s*/" , name )
241257
242258 def outputTypeObject (self ):
243259 sf = self .static and "static "
@@ -266,13 +282,13 @@ def outputTypeObject(self):
266282 Output ("(PyMappingMethods *)0, /* tp_as_mapping */" )
267283
268284 Output ("(hashfunc) %s_hash, /*tp_hash*/" , self .prefix )
269- Output ( "0, /* tp_call*/ " )
285+ self . outputHook ( " tp_call" )
270286 Output ("0, /*tp_str*/" )
271287 Output ("PyObject_GenericGetAttr, /*tp_getattro*/" )
272288 Output ("PyObject_GenericSetAttr, /*tp_setattro */" )
273289
274290 self .outputHook ("tp_as_buffer" )
275- self . outputHook ( " tp_flags" )
291+ Output ( "%s, /* tp_flags */" , self . tp_flags )
276292 self .outputHook ("tp_doc" )
277293 self .outputHook ("tp_traverse" )
278294 self .outputHook ("tp_clear" )
@@ -284,6 +300,14 @@ def outputTypeObject(self):
284300 self .outputHook ("tp_members" )
285301 Output ("%s_getsetlist, /*tp_getset*/" , self .prefix )
286302 self .outputHook ("tp_base" )
303+ self .outputHook ("tp_dict" )
304+ self .outputHook ("tp_descr_get" )
305+ self .outputHook ("tp_descr_set" )
306+ self .outputHook ("tp_dictoffset" )
307+ self .outputHook ("tp_init" )
308+ self .outputHook ("tp_alloc" )
309+ self .outputHook ("tp_new" )
310+ self .outputHook ("tp_free" )
287311 DedentLevel ()
288312 Output ("};" )
289313
@@ -333,6 +357,85 @@ def outputSetter(self, name, code):
333357 Output ("return 0;" )
334358 OutRbrace ()
335359 Output ()
360+
361+ class PEP253Mixin (PEP252Mixin ):
362+ tp_flags = "Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE"
363+
364+ def outputHook_tp_init (self ):
365+ Output ("%s_tp_init, /* tp_init */" , self .prefix )
366+
367+ def outputHook_tp_alloc (self ):
368+ Output ("%s_tp_alloc, /* tp_alloc */" , self .prefix )
369+
370+ def outputHook_tp_new (self ):
371+ Output ("%s_tp_new, /* tp_new */" , self .prefix )
372+
373+ def outputHook_tp_free (self ):
374+ Output ("%s_tp_free, /* tp_free */" , self .prefix )
375+
376+ output_tp_initBody = None
377+
378+ def output_tp_init (self ):
379+ if self .output_tp_initBody :
380+ Output ("static int %s_init(PyObject *self, PyObject *args, PyObject *kwds)" , self .prefix )
381+ OutLbrace ()
382+ self .output_tp_initBody ()
383+ OutRbrace ()
384+ else :
385+ Output ("#define %s_tp_init 0" , self .prefix )
386+ Output ()
387+
388+ output_tp_allocBody = None
389+
390+ def output_tp_alloc (self ):
391+ if self .output_tp_allocBody :
392+ Output ("static PyObject *%s_tp_alloc(PyTypeObject *type, int nitems)" ,
393+ self .prefix )
394+ OutLbrace ()
395+ self .output_tp_allocBody ()
396+ OutRbrace ()
397+ else :
398+ Output ("#define %s_tp_alloc PyType_GenericAlloc" , self .prefix )
399+ Output ()
400+
401+ def output_tp_newBody (self ):
402+ Output ("PyObject *self;" );
403+ Output ("%s itself;" , self .itselftype );
404+ Output ("char *kw[] = {\" itself\" , 0};" )
405+ Output ()
406+ Output ("if (!PyArg_ParseTupleAndKeywords(args, kwds, \" O&\" , kw, %s_Convert, &itself)) return NULL;" ,
407+ self .prefix );
408+ Output ("if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;" )
409+ Output ("((%s *)self)->ob_itself = itself;" , self .objecttype )
410+ Output ("return self;" )
411+
412+ def output_tp_new (self ):
413+ if self .output_tp_newBody :
414+ Output ("static PyObject *%s_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds)" , self .prefix )
415+ OutLbrace ()
416+ self .output_tp_newBody ()
417+ OutRbrace ()
418+ else :
419+ Output ("#define %s_tp_new PyType_GenericNew" , self .prefix )
420+ Output ()
421+
422+ output_tp_freeBody = None
423+
424+ def output_tp_free (self ):
425+ if self .output_tp_freeBody :
426+ Output ("static void %s_tp_free(PyObject *self)" , self .prefix )
427+ OutLbrace ()
428+ self .output_tp_freeBody ()
429+ OutRbrace ()
430+ else :
431+ Output ("#define %s_tp_free PyObject_Del" , self .prefix )
432+ Output ()
433+
434+ def outputPEP253Hooks (self ):
435+ self .output_tp_init ()
436+ self .output_tp_alloc ()
437+ self .output_tp_new ()
438+ self .output_tp_free ()
336439
337440class GlobalObjectDefinition (ObjectDefinition ):
338441 """Like ObjectDefinition but exports some parts.
0 commit comments