|
@@ -52,56 +52,12 @@ namespace {
|
|
// Shortcut type which would be convenient for adding class variables safely.
|
|
// Shortcut type which would be convenient for adding class variables safely.
|
|
typedef CPPPyObjectContainer<s_@CPPCLASS@, @CPPCLASS@> @CPPCLASS@Container;
|
|
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
|
|
// 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
|
|
// with C++ backend. You'll need to adjust it according to details of the
|
|
// actual C++ class.
|
|
// actual C++ class.
|
|
int
|
|
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 {
|
|
try {
|
|
if (PyArg_ParseTuple(args, "REPLACE ME")) {
|
|
if (PyArg_ParseTuple(args, "REPLACE ME")) {
|
|
// YOU'LL NEED SOME VALIDATION, PREPARATION, ETC, HERE.
|
|
// YOU'LL NEED SOME VALIDATION, PREPARATION, ETC, HERE.
|
|
@@ -114,13 +70,14 @@ int
|
|
PyErr_SetString(po_IscException, ex_what.c_str());
|
|
PyErr_SetString(po_IscException, ex_what.c_str());
|
|
return (-1);
|
|
return (-1);
|
|
} catch (...) {
|
|
} catch (...) {
|
|
- PyErr_SetString(po_IscException,
|
|
|
|
- "Unexpected exception in constructing @CPPCLASS@");
|
|
|
|
|
|
+ PyErr_SetString(PyExc_SystemError, "Unexpected C++ exception");
|
|
return (-1);
|
|
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);
|
|
return (-1);
|
|
}
|
|
}
|
|
@@ -128,7 +85,8 @@ int
|
|
// This is a template of typical code logic of python object destructor.
|
|
// 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.
|
|
// In many cases you can use it without modification, but check that carefully.
|
|
void
|
|
void
|
|
-@CPPCLASS@_destroy(s_@CPPCLASS@* const self) {
|
|
|
|
|
|
+@CPPCLASS@_destroy(PyObject* po_self) {
|
|
|
|
+ s_@CPPCLASS@* self = static_cast<s_@CPPCLASS@*>(po_self);
|
|
delete self->cppobj;
|
|
delete self->cppobj;
|
|
self->cppobj = NULL;
|
|
self->cppobj = NULL;
|
|
Py_TYPE(self)->tp_free(self);
|
|
Py_TYPE(self)->tp_free(self);
|
|
@@ -137,7 +95,8 @@ void
|
|
// This should be able to be used without modification as long as the
|
|
// This should be able to be used without modification as long as the
|
|
// underlying C++ class has toText().
|
|
// underlying C++ class has toText().
|
|
PyObject*
|
|
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 {
|
|
try {
|
|
// toText() could throw, so we need to catch any exceptions below.
|
|
// toText() could throw, so we need to catch any exceptions below.
|
|
return (Py_BuildValue("s", self->cppobj->toText().c_str()));
|
|
return (Py_BuildValue("s", self->cppobj->toText().c_str()));
|
|
@@ -160,11 +119,17 @@ PyObject*
|
|
const_cast<char*>("")));
|
|
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*
|
|
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;
|
|
bool c = false;
|
|
|
|
|
|
// Check for null and if the types match. If different type,
|
|
// Check for null and if the types match. If different type,
|
|
@@ -200,6 +165,22 @@ PyObject*
|
|
Py_RETURN_FALSE;
|
|
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
|
|
} // end of unnamed namespace
|
|
|
|
|
|
namespace isc {
|
|
namespace isc {
|
|
@@ -213,7 +194,7 @@ PyTypeObject @cppclass@_type = {
|
|
"@MODULE@.@CPPCLASS@",
|
|
"@MODULE@.@CPPCLASS@",
|
|
sizeof(s_@CPPCLASS@), // tp_basicsize
|
|
sizeof(s_@CPPCLASS@), // tp_basicsize
|
|
0, // tp_itemsize
|
|
0, // tp_itemsize
|
|
- reinterpret_cast<destructor>(@CPPCLASS@_destroy), // tp_dealloc
|
|
|
|
|
|
+ @CPPCLASS@_destroy, // tp_dealloc
|
|
NULL, // tp_print
|
|
NULL, // tp_print
|
|
NULL, // tp_getattr
|
|
NULL, // tp_getattr
|
|
NULL, // tp_setattr
|
|
NULL, // tp_setattr
|
|
@@ -230,11 +211,11 @@ PyTypeObject @cppclass@_type = {
|
|
NULL, // tp_setattro
|
|
NULL, // tp_setattro
|
|
NULL, // tp_as_buffer
|
|
NULL, // tp_as_buffer
|
|
Py_TPFLAGS_DEFAULT, // tp_flags
|
|
Py_TPFLAGS_DEFAULT, // tp_flags
|
|
- "The @CPPCLASS@ class objects is...(COMPLETE THIS)",
|
|
|
|
|
|
+ @CPPCLASS@_doc,
|
|
NULL, // tp_traverse
|
|
NULL, // tp_traverse
|
|
NULL, // tp_clear
|
|
NULL, // tp_clear
|
|
// THIS MAY HAVE TO BE CHANGED TO NULL:
|
|
// THIS MAY HAVE TO BE CHANGED TO NULL:
|
|
- reinterpret_cast<richcmpfunc>(@CPPCLASS@_richcmp), // tp_richcompare
|
|
|
|
|
|
+ @CPPCLASS@_richcmp, // tp_richcompare
|
|
0, // tp_weaklistoffset
|
|
0, // tp_weaklistoffset
|
|
NULL, // tp_iter
|
|
NULL, // tp_iter
|
|
NULL, // tp_iternext
|
|
NULL, // tp_iternext
|
|
@@ -246,7 +227,7 @@ PyTypeObject @cppclass@_type = {
|
|
NULL, // tp_descr_get
|
|
NULL, // tp_descr_get
|
|
NULL, // tp_descr_set
|
|
NULL, // tp_descr_set
|
|
0, // tp_dictoffset
|
|
0, // tp_dictoffset
|
|
- reinterpret_cast<initproc>(@CPPCLASS@_init), // tp_init
|
|
|
|
|
|
+ @CPPCLASS@_init, // tp_init
|
|
NULL, // tp_alloc
|
|
NULL, // tp_alloc
|
|
PyType_GenericNew, // tp_new
|
|
PyType_GenericNew, // tp_new
|
|
NULL, // tp_free
|
|
NULL, // tp_free
|