
Hi,
tl; dr the C API of PyFrameObject changed. If you have issues, please speak up!
I moved the PyFrameObject structure to the internal C API headers. You should now use the public C API to access its members:
f_back
: use :c:func:PyFrame_GetBack
.f_blockstack
: removed.f_builtins
: usePyObject_GetAttrString((PyObject*)frame, "f_builtins")
.f_code
: use :c:func:PyFrame_GetCode
.f_gen
: removed.f_globals
: usePyObject_GetAttrString((PyObject*)frame, "f_globals")
.f_iblock
: removed.f_lasti
: usePyObject_GetAttrString((PyObject*)frame, "f_lasti")
. Code usingf_lasti
withPyCode_Addr2Line()
must use :c:func:PyFrame_GetLineNumber
instead.f_lineno
: use :c:func:PyFrame_GetLineNumber
f_locals
: usePyObject_GetAttrString((PyObject*)frame, "f_locals")
.f_stackdepth
: removed.f_state
: no public API (renamed tof_frame.f_state
).f_trace
: no public API.f_trace_lines
: usePyObject_GetAttrString((PyObject*)frame, "f_trace_lines")
(it also be modified).f_trace_opcodes
: usePyObject_GetAttrString((PyObject*)frame, "f_trace_opcodes")
(it also be modified).f_localsplus
: no public API (renamed tof_frame.localsplus
).f_valuestack
: removed.
See What's New in Python 3.11 for more details (I completed the doc, but it will only be updated online tomorrow, there is a cron task once per day): https://docs.python.org/dev/whatsnew/3.11.html#id2
You can use the pythoncapi_compat project to get PyFrame_GetBack() and PyFrame_GetCode() on Python 3.8 and older: https://pythoncapi-compat.readthedocs.io/
If there is no public C API to access the PyFrameObject members used by your project, please speak up!
See for example my PR to use the public C API in coverage: https://github.com/nedbat/coveragepy/pull/1331
There is an on-going work for 2 years to add new getter functions for PyFrameObject: https://bugs.python.org/issue40421
In Python 3.10, there was no rush to make the structure internal. Things changed quickly in Python 3.11: a heavy rework on Python internals is on-going to optimize Python (especially ceval.c and how frames are created and used). For example, the _PyEval_EvalFrameDefault() function now gets a new InterpreterFrame structure, it no longer takes a PyFrameObject. Python 3.11 now creates Python frame objects on demand.
Because of these changes, reading directly PyFrameObject.f_back is now an error since the member is not always filled, but it wasn't a compiler error. You must now call the public PyFrame_GetBack() function rather than accessing directly to the member.
Since Python 2.3 (that's quite old ;-)), reading directly PyFrameObject.f_lineno is unsafe since it depends if the Python code is being traced or not: you must use PyFrame_GetLineNumber() instead.
See also the issue for the longer rationale: https://bugs.python.org/issue46836
I know that these changes are inconvenient, but I'm here if you need my help for updating your project! Moreover, Python 3.11 is scheduled for October, so there are still a few months to adapt your project, and maybe add new getter functions. The best would be to add all required getter functions before Python 3.11 beta1 scheduled for the beginning of May (2022-05-06).
Victor
Night gathers, and now my watch begins. It shall not end until my death.