Allan Feldman <allan.d.feld...@gmail.com> added the comment:

Reading more carefully, I may have jumped to conclusions here :)

Looking at the weakref docs, I see the following description of the callback 
functionality:

> If callback is provided and not None, and the returned weakref object is 
> still alive, the callback will be called when the object is about to be 
> finalized; the weak reference object will be passed as the only parameter to 
> the callback; the referent will no longer be available.

This description seems to imply that even if an object is resurrected, the 
callback will be run.

Using the `ForeverObject` example above, I see the weakref callback behavior is 
different when going through gc versus going through `_Py_Dealloc`.

The behavior being different seems to imply that a contract is broken somewhere.

In this case I think I assumed it was gc, but it looks like it might actually 
be that the contract (as currently defined) is broken by dealloc. Finalizers 
are always called before weakref callbacks on the reference counted path:
https://github.com/python/cpython/blob/482259d0dcf27714a84cf56b93977320bea7e093/Objects/typeobject.c#L1245

Here is the output from the `ForeverObject` example above:

------- Circular reference: True -------
callback running <weakref at 0x10fedea10; dead>
--------------
------- Circular reference: False -------
--------------

For my own understanding, why is the API documented as running the callback 
prior to finalizers running? The referent is unavailable when the callback 
runs, so isn't it safe to run the weakref callbacks consistently after the 
finalizers?

----------

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

Reply via email to