Reputation: 327
I have a C++ code which executes Python script using the PyRun_SimpleFileEx
C API.
The py file looks like this
import time
time.sleep(2)
raise SystemExit("Sorry, it is time to exit.")
SystemExit is what is also raised by calling python stuff like either quit()
or abort()
Since SystemExit inherits from BaseException instead of Exception it is not catched and shuts-off the Python environment as well as the C++ application.
Is there any way to catch the exception above from C++?
Thanks in advance All the best MB
Upvotes: 2
Views: 377
Reputation: 327
Maybe it will turn useful to someone else:
using the PyRun_File*
C API family makes the outer C++ application to stay in place (no shut-off).
The script will fail and the PyObject pointer returned by the function will be invalid to indicate that
Upvotes: 0
Reputation: 5783
You can create a wrapper.py
and run the code from it.
class ExceptionWrapper(Exception):
def __init__(self, exc):
self.exc = exc
def run_code(filename):
try:
exec(open(filename).read(), globals=globals(), locals=locals())
except BaseException as ex:
raise ExceptionWrapper(ex)
Using this wrapper from C++:
#include <Python.h>
int main() {
Py_Initialize();
PyObject * wrapper = PyImport_ImportModule("wrapper");
if (!wrapper) {
PyErr_Print();
exit(1);
}
PyObject * res = PyObject_CallMethod(wrapper, "run_code", "s", "simple.py");
if (!res) {
PyErr_Print();
// PyObject *type, *value, *traceback;
// PyErr_Fetch(&type, &value, &traceback);
// PyErr_NormalizeException(&type, &value, &traceback);
// or handle exception manually here
// PyErr_Restore(type, value, traceback);
}
Py_XDECREF(res);
printf("exit from C\n");
}
Please note that this is just a POC and it is not safe to run arbitrary code.
You can modify the wrapper to accept a file descriptor as argument.
Upvotes: 1