Browse Source

[1452b] updated the python wrapper template with recent cleanups, mostly
with eliminating the need for reinterpret_cast.

JINMEI Tatuya 13 years ago
parent
commit
9d392668cd
1 changed files with 41 additions and 60 deletions
  1. 41 60
      src/lib/util/python/wrapper_template.cc

+ 41 - 60
src/lib/util/python/wrapper_template.cc

@@ -52,56 +52,12 @@ namespace {
 // Shortcut type which would be convenient for adding class variables safely.
 typedef CPPPyObjectContainer<s_@CPPCLASS@, @CPPCLASS@> @CPPCLASS@Container;
 
-//
-// We declare the functions here, the definitions are below
-// the type definition of the object, since both can use the other
-//
-
-// General creation and destruction
-int @CPPCLASS@_init(s_@CPPCLASS@* self, PyObject* args);
-void @CPPCLASS@_destroy(s_@CPPCLASS@* self);
-
-// These are the functions we export
-// ADD/REMOVE/MODIFY THE FOLLOWING AS APPROPRIATE FOR THE ACTUAL CLASS.
-//
-PyObject* @CPPCLASS@_toText(const s_@CPPCLASS@* const self);
-PyObject* @CPPCLASS@_str(PyObject* self);
-PyObject* @CPPCLASS@_richcmp(const s_@CPPCLASS@* const self,
-                            const s_@CPPCLASS@* const other, int op);
-
-// This is quite specific pydnspp.  For other wrappers this should probably
-// be removed.
-PyObject* @CPPCLASS@_toWire(const s_@CPPCLASS@* self, PyObject* args);
-
-// These are the functions we export
-// For a minimal support, we don't need them.
-
-// This list contains the actual set of functions we have in
-// python. Each entry has
-// 1. Python method name
-// 2. Our static function here
-// 3. Argument type
-// 4. Documentation
-PyMethodDef @CPPCLASS@_methods[] = {
-    { "to_text", reinterpret_cast<PyCFunction>(@CPPCLASS@_toText), METH_NOARGS,
-      "Returns the text representation" },
-    // This is quite specific pydnspp.  For other wrappers this should probably
-    // be removed:
-    { "to_wire", reinterpret_cast<PyCFunction>(@CPPCLASS@_toWire), METH_VARARGS,
-      "Converts the @CPPCLASS@ object to wire format.\n"
-      "The argument can be either a MessageRenderer or an object that "
-      "implements the sequence interface. If the object is mutable "
-      "(for instance a bytearray()), the wire data is added in-place.\n"
-      "If it is not (for instance a bytes() object), a new object is "
-      "returned" },
-    { NULL, NULL, 0, NULL }
-};
-
 // This is a template of typical code logic of python class initialization
 // with C++ backend.  You'll need to adjust it according to details of the
 // actual C++ class.
 int
-@CPPCLASS@_init(s_@CPPCLASS@* self, PyObject* args) {
+@CPPCLASS@_init(PyObject* po_self, PyObject* args, PyObject*) {
+    s_@CPPCLASS@* self = static_cast<s_@CPPCLASS@*>(po_self);
     try {
         if (PyArg_ParseTuple(args, "REPLACE ME")) {
             // YOU'LL NEED SOME VALIDATION, PREPARATION, ETC, HERE.
@@ -114,13 +70,14 @@ int
         PyErr_SetString(po_IscException, ex_what.c_str());
         return (-1);
     } catch (...) {
-        PyErr_SetString(po_IscException,
-                        "Unexpected exception in constructing @CPPCLASS@");
+        PyErr_SetString(PyExc_SystemError, "Unexpected C++ exception");
         return (-1);
     }
 
-    PyErr_SetString(PyExc_TypeError,
-                    "Invalid arguments to @CPPCLASS@ constructor");
+    // If we are here PyArg_ParseTuple() failed and TypeError should have
+    // been set.  If the constructor is more complicated and the control
+    // could reach this point for other reasons, an appropriate Python
+    // exception should be set by PyErr_SetString.
 
     return (-1);
 }
@@ -128,7 +85,8 @@ int
 // This is a template of typical code logic of python object destructor.
 // In many cases you can use it without modification, but check that carefully.
 void
-@CPPCLASS@_destroy(s_@CPPCLASS@* const self) {
+@CPPCLASS@_destroy(PyObject* po_self) {
+    s_@CPPCLASS@* self = static_cast<s_@CPPCLASS@*>(po_self);
     delete self->cppobj;
     self->cppobj = NULL;
     Py_TYPE(self)->tp_free(self);
@@ -137,7 +95,8 @@ void
 // This should be able to be used without modification as long as the
 // underlying C++ class has toText().
 PyObject*
-@CPPCLASS@_toText(const s_@CPPCLASS@* const self) {
+@CPPCLASS@_toText(PyObject* po_self) {
+    const s_@CPPCLASS@* self = static_cast<const s_@CPPCLASS@*>(po_self);
     try {
         // toText() could throw, so we need to catch any exceptions below.
         return (Py_BuildValue("s", self->cppobj->toText().c_str()));
@@ -160,11 +119,17 @@ PyObject*
                                 const_cast<char*>("")));
 }
 
+// This is quite specific isc.dns.  For other wrappers this should probably
+// be removed.
+PyObject* @CPPCLASS@_toWire(PyObject* self, PyObject* args) {
+}
+
 PyObject* 
-@CPPCLASS@_richcmp(const s_@CPPCLASS@* const self,
-                   const s_@CPPCLASS@* const other,
-                   const int op)
-{
+@CPPCLASS@_richcmp(PyObject* po_self, PyObject* po_other, const int op) {
+    const s_@CPPCLASS@* const self = static_cast<const s_@CPPCLASS@*>(po_self);
+    const s_@CPPCLASS@* const other =
+        static_cast<const s_@CPPCLASS@*>(po_other);
+
     bool c = false;
 
     // Check for null and if the types match. If different type,
@@ -200,6 +165,22 @@ PyObject*
         Py_RETURN_FALSE;
     }
 }
+
+// This list contains the actual set of functions we have in
+// python. Each entry has
+// 1. Python method name
+// 2. Our static function here
+// 3. Argument type
+// 4. Documentation
+PyMethodDef @CPPCLASS@_methods[] = {
+    { "to_text", @CPPCLASS@_toText, METH_NOARGS,
+      @CPPCLASS@_toText_doc },
+    // This is quite specific isc.dns.  For other wrappers this should probably
+    // be removed:
+    { "to_wire", @CPPCLASS@_toWire, METH_VARARGS,
+      @CPPCLASS@_toWire_doc },
+    { NULL, NULL, 0, NULL }
+};
 } // end of unnamed namespace
 
 namespace isc {
@@ -213,7 +194,7 @@ PyTypeObject @cppclass@_type = {
     "@MODULE@.@CPPCLASS@",
     sizeof(s_@CPPCLASS@),                 // tp_basicsize
     0,                                  // tp_itemsize
-    reinterpret_cast<destructor>(@CPPCLASS@_destroy),       // tp_dealloc
+    @CPPCLASS@_destroy,                 // tp_dealloc
     NULL,                               // tp_print
     NULL,                               // tp_getattr
     NULL,                               // tp_setattr
@@ -230,11 +211,11 @@ PyTypeObject @cppclass@_type = {
     NULL,                               // tp_setattro
     NULL,                               // tp_as_buffer
     Py_TPFLAGS_DEFAULT,                 // tp_flags
-    "The @CPPCLASS@ class objects is...(COMPLETE THIS)",
+    @CPPCLASS@_doc,
     NULL,                               // tp_traverse
     NULL,                               // tp_clear
     // THIS MAY HAVE TO BE CHANGED TO NULL:
-    reinterpret_cast<richcmpfunc>(@CPPCLASS@_richcmp), // tp_richcompare
+    @CPPCLASS@_richcmp,                 // tp_richcompare
     0,                                  // tp_weaklistoffset
     NULL,                               // tp_iter
     NULL,                               // tp_iternext
@@ -246,7 +227,7 @@ PyTypeObject @cppclass@_type = {
     NULL,                               // tp_descr_get
     NULL,                               // tp_descr_set
     0,                                  // tp_dictoffset
-    reinterpret_cast<initproc>(@CPPCLASS@_init),            // tp_init
+    @CPPCLASS@_init,                    // tp_init
     NULL,                               // tp_alloc
     PyType_GenericNew,                  // tp_new
     NULL,                               // tp_free