[C++-sig] Boost.Python C++ exception translation question

Jeffrey Van Voorst vanv0059 at umn.edu
Tue Oct 30 14:39:37 CET 2012


Greetings,

I have used a method mentioned on stackoverflow 
(http://stackoverflow.com/questions/6908976/generalized-exception-translation-for-boost-python) 
for a generalized method to translate C++ exceptions to python exceptions.

When debugging my code using gdb the frames seem to indicate that a C++ 
requires a call to all of the translation instances.  Is this because of 
a Boost.Python implementation issue, my deriving all my python 
exceptions from PyExc_EnvironmentError (using PyErr_NewException), or 
possibly a misunderstanding I have about C++ and template function 
evaluations?

My code for a generic approach is:

template<class E>
class GeneralizedTranslator{
public:
   GeneralizedTranslator(PyObject* py_exc): A_PyExc(py_exc)
   {
     bp::register_exception_translator<E>(*this);
   }

   GeneralizedTranslator(const GeneralizedTranslator &other)
     : A_PyExc(other.A_PyExc)
   { ; }

   void
   operator()(const E &my_error) const
   {
     std::stringstream ostr;
     ostr << boost::diagnostic_information(my_error);
     PyErr_SetString(A_PyExc, ostr.str().c_str());
   }

private:
   PyObject *A_PyExc;};

// Allow for a simple translation declaration, remove scope problem
template <class ErrType> void
translate_error(PyObject *E)
{
   GeneralizedTranslator<ErrType> my_translator(E);
}

New exceptions are created by:
PyObject *PyExc_Error_A =
   PyError_NewException("Exception_A", PyExc_EnvironmentError, NULL);

The class is used as:
BOOST_PYTHON_MODULE(_test)
{
   // Here the exceptions (My_Exception_*) are derived from 
boost::exception and std::exception
   translate_error<My_Exception_A>(PyExc_Error_A);
   translate_error<My_Exception_B>(PyExc_Error_B);
    .
    .
    .
}

In gdb I see:


   .
   .
   .
#52 0x00007fffeff04827 in 
boost::detail::function::function_obj_invoker2<boost::_bi::bind_t<bool, 
boost::python::detail::translate_exception<My_Exception_B, 
GeneralizedTranslator<My_Exception_B> >, 
boost::_bi::list3<boost::arg<1>, boost::arg<2>, 
boost::_bi::value<GeneralizedTranslator<My_Exception_B> > > >, bool, 
boost::python::detail::exception_handler const&, boost::function0<void> 
const&>::invoke(boost::detail::function::function_buffer&, 
boost::python::detail::exception_handler const&, boost::function0<void> 
const&) ()
    from /path/to/_test.so
#53 0x00007ffff38a9ef4 in 
boost::python::detail::exception_handler::operator()(boost::function0<void> 
const&) const ()
    from /path/to/libboost_python.so
#54 0x00007fffeff04977 in 
boost::detail::function::function_obj_invoker2<boost::_bi::bind_t<bool, 
boost::python::detail::translate_exception<My_Exception_A, 
GeneralizedTranslator<My_Exception_A> >, 
boost::_bi::list3<boost::arg<1>, boost::arg<2>, 
boost::_bi::value<GeneralizedTranslator<My_Exception_A> > > >, bool, 
boost::python::detail::exception_handler const&, boost::function0<void> 
const&>::invoke(boost::detail::function::function_buffer&, 
boost::python::detail::exception_handler c
onst&, boost::function0<void> const&) ()
    from /path/to/_test.so
#55 0x00007ffff38a9cfa in 
boost::python::handle_exception_impl(boost::function0<void>) ()
    from /path/to/libboost_python.so
#56 0x00007ffff38983e8 in ?? ()
from /path/to/libboost_python.so
#57 0x000000000041ef47 in PyObject_Call ()
#58 0x00000000004a72b8 in PyEval_EvalFrameEx ()
#59 0x00000000004a95c1 in PyEval_EvalCodeEx ()
#60 0x00000000004a7752 in PyEval_EvalFrameEx ()

   .
   .
   .


Thanks,

Jeff Van Voorst


More information about the Cplusplus-sig mailing list