On Sat, 01 Jun 2013 23:50:40 +0100, Александров Петр <petr_aleksand...@mail.ru> wrote:

I want to catch a custom C++ exception in Python. I have described my custom exception class as usual:

class_<CMyException>(...);

and created a translator:

void translate(CMyException const &e) {
     object o(e);
     PyErr_SetObject(PyExc_Exception, o.ptr());
}

This exception can be caught from Python:
try:
   do_something()
except Exception as exc:
   #exc.args[0] - the custom exception object
   print exc.args[0]

Is it safe to do in such a way? Is the Python object, created in the function "translate", destroyed? Need I add "Py_INCREF" to this function?


Looks fine to me.
You'd probably get a segfault if it was missing an incref. The `object o(e)` line should increment the reference count for you, as you didn't wrap `e` in `boost::ref` or similar in the conversion to object.

A couple of pointers, though:-

1. Boost Python has a dedicated exception handling API[1] that doesn't require you to wrap the exception in a class_<> template. The class_ template is a bit heavy duty for registering exceptions, I think. Instead, I register exceptions like this:-

#include <boost/python/exception_translator.hpp>

void TranslateMyException(const MyException& err)
{
    PyErr_SetString(PyExc_Exception, err.ptr());
}

void RegisterMyExceptionTranslator(void)
{
    boost::python::register_exception_translator<
        MyException&>( TranslateMyException );
}


2. If you're concerned about reference counting, it'd probably be worth you building a debug version of Python.[2] In the interpreter, this prints the global reference count at the end of each code block. The two ways it could go wrong:- too few calls to incref and you'll get a free error, so your program will segfault. Too many incref's and garbage collection of your objects won't happen until the program exits. A debug build of Python really helps here, as you'll see that the global reference count go down when you delete an instance of your object. With exceptions, I've found that Py_DECREF is called a little late though, which is a bit confusing at first. So when looking at the reference counting behaviour in relation to C++ exceptions, be sure to compare the behaviour against that of normal Python exceptions.


HTH,
Alex


[1]: http://www.boost.org/doc/libs/1_53_0/libs/python/doc/v2/exception_translator.html
[2]: http://docs.python.org/devguide/setup.html#compiling-for-debugging
_______________________________________________
Cplusplus-sig mailing list
Cplusplus-sig@python.org
http://mail.python.org/mailman/listinfo/cplusplus-sig

Reply via email to