<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <p><br>
    </p>
    <div class="moz-cite-prefix">On 06.02.19 12:41, Matthias Kuhn wrote:<br>
    </div>
    <blockquote type="cite"
      cite="mid:275cbce2-2998-daa4-f127-e442e97336f4@opengis.ch">
      <meta http-equiv="content-type" content="text/html; charset=UTF-8">
      <p>Hi</p>
      <blockquote type="cite"><span>On 7 Jan 2019, at 4:32 pm, <span
            class="bold highlight search-highlight">Sandro</span> <span
            class="bold highlight search-highlight">Mani</span> <</span><a
href="http://python.6.x6.nabble.com/user/SendEmail.jtp?type=node&node=5246016&i=0"
          target="_top" rel="nofollow" moz-do-not-send="true"><span>[hidden
            email]</span></a><span>> wrote: </span>
        <div class="shrinkable-quote" style="height: 300px; overflow-y:
          hidden;"><br>
          <span>> </span><br>
          <span>> Hi </span><br>
          <span>> </span><br>
          <span>> I have the following scenario: </span><br>
          <span>> </span><br>
          <span>> ----------- </span><br>
          <span>> </span><br>
          <span>> </span><br>
          <span>> C++: </span><br>
          <span>> </span><br>
          <span>> class AbstractItem { </span><br>
          <span>>     AbstractItem(const QString& id); </span><br>
          <span>>     virtual ~AbstractItem(); </span><br>
          <span>> }; </span><br>
          <span>> </span><br>
          <span>> </span><br>
          <span>> class Pool { </span><br>
          <span>>     void addItem(AbstractItem* item /Transfer/); </span><br>
          <span>>     AbstractItem* getItem(const QString& id); </span><br>
          <span>> }; </span><br>
          <span>> </span><br>
          <span>> </span><br>
          <span>> </span><br>
          <span>> </span><br>
          <span>> Python: </span><br>
          <span>> </span><br>
          <span>> class Item(AbstractItem): </span><br>
          <span>>     def __init__(self, id): </span><br>
          <span>>         AbstractItem.__init__(self, id) </span><br>
          <span>>         self.value = "value" </span><br>
          <span>>     def getValue(self): </span><br>
          <span>>         return self.value </span><br>
          <span>> </span><br>
          <span>> </span><br>
          <span>> pool = Pool() </span><br>
          <span>> pool.addItem(Item("xyz")) </span><br>
          <span>> # ... </span><br>
          <span>> item = pool.getItem("xyz") </span><br>
          <span>> print(item.getValue()) ### AttributeError: 'Item'
            object has no attribute 'value' </span><br>
          <span>> </span><br>
          <span>> </span><br>
          <span>> ----------- </span><br>
          <span>> </span><br>
          <span>> </span><br>
          <span>> The issue is that, when I pass the Python-deriver
            Item instance to the pool, lose the reference to it, and
            then re-retreive it from the pool, the Item instance will
            have lost class variables set in the Item __init__ function.
            As I understand, this is expected, because SIP keeps a
            python part and a c++ part of each object, and the python
            part is garbage-collected when the variable gets out of
            scope. Is there a way to make the above logic work? </span></div>
        <div class="shrink-quote"><span>...</span> [<a
            moz-do-not-send="true">show rest of quote</a>]</div>
        <br>
        <span>Use of /Transfer/ should get the behaviour that you want.
          However you need to make sure you are using the right
          supertype for any classes that implement any sort of ownership
          rules. Adding the /Supertype=sip.wrapper/ class annotation to
          both AbstractItem and Pool classes may help. </span><br>
        <br>
        <span>Phil </span></blockquote>
      <p>PSA:<br>
      </p>
      <p>After the latest insights into how /Transfer/ works, I was able
        to find a solution for this.</p>
      <p>As soon as the Transfer annotation is involved, the target
        class wrapper (the pool in this case) will hold a reference to
        the transferred child wrapper (item subclass here). If pool's
        wrapper gets garbage collected, the transferred item's wrapper
        is free to be garbage collected as well.</p>
      <p>To avoid this issue, there are the following possibilities I
        can see</p>
      <ul>
        <li>Keep a reference to the item subclass (the current
          workaround)</li>
        <li>Keep a (global or long-living) reference to the pool</li>
        <li>And for singleton-like classes: add a /KeepReference/
          annotation to the getter of the pool (see <a
            class="moz-txt-link-freetext"
            href="https://github.com/qgis/QGIS/pull/9112"
            moz-do-not-send="true">https://github.com/qgis/QGIS/pull/9112</a>)<br>
        </li>
      </ul>
    </blockquote>
    <p>Thanks for the followup!</p>
    <p>Sandro</p>
  </body>
</html>