[Python-Dev] Is there any remaining reason why weakref callbacks shouldn't be able to access the referenced object? (original) (raw)
Nick Coghlan ncoghlan at gmail.com
Fri Oct 21 23:32:04 EDT 2016
- Previous message (by thread): [Python-Dev] Is there any remaining reason why weakref callbacks shouldn't be able to access the referenced object?
- Next message (by thread): [Python-Dev] Is there any remaining reason why weakref callbacks shouldn't be able to access the referenced object?
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On 21 October 2016 at 17:09, Nathaniel Smith <njs at pobox.com> wrote:
But that was 2.4. In the mean time, of course, PEP 442 fixed it so that finalizers and weakrefs mix just fine. In fact, weakref callbacks are now run before del methods [2], so clearly it's now okay for arbitrary code to touch the objects during that phase of the GC -- at least in principle.
So what I'm wondering is, would anything terrible happen if we started passing still-live weakrefs into weakref callbacks, and then clearing them afterwards?
The weakref-before-del ordering change in https://www.python.org/dev/peps/pep-0442/#disposal-of-cyclic-isolates only applies to cyclic garbage collection,so for normal refcount driven object cleanup in CPython, the del still happens first:
>>> class C:
... def __del__(self):
... print("__del__ called")
...
>>> c = C()
>>> import weakref
>>> def cb():
... print("weakref callback called")
...
>>> weakref.finalize(c, cb)
<finalize object at 0x7f4300b710a0; for 'C' at 0x7f42f8ae3470>
>>> del c
__del__ called
weakref callback called
This means the main problem with a strong reference being reachable from the weakref callback object remains: if the callback itself is reachable, then the original object is reachable, and you don't have a collectible cycle anymore.
>>> c = C()
>>> def cb2(obj):
... print("weakref callback called with object reference")
...
>>> weakref.finalize(c, cb2, c)
<finalize object at 0x7f4300b710b0; for 'C' at 0x7f42f8ae3470>
>>> del c
>>>
Changing that to support resurrecting the object so it can be passed into the callback without the callback itself holding a strong reference means losing the main "reasoning about software" benefit that weakref callbacks offer: they currently can't resurrect the object they relate to (since they never receive a strong reference to it), so it nominally doesn't matter if the interpreter calls them before or after that object has been entirely cleaned up.
Cheers, Nick.
-- Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia
- Previous message (by thread): [Python-Dev] Is there any remaining reason why weakref callbacks shouldn't be able to access the referenced object?
- Next message (by thread): [Python-Dev] Is there any remaining reason why weakref callbacks shouldn't be able to access the referenced object?
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]