[QGIS-Developer] PSA: The new SIP_THROW macro

Matthias Kuhn matthias at opengis.ch
Tue May 15 22:34:52 PDT 2018


Thanks Nyall,

That sounds like a VERY good addition, thanks a lot for sharing this.

Matthias

On 05/16/2018 01:18 AM, Nyall Dawson wrote:
> Hi all,
>
> Just a quick heads up about a recent addition to QGIS 3.2 regarding
> the Python bindings.
>
> In https://github.com/qgis/QGIS/commit/0f78277 I've added a new
> "SIP_THROW" macro. The idea behind this is that SIP uses the
> deprecated "throw(...)" annotations in order to determine which
> exceptions may be thrown by c++ code. Without these, only a generic
> unknown exception is throw, which is of limited value to Python code
> (losing any valuable message and exception type). (side note - this
> took a LONG time for me to discover... I don't believe it's explicitly
> stated anywhere in the sip documentation, at least not that I've been
> able to find).
>
> So in this commit I've added a new SIP_THROW macro, which can be added
> to a method's declaration:
>
>     bool doSomething() SIP_THROW( QgsCsException );
>
> This is ignored outside of sipify, so we don't actually use the
> deprecated c++ throw annotations when compiling, but sipify picks it
> up and adds the appropriate change to the sip definition for the
> method:
>
>    bool doSomething() throw( QgsCsException );
>
> Without the throw annotation the generated sip code looks something like this:
>
>             try
>             {
>             sipCpp= new  ::(sipCpp->doSomething());
>             }
>             catch (...)
>             {
>                 ...
>                 sipRaiseUnknownException();
>                 return NULL;
>             }
>
> So when the doSomething raises a c++ exception, all the Python caller
> gets is the unknown generic exception.
>
> Using the throw annotation the generated code gets expanded to something like:
>
>             try
>             {
>             sipRes = new  ::(sipCpp->doSomething());
>             }
>             catch (QgsCsException &sipExceptionRef)
>             {
>                 ...
>                 PyErr_SetString(sipException_QgsCsException,
> sipExceptionRef.what().toUtf8().constData() );
>                ...
>                 return NULL;
>             }
>             catch (...)
>             {
>                 ....
>                 sipRaiseUnknownException();
>                 return NULL;
>             }
>
> This means that calling the method from Python will raise the
> QgsCsException (when thrown by the c++ method) instead of a generic
> exception, giving much more useful debugging information to the caller
> and allowing them to handle the specific exception type.
>
> I've made this change throughout Processing (for
> QgsProcessingException), so now there's much more explicit error
> messages given to both Python and end users of processing algorithms.
> It'd be nice to start adding the same for QgsCsException to any
> methods which can throw this exception... so if you come across one of
> these methods in the c++ code which is missing the SIP_THROW
> annotation, please feel free to go ahead and add it!
>
> Cheers,
> Nyall
> _______________________________________________
> QGIS-Developer mailing list
> QGIS-Developer at lists.osgeo.org
> List info: https://lists.osgeo.org/mailman/listinfo/qgis-developer
> Unsubscribe: https://lists.osgeo.org/mailman/listinfo/qgis-developer
>

-- 
Matthias Kuhn
matthias at opengis.ch <mailto:matthias at opengis.ch>
+41 (0)76 435 67 63 <tel:+41764356763>
OPENGIS.ch Logo <http://www.opengis.ch>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/qgis-developer/attachments/20180516/cabbc736/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image.png
Type: image/png
Size: 6671 bytes
Desc: not available
URL: <http://lists.osgeo.org/pipermail/qgis-developer/attachments/20180516/cabbc736/attachment.png>


More information about the QGIS-Developer mailing list