Do you think that this answer is worth adding to the BPL FAQ? Normally you don't need to derive from Python's Exception object, and indeed in my own custom exception implementations I never did so. However, if this has changed, an FAQ entry is appropriate.
Ideally, a wishlist work item would map std::exception onto Python's Exception, so if you inherit from std::exception it appears as Python's Exception. I was just reading last night in Nicolai Josuttis' C++11 updated "The C++ Standard Library" how very much easier this has become to implement in C++11. The only fault with that book so far is it makes me want to dump old compilers right now. Niall On 13 Jun 2012 at 19:02, Jim Bosch wrote: > On 06/13/2012 06:31 AM, Wichert Akkerman wrote: > > I have some glue code that calls a C++ function which can raise an > > unsuitable_error exception. I have an exception translator which will > > convert that to a more pythonic version (UnsuitableError), but when I > > use that I get an "SystemError: 'finally' pops bad exception" error on > > the python side. As far as I can see my code looks correct, but I > > suspect I am overlooking something trivial somewhere. > > > > > > using namespace boost::python; > > > > class UnsuitableError : public std::exception { > > public: > > UnsuitableError() : reasons() { } > > ~UnsuitableError() throw() {} > > boost::python::list reasons; > > }; > > > > namespace { > > PyObject *UnsuitableErrorType = NULL; > > > > void translator(const unsuitable_error &e) { > > std::list<const char*>::const_iterator i; > > PyObject* unicode; > > UnsuitableError error=UnsuitableError(); > > for (i=e.reasons.begin(); i!=e.reasons.end(); i++) { > > unicode = PyUnicode_FromString(*i); > > error.reasons.append(boost::python::object(boost::python::handle<>(unicode))); > > > > } > > > > boost::python::object exc(error); > > PyErr_SetObject(UnsuitableErrorType, exc.ptr()); > > } > > } > > > > > > void export() { > > object > > module(handle<>(borrowed(PyImport_AddModule("mypkg.article")))); > > scope().attr("article")=module; > > scope module_scope = module; > > > > class_<UnsuitableError> UnsuitableErrorClass("UnsuitableError"); > > UnsuitableErrorClass.def_readonly("reasons", > > &UnsuitableError::reasons); > > UnsuitableErrorType=UnsuitableErrorClass.ptr(); > > > > register_exception_translator<unsuitable_error>(&translator); > > } > > I suspect the problem is that your custom exception doesn't derived from > Python's built-in Exception base class. Unfortunately, it's impossible > to do that with a Boost.Python wrapped class, but you can get it all > done with the Python C API: > > namespace { > PyObject *UnsuitableErrorType = NULL; > > void translator(const unsuitable_error &e) { > std::list<const char*>::const_iterator i; > PyObject* unicode; > boost::python::list reasons; > for (i=e.reasons.begin(); i!=e.reasons.end(); i++) { > boost::python::handle<> unicode(PyUnicode_FromString(*i)); > reasons.append(boost::python::object(unicode)); > } > boost::python::handle<> error( > PyObject_CallFunctionObjArgs( > UnsuitableErrorType, NULL > ) > ); > PyObject_SetAttrString(error.get(), "reasons", reasons.get()); > PyErr_SetObject(UnsuitableErrorType, error.get()); > } > } > > > void export() { > object module(handle<>(borrowed(PyImport_AddModule("mypkg.article")))); > scope().attr("article")=module; > scope module_scope = module; > > // NOTE: can use something other than RuntimeError for base class > UnsuitableErrorType = PyErr_NewException( > "UnsuitableError", PyExc_RuntimeError, NULL > ); > module_scope.attr("UnsuitableError") = > object(handle<>(borrowed(UnsuitableErrorType))); > > register_exception_translator<unsuitable_error>(&translator); > } > > > I haven't tested any of that, but hopefully it's close enough to point > you in the right direction. > > > Jim > _______________________________________________ > Cplusplus-sig mailing list > Cplusplus-sig@python.org > http://mail.python.org/mailman/listinfo/cplusplus-sig -- Technology & Consulting Services - ned Productions Limited. http://www.nedproductions.biz/. VAT reg: IE 9708311Q. Work Portfolio: http://careers.stackoverflow.com/nialldouglas/ _______________________________________________ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig