[PyQt] sip: extend exception support

Phil Thompson phil at riverbankcomputing.com
Sun Aug 26 15:07:52 BST 2012


On Sun, 26 Aug 2012 14:30:32 +0200, Mathias.Born at gmx.de wrote:
> On 26.08.2012, 16:46:24 Phil Thompson wrote:
>> On Wed, 15 Aug 2012 15:54:11 +0200, Mathias.Born at gmx.de wrote:
>>> Phil,
>>> 
>>> sip can already propagate C++ exceptions into Python in cases
>>> where Python calls a C++ function which throws an exception.
>>> 
>>> However, if I extend a C++ class in Python and call a corresponding
>>> (Python-)method in C++ via the wrapper, the sip generated
>>> wrapper code checks for a Python exception, but doesn't throw an
>>> excpetion itself.
>>> For example:
>>> 
>>> ========= <code generated by sip> =======================
>>> boost::optional<int> sipVH_ltse_app_0(sip_gilstate_t
>> sipGILState,PyObject
>>> *sipMethod,const std::string& a0)
>>> {
>>>     boost::optional<int> sipRes;
>>>     PyObject *resObj = sipCallMethod(0,sipMethod,"N",new
>>>     std::string(a0),sipType_std_string,NULL);
>>> 
>>>     if (!resObj ||
>>>    
>>
sipParseResult(0,sipMethod,resObj,"H5",sipType_boost_optional_1800,&sipRes)
>>>     < 0)
>>>         PyErr_Print();
>>> 
>>>     Py_XDECREF(resObj);
>>>     Py_DECREF(sipMethod);
>>> 
>>>     SIP_RELEASE_GIL(sipGILState)
>>> 
>>>     return sipRes;
>>> }
>>> =========================================================
>>> 
>>> Here, "PyErr_Print" is called if the Python implementation of
>>> the method raises an exception. This is fine for Qt which
>>> cannot deal with exceptions, but in general I would find it
>>> much more helpful if the wrapper code generated by sip
>>> threw a C++ exception itself to signal the problem to the
>>> caller.
>>> 
>>> Just define a class, e.g. "SIPPyException" (derived from
>>> std::exception), which becomes part of the API and is always used
>>> in such cases.
>>> In order not to break existing code, it would only be used in
>>> classes or methods which are annotated appropriately.
>>> (So an additional annotation is necessary to activate this behavior.)
>>> 
>>> I believe an extension like this would make sip a lot more useful
>>> for embedding Python into a C++ program.
>>> 
>>> Best Regards,
>>> Mathias Born
> 
>> Try current hg or tonight's snapshot. See the all_throw_cpp_exception
>> %Module argument and the /ThrowsCppException/ and
/NoThrowsCppException/
>> function annotations.
> 
>> Not heavily tested.
> 
> That's great!
> I tried "sip-4.13.4-snapshot-5f97352e818f.zip".
> 
> When buidling sip, my MSVC2010 complains:
> 
> sip.h(347) : error C2016: C requires that a struct or union has at least
> one member
> 
> Possible fix: just change
> 
> struct SIPPyException {};
> 
> to
> 
> #ifdef __cplusplus
> struct SIPPyException {};
> #endif
> 
> That should be ok because it's for an exception, a C++ only feature.
> 
> 
> The generated code, for example:
> 
> ========= <code generated by sip> =======================
> std::string sipVH_ltse_app_1(sip_gilstate_t sipGILState,PyObject
> *sipMethod,const std::string& a0)
> {
>     std::string sipRes;
>     PyObject *resObj = sipCallMethod(0,sipMethod,"N",new
>     std::string(a0),sipType_std_string,NULL);
> 
>     if (!resObj ||
>     sipParseResult(0,sipMethod,resObj,"H5",sipType_std_string,&sipRes) <
0)
>         throw SIPPyException();
> 
>     Py_XDECREF(resObj);
>     Py_DECREF(sipMethod);
> 
>     SIP_RELEASE_GIL(sipGILState)
> 
>     return sipRes;
> }
> =========================================================
> 
> will leak memory, though. All the
> 
>     Py_XDECREF(resObj);
>     Py_DECREF(sipMethod);
>     SIP_RELEASE_GIL(sipGILState)
> 
> won't be executed in case of an exception.
> 
> 
> In addition, I get a lot of compilation errors when I try to build PyQt
> v4.9.4 with this new sip,
> for example:
> 
> .\sipQtGuiQFontDialog.cpp(3298) : error C2664: 'void
> QFontDialog::open(QObject *,const char *)' : cannot convert parameter 1
> from 'QObject **' to 'QObject *'
>         Types pointed to are unrelated; conversion requires
>         reinterpret_cast, C-style cast or function-style cast
> 
> That's a show stopper, as my stuff can't do without PyQT ...
> 
> Best Regards,
> Mathias Born

Should all be fixed in current hg and tonight's snapshot.

Thanks,
Phil


More information about the PyQt mailing list