On 26.08.2012, 16:46:24 Phil Thompson wrote: > On Wed, 15 Aug 2012 15:54:11 +0200, mathias.b...@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 _______________________________________________ PyQt mailing list PyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt