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

Reply via email to