From 41be80019f62cc823cc5c29b1ff47866473bd04e Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Thu, 10 Nov 2022 17:42:14 +0100 Subject: [PATCH 1/2] gh-99249: Clarify "read-only" slots tp_bases & tp_mro These slots are marked "should be treated as read-only" in the table at the start of the document. That doesn't say anything about setting them in the static struct. `tp_bases` docs did say that it should be ``NULL`` (TIL!). If you ignore that, seemingly nothing bad happens. However, some slots may not be inherited, depending on which sub-slot structs are present. (FWIW, NumPy sets tp_bases and is affected by the quirk -- though to be fair, its DUAL_INHERIT code probably predates tp_bases docs, and also the result happens to be benign.) This patch makes things explicit. It also makes the summary table legend easier to scan. --- Doc/c-api/typeobj.rst | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst index 4c462f46056739..0a304600ed3de0 100644 --- a/Doc/c-api/typeobj.rst +++ b/Doc/c-api/typeobj.rst @@ -149,10 +149,16 @@ Quick Reference +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ .. [#slots] - A slot name in parentheses indicates it is (effectively) deprecated. - Names in angle brackets should be treated as read-only. - Names in square brackets are for internal use only. - "" (as a prefix) means the field is required (must be non-``NULL``). + + **()**: A slot name in parentheses indicates it is (effectively) deprecated. + + **<>**: Names in angle brackets should be initially set to ``NULL`` and + treated as read-only. + + **[]**: Names in square brackets are for internal use only. + + **** (as a prefix) means the field is required (must be non-``NULL``). + .. [#cols] Columns: **"O"**: set on :c:type:`PyBaseObject_Type` @@ -1923,8 +1929,19 @@ and :c:type:`PyType_Type` effectively act as defaults.) Tuple of base types. - This is set for types created by a class statement. It should be ``NULL`` for - statically defined types. + This field should be set to ``NULL`` and treated as read-only. + Python will fill it in when the type is :c:func:`finalized `. + + For dynamically created classes, the ``Py_tp_bases`` + :c:type:`slot ` can be used instead of the *bases* argument + of :c:func:`PyType_FromSpecWithBases`. + The argument form is preferred. + + .. warning:: + + Multiple inheritance does not work well for statically defined types. + If you set ``tp_bases`` to a tuple, Python will not raise an error, + but some slots will only be inherited from the first base. **Inheritance:** @@ -1936,6 +1953,8 @@ and :c:type:`PyType_Type` effectively act as defaults.) Tuple containing the expanded set of base types, starting with the type itself and ending with :class:`object`, in Method Resolution Order. + This field should be set to ``NULL`` and treated as read-only. + Python will fill it in when the type is :c:func:`finalized `. **Inheritance:** From d6a5609663500c3012bbd6196557142dd61b8e0f Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Fri, 25 Nov 2022 15:05:30 +0100 Subject: [PATCH 2/2] Apply suggestions from code review Co-authored-by: Kumar Aditya <59607654+kumaraditya303@users.noreply.github.com> --- Doc/c-api/typeobj.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst index 0a304600ed3de0..8f8869ec668a8d 100644 --- a/Doc/c-api/typeobj.rst +++ b/Doc/c-api/typeobj.rst @@ -1930,7 +1930,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) Tuple of base types. This field should be set to ``NULL`` and treated as read-only. - Python will fill it in when the type is :c:func:`finalized `. + Python will fill it in when the type is :c:func:`initialized `. For dynamically created classes, the ``Py_tp_bases`` :c:type:`slot ` can be used instead of the *bases* argument @@ -1954,7 +1954,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) and ending with :class:`object`, in Method Resolution Order. This field should be set to ``NULL`` and treated as read-only. - Python will fill it in when the type is :c:func:`finalized `. + Python will fill it in when the type is :c:func:`initialized `. **Inheritance:**