Generalized exception translation for boost python

The current boost :: python example for translating a specific C ++ exception in python is as follows:

void translate (const MyException& e) { PyErr_SetString(PyExc_RuntimeError, e.what()); } boost::python::register_exception_translator<MyException>(translate); 

Unfortunately, this requires writing a specific function for each of our exceptions. We tried to simplify this by writing a generic 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); } 

Whether this bit of code would work, you could wrap exceptions that implement "what ()" as follows:

 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 will be a call to GeneralizedTranslator :: operator (), and this will not work for g ++, giving:

 error: 'translate' cannot be used as a function 

Is there a proper way to write this?

+8
c ++ exception-handling boost-python
source share
1 answer

You pass the this pointer as a translation function, and it fails because the pointer to the object cannot be called a function. If you pass *this , it should work instead (note that this will copy-build the GeneralizedTranslator object). Or you can move the registration from the constructor and call

 register_exception_translator<std::out_of_range>(GeneralizedTranslator<std::out_of_range>(PyExc_RuntimeError)); 
+5
source share

All Articles