The current boost::python example for translating a specific C++ exception into python goes like this:
void translate (const MyException& e) {
PyErr_SetString(PyExc_RuntimeError, e.what());
}
boost::python::register_exception_translator<MyException>(translate);
Unfortunately, this requires that we write a specific function for each of our exceptions. We tried to simplify this, by writing a generalized exception translator:
#include <boost/python.hpp>
// Generalized exception translator for Boost Python
template <typename T> struct GeneralizedTranslator {
public:
void operator()(const T& cxx_except) const {
PyErr_SetString(m_py_except, cxx_except.what());
}
GeneralizedTranslator(PyObject* py_except): m_py_except(py_except) {
boost::python::register_exception_translator<T>(this);
}
GeneralizedTranslator(const GeneralizedTranslator& other): m_py_except(other.m_py_except) {
//attention: do not re-register the translator!
}
private:
PyObject* m_py_except;
};
//allows for a simple translation declaration, removes scope problem
template <typename T> void translate(PyObject* e) {
ExceptionTranslator<T> my_translator(e);
}
Would that bit of code work, you could wrap exceptions that implement "what()" like this:
BOOST_PYTHON_MODULE(libtest)
{
translate<std::out_of_range>(PyExc_RuntimeError);
}
Unfortunately, it seems boost::python will call the "translation" code as a function inside "boost/python/detail/translate_exception.hpp" (line 61):
translate(e);
In our generalized exception handler this would be a call to GeneralizedTranslator::operator() and that will not work for g++, giving:
error: ‘translate’ cannot be used as a function
Is there a correct way to write this?
You're passing the this
pointer as the translate function, and this fails because a pointer to an object can't be called as a function. If you pass *this
instead this should work (note that this will copy-construct the GeneralizedTranslator object). Or you can move the registration out of the constructor, and call
register_exception_translator<std::out_of_range>(GeneralizedTranslator<std::out_of_range>(PyExc_RuntimeError));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With