<html>
  <head>

    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <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"><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>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">https://github.com/qgis/QGIS/pull/9112</a>)<br>
      </li>
    </ul>
    <p>Regards</p>
    <p>Matthias<br>
    </p>
  </body>
</html>