[C++-sig] Proposal to improve Python exception handling in Boost.Python
David Abrahams
dave at boostpro.com
Tue Jun 24 20:58:40 CEST 2008
Frank Benkstein wrote:
> Hi,
>
> David Abrahams wrote:
>> Frank Benkstein wrote:
>>> David Abrahams wrote:
>> I don't know if you're aware of this, but Boost.Python is currently
>> incompatible with the use of Py_Finalize
>
> We currently call Py_Initialize/Py_Finalize in our applications multiple
> times while using Boost.Python and didn't notice any problems other than
> ensuring that the error indicator is not set, i.e. calling
> PyErr_Clear/PyErr_Print.
>
> Is there a document somewhere summarizing what's expected to fail and
> what must be done to make it fully work?
file:///tmp/todo.html#pyfinalize-safety is the best I can come up with.
>> All I was saying was that that single function probably ought to include
>> the PyErr_Occurred check
>
> If don't understand how that should work. Do want to call this function
> after every call to the C API? The way I see it every function that
> calls the C API has to check for errors itself. If it detects one
> (through a zero or a null pointer return value or a mandatory call to
> PyErr_Occurred) it should call a function that knows how to translate
> this error to a C++ exception. Currently this translation is done by
> throw_error_already_set.
And why should a function that would only check by calling
PyErr_Occurred have to check for itself?
An extra call to PyErr_Occurred when you're about to throw a C++
exception anyway (e.g. because you detected a -1) isn't going to hurt
anyone.
> Yes, error_already_set should go. An intermediate solution in the
> deprecation phase could be a runtime switch so new and old code can
> coexist. In the transitional phase the base exception class could
> provide a restore method that puts the error indicator back. This way
> code that's handling the Python exceptions itself can be changed from
>
> catch (error_already_set &) {
> ...
> }
>
> to
>
> catch (exceptions::python_exception &e) {
> e.restore();
> ...
> }
>
> Maybe it's possible to do some wizardry to do that automatically but I
> don't know about that. I also would like to think about deprecation
> warnings and compile time switches later when there is any code and it
> is in a working shape.
Suit yourself, but I won't want to proceed until the transition issue
has been carefully thought through and discussed.
> Suppose you want to define a C++ exception class that wraps python's
> LookupError. This could look like the following:
>
> <code>
> // Define the wrapper class.
> class LookupError {
> public:
> // Every wrapper class must have this member. It is a handle for the
> // Python type object whose instances this class will wrap.
> static object type;
>
> // This is the real type of the exception. It may be LookupError but
> // also KeyError or IndexError or something else.
> object real_type;
> // This is the exception instance.
> object value;
> // This is the traceback or None.
> object traceback;
>
> LookupError(PyObject *t, PyObject *v, PyObject *tb);
> };
>
> LookupError::type = handle<>(borrowed(PyExc_LookupError));
> </code>
>
> To register the exception you would call something like this somewhere
> in your code:
>
> </code>
> exceptions::register<LookupError>();
> </code>
>
Hmm. My intention had always been to implement the feature discussed in
http://article.gmane.org/gmane.comp.python.c%2B%2B/3812,
Is this compatible with those ideas?
> After that calls to the function that will replace
> throw_error_already_set will throw this LookupError class if
> PyErr_ExceptionMatches(LookupError::type.ptr()).
>
> The registry would ensure that subclasses come before their base
> classes.
>
>> I think I'd prefer a single analysis and proposal of what should be
>> done. We can talk about how to get there after I understand where we're
>> going.
>
> Ok, I think most of the pieces are already there but I'll try to come up
> with something more formal.
I don't need anything more formal; I'd just like you to leave out
intermediate steps: propose where you think things should end up, not a
plan for getting there over several releases of the code (or several SVN
checkins), just to keep things clearer for me.
Thanks,
--
Dave Abrahams
BoostPro Computing
http://www.boostpro.com
More information about the Cplusplus-sig
mailing list