[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