Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 99899b9

Browse files
committed
Added PEP253 support.
1 parent 6eadc6c commit 99899b9

1 file changed

Lines changed: 114 additions & 11 deletions

File tree

Tools/bgen/bgen/bgenObjectDefinition.py

Lines changed: 114 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
class 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+
208224
class 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

337440
class GlobalObjectDefinition(ObjectDefinition):
338441
"""Like ObjectDefinition but exports some parts.

0 commit comments

Comments
 (0)