<div dir="ltr"><div>Hello. I'm not sure if I'm posting to the right list. If it's not the</div><div>case, please tell me which one to post to.</div><div><br></div><div>Using Python 3.5.2.</div><div><br></div><div>I'm developing a C module with the help of SWIG. My library manages</div><div>objects with reference counting, much like Python, except that it's</div><div>deterministic: there's no GC.</div><div><br></div><div>I create two Python objects like this:</div><div><br></div><div>    bakery = Bakery()</div><div>    bread = bakery.create_bread()</div><div><br></div><div>Behind the scenes, the situation looks like this:</div><div><br></div><div>                                       +--------------------+</div><div>                                       | UserBread obj (Py) |</div><div>                                       +----------^---+-----+</div><div>                                                  |   :</div><div>                                                  |   :</div><div>                                                  |   :</div><div>    +------------------+                +---------+---V---+</div><div>    | Bakery obj (lib) <----------------+ Bread obj (lib) |</div><div>    +--------^---+-----+                +--------^--------+</div><div>             |   :                               |</div><div>             |   :                               |</div><div>    +--------+---V----+                 +--------+-------+</div><div>    | Bakery obj (Py) |                 | Bread obj (Py) |</div><div>    +---------^-------+                 +------^---------+</div><div>              |                                |</div><div>              |                                |</div><div>              +                                +</div><div>           bakery                            bread</div><div><br></div><div>A pipe link means one "strong" reference and a colon link means one</div><div>borrowed/weak reference.</div><div><br></div><div>I have some ownership inversion magic for the Bakery lib. and Python</div><div>objects to always coexist.</div><div><br></div><div>So here it's pretty clear what can happen. I don't know which reference</div><div>gets deleted first, but let's assume it's `bakery`. Then the situation</div><div>looks like this:</div><div><br></div><div>                                       +--------------------+</div><div>                                       | UserBread obj (Py) |</div><div>                                       +----------^---+-----+</div><div>                                                  |   :</div><div>                                                  |   :</div><div>                                                  |   :</div><div>    +------------------+                +---------+---V---+</div><div>    | Bakery obj (lib) <----------------+ Bread obj (lib) |</div><div>    +--------^---+-----+                +--------^--------+</div><div>             :   |                               |</div><div>             :   |                               |</div><div>    +--------+---V----+                 +--------+-------+</div><div>    | Bakery obj (Py) |                 | Bread obj (Py) |</div><div>    +-----------------+                 +------^---------+</div><div>                                               |</div><div>                                               |</div><div>                                               +</div><div>                                             bread</div><div><br></div><div>The Bakery Python object's __del__() drops the reference to its library</div><div>object, but first its reference count is incremented during this call</div><div>(so it's not really destroyed) and it's marked as only owned by the</div><div>library object from now on.</div><div><br></div><div>When `bread` gets deleted:</div><div><br></div><div>1. The Bread Python object's __del__() method gets called: the reference</div><div>   to its library object is dropped.</div><div>2. The Bread library object's destroy function drops its reference to</div><div>   the Bakery library object.</div><div>3. The Bakery library object's destroy function drops its reference to</div><div>   the Bakery Python object.</div><div>4. The Bakery Python object's __del__() method does nothing this time,</div><div>   since the object is marked as only owned by its library object</div><div>   (inverted ownership).</div><div>5. The Bread library object's destroy function then drops its reference</div><div>   to the UserBread Python object.</div><div><br></div><div>In the end, everything is correctly destroyed and released. This also</div><div>works if `bread` is deleted before `bakery`.</div><div><br></div><div>My problem is that this works as expected when used like this:</div><div><br></div><div>    def func():</div><div>        bakery = Bakery()</div><div>        bread = bakery.create_bread()</div><div><br></div><div>    if __name__ == '__main__':</div><div>        func()</div><div><br></div><div>but NOTHING is destroyed when used like this:</div><div><br></div><div>    bakery = Bakery()</div><div>    bread = bakery.create_bread()</div><div><br></div><div>That is, directly during the module's initialization. It works, however,</div><div>if I delete `bread` manually:</div><div><br></div><div>    bakery = Bakery()</div><div>    bread = bakery.create_bread()</div><div>    del bread</div><div><br></div><div>It also works with `bakery` only:</div><div><br></div><div>    bakery = Bakery()</div><div><br></div><div>My question is: what could explain this?</div><div><br></div><div>My guess is that my logic is correct since it works fine in the function</div><div>call situation.</div><div><br></div><div>It feels like `bread` is never deleted in the module initialization</div><div>situation, but I don't know why: the only reference to the Bread Python</div><div>object is this `bread` name in the module... what could prevent this</div><div>object's __del__() method to be called? It works when I call `del bread`</div><div>manually: I would expect that the module finalization does the exact</div><div>same thing?</div><div><br></div><div>Am I missing anything?</div><div><br></div><div>Thanks,</div><div>Phil</div>
</div>