diff options
author | Tim Peters <tim.peters@gmail.com> | 2006-05-12 01:57:59 (GMT) |
---|---|---|
committer | Tim Peters <tim.peters@gmail.com> | 2006-05-12 01:57:59 (GMT) |
commit | b06d28c16006ec66166f8bdf9523d68f200976af (patch) | |
tree | 4f2a7dd5239186fd844a8af147c87b5f1c9c01cf /Doc/api | |
parent | 1fb9f528bd69efa135bacda917ec7bb166068d5d (diff) | |
download | cpython-b06d28c16006ec66166f8bdf9523d68f200976af.zip cpython-b06d28c16006ec66166f8bdf9523d68f200976af.tar.gz cpython-b06d28c16006ec66166f8bdf9523d68f200976af.tar.bz2 |
SF patch #1473132: Improve docs for tp_clear and tp_traverse,
by Collin Winter.
Bugfix candidate (but I'm not going to bother).
Diffstat (limited to 'Doc/api')
-rw-r--r-- | Doc/api/newtypes.tex | 88 |
1 files changed, 84 insertions, 4 deletions
diff --git a/Doc/api/newtypes.tex b/Doc/api/newtypes.tex index 2d758b0..64c2f6b 100644 --- a/Doc/api/newtypes.tex +++ b/Doc/api/newtypes.tex @@ -883,8 +883,39 @@ The following three fields only exist if the \begin{cmemberdesc}{PyTypeObject}{traverseproc}{tp_traverse} An optional pointer to a traversal function for the garbage collector. This is only used if the \constant{Py_TPFLAGS_HAVE_GC} - flag bit is set. More information in section - \ref{supporting-cycle-detection} about garbage collection. + flag bit is set. More information about Python's garbage collection + scheme can be found in section \ref{supporting-cycle-detection}. + + The \member{tp_traverse} pointer is used by the garbage collector + to detect reference cycles. A typical implementation of a + \member{tp_traverse} function simply calls \cfunction{Py_VISIT()} on + each of the instance's members that are Python objects. For exampe, this + is function \cfunction{local_traverse} from the \module{thread} extension + module: + + \begin{verbatim} + static int + local_traverse(localobject *self, visitproc visit, void *arg) + { + Py_VISIT(self->args); + Py_VISIT(self->kw); + Py_VISIT(self->dict); + return 0; + } + \end{verbatim} + + Note that \cfunction{Py_VISIT()} is called only on those members that can + participate in reference cycles. Although there is also a + \samp{self->key} member, it can only be \NULL{} or a Python string and + therefore cannot be part of a reference cycle. + + On the other hand, even if you know a member can never be part of a cycle, + as a debugging aid you may want to visit it anyway just so the + \module{gc} module's \function{get_referents()} function will include it. + + Note that \cfunction{Py_VISIT()} requires the \var{visit} and \var{arg} + parameters to \cfunction{local_traverse} to have these specific names; + don't name them just anything. This field is inherited by subtypes together with \member{tp_clear} and the \constant{Py_TPFLAGS_HAVE_GC} flag bit: the flag bit, @@ -896,8 +927,57 @@ The following three fields only exist if the \begin{cmemberdesc}{PyTypeObject}{inquiry}{tp_clear} An optional pointer to a clear function for the garbage collector. This is only used if the \constant{Py_TPFLAGS_HAVE_GC} flag bit is - set. More information in section - \ref{supporting-cycle-detection} about garbage collection. + set. + + The \member{tp_clear} member function is used to break reference + cycles in cyclic garbage detected by the garbage collector. Taken + together, all \member{tp_clear} functions in the system must combine to + break all reference cycles. This is subtle, and if in any doubt supply a + \member{tp_clear} function. For example, the tuple type does not + implement a \member{tp_clear} function, because it's possible to prove + that no reference cycle can be composed entirely of tuples. Therefore + the \member{tp_clear} functions of other types must be sufficient to + break any cycle containing a tuple. This isn't immediately obvious, and + there's rarely a good reason to avoid implementing \member{tp_clear}. + + Implementations of \member{tp_clear} should drop the instance's + references to those of its members that may be Python objects, and set + its pointers to those members to \NULL{}, as in the following example: + + \begin{verbatim} + static int + local_clear(localobject *self) + { + Py_CLEAR(self->key); + Py_CLEAR(self->args); + Py_CLEAR(self->kw); + Py_CLEAR(self->dict); + return 0; + } + \end{verbatim} + + The \cfunction{Py_CLEAR()} macro should be used, because clearing + references is delicate: the reference to the contained object must not be + decremented until after the pointer to the contained object is set to + \NULL{}. This is because decrementing the reference count may cause + the contained object to become trash, triggering a chain of reclamation + activity that may include invoking arbitrary Python code (due to + finalizers, or weakref callbacks, associated with the contained object). + If it's possible for such code to reference \var{self} again, it's + important that the pointer to the contained object be \NULL{} at that + time, so that \var{self} knows the contained object can no longer be + used. The \cfunction{Py_CLEAR()} macro performs the operations in a + safe order. + + Because the goal of \member{tp_clear} functions is to break reference + cycles, it's not necessary to clear contained objects like Python strings + or Python integers, which can't participate in reference cycles. + On the other hand, it may be convenient to clear all contained Python + objects, and write the type's \member{tp_dealloc} function to + invoke \member{tp_clear}. + + More information about Python's garbage collection + scheme can be found in section \ref{supporting-cycle-detection}. This field is inherited by subtypes together with \member{tp_clear} and the \constant{Py_TPFLAGS_HAVE_GC} flag bit: the flag bit, |