Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork32.4k
Description
I propose to investigate an incompatible C API change: make thePyTypeObject
andPyHeapTypeObject
structures opaque, remove their members from the public C API (move them to the internal C API). We have to investigate how it's outside in 3rd party C extensions (ex: Cython, pybind11, etc.), and design a smooth migration plan.
The PyTypeObject structure is exposed as part of the public Python C API. For example,Py_TYPE(obj)->tp_name
directly gets a type name (as a UTF-8 encoded byte string,char*
).
The PyTypeObject members areNOT part of the limited C API (PEP 384).
In Python 3.9 (2020), I reworked the C API to avoid accessing directly PyTypeObject members at the ABI level: issue#84351. For example, Python 3.8 implementsPyObject_IS_GC()
as a macro:
/* Test if an object has a GC head */#definePyObject_IS_GC(o) \ (PyType_IS_GC(Py_TYPE(o)) \ && (Py_TYPE(o)->tp_is_gc == NULL || Py_TYPE(o)->tp_is_gc(o)))
whereas Python 3.9 only provides an opaque function call:
/* Test if an object implements the garbage collector protocol */PyAPI_FUNC(int)PyObject_IS_GC(PyObject*obj);
At the ABI level, the direct access to thePyTypeObject.tp_is_gc
member became an opaque function call.
Changing PyTypeObject API and ABI caused a lot of troubles in the past. Example:
- issueC files generated by Cython set tp_print to 0: PyTypeObject.tp_print removed #81431: Cython broken by
PyTypeObject.tp_print
removal -- related toPyTypeObject.tp_vectorcall_offset
addition - issueRemove cross-version binary compatibility #76569: ABI issue with the addition of
PyTypeObject.tp_finalize
(PEP 442). IsPy_TPFLAGS_HAVE_FINALIZE
needed for ABI compatibility? See also thepython-dev thread. - issueRemove Py_TPFLAGS_HAVE_VERSION_TAG flag? #86913: remove
Py_TPFLAGS_HAVE_VERSION_TAG
flag (ABI compatibility) - issueDocumentation inconsistency with the stable ABI #91271: Documentation inconsistency with the stable ABI (PyTypeObject)
- ThePEP 620 uses PyTypeObject incompatible changes in its rationale.
For many years, there is a work-in-progress to convert all Python built-in types and types of stdlib extensions from static types to heap types. See for example issue#84258 andPEP 630.
The API and ABI for heap type was also enhanced over the years. Examples:
- Python 3.12 adds
PyType_FromMetaclass()
- Add the buffer protocol to the limited C API (to PyType_FromSpec()): issueLimited API support for Py_buffer #89622
- issue[C API] PyType_GetSlot cannot get tp_name #86201: get tp_name with PyType_GetSlot()
In the past, other structure members were removed:
- PyInterpreterState: Python 3.8
- PyGC_Head: Python 3.9
- PyFrameObject: Python 3.11
The work was also prepared for:
- PyObject: issue[C API] Avoid accessing PyObject and PyVarObject members directly: add Py_SET_TYPE() and Py_IS_TYPE(), disallow Py_TYPE(obj)=type #83754, Python 3.10 and Python 3.11, add Py_SET_REFCNT() and Py_SET_TYPE()
- PyTheadState: issue[C API] Prepare the C API to make PyThreadState opaque: add getter functions #84128, Python 3.11