summaryrefslogtreecommitdiffstats
path: root/Doc/extending
diff options
context:
space:
mode:
authorMark Shannon <mark@hotpy.org>2022-08-30 15:26:08 (GMT)
committerGitHub <noreply@github.com>2022-08-30 15:26:08 (GMT)
commit0f733fffe8f4caaac3ce1b5306af86b42fb0c7fa (patch)
tree37c1413c8f9d3bb6a75ee53cb4db3611dba09e40 /Doc/extending
parent07f12b5c1567581aa77d523e462b0e7f75c1f05c (diff)
downloadcpython-0f733fffe8f4caaac3ce1b5306af86b42fb0c7fa.zip
cpython-0f733fffe8f4caaac3ce1b5306af86b42fb0c7fa.tar.gz
cpython-0f733fffe8f4caaac3ce1b5306af86b42fb0c7fa.tar.bz2
GH-95245: Document use of `MANAGED` flags instead of offsets. (GH-96044)
Diffstat (limited to 'Doc/extending')
-rw-r--r--Doc/extending/newtypes.rst33
1 files changed, 9 insertions, 24 deletions
diff --git a/Doc/extending/newtypes.rst b/Doc/extending/newtypes.rst
index c7c434e..b797dc2 100644
--- a/Doc/extending/newtypes.rst
+++ b/Doc/extending/newtypes.rst
@@ -570,43 +570,28 @@ performance-critical objects (such as numbers).
.. seealso::
Documentation for the :mod:`weakref` module.
-For an object to be weakly referencable, the extension type must do two things:
+For an object to be weakly referencable, the extension type must set the
+``Py_TPFLAGS_MANAGED_WEAKREF`` bit of the :c:member:`~PyTypeObject.tp_flags`
+field. The legacy :c:member:`~PyTypeObject.tp_weaklistoffset` field should
+be left as zero.
-#. Include a :c:type:`PyObject\*` field in the C object structure dedicated to
- the weak reference mechanism. The object's constructor should leave it
- ``NULL`` (which is automatic when using the default
- :c:member:`~PyTypeObject.tp_alloc`).
-
-#. Set the :c:member:`~PyTypeObject.tp_weaklistoffset` type member
- to the offset of the aforementioned field in the C object structure,
- so that the interpreter knows how to access and modify that field.
-
-Concretely, here is how a trivial object structure would be augmented
-with the required field::
-
- typedef struct {
- PyObject_HEAD
- PyObject *weakreflist; /* List of weak references */
- } TrivialObject;
-
-And the corresponding member in the statically declared type object::
+Concretely, here is how the statically declared type object would look::
static PyTypeObject TrivialType = {
PyVarObject_HEAD_INIT(NULL, 0)
/* ... other members omitted for brevity ... */
- .tp_weaklistoffset = offsetof(TrivialObject, weakreflist),
+ .tp_flags = Py_TPFLAGS_MANAGED_WEAKREF | ...,
};
+
The only further addition is that ``tp_dealloc`` needs to clear any weak
-references (by calling :c:func:`PyObject_ClearWeakRefs`) if the field is
-non-``NULL``::
+references (by calling :c:func:`PyObject_ClearWeakRefs`)::
static void
Trivial_dealloc(TrivialObject *self)
{
/* Clear weakrefs first before calling any destructors */
- if (self->weakreflist != NULL)
- PyObject_ClearWeakRefs((PyObject *) self);
+ PyObject_ClearWeakRefs((PyObject *) self);
/* ... remainder of destruction code omitted for brevity ... */
Py_TYPE(self)->tp_free((PyObject *) self);
}