Skip to content

Commit 1b0fddc

Browse files
author
jackjansen
committed
Added a class PEP252Mixin. By adding this to your ObjectDefinition you
get PEP-252 style objects in stead of old-fashioned objects. In stead of defining a GetattrHook you declare a class variable getsetlist, which contains tuples (name, getcode, setcode, docstring). Only lightly tested: the code still works if you don't inherit PEP252Mixin and the code works if you inherit it but don't define any getters or setters. Also, this will not work together with the "poor mans inheritance" offered by method chains, so the CF module will remain with old-style objects until PEP253 is supported too. git-svn-id: http://svn.python.org/projects/python/trunk@29880 6015fed2-1504-0410-9fe1-9d1591cc4771
1 parent 3710913 commit 1b0fddc

1 file changed

Lines changed: 127 additions & 2 deletions

File tree

Tools/bgen/bgen/bgenObjectDefinition.py

Lines changed: 127 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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

205330
class GlobalObjectDefinition(ObjectDefinition):
206331
"""Like ObjectDefinition but exports some parts.

0 commit comments

Comments
 (0)