Skip to content

Commit 5faff97

Browse files
ammaraskarmiss-islington
authored andcommitted
bpo-38206: Clarify tp_dealloc requirements for heap allocated types. (GH-16248)
As mentioned in the bpo ticket, this mistake came up on two reviews: - #16127 (review) - #16071 (review) Would be nice to have it documented in a more permanent place than 3.8's whatsnew entry. https://bugs.python.org/issue38206 Automerge-Triggered-By: @encukou
1 parent 6ce03ec commit 5faff97

File tree

2 files changed

+22
-5
lines changed

2 files changed

+22
-5
lines changed

Doc/c-api/type.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,8 @@ The following functions and structs are used to create
118118
119119
.. c:function:: PyObject* PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases)
120120
121-
Creates and returns a heap type object from the *spec*.
121+
Creates and returns a heap type object from the *spec*
122+
(:const:`Py_TPFLAGS_HEAPTYPE`).
122123
123124
If *bases* is a tuple, the created heap type contains all types contained
124125
in it as base types.

Doc/c-api/typeobj.rst

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -654,16 +654,31 @@ and :c:type:`PyType_Type` effectively act as defaults.)
654654
the instance is still in existence, but there are no references to it. The
655655
destructor function should free all references which the instance owns, free all
656656
memory buffers owned by the instance (using the freeing function corresponding
657-
to the allocation function used to allocate the buffer), and finally (as its
658-
last action) call the type's :c:member:`~PyTypeObject.tp_free` function. If the type is not
659-
subtypable (doesn't have the :const:`Py_TPFLAGS_BASETYPE` flag bit set), it is
657+
to the allocation function used to allocate the buffer), and call the type's
658+
:c:member:`~PyTypeObject.tp_free` function. If the type is not subtypable
659+
(doesn't have the :const:`Py_TPFLAGS_BASETYPE` flag bit set), it is
660660
permissible to call the object deallocator directly instead of via
661661
:c:member:`~PyTypeObject.tp_free`. The object deallocator should be the one used to allocate the
662662
instance; this is normally :c:func:`PyObject_Del` if the instance was allocated
663663
using :c:func:`PyObject_New` or :c:func:`PyObject_VarNew`, or
664664
:c:func:`PyObject_GC_Del` if the instance was allocated using
665665
:c:func:`PyObject_GC_New` or :c:func:`PyObject_GC_NewVar`.
666666

667+
Finally, if the type is heap allocated (:const:`Py_TPFLAGS_HEAPTYPE`), the
668+
deallocator should decrement the reference count for its type object after
669+
calling the type deallocator. In order to avoid dangling pointers, the
670+
recommended way to achieve this is:
671+
672+
.. code-block:: c
673+
674+
static void foo_dealloc(foo_object *self) {
675+
PyTypeObject *tp = Py_TYPE(self);
676+
// free references and buffers here
677+
tp->tp_free(self);
678+
Py_DECREF(tp);
679+
}
680+
681+
667682
**Inheritance:**
668683

669684
This field is inherited by subtypes.
@@ -1021,7 +1036,8 @@ and :c:type:`PyType_Type` effectively act as defaults.)
10211036

10221037
.. data:: Py_TPFLAGS_HEAPTYPE
10231038

1024-
This bit is set when the type object itself is allocated on the heap. In this
1039+
This bit is set when the type object itself is allocated on the heap, for
1040+
example, types created dynamically using :c:func:`PyType_FromSpec`. In this
10251041
case, the :attr:`ob_type` field of its instances is considered a reference to
10261042
the type, and the type object is INCREF'ed when a new instance is created, and
10271043
DECREF'ed when an instance is destroyed (this does not apply to instances of

0 commit comments

Comments
 (0)