// 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.
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);
}
// 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);
// 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()));
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,
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 {
"@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
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
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