Skip to content
Open
Show file tree
Hide file tree
Changes from 11 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
4 changes: 3 additions & 1 deletion Doc/c-api/typeobj.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1260,7 +1260,7 @@ and :c:data:`PyType_Type` effectively act as defaults.)
This bit indicates that instances of the class have a :attr:`~object.__dict__`
attribute, and that the space for the dictionary is managed by the VM.

If this flag is set, :c:macro:`Py_TPFLAGS_HAVE_GC` should also be set.
If this flag is set, :c:macro:`Py_TPFLAGS_HAVE_GC` must also be set.

The type traverse function must call :c:func:`PyObject_VisitManagedDict`
and its clear function must call :c:func:`PyObject_ClearManagedDict`.
Expand All @@ -1278,6 +1278,8 @@ and :c:data:`PyType_Type` effectively act as defaults.)
This bit indicates that instances of the class should be weakly
referenceable.

If this flag is set, :c:macro:`Py_TPFLAGS_HAVE_GC` must also be set.

.. versionadded:: 3.12

**Inheritance:**
Expand Down
2 changes: 2 additions & 0 deletions Doc/extending/newtypes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,8 @@ For an object to be weakly referenceable, the extension type must set the
field. The legacy :c:member:`~PyTypeObject.tp_weaklistoffset` field should
be left as zero.

If this flag is set, :c:macro:`Py_TPFLAGS_HAVE_GC` should also be set.

Concretely, here is how the statically declared type object would look::

static PyTypeObject TrivialType = {
Expand Down
8 changes: 8 additions & 0 deletions Doc/whatsnew/3.15.rst
Original file line number Diff line number Diff line change
Expand Up @@ -785,6 +785,14 @@ New features
(Contributed by Victor Stinner in :gh:`129813`.)


Limited C API changes
---------------------

* If the :c:macro:`Py_TPFLAGS_MANAGED_DICT` and :c:macro:`Py_TPFLAGS_MANAGED_WEAKREF`
flags are set then :c:macro:`Py_TPFLAGS_HAVE_GC` must be set too.
Comment on lines +809 to +810
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* If the :c:macro:`Py_TPFLAGS_MANAGED_DICT` and :c:macro:`Py_TPFLAGS_MANAGED_WEAKREF`
flags are set then :c:macro:`Py_TPFLAGS_HAVE_GC` must be set too.
* If the :c:macro:`Py_TPFLAGS_MANAGED_DICT` or :c:macro:`Py_TPFLAGS_MANAGED_WEAKREF`
flag is set then :c:macro:`Py_TPFLAGS_HAVE_GC` must be set too.

Maybe it should be "or", not "and"?

(Contributed by Sergey Miryanov in :gh:`134786`)


Porting to Python 3.15
----------------------

Expand Down
2 changes: 1 addition & 1 deletion Include/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,7 @@ given type object has a specified feature.
#define Py_TPFLAGS_INLINE_VALUES (1 << 2)

/* Placement of weakref pointers are managed by the VM, not by the type.
* The VM will automatically set tp_weaklistoffset.
* The VM will automatically set tp_weaklistoffset. Implies Py_TPFLAGS_HAVE_GC.
*/
#define Py_TPFLAGS_MANAGED_WEAKREF (1 << 3)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
If :c:macro:`Py_TPFLAGS_MANAGED_DICT` and :c:macro:`Py_TPFLAGS_MANAGED_WEAKREF`
are used, then :c:macro:`Py_TPFLAGS_HAVE_GC` must be used as well.
14 changes: 14 additions & 0 deletions Objects/typeobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -8893,6 +8893,13 @@ type_ready_preheader(PyTypeObject *type)
type->tp_name);
return -1;
}
if (!(type->tp_flags & Py_TPFLAGS_HAVE_GC)) {
PyErr_Format(PyExc_SystemError,
"type %s has the Py_TPFLAGS_MANAGED_DICT flag "
"but not Py_TPFLAGS_HAVE_GC flag",
type->tp_name);
return -1;
}
type->tp_dictoffset = -1;
}
if (type->tp_flags & Py_TPFLAGS_MANAGED_WEAKREF) {
Expand All @@ -8905,6 +8912,13 @@ type_ready_preheader(PyTypeObject *type)
type->tp_name);
return -1;
}
if (!(type->tp_flags & Py_TPFLAGS_HAVE_GC)) {
PyErr_Format(PyExc_SystemError,
"type %s has the Py_TPFLAGS_MANAGED_WEAKREF flag "
"but not Py_TPFLAGS_HAVE_GC flag",
type->tp_name);
return -1;
}
type->tp_weaklistoffset = MANAGED_WEAKREF_OFFSET;
}
return 0;
Expand Down
Loading