summaryrefslogtreecommitdiffstats
path: root/Doc/c-api
diff options
context:
space:
mode:
authorSebastian Berg <sebastian@sipsolutions.net>2022-06-09 15:11:08 (GMT)
committerGitHub <noreply@github.com>2022-06-09 15:11:08 (GMT)
commit7fef8476629775c790f522a073ab279887bd81f9 (patch)
tree5a4e5e7c744da6322caf13fe0df5cecf787924ce /Doc/c-api
parenta5ba0f4ebca5020f6c77718a20663e0ac6e194ac (diff)
downloadcpython-7fef8476629775c790f522a073ab279887bd81f9.zip
cpython-7fef8476629775c790f522a073ab279887bd81f9.tar.gz
cpython-7fef8476629775c790f522a073ab279887bd81f9.tar.bz2
bpo-45383: Get metaclass from bases in PyType_From* (GH-28748)
This checks the bases of of a type created using the FromSpec API to inherit the bases metaclasses. The metaclass's alloc function will be called as is done in `tp_new` for classes created in Python. Co-authored-by: Petr Viktorin <encukou@gmail.com> Co-authored-by: Erlend Egeberg Aasland <erlend.aasland@protonmail.com>
Diffstat (limited to 'Doc/c-api')
-rw-r--r--Doc/c-api/type.rst36
1 files changed, 33 insertions, 3 deletions
diff --git a/Doc/c-api/type.rst b/Doc/c-api/type.rst
index 99b3845..fece3e6 100644
--- a/Doc/c-api/type.rst
+++ b/Doc/c-api/type.rst
@@ -193,11 +193,12 @@ The following functions and structs are used to create
.. c:function:: PyObject* PyType_FromMetaclass(PyTypeObject *metaclass, PyObject *module, PyType_Spec *spec, PyObject *bases)
Create and return a :ref:`heap type <heap-types>` from the *spec*
- (:const:`Py_TPFLAGS_HEAPTYPE`).
+ (see :const:`Py_TPFLAGS_HEAPTYPE`).
The metaclass *metaclass* is used to construct the resulting type object.
- When *metaclass* is ``NULL``, the default :c:type:`PyType_Type` is used
- instead. Note that metaclasses that override
+ When *metaclass* is ``NULL``, the metaclass is derived from *bases*
+ (or *Py_tp_base[s]* slots if *bases* is ``NULL``, see below).
+ Note that metaclasses that override
:c:member:`~PyTypeObject.tp_new` are not supported.
The *bases* argument can be used to specify base classes; it can either
@@ -215,6 +216,19 @@ The following functions and structs are used to create
This function calls :c:func:`PyType_Ready` on the new type.
+ Note that this function does *not* fully match the behavior of
+ calling :py:class:`type() <type>` or using the :keyword:`class` statement.
+ With user-provided base types or metaclasses, prefer
+ :ref:`calling <capi-call>` :py:class:`type` (or the metaclass)
+ over ``PyType_From*`` functions.
+ Specifically:
+
+ * :py:meth:`~object.__new__` is not called on the new class
+ (and it must be set to ``type.__new__``).
+ * :py:meth:`~object.__init__` is not called on the new class.
+ * :py:meth:`~object.__init_subclass__` is not called on any bases.
+ * :py:meth:`~object.__set_name__` is not called on new descriptors.
+
.. versionadded:: 3.12
.. c:function:: PyObject* PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases)
@@ -228,6 +242,11 @@ The following functions and structs are used to create
The function now accepts a single class as the *bases* argument and
``NULL`` as the ``tp_doc`` slot.
+ .. versionchanged:: 3.12
+
+ The function now finds and uses a metaclass corresponding to the provided
+ base classes. Previously, only :class:`type` instances were returned.
+
.. c:function:: PyObject* PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases)
@@ -235,10 +254,21 @@ The following functions and structs are used to create
.. versionadded:: 3.3
+ .. versionchanged:: 3.12
+
+ The function now finds and uses a metaclass corresponding to the provided
+ base classes. Previously, only :class:`type` instances were returned.
+
.. c:function:: PyObject* PyType_FromSpec(PyType_Spec *spec)
Equivalent to ``PyType_FromMetaclass(NULL, NULL, spec, NULL)``.
+ .. versionchanged:: 3.12
+
+ The function now finds and uses a metaclass corresponding to the
+ base classes provided in *Py_tp_base[s]* slots.
+ Previously, only :class:`type` instances were returned.
+
.. c:type:: PyType_Spec
Structure defining a type's behavior.