summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2021-10-28 12:23:19 -0700
committerGitHub <noreply@github.com>2021-10-28 21:23:19 +0200
commit193504acf3bfb7cff1edf7f568c2405b857fa1f7 (patch)
tree0b41ef542a8095bc4ce266fd55ee83f0db8c5d6e
parent8e5e74e3049875e9d834fe4408263676fe21e890 (diff)
downloadcpython-git-193504acf3bfb7cff1edf7f568c2405b857fa1f7.tar.gz
bpo-28737: Document when tp_dealloc should call PyObject_GC_UnTrack() (GH-29246) (GH-29248)
Objects that support garbage collection ("container" objects) should call PyObject_GC_UnTrack() from their destructors before clearing any fields which may point to other "container" objects. (cherry picked from commit 35e1ff38ee67ee543d9fcb268c3552c5397f9b3f) Co-authored-by: Sam Gross <colesbury@gmail.com>
-rw-r--r--Doc/c-api/gcsupport.rst16
-rw-r--r--Doc/c-api/typeobj.rst12
-rw-r--r--Doc/extending/newtypes.rst14
3 files changed, 33 insertions, 9 deletions
diff --git a/Doc/c-api/gcsupport.rst b/Doc/c-api/gcsupport.rst
index f821b45090..b0d62d8cf8 100644
--- a/Doc/c-api/gcsupport.rst
+++ b/Doc/c-api/gcsupport.rst
@@ -33,6 +33,14 @@ Constructors for container types must conform to two rules:
#. Once all the fields which may contain references to other containers are
initialized, it must call :c:func:`PyObject_GC_Track`.
+Similarly, the deallocator for the object must conform to a similar pair of
+rules:
+
+#. Before fields which refer to other containers are invalidated,
+ :c:func:`PyObject_GC_UnTrack` must be called.
+
+#. The object's memory must be deallocated using :c:func:`PyObject_GC_Del`.
+
.. warning::
If a type adds the Py_TPFLAGS_HAVE_GC, then it *must* implement at least
a :c:member:`~PyTypeObject.tp_traverse` handler or explicitly use one
@@ -100,14 +108,6 @@ Constructors for container types must conform to two rules:
.. versionadded:: 3.9
-Similarly, the deallocator for the object must conform to a similar pair of
-rules:
-
-#. Before fields which refer to other containers are invalidated,
- :c:func:`PyObject_GC_UnTrack` must be called.
-
-#. The object's memory must be deallocated using :c:func:`PyObject_GC_Del`.
-
.. c:function:: void PyObject_GC_Del(void *op)
diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst
index 661e87f689..a800616730 100644
--- a/Doc/c-api/typeobj.rst
+++ b/Doc/c-api/typeobj.rst
@@ -657,6 +657,18 @@ and :c:type:`PyType_Type` effectively act as defaults.)
:c:func:`PyObject_GC_Del` if the instance was allocated using
:c:func:`PyObject_GC_New` or :c:func:`PyObject_GC_NewVar`.
+ If the type supports garbage collection (has the :const:`Py_TPFLAGS_HAVE_GC`
+ flag bit set), the destructor should call :c:func:`PyObject_GC_UnTrack`
+ before clearing any member fields.
+
+ .. code-block:: c
+
+ static void foo_dealloc(foo_object *self) {
+ PyObject_GC_UnTrack(self);
+ Py_CLEAR(self->ref);
+ Py_TYPE(self)->tp_free((PyObject *)self);
+ }
+
Finally, if the type is heap allocated (:const:`Py_TPFLAGS_HEAPTYPE`), the
deallocator should decrement the reference count for its type object after
calling the type deallocator. In order to avoid dangling pointers, the
diff --git a/Doc/extending/newtypes.rst b/Doc/extending/newtypes.rst
index d9023709fd..638b00a4c0 100644
--- a/Doc/extending/newtypes.rst
+++ b/Doc/extending/newtypes.rst
@@ -73,7 +73,19 @@ function::
newdatatype_dealloc(newdatatypeobject *obj)
{
free(obj->obj_UnderlyingDatatypePtr);
- Py_TYPE(obj)->tp_free(obj);
+ Py_TYPE(obj)->tp_free((PyObject *)obj);
+ }
+
+If your type supports garbage collection, the destructor should call
+:c:func:`PyObject_GC_UnTrack` before clearing any member fields::
+
+ static void
+ newdatatype_dealloc(newdatatypeobject *obj)
+ {
+ PyObject_GC_UnTrack(obj);
+ Py_CLEAR(obj->other_obj);
+ ...
+ Py_TYPE(obj)->tp_free((PyObject *)obj);
}
.. index::