1

I'm trying to port some Python 2 code to Python 3. In the code there is a module that is initialized in the C part that is later invoked by the python code. However my python code does not see the module that was initialized in C. Here is a simplified example:

#include <Python.h>
#include <stdio.h>

static PyMethodDef BenchMethods[] = {
        {NULL, NULL, 0, NULL}
};

int main(int argc, char **argv)
{
        PyObject *module;

        Py_SetProgramName(argv[0]);
        Py_Initialize();

        static struct PyModuleDef benchdef = {
                PyModuleDef_HEAD_INIT,
                "bench",
                NULL,
                -1,
                BenchMethods,
                NULL,
                NULL,
                NULL,
                NULL,
        };
        module = PyModule_Create(&benchdef);
        if (module == NULL) {
                printf("ERROR!\n");
                exit(0);
        }
        PyRun_SimpleString("import bench");

        Py_Finalize();
        return 0;
}

However upon compiling and trying to execute it I get an error:

$ gcc -I/path/to/include/python3.9 -o bench_simple.x bench_simple.c -L/path/to/lib -lpython3.9
$ ./bench_simple.x 
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ModuleNotFoundError: No module named 'bench'

In Python 2 version the module is initialized via module = Py_InitModule("bench", BenchMethods);. I ported the code according to the instructions I found here

0

1 Answer 1

2

PyModule_Create() (when successful) creates a module object. It does not load that object into any interpreter, and the fact that a module object has been created does not automatically put it in any interpreter's module load path. This is why the import bench in your example program fails.

The Python C API docs give specific instructions, supported by an example, for how an application embedding python can programmatically define a module and have the embedded interpreter load it. In a nutshell, the key is that instead of your application calling PyModule_Create() directly, it must

  1. define a module initialization function that makes that call and returns the result, and
  2. call PyImport_AppendInittab() to register that initialization function to the chosen module name, before initializing an interpreter.
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much for the pointer and the explanation! I was able to make it work after following the suggested example.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.