I have a C script,
#include "main.h"
static const char *path_here = "./path/to/here";
static PyConfig py_config;
extern PyObject *fn_arg;
void *init_Python(void *) {
pthread_cleanup_push(del_Python, NULL);
/* Set-up the Python interpreter */
PyConfig_InitPythonConfig(&py_config);
setenv("PYTHONPATH", path_here, true);
PyConfig_SetString(&py_config, &py_config.program_name, (wchar_t *)path_here);
if (PyStatus_Exception(Py_InitializeFromConfig(&py_config)))
del_Python(NULL);
PyConfig_Clear(&py_config);
/* Run the Python script */
PyObject *fn_def = PyObject_GetAttrString(PyImport_ImportModule("test_module"), "test_function");
if (!PyObject_CallOneArg(fn_def, fn_arg))
del_Python(NULL);
pthread_cleanup_pop(NULL);
return NULL;
}
void del_Python(void *) {
PyConfig_Clear(&py_config);
/* ... cleanup in Python with e.g. PyRun_String() ... */
Py_Finalize();
exit(EXIT_SUCCESS);
}
which I want to pthread_create
from another file. The Python module test_module
contains a function, test_function
, which functions as a context manager for a blocking I/O operation and is called from C using PyObject_CallOneArg
.
How do I raise an exception in del_Python
from C using e.g. PyRun_SimpleString
to tell test_function
to perform a cleanup?
I've tried to do something simple, i.e. change a variable, to test this out. However, PyRun_SimpleString("print(locals())");
reports garbage and even PyRun_String
with PyEval_GetLocals()
and PyEval_GetGlobals()
fails silently when I attempt this (even though their respective dictionaries are populated properly with the relevant names). Ideally, I would want the Python interpreter to be "interrupted" and execute Python Bytecode compiled from C verbatim.
Furthermore, Py_Finalize()
segfaults. Acquiring the GIL with PyGILState_Ensure()
before calling Py_Finalize
is a temporary fix but throws many Valgrind errors which all seem to relate to _PyEval_EvalFrameDefault
.
I've read this, this, this, and this question but still can't figure it out. Did I simply skip over the solution or am I fundamentally misunderstand something? Can anybody please help me out?
Note: the "in 2023" in the title referred to most of the functions in the aforementioned questions being deprecated or removed entirely.