Make weak references subclassable:

- 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

This closes SF patch #983019.
This commit is contained in:
Fred Drake 2004-07-02 18:57:45 +00:00
parent 813914049d
commit 0a4dd390bf
8 changed files with 338 additions and 109 deletions

View file

@ -68,7 +68,7 @@ Extension types can easily be made to support weak references; see section
information.
\begin{funcdesc}{ref}{object\optional{, callback}}
\begin{classdesc}{ref}{object\optional{, callback}}
Return a weak reference to \var{object}. The original object can be
retrieved by calling the reference object if the referent is still
alive; if the referent is no longer alive, calling the reference
@ -100,7 +100,11 @@ information.
\var{callback}). If either referent has been deleted, the
references are equal only if the reference objects are the same
object.
\end{funcdesc}
\versionchanged[This is now a subclassable type rather than a
factory function; it derives from \class{object}]
{2.4}
\end{classdesc}
\begin{funcdesc}{proxy}{object\optional{, callback}}
Return a proxy to \var{object} which uses a weak reference. This
@ -236,6 +240,41 @@ become invalidated before the weak reference is called; the
idiom shown above is safe in threaded applications as well as
single-threaded applications.
Specialized versions of \class{ref} objects can be created through
subclassing. This is used in the implementation of the
\class{WeakValueDictionary} to reduce the memory overhead for each
entry in the mapping. This may be most useful to associate additional
information with a reference, but could also be used to insert
additional processing on calls to retrieve the referent.
This example shows how a subclass of \class{ref} can be used to store
additional information about an object and affect the value that's
returned when the referent is accessed:
\begin{verbatim}
import weakref
class ExtendedRef(weakref.ref):
def __new__(cls, ob, callback=None, **annotations):
weakref.ref.__new__(cls, ob, callback)
self.__counter = 0
def __init__(self, ob, callback=None, **annotations):
super(ExtendedRef, self).__init__(ob, callback)
for k, v in annotations:
setattr(self, k, v)
def __call__(self):
"""Return a pair containing the referent and the number of
times the reference has been called.
"""
ob = super(ExtendedRef, self)()
if ob is not None:
self.__counter += 1
ob = (ob, self.__counter)
return ob
\end{verbatim}
\subsection{Example \label{weakref-example}}