Question

i am migrating an application that embeds python, from version 2.7 to version 3.3. The application makes functions available to script, by calling Py_InitModule() with the appropriate data. Just to annoy poor guys like me, the api was dropped in python 3 and replaced by PyModule_Create, which takes a fairly complex structure.

When i use the python2 api, everything works fine, when i use the new v3 one, the api loads fine (returns a valid pointer), but using the exposed functions in a script will yield an error:

//ImportError: No module named 'emb'

Where emb is my module name. Very annoying! I have included the two version, maybe someone can help. I followed the porting guide here:

http://docs.python.org/3/howto/cporting.html

which does exactly the same thing as me. Why the api was changed is beyond me.

static int numargs=0;


static PyObject*
emb_numargs(PyObject *self, PyObject *args) //what this function does is not important
{
    if(!PyArg_ParseTuple(args, ":numargs"))
        return NULL;
    return Py_BuildValue("i", numargs);
}

static PyMethodDef EmbMethods[] = {
    {"numargs", emb_numargs, METH_VARARGS,
    "Return the number of arguments received by the process."},
    {NULL, NULL, 0, NULL}
};


#ifdef PYTHON2

    //works perfect with Pytho 27

    Py_InitModule("emb", EmbMethods);

    PyRun_SimpleString(
        "import emb\n"
        "print(emb.numargs())\n"
        );      

#else


static struct PyModuleDef mm2 = {
    PyModuleDef_HEAD_INIT,
    "emb",
    NULL,
    sizeof(struct module_state),
    EmbMethods,
    NULL,
    0,
    0,
    NULL
};

    //does not work with python 33:
    //ImportError: No module named 'emb'


    PyObject* module = PyModule_Create(&mm2);

    PyRun_SimpleString(
        "import emb\n"
        "print(emb.numargs())\n"
        );

#endif
Was it helpful?

Solution

Based off this issue it seems they have changed the way to import modules has also changed.

Here is what should hopefully work for you:

// this replaces what is currently under your comments

static PyObject*
PyInit_emb(void)
{
    return PyModule_Create(&mm2);
}

numargs = argc;
PyImport_AppendInittab("emb", &PyInit_emb);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top