summaryrefslogtreecommitdiffstats
path: root/Tools
diff options
context:
space:
mode:
authorJack Jansen <jack.jansen@cwi.nl>2002-11-25 16:36:49 (GMT)
committerJack Jansen <jack.jansen@cwi.nl>2002-11-25 16:36:49 (GMT)
commit3d654d6dff9de4ec1034dff667ff665fa5456215 (patch)
treefb4c04cfbd8e3d22eb5978553504acab68accaa6 /Tools
parent9e7453dc718431cef3832f6ab32c57f64f574dfb (diff)
downloadcpython-3d654d6dff9de4ec1034dff667ff665fa5456215.zip
cpython-3d654d6dff9de4ec1034dff667ff665fa5456215.tar.gz
cpython-3d654d6dff9de4ec1034dff667ff665fa5456215.tar.bz2
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.
Diffstat (limited to 'Tools')
-rw-r--r--Tools/bgen/bgen/bgenObjectDefinition.py129
1 files changed, 127 insertions, 2 deletions
diff --git a/Tools/bgen/bgen/bgenObjectDefinition.py b/Tools/bgen/bgen/bgenObjectDefinition.py
index 86878b9..d50490a 100644
--- a/Tools/bgen/bgen/bgenObjectDefinition.py
+++ b/Tools/bgen/bgen/bgenObjectDefinition.py
@@ -23,6 +23,8 @@ class ObjectDefinition(GeneratorGroup):
self.argref = "" # set to "*" if arg to <type>_New should be pointer
self.static = "static " # set to "" to make <type>_New and <type>_Convert public
self.modulename = None
+ if hasattr(self, "assertions"):
+ self.assertions()
def add(self, g, dupcheck=0):
g.setselftype(self.objecttype, self.itselftype)
@@ -62,8 +64,7 @@ class ObjectDefinition(GeneratorGroup):
GeneratorGroup.generate(self)
Output()
- Output("%sPyMethodChain %s_chain = { %s_methods, %s };",
- self.static, self.prefix, self.prefix, self.basechain)
+ self.outputMethodChain()
self.outputGetattr()
@@ -78,6 +79,10 @@ class ObjectDefinition(GeneratorGroup):
self.outputTypeObject()
OutHeader2("End object type " + self.name)
+
+ def outputMethodChain(self):
+ Output("%sPyMethodChain %s_chain = { %s_methods, %s };",
+ self.static, self.prefix, self.prefix, self.basechain)
def outputStructMembers(self):
Output("%s ob_itself;", self.itselftype)
@@ -200,7 +205,127 @@ class ObjectDefinition(GeneratorGroup):
self.name)
DedentLevel()
+class PEP252Mixin:
+ getsetlist = []
+
+ def assertions(self):
+ # Check that various things aren't overridden. If they are it could
+ # signify a bgen-client that has been partially converted to PEP252.
+ assert self.outputGetattr.im_func == PEP252Mixin.outputGetattr.im_func
+ assert self.outputSetattr.im_func == PEP252Mixin.outputSetattr.im_func
+ assert self.outputGetattrBody == None
+ assert self.outputGetattrHook == None
+
+ def outputGetattr(self):
+ pass
+
+ outputGetattrBody = None
+
+ outputGetattrHook = None
+ def outputSetattr(self):
+ pass
+
+ def outputMethodChain(self):
+ # This is a good place to output the getters and setters
+ self.outputGetSetList()
+
+ def outputHook(self, name):
+ methodname = "outputHook_" + name
+ if hasattr(self, methodname):
+ func = getattr(self, methodname)
+ func()
+ else:
+ Output("0, /*%s*/", methodname)
+
+ def outputTypeObject(self):
+ sf = self.static and "static "
+ Output()
+ Output("%sPyTypeObject %s = {", sf, self.typename)
+ IndentLevel()
+ Output("PyObject_HEAD_INIT(NULL)")
+ Output("0, /*ob_size*/")
+ if self.modulename:
+ Output("\"%s.%s\", /*tp_name*/", self.modulename, self.name)
+ else:
+ Output("\"%s\", /*tp_name*/", self.name)
+ Output("sizeof(%s), /*tp_basicsize*/", self.objecttype)
+ Output("0, /*tp_itemsize*/")
+
+ Output("/* methods */")
+ Output("(destructor) %s_dealloc, /*tp_dealloc*/", self.prefix)
+ Output("0, /*tp_print*/")
+ Output("(getattrfunc)0, /*tp_getattr*/")
+ Output("(setattrfunc)0, /*tp_setattr*/")
+ Output("(cmpfunc) %s_compare, /*tp_compare*/", self.prefix)
+ Output("(reprfunc) %s_repr, /*tp_repr*/", self.prefix)
+
+ Output("(PyNumberMethods *)0, /* tp_as_number */")
+ Output("(PySequenceMethods *)0, /* tp_as_sequence */")
+ Output("(PyMappingMethods *)0, /* tp_as_mapping */")
+
+ Output("(hashfunc) %s_hash, /*tp_hash*/", self.prefix)
+ Output("0, /*tp_call*/")
+ Output("0, /*tp_str*/")
+ Output("PyObject_GenericGetAttr, /*tp_getattro*/")
+ Output("PyObject_GenericSetAttr, /*tp_setattro */")
+
+ self.outputHook("tp_as_buffer")
+ self.outputHook("tp_flags")
+ self.outputHook("tp_doc")
+ self.outputHook("tp_traverse")
+ self.outputHook("tp_clear")
+ self.outputHook("tp_richcompare")
+ self.outputHook("tp_weaklistoffset")
+ self.outputHook("tp_iter")
+ self.outputHook("tp_iternext")
+ Output("%s_methods, /* tp_methods */", self.prefix)
+ self.outputHook("tp_members")
+ Output("%s_getsetlist, /*tp_getset*/", self.prefix)
+ self.outputHook("tp_base")
+ DedentLevel()
+ Output("};")
+
+ def outputGetSetList(self):
+ if self.getsetlist:
+ for name, get, set, doc in self.getsetlist:
+ if get:
+ self.outputGetter(name, get)
+ else:
+ Output("#define %s_get_%s NULL", self.prefix, name)
+ if set:
+ self.outputSetter(name, set)
+ else:
+ Output("#define %s_set_%s NULL", self.prefix, name)
+
+ Output("static PyGetSetDef %s_getsetlist[] = {", self.prefix)
+ IndentLevel()
+ for name, get, set, doc in self.getsetlist:
+ if doc:
+ doc = `doc`
+ else:
+ doc = "NULL"
+ Output("{\"%s\", (getter)%s_get_%s, (setter)%s_set_%s, %s}",
+ name, self.prefix, name, self.prefix, name, doc)
+ DedentLevel()
+ Output("};")
+ else:
+ Output("#define %s_getsetlist NULL", self.prefix)
+
+ def outputGetter(self, name, code):
+ Output("static PyObject *%s_get_%s(%s *self, void *closure)",
+ self.prefix, name, self.objecttype)
+ OutLbrace()
+ Output(code)
+ OutRbrace()
+
+ def outputSetter(self, name, code):
+ Output("static int %s_get_%s(%s *self, PyObject *v, void *closure)",
+ self.prefix, name, self.objecttype)
+ OutLbrace()
+ Output(code)
+ Output("return 0;")
+ OutRbrace()
class GlobalObjectDefinition(ObjectDefinition):
"""Like ObjectDefinition but exports some parts.