[Qgis-developer] SIP and transfer of ownership

Martin Dobias wonder.sk at gmail.com
Fri Nov 7 23:07:43 PST 2014


Hi Chris

(sorry for the long delay!)

You are raising good points.

On Sun, Oct 12, 2014 at 1:35 AM, Chris Crook <ccrook at linz.govt.nz> wrote:
>
>     void setSourceColorRamp( QgsVectorColorRampV2* ramp /Transfer/ );
>
> So this could be used from python with code something like
>
>     ramp=myColorRamp()
>     renderer.setSourceColorRamp(ramp)
>
> However if you were using the same ramp in two places, then you'd need to make sure that you didn't pass the same object to both, so you might have something like
>
>    ramp=myColorRamp()
>    renderer1.setSourceColorRamp(ramp.clone())
>    renderer2.setSourceColorRamp(ramp.clone())
>
> Is this right?

Yes. But you could as well do this:

    renderer1.setSourceColorRamp(ramp.clone())
    renderer2.setSourceColorRamp(ramp)


> If so, then I wonder if having to pay attention to this sort of memory allocation/ownership issue is not very "pythonic".

Indeed it is not very Pythonic. Qt library is able to avoid such
issues much better. Why is that: when /Transfer/ is needed (e.g. in
calls involving QObject-based classes), the classes explicitly
remember their parents/children. So even if you try to assign one
object to two different parents (like above), it will be actually
moved from one parent to another. QGIS API does not handle it and
that's why we have these issues. A solution would be to make internal
copies of objects in functions like setSourceColorRamp(). That would
solve the issue, but it will add an extra copy we didn't want. There
is solution for that either - to use implicit sharing. If the color
ramp class supported implicit sharing, the copy would be just shallow
(no memory copying) - and it would be a win.

I think for a future major release of QGIS we could go through the API
and see where we have these problems - and ideally fix them as
suggested above. However the implicit sharing has also its downsides -
the implementation is slightly more complex and it adds a little bit
of overhead. But it's nothing we couldn't handle :-)


> Would it be better to set up the SIP so that it always used the clone() function, and so that a python coder didn't have think about whether they might have yielded ownership of a python object.  Presumably there is a way to write the SIP to do this?  And would this create issues in those environments (eg windows 64) where the transfer function doesn't seem to work reliably, and python subclassed objects need to be deliberately kept alive?

I don't think that trying to solve this at SIP level would be good.
Any deviation between C++ and Python API (in terms of some special
code for SIP) is a pain, so if possible let's address that in C++ code
(with improvements for both C++ and Python devs). Also from C++
developer's point of view, it is much nicer if you do not need to
think how the ownership is handled in each such method.

Cheers
Martin


More information about the Qgis-developer mailing list