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.
This commit is contained in:
Victor Stinner 2022-01-13 19:21:50 +01:00 committed by GitHub
parent f779faccd3
commit 0885999a8e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 104 additions and 0 deletions

View File

@ -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
<https://github.com/pythoncapi/pythoncapi_compat>`__ 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
<https://github.com/pythoncapi/pythoncapi_compat>`__ to get these functions
on old Python functions.
Deprecated
----------