I am executing the following Python function from C:
Python:
def runLoop(self):
try:
while True:
print("working")
time.sleep(1) # Delay for 1 second.
self.incrementcounter()
except:
print("caught exception")
C:
//Here we register traceFunction to give us a hook into the python
PyEval_SetProfile((Py_tracefunc)traceFunction, NULL);
//Abort interrupt reset to false
m_interruptRequest = false;
//Call the runLoop method
const char *szName = "runLoop";
PyObject_CallMethod(m_pyObject, szName, nullptr);
In the middle of this loop, I would like to inject an exception from C to abort the loop, but also handle the exception in the try/except in Python. As mentioned in the comments I am registering a profiling function in C called tracer be able to inject an exception from C. The following code below injects an exception and kills the program because it is not caught in the try/except.
//Tracer function callback hook into Python execution. Here we handle pause, resume and abort requests.
void PythonRunner::tracer(void)
{
...
//Abort requested
else if (true == interruptRequested())
{
PyErr_SetString(PyExc_Exception, "ABORT");
}
}
Does anyone know how I can throw an exception from C to be handled in Python? Thanks
Update: With the help of @zwol and this article stackoverflow.com/questions/1420957/stopping-embedded-python I found a solution. The key was to add a pending call to python e.g
int PythonRunner::tracer(PyObject *, _frame *, int, PyObject *)
{
...
//Abort requested
else if (true == _instance->interruptRequested())
{
Py_AddPendingCall(&PythonRunner::raiseException, NULL);
}
return 0;
}
int PythonRunner::raiseException(void *)
{
PyErr_SetString(PyExc_KeyboardInterrupt, "Abort");
return -1;
}