[Python-Dev] Define metatype and a type that uses it
Erik Groeneveld
erik at cq2.nl
Wed Jul 8 14:43:29 CEST 2009
L.S.
I am working on an extension that allows one to open Java .jar files
and use the objects defined in it (via CNI or JNI) in Python. It
works like a charm, but I am stuck with the definition of a metatype
for the wrappers. I have to do this in Python now, with a helper
class.
I did find examples of how to define metatypes, but I can't find
anything on how to declare one type using this metatype.
Could anyone point me to examples or documentation or help me fix my code below?
What I have is a type JObject that has a metatype JObjectMeta, but the
objects created from it seem not properly initialized. If I call
PyString_Str(self) in JObjectMeta_init, it seg faults. De Python code
that initiates this is:
class MyJObject(JObject):
pass
Below is the complete, contained code of the extension.
Thanks in advance,
Erik Groeneveld
#include <Python.h>
/*************** JObjectMeta *******************/
typedef struct {
PyObject_HEAD
} JObjectMeta;
PyTypeObject JObjectMetaType = {
PyObject_HEAD_INIT(NULL)
};
int JObjectMeta_init(PyObject* self, PyObject* args, PyObject *kwargs) {
printf("before str\n");
PyObject_Str(self);
printf("after str\n");
return 0;
}
PyObject* JObjectMeta_getattro(PyObject *self, PyObject *name) {
return PyBaseObject_Type.tp_getattro(self, name);
}
/*************** JObject ***********************/
typedef struct {
PyObject_HEAD
} JObject;
PyTypeObject JObjectType = {
PyObject_HEAD_INIT(&JObjectMetaType)
};
int JObject_init(PyObject* self, PyObject* args, PyObject *kwargs) {
return 0;
}
static PyMethodDef methods[] = {
{NULL, NULL, 0, NULL}
};
/*************** INIT *******************/
PyMODINIT_FUNC
initmetaclass(void) {
JObjectMetaType.tp_name = "metaclass.JObjectMeta";
JObjectMetaType.tp_basicsize = sizeof(JObjectMeta);
JObjectMetaType.tp_flags = Py_TPFLAGS_DEFAULT;
JObjectMetaType.tp_doc = "JObject objects";
JObjectMetaType.tp_init = JObjectMeta_init;
JObjectMetaType.tp_base = &PyType_Type; // must ?
JObjectMetaType.tp_new = PyType_GenericNew;
JObjectMetaType.tp_getattro = JObjectMeta_getattro;
JObjectType.tp_name = "metaclass.JObject";
JObjectType.tp_basicsize = sizeof(JObject);
JObjectType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE;
JObjectType.tp_doc = "JObjectMeta objects";
JObjectType.tp_init = JObject_init;
JObjectType.tp_base = &JObjectMetaType; // must ?
JObjectType.tp_new = PyType_GenericNew;
PyObject* module = Py_InitModule3("metaclass", methods, "Metaclass
try out.");
if (module == NULL) {
PyErr_Print();
exit(-1);
}
if (PyType_Ready(&JObjectMetaType) < 0) {
PyErr_Print();
exit(-1);
}
if (PyModule_AddObject(module, "JObjectMeta", (PyObject*)
&JObjectMetaType) < 0) {
PyErr_Print();
exit(-1);
}
if (PyType_Ready(&JObjectType) < 0) {
PyErr_Print();
exit(-1);
}
if (PyModule_AddObject(module, "JObject", (PyObject*) &JObjectType) < 0 ) {
PyErr_Print();
exit(-1);
}
}
More information about the Python-Dev
mailing list