Re: [PyKDE] Handling exceptions in SIP
On Fri, 1 Jul 2005 17:37:44 +0100 Phil Thompson <[EMAIL PROTECTED]> wrote: > If we solve the problem of how to specify "..." then you could define > std::bad_alloc, std::exception, and (somehow) "..." using %Exception and > then... > > void foo() throw (std::bad_alloc, std::exception, ...); > > If this is too much trouble, then I can only suggest implementing something > like %DefaultExceptionHandler than contains your code and is applied to > anything that has no throw specifier (so long as the -e option is used). I think we need some more feedback from other SIP users before going farther. -- Denis S. Otkidach http://www.python.ru/ [ru] ___ PyKDE mailing listPyKDE@mats.imk.fraunhofer.de http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] Handling exceptions in SIP
On Friday 01 July 2005 7:55 am, Denis S. Otkidach wrote: > On Thu, 30 Jun 2005 17:24:27 +0100 > > Phil Thompson <[EMAIL PROTECTED]> wrote: > > > 4) There are several standard exceptions which I always have to catch. > > > Now I have a macro for them: > > > > > > #define CATCH_STD_EXCEPTIONS \ > > > catch (std::bad_alloc&) {\ > > > PyErr_NoMemory(); \ > > > sipIsErr = 1; \ > > > } catch (std::exception &exc) {\ > > > PyErr_SetString(PyExc_RuntimeError, exc.what()); \ > > > sipIsErr = 1; \ > > > } catch (...) {\ > > > PyErr_SetString(PyExc_RuntimeError, "unknown"); \ > > > sipIsErr = 1; \ > > > } > > > > > > used in %MethodCode: > > > > > > %MethodCode > > > try { > > > sipRes = someMethod(...); > > > } CATCH_STD_EXCEPTIONS // sipIsErr - this comment is important hint > > > to SIP! %End > > > > If your point is the need for the comment, then yes - consider it a > > feature. > > No, I meant these exceptions must be caught almost everywhere. So I > have to add %MethodCode to almost every method, which is annoying. The > latest release of SIP always catch all exceptions with "catch(...)" > clause with -e option, but now it doesn't. If we solve the problem of how to specify "..." then you could define std::bad_alloc, std::exception, and (somehow) "..." using %Exception and then... void foo() throw (std::bad_alloc, std::exception, ...); If this is too much trouble, then I can only suggest implementing something like %DefaultExceptionHandler than contains your code and is applied to anything that has no throw specifier (so long as the -e option is used). Phil ___ PyKDE mailing listPyKDE@mats.imk.fraunhofer.de http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] Handling exceptions in SIP
On Fri, 1 Jul 2005 08:54:19 +0100 Phil Thompson <[EMAIL PROTECTED]> wrote: > Whoops. Change the argument to the strstr() call that checks for > "sipExceptionRef" from... > > xd->raisecode > > ...to... > > xd->raisecode->frag Now it works fine, thanks. -- Denis S. Otkidach http://www.python.ru/ [ru] ___ PyKDE mailing listPyKDE@mats.imk.fraunhofer.de http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] Handling exceptions in SIP
On Friday 01 July 2005 8:34 am, Denis S. Otkidach wrote: > On Thu, 30 Jun 2005 17:24:27 +0100 > > Phil Thompson <[EMAIL PROTECTED]> wrote: > > > 1) If sipExceptionRef is not used in RaiseCode we'll get a warning. > > > > Tonight's snapshot will only generate it if it is used. > > Now I get no sipExceptionRef in catch clause even when it's used in > %RaiseCode. Whoops. Change the argument to the strstr() call that checks for "sipExceptionRef" from... xd->raisecode ...to... xd->raisecode->frag Phil ___ PyKDE mailing listPyKDE@mats.imk.fraunhofer.de http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] Handling exceptions in SIP
On Thu, 30 Jun 2005 17:24:27 +0100 Phil Thompson <[EMAIL PROTECTED]> wrote: > > 1) If sipExceptionRef is not used in RaiseCode we'll get a warning. > > Tonight's snapshot will only generate it if it is used. Now I get no sipExceptionRef in catch clause even when it's used in %RaiseCode. -- Denis S. Otkidach http://www.python.ru/ [ru] ___ PyKDE mailing listPyKDE@mats.imk.fraunhofer.de http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] Handling exceptions in SIP
On Thu, 30 Jun 2005 17:24:27 +0100 Phil Thompson <[EMAIL PROTECTED]> wrote: > > 4) There are several standard exceptions which I always have to catch. > > Now I have a macro for them: > > > > #define CATCH_STD_EXCEPTIONS \ > > catch (std::bad_alloc&) {\ > > PyErr_NoMemory(); \ > > sipIsErr = 1; \ > > } catch (std::exception &exc) {\ > > PyErr_SetString(PyExc_RuntimeError, exc.what()); \ > > sipIsErr = 1; \ > > } catch (...) {\ > > PyErr_SetString(PyExc_RuntimeError, "unknown"); \ > > sipIsErr = 1; \ > > } > > > > used in %MethodCode: > > > > %MethodCode > > try { > > sipRes = someMethod(...); > > } CATCH_STD_EXCEPTIONS // sipIsErr - this comment is important hint to > > SIP! %End > > If your point is the need for the comment, then yes - consider it a feature. No, I meant these exceptions must be caught almost everywhere. So I have to add %MethodCode to almost every method, which is annoying. The latest release of SIP always catch all exceptions with "catch(...)" clause with -e option, but now it doesn't. -- Denis S. Otkidach http://www.python.ru/ [ru] ___ PyKDE mailing listPyKDE@mats.imk.fraunhofer.de http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] Handling exceptions in SIP
On Thursday 30 June 2005 10:25 am, Denis S. Otkidach wrote: > On Wed, 29 Jun 2005 15:59:08 +0100 > > Phil Thompson <[EMAIL PROTECTED]> wrote: > > > sip command passes without error, but I have an error when linking: > > > $OFILES in Makefile contains sipMyModuleMyException.o, while there is > > > no corresponding .cpp file generated. > > > > > > BTW, when I use throw specifier in method signature without > > > corresponding %Exception directive, sip exits with non-zero code, but > > > reports no error message. > > > > > > All tests were done with sip-snapshot-20050626. > > > > Should be fixed in tonight's snapshot. > > Simple examples work like a charm with sip-snapshot-20050629, thanks! > There are some points to discuss: > > 1) If sipExceptionRef is not used in RaiseCode we'll get a warning. Tonight's snapshot will only generate it if it is used. > 2) Exceptions that were not specified in throw are not caught and I see > no way to add "catch(...)" to generated code. It could be specified by allowing "..." as the last in the throw list, but I'm not sure how to specify the %RaiseCode. Allowing "..." to be specified with %Exception would mean the same code would have to be used everywhere in the module. Alternatively, %RaiseCode could also be allowed as part of a method definition - but that would need it to be specified every time. > 3) throw specifier has no effect on generated code when %MethodCode is > used, shouldn't it? It shouldn't. If you are providing code to call the method, you should also handle the exceptions. > 4) There are several standard exceptions which I always have to catch. > Now I have a macro for them: > > #define CATCH_STD_EXCEPTIONS \ > catch (std::bad_alloc&) {\ > PyErr_NoMemory(); \ > sipIsErr = 1; \ > } catch (std::exception &exc) {\ > PyErr_SetString(PyExc_RuntimeError, exc.what()); \ > sipIsErr = 1; \ > } catch (...) {\ > PyErr_SetString(PyExc_RuntimeError, "unknown"); \ > sipIsErr = 1; \ > } > > used in %MethodCode: > > %MethodCode > try { > sipRes = someMethod(...); > } CATCH_STD_EXCEPTIONS // sipIsErr - this comment is important hint to > SIP! %End If your point is the need for the comment, then yes - consider it a feature. Phil ___ PyKDE mailing listPyKDE@mats.imk.fraunhofer.de http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] Handling exceptions in SIP
On Wed, 29 Jun 2005 15:59:08 +0100 Phil Thompson <[EMAIL PROTECTED]> wrote: > > sip command passes without error, but I have an error when linking: > > $OFILES in Makefile contains sipMyModuleMyException.o, while there is no > > corresponding .cpp file generated. > > > > BTW, when I use throw specifier in method signature without > > corresponding %Exception directive, sip exits with non-zero code, but > > reports no error message. > > > > All tests were done with sip-snapshot-20050626. > > Should be fixed in tonight's snapshot. Simple examples work like a charm with sip-snapshot-20050629, thanks! There are some points to discuss: 1) If sipExceptionRef is not used in RaiseCode we'll get a warning. 2) Exceptions that were not specified in throw are not caught and I see no way to add "catch(...)" to generated code. 3) throw specifier has no effect on generated code when %MethodCode is used, shouldn't it? 4) There are several standard exceptions which I always have to catch. Now I have a macro for them: #define CATCH_STD_EXCEPTIONS \ catch (std::bad_alloc&) {\ PyErr_NoMemory(); \ sipIsErr = 1; \ } catch (std::exception &exc) {\ PyErr_SetString(PyExc_RuntimeError, exc.what()); \ sipIsErr = 1; \ } catch (...) {\ PyErr_SetString(PyExc_RuntimeError, "unknown"); \ sipIsErr = 1; \ } used in %MethodCode: %MethodCode try { sipRes = someMethod(...); } CATCH_STD_EXCEPTIONS // sipIsErr - this comment is important hint to SIP! %End -- Denis S. Otkidach http://www.python.ru/ [ru] ___ PyKDE mailing listPyKDE@mats.imk.fraunhofer.de http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] Handling exceptions in SIP
On Wednesday 29 June 2005 3:06 pm, Denis S. Otkidach wrote: > On Sun, 26 Jun 2005 23:05:33 +0100 > > Phil Thompson <[EMAIL PROTECTED]> wrote: > > Support for this is in tonight's snapshot - some changes to what I > > described above, but nothing sigificant. > > > > Support for converting Python exceptions to C++ exceptions in Python > > re-implementations of C++ virtuals not yet implemented. > > > > This hasn't been tested - feedback please. > > sip command passes without error, but I have an error when linking: > $OFILES in Makefile contains sipMyModuleMyException.o, while there is no > corresponding .cpp file generated. > > BTW, when I use throw specifier in method signature without > corresponding %Exception directive, sip exits with non-zero code, but > reports no error message. > > All tests were done with sip-snapshot-20050626. Should be fixed in tonight's snapshot. Phil ___ PyKDE mailing listPyKDE@mats.imk.fraunhofer.de http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] Handling exceptions in SIP
On Sun, 26 Jun 2005 23:05:33 +0100 Phil Thompson <[EMAIL PROTECTED]> wrote: > Support for this is in tonight's snapshot - some changes to what I described > above, but nothing sigificant. > > Support for converting Python exceptions to C++ exceptions in Python > re-implementations of C++ virtuals not yet implemented. > > This hasn't been tested - feedback please. sip command passes without error, but I have an error when linking: $OFILES in Makefile contains sipMyModuleMyException.o, while there is no corresponding .cpp file generated. BTW, when I use throw specifier in method signature without corresponding %Exception directive, sip exits with non-zero code, but reports no error message. All tests were done with sip-snapshot-20050626. -- Denis S. Otkidach http://www.python.ru/ [ru] ___ PyKDE mailing listPyKDE@mats.imk.fraunhofer.de http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] Handling exceptions in SIP
On Tuesday 07 June 2005 2:15 pm, Denis S. Otkidach wrote: > On Tue, 7 Jun 2005 13:30:29 +0100 (BST) > > "Phil Thompson" <[EMAIL PROTECTED]> wrote: > > Ok. How about this... > > > > %Exception MyException - will be used with an externally defined > > exception. (Note, you will not be able to specify a base exception, but > > why would you want to?) > > > > %Exception MyException(Base) - will be used to specify a derived > > exception. SIP will recognise "Exception" as the standard Python > > exception, eg. > > > > %Exception MyBase(Exception) > > > > %Exception MyException(MyBase) > > Looks a bit tricky, but it suites all possible cases I think. Let it be > so. > > > Or maybe an empty base exception should be interpreted as the standard > > Python exception, eg. > > > > %Exception MyBase() > > > > ??? > > It doesn't matter for me. > > > > Exactly. Calling PyErr_SetString etc. is quite convenient for > > > extension module authors vs. returning initialized exception instance. > > > > So we have... > > > > %RaiseCode > > // Raise a Python exception. sipCpp will be the C++ pointer, > > // sipException_MyException will be the exception type (unless the > > // exception was defined externally). > > PyObject *val = PyObject_CallFunction(sipException_MyException, > > "S", sipCpp->what()); > > > > PyErr_SetObject(sipException_MyException, val); > > %End > > In most cases it will be even simplier: > > %RaiseCode > PyErr_SetString(sipException_MyException, sipCpp->what()); > %End Support for this is in tonight's snapshot - some changes to what I described above, but nothing sigificant. Support for converting Python exceptions to C++ exceptions in Python re-implementations of C++ virtuals not yet implemented. This hasn't been tested - feedback please. Phil ___ PyKDE mailing listPyKDE@mats.imk.fraunhofer.de http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] Handling exceptions in SIP
On 6/18/05, Denis S. Otkidach <[EMAIL PROTECTED]> wrote: > 2) You overwrite virtual method of wrapped class in Python, so that > other methods (implemented in C++) use it instead of base. This is more > interesting case, but I believe SIP can't handle it too. Please correct > me if I'm wrong. Bingo. I use Python to implement abstract classes defined in Python. The calling C++ has no idea that it is ultimately calling into Python, thus there is no opportunity for checking the Python error state outside of the binding code. My existing C++ code is fairly heavily exception based. All error handling is done though exceptions which will cause database transactions to abort cleanly. The problem is when Python raises an exception (or calls back into some C++ code that throws an exception) control is returned to C++ which continues quite happily. Throwing anything would be an improvement in this case. I can see some sort of exception class defined in SIP for encapsulating Python errors. This would be thrown in response to your garden variety PyExc_* errors. If the exception coming from Python is a wrapped C++ type, then it can be unwrapped and thrown as the original type. I think the problem here is whether to throw it as a pointer or make a copy. Personally, I always catch references, so I would prefer the copy. That brings us back to the problem of copying exceptions. When SIP catches a matching exception, it makes a copy of the exception object, potentially discarding type information. (Isn't this where the thread started?) This precludes using the type at the root of an inheritance heirarchy in the exception specifier as shorthand for 'could throw anything derived from x.' James ___ PyKDE mailing listPyKDE@mats.imk.fraunhofer.de http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] Handling exceptions in SIP
On Thu, 9 Jun 2005 09:33:22 -0700 James Emerton <[EMAIL PROTECTED]> wrote: > I think there is a need for biderectional conversion of exceptions. > I'd like to be able to throw them back into the C++. > > In fact, a mechanism that could be enable to check the Python error > state after calling a Python method from C++ could throw the exception > instead of returning to the C++. Could you provide some examples? I see 2 use cases: 1) Your C++ method accepts callback function implemented in Python. SIP translates C++ functions to Python, but it doesn't translate Python callables to C++ ones. You have to call it yourself. There is no even automatic argument translation for it. Why do you think exception should be translated automatically? You can never trust user provided Python code, you can't predict what exceptions it will ever raise, so you have to handle all possible errors. I even can't imaging syntax for backward exception translation. 2) You overwrite virtual method of wrapped class in Python, so that other methods (implemented in C++) use it instead of base. This is more interesting case, but I believe SIP can't handle it too. Please correct me if I'm wrong. So far I don't see any need for automatic backward exception translation, since you have to code mannually Python exception handling anyway. -- Denis S. Otkidach http://www.python.ru/ [ru] ___ PyKDE mailing listPyKDE@mats.imk.fraunhofer.de http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] Handling exceptions in SIP
On Thursday 09 June 2005 5:33 pm, James Emerton wrote: > On 6/7/05, Phil Thompson <[EMAIL PROTECTED]> wrote: > > So if I introduce something like... > > > > %ExceptionType MyException > > %TypeHeaderCode > > #include > > %End > > %ConvertFromTypeCode > > // C++ code to return a PyObject instance of the exception. > > // sipCpp (the C++ poiter) and sipException_MyException (the > > // PyObject exception type) will be available, eg... > > return PyObject_CallFunction(sipException_MyException, "S", > > sipCpp->what()); > > %End > > %End > > I think there is a need for biderectional conversion of exceptions. > I'd like to be able to throw them back into the C++. > > In fact, a mechanism that could be enable to check the Python error > state after calling a Python method from C++ could throw the exception > instead of returning to the C++. Seems reasonable. Phil ___ PyKDE mailing listPyKDE@mats.imk.fraunhofer.de http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] Handling exceptions in SIP
On 6/7/05, Phil Thompson <[EMAIL PROTECTED]> wrote: > So if I introduce something like... > > %ExceptionType MyException > %TypeHeaderCode > #include > %End > %ConvertFromTypeCode > // C++ code to return a PyObject instance of the exception. > // sipCpp (the C++ poiter) and sipException_MyException (the > // PyObject exception type) will be available, eg... > return PyObject_CallFunction(sipException_MyException, "S", > sipCpp->what()); > %End > %End I think there is a need for biderectional conversion of exceptions. I'd like to be able to throw them back into the C++. In fact, a mechanism that could be enable to check the Python error state after calling a Python method from C++ could throw the exception instead of returning to the C++. James ___ PyKDE mailing listPyKDE@mats.imk.fraunhofer.de http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] Handling exceptions in SIP
On Tue, 7 Jun 2005 13:30:29 +0100 (BST) "Phil Thompson" <[EMAIL PROTECTED]> wrote: > Ok. How about this... > > %Exception MyException - will be used with an externally defined > exception. (Note, you will not be able to specify a base exception, but > why would you want to?) > > %Exception MyException(Base) - will be used to specify a derived > exception. SIP will recognise "Exception" as the standard Python > exception, eg. > > %Exception MyBase(Exception) > > %Exception MyException(MyBase) Looks a bit tricky, but it suites all possible cases I think. Let it be so. > Or maybe an empty base exception should be interpreted as the standard > Python exception, eg. > > %Exception MyBase() > > ??? It doesn't matter for me. > > Exactly. Calling PyErr_SetString etc. is quite convenient for extension > > module authors vs. returning initialized exception instance. > > So we have... > > %RaiseCode > // Raise a Python exception. sipCpp will be the C++ pointer, > // sipException_MyException will be the exception type (unless the > // exception was defined externally). > PyObject *val = PyObject_CallFunction(sipException_MyException, > "S", sipCpp->what()); > > PyErr_SetObject(sipException_MyException, val); > %End In most cases it will be even simplier: %RaiseCode PyErr_SetString(sipException_MyException, sipCpp->what()); %End -- Denis S. Otkidach http://www.python.ru/ [ru] ___ PyKDE mailing listPyKDE@mats.imk.fraunhofer.de http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] Handling exceptions in SIP
> On Mon, 6 Jun 2005 17:54:43 +0100 > Phil Thompson <[EMAIL PROTECTED]> wrote: > >> SIP's exception support was added by a user - I've never used it myself. >> Suggestions for improvements always welcome. > > I see the following scenario. User creates exception class and expose > it in module namespace (Please correct me if there is a better way): > > %ModuleCode > static PyObject *MyException_object; > %End > > %PostInitialisationCode > MyException_object = PyErr_NewException("MyModule.MyException", 0, 0); > if (!MyException_object) return; > PyDict_SetItemString(sip_mdict, "MyException", MyException_object); > %End > > Then he has to define one way mapping for it (assuming MyException has > the same interface as std::exception): > > %MappedType MyException > { > > %ConvertFromTypeCode > return PyObject_CallFunction(MyException_object, "S", sipCpp->what()); > %End > > %ConvertToTypeCode > // We don't need backward convertion, but SIP requires it. > *sipIsErr = 1; > return 0; > %End > > }; So if I introduce something like... %ExceptionType MyException %TypeHeaderCode #include %End %ConvertFromTypeCode // C++ code to return a PyObject instance of the exception. // sipCpp (the C++ poiter) and sipException_MyException (the // PyObject exception type) will be available, eg... return PyObject_CallFunction(sipException_MyException, "S", sipCpp->what()); %End %End ...that has the same effect as your code above. > That's all. Now generated code for method with signature > "void error() throw (MyException);" should be equivalent to > something like the following: > > try > { > sipCpp -> Test::error(); > } > catch (MyException &e) > { > PyObject *MyException_instance = ... // %ConvertFromTypeCode > PyObject *MyException_object = > PyObject_Type(MyException_instance); > PyErr_SetObject(MyException_object, MyException_instance); > return NULL; > } ...and generate the above code automatically, then that gives you what you want? If MyException isn't defined then it reverts to the current behaviour. Phil ___ PyKDE mailing listPyKDE@mats.imk.fraunhofer.de http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] Handling exceptions in SIP
On Mon, 6 Jun 2005 17:54:43 +0100 Phil Thompson <[EMAIL PROTECTED]> wrote: > SIP's exception support was added by a user - I've never used it myself. > Suggestions for improvements always welcome. I see the following scenario. User creates exception class and expose it in module namespace (Please correct me if there is a better way): %ModuleCode static PyObject *MyException_object; %End %PostInitialisationCode MyException_object = PyErr_NewException("MyModule.MyException", 0, 0); if (!MyException_object) return; PyDict_SetItemString(sip_mdict, "MyException", MyException_object); %End Then he has to define one way mapping for it (assuming MyException has the same interface as std::exception): %MappedType MyException { %ConvertFromTypeCode return PyObject_CallFunction(MyException_object, "S", sipCpp->what()); %End %ConvertToTypeCode // We don't need backward convertion, but SIP requires it. *sipIsErr = 1; return 0; %End }; That's all. Now generated code for method with signature "void error() throw (MyException);" should be equivalent to something like the following: try { sipCpp -> Test::error(); } catch (MyException &e) { PyObject *MyException_instance = ... // %ConvertFromTypeCode PyObject *MyException_object = PyObject_Type(MyException_instance); PyErr_SetObject(MyException_object, MyException_instance); return NULL; } -- Denis S. Otkidach http://www.python.ru/ [ru] ___ PyKDE mailing listPyKDE@mats.imk.fraunhofer.de http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] Handling exceptions in SIP
On Monday 06 June 2005 5:23 pm, Denis S. Otkidach wrote: > I hope it's correct place to ask general questions about SIP. > > Am I correct that automatic exception handling in SIP is useless? I see > several problems with it. First, the code for method with signature > "void error() throw (exception);" is: > > try > { > sipCpp -> Test::error(); > } > catch (exception &e) > { > /* Hope that there is a valid copy ctor. */ > exception *sipCpp = new exception(e); > > sipRaiseClassException(sipClass_exception,sipCpp); > return NULL; > } > > The copy of exception is generated and important information is lost (in > fact, std::exception used above is never raised itself, but holds what() > virtual method redefined in subclasses). > > Second, the only way to map C++ exception to python object is wrapping > exception class, %MappedType doesn't work. But then I see no way to > subclass standard Exception class. > > Am I missing something? SIP's exception support was added by a user - I've never used it myself. Suggestions for improvements always welcome. Phil ___ PyKDE mailing listPyKDE@mats.imk.fraunhofer.de http://mats.imk.fraunhofer.de/mailman/listinfo/pykde