[C++-sig] Howto expose exception classes using boost.python?

Roman Yakovenko roman.yakovenko at gmail.com
Thu Apr 27 07:44:01 CEST 2006


On 4/25/06, Juho Mäkinen <juho.makinen at gmail.com> wrote:
> I have stumbled across this problem when I started looking the right
> way how to expose a bunch of C++ Exception classes to python.
>
> I have a "master" exception class, which is delivered from
> std::exception. All other exception classes in our project are base on
> this.
>
> As far as I know, Python requires that the exceptions must be
> delivered from PyExc_Exception, or a class which is delivered from
> PyExc_Exception,

Are you sure? Where did you read it?

> but I haven't found any way how to expose a C++ class
> which delivers from a python class.

I think such functionality does not exists in boost.python library.
But I could be wrong.

>There's also PyErr_NewException() available within Python C API.
>
> This would be the ideal way how I'd like to use our exceptions.
>
> PyErr_SetObject(PyExc_MyException,  InstanceOfMyException)
> -or in python-
> raise mymodule.MyException(arg1, arg2)

Here is relevant piece of Python documentation:

void PyErr_SetObject( PyObject *type, PyObject *value)

This function is similar to PyErr_SetString() but lets you specify an
arbitrary Python object for the ``value'' of the exception.

I think that "an arbitrary" is the key to your solution.

In the past I created custom exception translator.
( I can not find code, so I will just write an algorithm )

Register all your exception classes as usual.

Write next function:

template<class MyCppException>
void translate_it( const MyCppException& err ){
    boost::python::object bp_err( err );

    extract PyObjectType and PyObject from py_err
    this exact code I don't remember, but it is not to difficult to find out.

    pay attention to reference count ( borrow or handle )

    PyErr_SetObject( py_type, py_error );
}

For every exception register it's translation using translate_it.

>From now your C++/Python code can throw/raise exceptions as usual.
They will be translated to Python.

The only (very) bad thing is that the code that treats exceptions now
should treat 2 exception kinds.

>
> I know that I can expose C++ exceptions with boost.python (the
> PodBayDoorException example) using
> boost::python::register_exception_translator, but I want to be able to
> distinguish my different C++ exceptions at the python side. (eg. It's
> not enough that all my exceptions are translated into
> PyExc_RuntimeError, or some other standard python exception)
>
> All ideas how to expose exception hierarchy from C++ to Python are appreciated.
>
> Thanks in advance,

I hope this will help you, also I am sure other people do know better solution.
In any case if you find a solution can you post it? I will add it to pyplusplus
( http://www.language-binding.net/pyplusplus/pyplusplus.html )

>  - Juho Mäkinen


--
Roman Yakovenko
C++ Python language binding
http://www.language-binding.net/



More information about the Cplusplus-sig mailing list