Issue 983019: Making weakref.ref subclassable (original) (raw)
This patch makes weak references subclassable. This includes the following changes:
weakref.ref and weakref.ReferenceType will become aliases for each other
weakref.ref will be a modern, new-style class with proper new and init methods
weakref.WeakValueDictionary will have a lighter memory footprint, using a new weakref.ref subclass to associate the key with the value, allowing us to have only a single object of overhead for each dictionary entry (currently, there are 3 objects of overhead per entry: a weakref to the value, a weakref to the dictionary, and a function object used as a weakref callback; the weakref to the dictionary could be avoided without this change)
a new macro, PyWeakref_CheckRefExact(), will be added
PyWeakref_CheckRef() will check for subclasses of weakref.ref
the cyclic garbage detector will be affected by the change to PyWeakref_CheckRef(); it will potentially call issubtype() for objects in the unreachable list that do not have finalizers (in the move_troublemakers() function). This should only happen for weakref objects which are not of one of the "standard" three types (ref, proxy, and callable proxy). For debug builds, it will also affect assertions in the clear_weakerfs() and release_weakrefs() functions.
The change to the cyclic garbage detector probably carries the most risk, and that only because the potential for a performance penalty. Running the Zope 3 test suite did not show any clear change in performance, and a key subsystem in Zope (zope.interface) uses weakrefs extensively.