-
-
Notifications
You must be signed in to change notification settings - Fork 32.2k
bpo-38206: Clarify tp_dealloc requirements for heap allocated types. #16248
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since this is a heap type, change this to use the slot API to be compliant with PEP384.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. PEP 384 defines a stable ABI – an API subset you can use when you can't recompile extensions for each minor version of CPython. How is it relevant here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @encukou it is very relevant! What you said is correct, but this PEP has the added benefit of making By the way, this is only relevant for C extensions, that is, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree that using the stable ABI is good, and we all migrate to it eventually. However, it's orthogonal to this change, which is about making the documentation correct. Pushing a stable ABI agenda in a fix for "Clarify that tp_dealloc must decref for heap allocated type" seems too sneaky for me – even though I count myself as a proponent of the stable ABI :) In CPython, And again: the text above talks about
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reverted back to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Woops, didn't mean to try any sneaky stuff! 😛 I agree with your point, let's get to anything related to PEP384 independently. |
||
Py_DECREF(tp); | ||
} | ||
|
||
|
||
**Inheritance:** | ||
|
||
This field is inherited by subtypes. | ||
|
@@ -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 | ||
|
Uh oh!
There was an error while loading. Please reload this page.