From 0885999a8e5ffad3fae0302675ad0030e33a15af Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 13 Jan 2022 19:21:50 +0100 Subject: bpo-46355: Document PyFrameObject and PyThreadState changes (GH-30558) Document PyFrameObject and PyThreadState changes in What's New in Python 3.11 and explain how to port code. --- Doc/whatsnew/3.11.rst | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 28ac57e..6a6c22c 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -755,6 +755,110 @@ Porting to Python 3.11 which are not available in the limited C API. (Contributed by Victor Stinner in :issue:`46007`.) +* Changes of the :c:type:`PyFrameObject` structure members: + + * ``f_code``: removed, use :c:func:`PyFrame_GetCode` instead. + Warning: the function returns a :term:`strong reference`, need to call + :c:func:`Py_DECREF`. + * ``f_back``: changed, use :c:func:`PyFrame_GetBack`. + * ``f_builtins``: removed, + use ``PyObject_GetAttrString(frame, "f_builtins")``. + * ``f_globals``: removed, + use ``PyObject_GetAttrString(frame, "f_globals")``. + * ``f_locals``: removed, + use ``PyObject_GetAttrString(frame, "f_locals")``. + * ``f_lasti``: removed, + use ``PyObject_GetAttrString(frame, "f_lasti")``. + * ``f_valuesstack``: removed. + * ``f_stackdepth``: removed. + * ``f_gen``: removed. + * ``f_iblock``: removed. + * ``f_state``: removed. + * ``f_blockstack``: removed. + * ``f_localsplus``: removed. + + The Python frame object is now created lazily. A side effect is that the + ``f_back`` member must not be accessed directly, since its value is now also + computed lazily. The :c:func:`PyFrame_GetBack` function must be called + instead. + + Code defining ``PyFrame_GetCode()`` on Python 3.8 and older:: + + #if PY_VERSION_HEX < 0x030900B1 + static inline PyCodeObject* PyFrame_GetCode(PyFrameObject *frame) + { + Py_INCREF(frame->f_code); + return frame->f_code; + } + #endif + + Code defining ``PyFrame_GetBack()`` on Python 3.8 and older:: + + #if PY_VERSION_HEX < 0x030900B1 + static inline PyFrameObject* PyFrame_GetBack(PyFrameObject *frame) + { + Py_XINCREF(frame->f_back); + return frame->f_back; + } + #endif + + Or use `the pythoncapi_compat project + `__ to get these functions + on old Python functions. + +* Changes of the :c:type:`PyThreadState` structure members: + + * ``frame``: removed, use :c:func:`PyThreadState_GetFrame` (function added + to Python 3.9 by :issue:`40429`). + Warning: the function returns a :term:`strong reference`, need to call + :c:func:`Py_XDECREF`. + * ``tracing``: changed, use :c:func:`PyThreadState_EnterTracing` + and :c:func:`PyThreadState_LeaveTracing` + (functions added to Python 3.11 by :issue:`43760`). + * ``recursion_depth``: removed, + use ``(tstate->recursion_limit - tstate->recursion_remaining)`` instead. + * ``stackcheck_counter``: removed. + + Code defining ``PyThreadState_GetFrame()`` on Python 3.8 and older:: + + #if PY_VERSION_HEX < 0x030900B1 + static inline PyFrameObject* PyThreadState_GetFrame(PyThreadState *tstate) + { + Py_XINCREF(tstate->frame); + return tstate->frame; + } + #endif + + Code defining ``PyThreadState_EnterTracing()`` and + ``PyThreadState_LeaveTracing()`` on Python 3.10 and older:: + + #if PY_VERSION_HEX < 0x030B00A2 + static inline void PyThreadState_EnterTracing(PyThreadState *tstate) + { + tstate->tracing++; + #if PY_VERSION_HEX >= 0x030A00A1 + tstate->cframe->use_tracing = 0; + #else + tstate->use_tracing = 0; + #endif + } + + static inline void PyThreadState_LeaveTracing(PyThreadState *tstate) + { + int use_tracing = (tstate->c_tracefunc != NULL || tstate->c_profilefunc != NULL); + tstate->tracing--; + #if PY_VERSION_HEX >= 0x030A00A1 + tstate->cframe->use_tracing = use_tracing; + #else + tstate->use_tracing = use_tracing; + #endif + } + #endif + + Or use `the pythoncapi_compat project + `__ to get these functions + on old Python functions. + Deprecated ---------- -- cgit v0.12