[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