Skip to content

[3.8] bpo-38206: Clarify tp_dealloc requirements for heap allocated types. (GH-16248) #16436

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 27, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Doc/c-api/type.rst
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ The following functions and structs are used to create

.. c:function:: PyObject* PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases)

Creates and returns a heap type object from the *spec*.
Creates and returns a heap type object from the *spec*
(:const:`Py_TPFLAGS_HEAPTYPE`).

If *bases* is a tuple, the created heap type contains all types contained
in it as base types.
Expand Down
24 changes: 20 additions & 4 deletions Doc/c-api/typeobj.rst
Original file line number Diff line number Diff line change
Expand Up @@ -654,16 +654,31 @@ and :c:type:`PyType_Type` effectively act as defaults.)
the instance is still in existence, but there are no references to it. The
destructor function should free all references which the instance owns, free all
memory buffers owned by the instance (using the freeing function corresponding
to the allocation function used to allocate the buffer), and finally (as its
last action) call the type's :c:member:`~PyTypeObject.tp_free` function. If the type is not
subtypable (doesn't have the :const:`Py_TPFLAGS_BASETYPE` flag bit set), it is
to the allocation function used to allocate the buffer), and call the type's
:c:member:`~PyTypeObject.tp_free` function. If the type is not subtypable
(doesn't have the :const:`Py_TPFLAGS_BASETYPE` flag bit set), it is
permissible to call the object deallocator directly instead of via
:c:member:`~PyTypeObject.tp_free`. The object deallocator should be the one used to allocate the
instance; this is normally :c:func:`PyObject_Del` if the instance was allocated
using :c:func:`PyObject_New` or :c:func:`PyObject_VarNew`, or
:c:func:`PyObject_GC_Del` if the instance was allocated using
:c:func:`PyObject_GC_New` or :c:func:`PyObject_GC_NewVar`.

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
recommended way to achieve this is:

.. code-block:: c

static void foo_dealloc(foo_object *self) {
PyTypeObject *tp = Py_TYPE(self);
// free references and buffers here
tp->tp_free(self);
Py_DECREF(tp);
}


**Inheritance:**

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

.. data:: Py_TPFLAGS_HEAPTYPE

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