[PyQt] SIP default exception handler

Sébastien Petitdemange sebastien.petitdemange at esrf.fr
Tue Nov 3 16:04:38 GMT 2009


We have tested your snapshot code and it works as expected. In fact, we
had a rather "obscure" problem where our exceptions were thrown in our
library, but it was not seen by your specific catch route. After a lot
of research, we saw that the Python (distutils) Makefile hides by
default the library symbols, except the "init<Module>" function. It
seems that this filtering also affect weak symbols with default values,
and we believe that this avoided the try ... catch block to properly
identify in run-time the good exception type id. The solution we found
was to specify export_all=True in the Module Makefile.

However, we have also seen a problem with dynamic parameter allocation.
In the example below, the /Out/ std::string buffer parameter is created
by sip. However, inside of our /Default/ exception handler or even the
catch (...) handler, the object is not deleted.

Do you have an idea of what could be happening?

Thanks again,


In the sip file:

class SerialLine : HwSerialLine
        virtual void read( std::string& buffer /Out/, int max_len,
                           double timeout=HwSerialLine::TimeoutDefault );

The generated code:

extern "C" {static PyObject *meth_Espia_SerialLine_read(PyObject *,
PyObject *);}
static PyObject *meth_Espia_SerialLine_read(PyObject *sipSelf, PyObject
    int sipArgsParsed = 0;
    bool sipSelfWasArg = (!sipSelf || sipIsDerived((sipSimpleWrapper

        std::string * a0;
        int a1;
        double a2 = HwSerialLine::TimeoutDefault;
        Espia::SerialLine *sipCpp;

            a0 = new std::string();

            (sipSelfWasArg ? sipCpp->Espia::SerialLine::read(*a0,a1,a2)
: sipCpp->read(*a0,a1,a2));
            catch (Exception &sipExceptionRef)

#line 18 "../common/sip/Exceptions.sip"
        const char *detail = sipExceptionRef.getErrMsg().c_str();
        PyErr_SetString(sipException_Exception, detail);
#line 528 "siplimaEspiaSerialLine.cpp"

                return NULL;
            catch (...)

                return NULL;

            return sipConvertFromNewType(a0,sipType_std_string,NULL);

    /* Raise an exception if the arguments couldn't be parsed. */

    return NULL;

Sébastien Petitdemange wrote:
> Phil Thompson wrote:
>> On Thu, 29 Oct 2009 10:08:33 +0100, Sébastien Petitdemange
>> <sebastien.petitdemange at esrf.fr> wrote:
>>> Hi,
>>> We are developing a C++ library that uses a single exception class
>>> (Exception) for throwing errors.
>>> When wrapping the library with sip, we use the -e command line to
>>> activate the try/catch code on each C++ call.
>>> However, our C++ code does not include the "throw(Exception)" modifier
>>> on each class method, because virtually any method can throw this
>>> exception, and it would be quite heavy to add it on every declaration.
>>> In this scenario, sip (v4.7.9) just include a default try {} catch (...)
>>> { sipRaiseUnknownException }, so Python reports "Exception: Unknown".
>>> Is there a way to specify a default exception handler to sip, so the
>>> generated code in this case would like something like:
>>>   try {
>>>       // C++ call
>>>   } catch (OurDefaultException& e) {
>>>       ...
>>>       sipRaiseClassException(sipclass_OurDefaultException ... );
>>>   } catch (...) {
>>>       sipRaiseUnknownException();
>>>   }
>> I've added support for a /Default/ exception annotation in tonight's
>> snapshot. Untested - let me know if it's not quite right.
>> Phil
> Thanks a lot, I'll test that and let you know.
> _______________________________________________
> PyQt mailing list    PyQt at riverbankcomputing.com
> http://www.riverbankcomputing.com/mailman/listinfo/pyqt

-------------- next part --------------
A non-text attachment was scrubbed...
Name: sebastien_petitdemange.vcf
Type: text/x-vcard
Size: 218 bytes
Desc: not available
Url : http://www.riverbankcomputing.com/pipermail/pyqt/attachments/20091103/ce8996fd/sebastien_petitdemange.vcf

More information about the PyQt mailing list