On 31/07/12 21:14, Glenn Ramsey wrote:

Using boost::python how can I create an a custom exception that is derived from
Python's Exception? The functionality I would like to get by doing this is to
provide additional methods for the catching code to retrieve information from
the exception.

I know it is possible to just wrap and throw my own exception class but it seems
that because it is not derived from Exception then in certain situations I get
the error "SystemError: 'finally' pops bad exception".

This example [1] shows how to wrap a C++ exception class...

class MyCPPException : public std::exception {...}

using namespace boost::python;
...

PyObject *myCPPExceptionType=0;

void translate(MyCPPException const &e)
{
     PyErr_SetObject(myCPPExceptionType, object(e).ptr());
}


BOOST_PYTHON_MODULE(MyModule)
{
     ...

     class_<MyCPPException> myCPPExceptionClass("MyCPPException"...);
     myCPPExceptionClass
         .def("get_extra_info", &MyCPPException::get_extra_info);

     myCPPExceptionType=myCPPExceptionClass.ptr();

     register_exception_translator<MyCPPException>(&translate);
     ...
}

But this is not derived from Exception.

This example [2] shows how to create an exception that is derived from 
Exception.

PyObject* createExceptionClass(const char* name, PyObject* baseTypeObj =
PyExc_Exception)
{
     using std::string;
     namespace bp = boost::python;

     string scopeName = bp::extract<string>(bp::scope().attr("__name__"));
     string qualifiedName0 = scopeName + "." + name;
     char* qualifiedName1 = const_cast<char*>(qualifiedName0.c_str());

     PyObject* typeObj = PyErr_NewException(qualifiedName1, baseTypeObj, 0);
     if(!typeObj) bp::throw_error_already_set();
     bp::scope().attr(name) = bp::handle<>(bp::borrowed(typeObj));
     return typeObj;
}

PyObject* myExceptionTypeObj = 0;

void translate(MyCPPException const &e)
{
     PyErr_SetObject(myExceptionTypeObj, object(e).ptr());
}


BOOST_PYTHON_MODULE(MyModule)
{
     register_exception_translator<MyCPPException>(&translateFunc);
     ...
     myExceptionTypeObj = createExceptionClass("MyException");
     ...
}

But this doesn't have any custom methods to get info from the exception.

How can I do both at the same time?

Glenn

[2]
<http://stackoverflow.com/questions/9620268/boost-python-custom-exception-class>

[1]
<http://stackoverflow.com/questions/2261858/boostpython-export-custom-exception>

Forgot to mention a couple of things that I tried already...

Passing a tuple of PyExc_Exception and my wrapped custom exception to PyErr_NewException, for multiple inheritance, caused an error when attempting to load the module in Python, something about incompatible types.

Extracting __dict__ from my wrapped custom exception and passing it to PyErr_NewException also caused an error when attempting load the module. I don't have it in front of me now but it was complaining about wanting dict instead of dictproxy.

Glenn
_______________________________________________
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig

Reply via email to