The accepted answer to boost::python Export Custom Exception shows how to export a custom exception class from C++, and Boost.Python custom exception class shows how to export an exception class that inherits from Python's Exception. How can I do both? That is expose an exception class that has custom methods to retrieve information and also have that class be derived from Python's Exception.
Asked
Active
Viewed 1,098 times
1 Answers
5
A workable solution, suggested by Jim Bosch on the C++-sig list, is to use composition instead of inheriting from the wrapped C++ exception. The code must create a Python exception as is done here, and then add the wrapped C++ exception as an instance variable of the Python exception.
void translator(const MyCPPException &x) {
bp::object exc(x); // wrap the C++ exception
bp::object exc_t(bp::handle<>(bp::borrowed(exceptionType)));
exc_t.attr("cause") = exc; // add the wrapped exception to the Python exception
PyErr_SetString(exceptionType, x.what());
}
The wrapped C++ exception can then be accessed from Python like this:
try:
...
except MyModule.MyCPPExceptionType as e:
cause = e.cause # wrapped exception can be accessed here
but the exception will also be caught by
try:
...
except Exception:
...
-
2Note that `exc_t.attr("cause") = exc;` adds the C++ exception instance as an attribute to the Python exception *class*. So if you caught an exception instance e1 in Python and kept a reference to it a second raise of such a C++ exception would change the cause attribute of e1 to refer to the new C++ exception instance. – Holger Apr 24 '15 at 09:24