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
> [email protected]
> 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
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig