trinity-devel@lists.pearsoncomputing.net

Message: previous - next
Month: February 2014

SOLVED!!! - tdeutils superkaramba FTBFS python2/python3 -- patchavail

From: "David C. Rankin" <drankinatty@...>
Date: Sun, 09 Feb 2014 20:01:25 -0600
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.

Attachments: