Tim Peters <t...@python.org> added the comment:

> call_func and remove are part of a reference cycle. A forced garbage
> collection breaks the cycle and removes the two objects, but they are
> not removed in the expected order:
>
> * first: call_func
> * then: remove
>
> The crash requires to destroy the objects in the reverse order

Victor, I'm not sure what you had in mind there, so please flesh it out if the 
following isn't clear?

In any case "like" the one you constructed, __del__  will always run first, 
with everything needed wholly intact.

Because tp_clear can leave an object in a useless (or worse) state, gc runs all 
finalizers and all weakref callbacks before tp_clear is run on anything.  
tp_clear is used only in delete_garbage, which is the last non-trivial thing gc 
does.  Before then, clears and deallocations happen only as side effects of 
refcounting semantics while running finalizers and callbacks.  So refcount 
precedence order is respected, and nothing will get torn down before its 
refcount hits 0.

At the time gc first calls tp_clear, the intent is that no non-trivial code 
will run again - just tp_clear implementations applying Py_CLEAR to objects' 
members, and deallocations happening as refcounts fall to 0.  No finalizers, no 
callbacks, none, ever ;-)

So what I saw your program doing wasn't just an accident relying on the order 
the objects happened to appear in the list.  Regardless of that order, gc 
forces __del__ to run before tp_clear is applied to anything, and the call_func 
instance is wholly intact when its __del__ runs.

----------

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue38006>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to