From ebcf6a85736f7a9193d7293ec361d8e53bb0a063 Mon Sep 17 00:00:00 2001 From: Fred Drake Date: Thu, 1 Feb 2001 05:20:20 +0000 Subject: [PATCH] Documentation for the weakref module. --- Doc/lib/libweakref.tex | 227 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 227 insertions(+) create mode 100644 Doc/lib/libweakref.tex diff --git a/Doc/lib/libweakref.tex b/Doc/lib/libweakref.tex new file mode 100644 index 00000000000..ce44009a3ff --- /dev/null +++ b/Doc/lib/libweakref.tex @@ -0,0 +1,227 @@ +\section{\module{weakref} --- + Weak references} + +\declaremodule{extension}{weakref} +\moduleauthor{Fred L. Drake, Jr.}{fdrake@acm.org} +\sectionauthor{Fred L. Drake, Jr.}{fdrake@acm.org} + +\versionadded{2.1} + + +The \module{weakref} module allows the Python programmer to create +\dfn{weak references} to objects. + +XXX --- need to say more here! + +Not all objects can be weakly referenced; those objects which do +include class instances and dictionaries. Extension types can easily +be made to support weak references; see section \ref{weakref-extension}, +``Weak References in Extension Types,'' for more information. + + +\strong{Warning:} +The weak dictionaries provided in the current implementation and +described below are subject to change. They are included to solicit +feedback and usage experience, and may be changed or removed in the +final version. + +\strong{Warning:} +The desired semantics of weak-reference proxy objects are not +completely clear; it is very difficult to create proxies which behave +exactly like the type of the referent. The details of these objects +are likely to change to some degree before the final release as +experience reports become available. + +Please send specific feeback on this module to Fred Drake at +\email{fdrake@acm.org}. + + +\begin{funcdesc}{ref}{object\optional{, callback}} + Return a weak reference to \var{object}. If \var{callback} is + provided, it 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. + The original object can be retrieved by calling the reference + object, if the referent is still alive. + + It is allowable for many weak references to be constructed for the + same object. Callbacks registered for each weak reference will be + called from the most recently registered callback to the oldest + registered callback. + + Exceptions raised by the callback will be noted on the standard + error output, but cannot be propogated; they are handled in exactly + the same way as exceptions raised from an object's + \method{__del__()} method. +\end{funcdesc} + +\begin{funcdesc}{mapping}{\optional{dict}} + Return a weak dictionary. If \var{dict} is given and not + \code{None}, the new dictionary will contain the items contained in + \var{dict}. The values from \var{dict} must be weakly referencable; + if any values which would be inserted into the new mapping are not + weakly referencable, \exception{TypeError} will be raised and the + new mapping will be empty. +\end{funcdesc} + +\begin{funcdesc}{proxy}{object\optional{, callback}} + Return a proxy to \var{object} which uses a weak reference. This + supports use of the proxy in most contexts instead of requiring the + explicit dereferencing used with weak reference objects. The + returned object will have a type of either \code{ProxyType} or + \code{CallableProxyType}, depending on whether \var{object} is + callable. Proxy objects are not hashable regardless of the + referent; this avoids a number of problems related to their + fundamentally mutable nature, and prevent their use as dictionary + keys. \var{callable} is the same as the parameter of the same name + to the \function{ref()} function. +\end{funcdesc} + +\begin{funcdesc}{getweakrefcount}{object} + Return the number of weak references and proxies which refer to + \var{object}. +\end{funcdesc} + +\begin{funcdesc}{getweakrefs}{object} + Return a list of all weak reference and proxy objects which refer to + \var{object}. +\end{funcdesc} + +\begin{classdesc}{WeakDictionary}{\optional{dict}} + The class of the mapping objects returned by \function{mapping()}. + This can be used for subclassing the implementation if needed. +\end{classdesc} + +\begin{datadesc}{ReferenceType} + The type object for weak references objects. +\end{datadesc} + +\begin{datadesc}{ProxyType} + The type object for proxies of objects which are not callable. +\end{datadesc} + +\begin{datadesc}{CallableProxyType} + The type object for proxies of callable objects. +\end{datadesc} + +\begin{datadesc}{ProxyTypes} + Sequence containing all the type objects for proxies. This can make + it simpler to test if an object is a proxy without being dependent + on naming both proxy types. +\end{datadesc} + + +\begin{seealso} + \seepep{0205}{Weak References}{The proposal and rationale for this + feature, including links to earlier implementations + and information about similar features in other + languages.} +\end{seealso} + + +\subsection{Weak Reference Objects + \label{weakref-objects}} + +Weak reference objects have no attributes or methods, but do allow the +referent to be obtained, if it still exists, by calling it: + +\begin{verbatim} +>>> import weakref +>>> class Object: +... pass +... +>>> o = Object() +>>> r = weakref.ref(o) +>>> o2 = r() +>>> o is o2 +1 +\end{verbatim} + +If the referent no longer exists, calling the reference object returns +\code{None}: + +\begin{verbatim} +>>> del o, o2 +>>> print r() +None +\end{verbatim} + +Testing that a weak reference object is still live should be done +using the expression \code{\var{ref}.get() is not None}. Normally, +application code that needs to use a reference object should follow +this pattern: + +\begin{verbatim} +o = ref.get() +if o is None: + # referent has been garbage collected + print "Object has been allocated; can't frobnicate." +else: + print "Object is still live!" + o.do_something_useful() +\end{verbatim} + +Using a separate test for ``liveness'' creates race conditions in +threaded applications; another thread can cause a weak reference to +become invalidated before the \method{get()} method is called; the +idiom shown above is safe in threaded applications as well as +single-threaded applications. + + +\subsection{Weak References in Extension Types + \label{weakref-extension}} + +One of the goals of the implementation is to allow any type to +participate in the weak reference mechanism without incurring the +overhead on those objects which do not benefit by weak referencing +(such as numbers). + +For an object to be weakly referencable, the extension must include a +\ctype{PyObject *} field in the instance structure for the use of the +weak reference mechanism; it will be initialized by Python's functions +for object creation. It must also set the \code{tp_weaklistoffset} +field of the corresponding type object to the offset of the field. +For example, the instance type is defined with the following structure: + +\begin{verbatim} +typedef struct { + PyObject_HEAD + PyClassObject *in_class; /* The class object */ + PyObject *in_dict; /* A dictionary */ + PyObject *in_weakreflist; /* List of weak references */ +} PyInstanceObject; +\end{verbatim} + +The statically-declared type object for instances is defined this way: + +\begin{verbatim} +PyTypeObject PyInstance_Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, + "instance", + + /* lots of stuff omitted for brevity */ + + offsetof(PyInstanceObject, in_weakreflist) /* tp_weaklistoffset */ +}; +\end{verbatim} + +The only further addition is that the destructor needs to call the +weak reference manager to clear any weak references and return if the +object has been resurrected. This needs to occur before any other +parts of the destruction have occurred: + +\begin{verbatim} +static void +instance_dealloc(PyInstanceObject *inst) +{ + /* allocate tempories if needed, but do not begin + destruction here + */ + + if (!PyObject_ClearWeakRefs((PyObject *) inst)) + return; + + /* proceed with object destuction normally */ +} +\end{verbatim}