diff options
author | Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> | 2021-10-28 19:23:19 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-10-28 19:23:19 (GMT) |
commit | 193504acf3bfb7cff1edf7f568c2405b857fa1f7 (patch) | |
tree | 0b41ef542a8095bc4ce266fd55ee83f0db8c5d6e | |
parent | 8e5e74e3049875e9d834fe4408263676fe21e890 (diff) | |
download | cpython-193504acf3bfb7cff1edf7f568c2405b857fa1f7.zip cpython-193504acf3bfb7cff1edf7f568c2405b857fa1f7.tar.gz cpython-193504acf3bfb7cff1edf7f568c2405b857fa1f7.tar.bz2 |
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.rst | 16 | ||||
-rw-r--r-- | Doc/c-api/typeobj.rst | 12 | ||||
-rw-r--r-- | Doc/extending/newtypes.rst | 14 |
3 files changed, 33 insertions, 9 deletions
diff --git a/Doc/c-api/gcsupport.rst b/Doc/c-api/gcsupport.rst index f821b45..b0d62d8 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 661e87f..a800616 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 d902370..638b00a 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:: |