[C++-sig] Re: Wrapper for exception translation

Gottfried Ganßauge ganssauge at gmx.de
Sun Jul 13 13:59:17 CEST 2003


...
> > It could be even simpler with a completely different design but
frankly - I
> > have no clue how to implement that:
> > We would need a way to somehow derive (in the python sense) a class_<>
from
> > PyExc_Exception (the type of the python Exception class) or any other
python
> > class (PyErr_NewException() has a base parameter, which could be used
for
> > that).
> >
> > At the same time an exception_translator should be registered for that
> > class_<> which uses PyErr_SetObject() to raise a copy of the exception
> > caught.
>
> None of that sounds simpler to me.
>
> > This would allow us to have true Python exceptions in a pythonic sense
> > directly wrapped around the corresponding C++ exception.
>
> Doesn't sound like a big advantage to me, but I guess if you had
> stored data members in the C++ exception type you'd want them to be
> preserved.  Hmm, there's no reason you can't build a BPL extension
> class which also inherits from Exception, but it seems tough.

Maybe an example is in order:

// this is the exception to wrap
struct some_exception {
    some_exception (const char *description, int error_number);

    const char *what() const;
    int get_additional_errorinfo() const;
};

// This is how it could be wrapped
BOOST_PYTHON_MODULE(exception_test)
{
    class_<some_exception, exception_base<> > ("some_exception")
        .def ("what", &some_exception::what)
        .def ("get_additional_errorinfo",
&some_exception::get_additional_errorinfo)
        ;
}

This should be sufficient to fully automatically wrap the "some_exception"
class including exception translation.
Key to this automatism is the exception_base<> template, which by some magic
could determine that our wrapper needs to derived from PyExc_Exception and
that exception translation for "some_exception" is needed. exception_base<>
would be templated by the python exception type our new exception is to be
derived from.
When an instance of "some_exception" is thrown and caught by the library it
would then raise the associated python exception passing a python version of
the "some_exception" instance as the exception argument.
The exception handler in the python script could look like
try:
    do_something_eventually_raising_some_exception()
except exception_test.some_exception, e:
    print "Caught some_exception (%s, %d)" % (e.what(),
e.get_additional_errorinfo())

I think this *is* easier for the user of the library but as I said: I have
no clue how to implement something like that.

...
> This is a big improvement.  What I don't like about this is:
>
>    a. the need for users to mess with handle<>s.  handle<> can be
>       nil, so is less safe than object.
I'm not using null_ok(), so I thought that the handle can't be nil because
in that case the constructor would have thrown :-)

>
>    b. a  name in the public interface ("exception_") which
>       needlessly ends in an underscore
This is true.

>
>    c. Formatting inconsistent with the library and goofy @directives
>       in the comments <wink>
ok. my post was not meant as a submission but as a concept.

>
> I'd prefer an interface where boost::python::exception was a class
> derived from object:
>
>     exception<exc> e("exc");
>     exception<bad_exc>("bad_exc");
>     exception<obj_exc>("obj_exc");
>     exception<derived_exc>("derived_exc", e);
I'll do it.

Cheers,

Gottfried
>
> -- 
> Dave Abrahams
> Boost Consulting
> www.boost-consulting.com
>
>
> _______________________________________________
> C++-sig mailing list
> C++-sig at python.org
> http://mail.python.org/mailman/listinfo/c++-sig
>
>
>






More information about the Cplusplus-sig mailing list