Skip to content
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

gh-92678: Document Py_TPFLAGS_MANAGED_DICT and friends #95440

Closed
wants to merge 4 commits into from
Closed
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
23 changes: 23 additions & 0 deletions Doc/c-api/gcsupport.rst
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,29 @@ rules:
The :c:func:`_PyObject_GC_TRACK` and :c:func:`_PyObject_GC_UNTRACK` macros
have been removed from the public C API.


.. c:function:: int _PyObject_VisitManagedDict(PyObject *self, visitproc visit, void *arg)

Visitor function for types with :const:`Py_TPFLAGS_MANAGED_DICT` bit set.
Call this function in :c:member:`~PyTypeObject.tp_traverse`. The arguments
share the same meaning as the arguments of :c:member:`~PyTypeObject.tp_traverse`.
A non-zero return value indicates an error and that returned value should be
returned immediately.

.. warning:: This function is unstable and may change with time.

.. versionadded:: 3.11


.. c:function:: void _PyObject_ClearManagedDict(PyObject *self)

Inquiry function for types with :const:`Py_TPFLAGS_MANAGED_DICT` bit set.
Call this function in :c:member:`~PyTypeObject.tp_clear`.

.. warning:: This function is unstable and may change with time.

.. versionadded:: 3.11

The :c:member:`~PyTypeObject.tp_traverse` handler accepts a function parameter of this type:


Expand Down
14 changes: 14 additions & 0 deletions Doc/c-api/typeobj.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1260,6 +1260,20 @@ and :c:type:`PyType_Type` effectively act as defaults.)

.. versionadded:: 3.10

.. data:: Py_TPFLAGS_MANAGED_DICT

Set this bit to allow CPython to automatically manage the ``__dict__``
of the instances of a type. To tell CPython to clear the managed
dictionary, you must call
:c:func:`_PyObject_VisitManagedDict` in :c:member:`~PyTypeObject.tp_traverse`
and :c:func:`_PyObject_ClearManagedDict` in :c:member:`~PyTypeObject.tp_clear`
respectively.

**Inheritance:**

???

.. versionadded:: 3.11

.. c:member:: const char* PyTypeObject.tp_doc

Expand Down
9 changes: 9 additions & 0 deletions Doc/whatsnew/3.11.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1927,6 +1927,15 @@ Porting to Python 3.11
paths and then modify them, finish initialization and use :c:func:`PySys_GetObject`
to retrieve :data:`sys.path` as a Python list object and modify it directly.

* CPython no longer assumes that a ``__dict__`` exists after an object. C extension
types with inheritance and ``__dict__`` may have MRO problems. To fix this, allow
CPython to manage the ``__dict__`` of instances of your type by setting
:const:`Py_TPFLAGS_MANAGED_DICT` in :c:member:`~PyTypeObject.tp_flags`.
Comment on lines +1930 to +1933
Copy link
Member

Choose a reason for hiding this comment

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

This really raises more questions than it answers. In what cases did CPython assume a __dict__ exists after an object? (Didn't it put it there itself before 3.11?) What does it mean for a type to be “with inheritance”? What kind of MRO problems can you fix with the flag?

You must call :c:func:`_PyObject_VisitManagedDict` and
:c:func:`_PyObject_ClearManagedDict` to support GC collection. See the
respective functions for more information on how to use them.
(Contributed by Mark Shannon in :gh:`92678`.)

Deprecated
----------

Expand Down