Can `weakref` callbacks replace `__del__`?
destructor, garbage-collection, python, python-3.x, weak-references
Solution
There's a somewhat pragmatic reason `__del__` is still around. Several signficant `weakref` improvements, including `finalize`, were new in Python 3.4. So, replacing `__del__` with better weakrefs missed the window for language breaking changes with py3k.
I think most uses can be replaced by the base weakref functionality, but I'm struck by this observation from Richard Oudkerk in issue 15528 where proposed and implemented `finalize`:
[Weakref callbacks] are low level, and working out how to use them correctly requires a bit of head scratching. One must find somewhere to store the weakref till after the referent is dead, and without accidentally keeping the referent alive. Then one must ensure that the callback frees the weakref (without leaving any remnant ref-cycles).
When it is an option, using a `__del__` method is far less hassle.
Anyway, perhaps the question should be brought up again when Python 4 is being considered? ;)
Problem
Is there any obstacle that prevents `weakref` from doing everything that `__del__` does but with much stronger guarantees (e.g., `finalize` guarantees that the call will be made before the interpreter exits, and the order of calls is well-defined, etc.)? It seems that in the distant past it was thought that `weakref` would eventually lead to the removal of `__del__` from the language. What prevented this from happening? There seems to be few use cases for `__del__`, and all the ones I'm aware of seem to work at least as well (and usually much better) with `weakref` callbacks or `weakref.finalize`. Update: With PEP 442 dramatically improving the behavior of `__del__`, and the concerns with `weakref` mentioned by @gz and @user2357112, I'm wondering if the language is generally moving towards making `__del__` more reliable, or towards using `weakref` instead of `__del__`, or both.