Darrell, Slavek, E, All,
I have spent the past few days attempting to work out a version neutral port
of superkaramba so that it will build on both python2 and python 3.3.3 systems.
I have done it -- I think... The patch is:
tdeutils-superkaramba-python2_004.diff
The easy version neutral changes needed are the following:
PyString_CheckExact -> PyBytes_CheckExact
PyString_FromString -> PyBytes_FromString
PyString_FromStringAndSize -> PyBytes_FromStringAndSize
PyInt_FromLong -> PyLong_FromLong
However, help to get the "karamba" module initialized properly in
karamba_python.cpp at 359 the new python 3 module initialization routine must be
used.
I have tried to followed:
http://docs.python.org/3/howto/cporting.html under
the heading of "Module initialization and state" to include preprocessor checks
needed to accommodate python2 and python. Essentially for python 3, you must
define the karamba module with 'static struct PyModuleDef karambadef = {foo' and
then call 'PyModule_Create(&karambadef);' instead of calling
'Py_InitModule((char*)"karamba", karamba_methods);' To work with both
python2
and python, preprocessor checks are included as follows:
New code:
struct module_state {
PyObject *error;
};
#if PY_MAJOR_VERSION >= 3
#define GETSTATE(m) ((struct module_state*)PyModule_GetState(m))
#else
#define GETSTATE(m) (&_state)
static struct module_state _state;
#endif
static PyObject *
error_out(PyObject *m) {
struct module_state *st = GETSTATE(m);
PyErr_SetString(st->error, "something bad happened in
karamba_python.cpp");
return NULL;
}
<snip>
#if PY_MAJOR_VERSION >= 3
static int karamba_traverse(PyObject *m, visitproc visit, void *arg) {
Py_VISIT(GETSTATE(m)->error);
return 0;
}
static int karamba_clear(PyObject *m) {
Py_CLEAR(GETSTATE(m)->error);
return 0;
}
static struct PyModuleDef karambadef = {
PyModuleDef_HEAD_INIT,
"karamba",
NULL,
sizeof(struct module_state),
karamba_methods,
NULL,
karamba_traverse,
karamba_clear,
NULL
};
#define INITERROR return NULL
#else
#define INITERROR return
#endif
PyThreadState* KarambaPython::mainThreadState = 0;
KarambaPython::KarambaPython(const ThemeFile& theme, bool reloading):
pythonThemeExtensionLoaded(false), pName(0), pModule(0), pDict(0)
{
PyThreadState* myThreadState;
char pypath[1024];
getLock(&myThreadState);
// load the .py file for this .theme
PyRun_SimpleString((char*)"import sys");
//Add theme path to python path so that we can find the python file
snprintf(pypath, 1023, "sys.path.insert(0, '%s')",
theme.path().ascii());
PyRun_SimpleString(pypath);
PyRun_SimpleString((char*)"sys.path.insert(0, '')");
PyImport_AddModule((char*)"karamba");
#if PY_MAJOR_VERSION >= 3
PyModule_Create(&karambadef);
#else
Py_InitModule((char*)"karamba", karamba_methods);
#endif
That's it. Then it builds on bleeding-edge arch without issue. Darrell, will
you try this patch and confirm that it works fine with python2. Then let's get a
few more eyes on it and if no objections, push it.
The patch is included below.
--
David C. Rankin, J.D.,P.E.