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

David Abrahams dave at boost-consulting.com
Thu Jul 31 19:47:53 CEST 2003


Hi Gottfried,

Any progress on this front?

David Abrahams <dave at boost-consulting.com> writes:

> 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

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





More information about the Cplusplus-sig mailing list