diff --git a/pep-0620.rst b/pep-0620.rst index 9f7a91656..22e1ca28f 100644 --- a/pep-0620.rst +++ b/pep-0620.rst @@ -12,15 +12,16 @@ Abstract Introduce C API incompatible changes to hide implementation details. -Hiding implementation details reduces backward compatibility issues and -so ease evolution of CPython internals and addition of new features. +Once most implementation details will be hidden, evolution of CPython +internals would be less limited by C API backward compatibility issues. +It will be way easier to add new features. It makes possible to experiment in CPython more advanced optimizations -than just micro-optimizations. +than just micro-optimizations, like tagged pointers. Define a process to reduce the number of broken C extensions. -The implementation of this PEP is expected to be done slowly over +The implementation of this PEP is expected to be done carefully over multiple Python versions. It already started in Python 3.7 and most changes are already completed. The `Process to introduce incompatible changes to the C API`_ didactes the rythm. @@ -32,14 +33,12 @@ Motivation The C API blocks CPython evolutions ----------------------------------- -Adding or removing members of C structures is causing multiple -implementation issues. +Adding or removing members of C structures is causing multiple backward +compatibility issues. Adding a new member breaks the stable ABI (PEP 384), especially for types declared statically (e.g. ``static PyTypeObject MyType = -{...};``). - -In Python 3.4, the PEP 442 "Safe object finalization" added +{...};``). In Python 3.4, the PEP 442 "Safe object finalization" added ``tp_finalize`` member at the end of the ``PyTypeObject`` structure. For ABI backward compatibility, a new ``Py_TPFLAGS_HAVE_FINALIZE`` type flag was required to announce if the type structure contains the @@ -256,34 +255,44 @@ re-implement this private function to support this C extension. **STATUS**: Completed (in Python 3.9) -In Python 3.9, 4 private functions have been moved to the internal C API -and are no longer exported: +Private functions moved to the internal C API in Python 3.8: -* ``_PyDebug_PrintTotalRefs()`` -* ``_Py_AddToAllObjects()`` -* ``_Py_PrintReferenceAddresses()`` -* ``_Py_PrintReferences()`` +* ``_PyObject_GC_TRACK()``, ``_PyObject_GC_UNTRACK()`` -In Python 3.9, the public "clear free list" functions have been renamed -to private functions and moved to the internal C API: +Macros and functions excluded from the limited C API in Python 3.9: -* ``PyAsyncGen_ClearFreeLists()()`` -* ``PyContext_ClearFreeList()()`` -* ``PyDict_ClearFreeList()()`` -* ``PyFloat_ClearFreeList()()`` -* ``PyFrame_ClearFreeList()()`` -* ``PyList_ClearFreeList()()`` -* ``PyTuple_ClearFreeList()()`` +* ``_PyObject_SIZE()``, ``_PyObject_VAR_SIZE()`` +* ``PyThreadState_DeleteCurrent()`` +* ``PyFPE_START_PROTECT()``, ``PyFPE_END_PROTECT()`` +* ``_Py_NewReference()``, ``_Py_ForgetReference()`` +* ``_PyTraceMalloc_NewReference()`` +* ``_Py_GetRefTotal()`` -And the following functions have been simply removed: +Private functions moved to the internal C API in Python 3.9: -* ``PyMethod_ClearFreeList()`` and ``PyCFunction_ClearFreeList()``: - the free lists of bound method objects have been removed (in Python 3.9). -* ``PySet_ClearFreeList()``: the set free list has been removed in - Python 3.4. -* ``PyUnicode_ClearFreeList()``: the Unicode free list has been removed - in Python 3.3. +* GC functions like ``_Py_AS_GC()``, ``_PyObject_GC_IS_TRACKED()`` + and ``_PyGCHead_NEXT()`` +* ``_Py_AddToAllObjects()`` (not exported) +* ``_PyDebug_PrintTotalRefs()``, ``_Py_PrintReferences()``, + ``_Py_PrintReferenceAddresses()`` (not exported) +Public "clear free list" functions moved to the internal C API an +renamed to private functions and in Python 3.9: + +* ``PyAsyncGen_ClearFreeLists()`` +* ``PyContext_ClearFreeList()`` +* ``PyDict_ClearFreeList()`` +* ``PyFloat_ClearFreeList()`` +* ``PyFrame_ClearFreeList()`` +* ``PyList_ClearFreeList()`` +* ``PyTuple_ClearFreeList()`` +* Functions simply removed: + + * ``PyMethod_ClearFreeList()`` and ``PyCFunction_ClearFreeList()``: + bound method free list removed in Python 3.9. + * ``PySet_ClearFreeList()``: set free list removed in Python 3.4. + * ``PyUnicode_ClearFreeList()``: Unicode free list removed + in Python 3.3. Convert macros to static inline functions ----------------------------------------- @@ -320,11 +329,18 @@ Macros converted to static inline functions in Python 3.8: Macros converted to regular functions in Python 3.9: * ``Py_EnterRecursiveCall()``, ``Py_LeaveRecursiveCall()`` + (added to the limited C API) * ``PyObject_INIT()``, ``PyObject_INIT_VAR()`` - -In Python 3.9, the trashcan macros are now calling functions which hide -implementation details, rather than accessing directly members of the -``PyThreadState`` structure. +* ``PyObject_GET_WEAKREFS_LISTPTR()`` +* ``PyObject_CheckBuffer()`` +* ``PyIndex_Check()`` +* ``PyObject_IS_GC()`` +* ``PyObject_NEW()`` (alias to ``PyObject_New()``), + ``PyObject_NEW_VAR()`` (alias to ``PyObject_NewVar()``) +* ``PyType_HasFeature()`` (always call ``PyType_GetFlags()``) +* ``Py_TRASHCAN_BEGIN_CONDITION()`` and ``Py_TRASHCAN_END()`` macros + now call functions which hide implementation details, rather than + accessing directly members of the ``PyThreadState`` structure. Make structures opaque ---------------------- @@ -373,13 +389,16 @@ structures opaque: * ``PyObject``: `bpo-39573 `_ * ``PyTypeObject``: `bpo-40170 `_ -* ``PyFrameObject``: `bpo-40421 `_. - Python 3.9 adds ``PyFrame_GetCode()`` and ``PyFrame_GetBack()`` - getter functions, and moves ``PyFrame_GetLineNumber`` to the limited C - API. -* ``PyThreadState``: `bpo-39947 `_. - Python 3.9 adds 3 getter functions: ``PyThreadState_GetFrame()``, - ``PyThreadState_GetID()`` and ``PyThreadState_GetInterpreter()``. +* ``PyFrameObject``: `bpo-40421 `_ + + * Python 3.9 adds ``PyFrame_GetCode()`` and ``PyFrame_GetBack()`` + getter functions, and moves ``PyFrame_GetLineNumber`` to the limited + C API. + +* ``PyThreadState``: `bpo-39947 `_ + + * Python 3.9 adds 3 getter functions: ``PyThreadState_GetFrame()``, + ``PyThreadState_GetID()``, ``PyThreadState_GetInterpreter()``. Disallow using Py_TYPE() as l-value -----------------------------------