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

David Abrahams dave at boost-consulting.com
Sun Jul 13 19:34:41 CEST 2003


Gottfried Ganßauge <ganssauge at gmx.de> writes:

> ...
>> > 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)
>         ;
> }

Yes, I understood it to be something like that.  What about:

BOOST_PYTHON_MODULE(exception_test)
{
    exception<some_exception> ("some_exception")
        .def ("what", &some_exception::what)
        .def ("get_additional_errorinfo",
                &some_exception::get_additional_errorinfo)
        ;
}

This is actually quite straightforward to implement, I think.
Basically:

   * exception<...> is derived from class<...>

   * we extend class_ with a protected constructor which takes an
     object which represents an additional base class to use.  This
     argument is passed on to the class_base constructor and used as
     an additional base class.

   * exception<...> reproduces the class_ constructor signatures and
     forwards to the new class_ constructor, with the object
     referring to python's builtin Exception type.


> 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.

OK, I agree that it's easier.  Why don't you poke around a bit more
based on my hints?  I'm sure you can make it work.

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com





More information about the Cplusplus-sig mailing list