diff --git a/Doc/howto/isolating-extensions.rst b/Doc/howto/isolating-extensions.rst index 7da6dc8a39795e..f72a5855d587ad 100644 --- a/Doc/howto/isolating-extensions.rst +++ b/Doc/howto/isolating-extensions.rst @@ -340,6 +340,34 @@ safe access from C) and the module's ``__dict__`` (for access from Python code). +Type Checking with Heap Types +------------------------------ + +.. versionadded:: 3.14 + +Heap types defined with :c:func:`PyType_FromModuleAndSpec` can use the +:c:data:`Py_tp_token` slot to enable type checking across module boundaries +and inheritance hierarchies. + +Setting ``Py_tp_token`` to :c:data:`Py_TP_USE_SPEC` uses the +:c:type:`PyType_Spec`'s address as a unique identifier. This allows +:c:func:`PyType_GetBaseByToken` to search the :term:`method resolution order` +for types with compatible memory layouts:: + + static PyType_Slot MyType_slots[] = { + {Py_tp_token, Py_TP_USE_SPEC}, + // ... other slots + }; + +This addresses the type-checking problem for heap types described in +:pep:`630#type-checking`. See the +`xxlimited module `__ +for a complete example. + +For details, see :c:data:`Py_tp_token` and :c:func:`PyType_GetBaseByToken` +(added in :gh:`124153`). + + Garbage-Collection Protocol --------------------------- diff --git a/Modules/xxlimited.c b/Modules/xxlimited.c index 09c8d9487f5426..b6ae31524a10d8 100644 --- a/Modules/xxlimited.c +++ b/Modules/xxlimited.c @@ -64,10 +64,10 @@ pass */ -// Need limited C API version 3.13 for Py_mod_gil +// Need limited C API version 3.14 for Py_tp_token #include "pyconfig.h" // Py_GIL_DISABLED #ifndef Py_GIL_DISABLED -# define Py_LIMITED_API 0x030d0000 +# define Py_LIMITED_API 0x030e0000 #endif #include "Python.h" @@ -96,8 +96,6 @@ typedef struct { } XxoObject; #define XxoObject_CAST(op) ((XxoObject *)(op)) -// TODO: full support for type-checking was added in 3.14 (Py_tp_token) -// #define XxoObject_Check(v) Py_IS_TYPE(v, Xxo_Type) static XxoObject * newXxoObject(PyObject *module) @@ -298,6 +296,7 @@ static PyGetSetDef Xxo_getsetlist[] = { static PyType_Slot Xxo_Type_slots[] = { + {Py_tp_token, Py_TP_USE_SPEC}, {Py_tp_doc, (char *)Xxo_doc}, {Py_tp_traverse, Xxo_traverse}, {Py_tp_clear, Xxo_clear},