mirror of
https://github.com/python/cpython.git
synced 2025-11-02 03:01:58 +00:00
bpo-46836: Move PyFrameObject to pycore_frame.h (GH-31530)
Move the PyFrameObject type definition (struct _frame) to the internal C API pycore_frame.h header file.
This commit is contained in:
parent
4657bf7016
commit
18b5dd68c6
5 changed files with 57 additions and 48 deletions
|
|
@ -288,8 +288,16 @@ the same library that the Python runtime is using.
|
|||
|
||||
.. c:type:: PyFrameObject
|
||||
|
||||
The C structure of the objects used to describe frame objects. The
|
||||
fields of this type are subject to change at any time.
|
||||
The C structure of the objects used to describe frame objects.
|
||||
|
||||
The structure is only part of the internal C API: fields should not be
|
||||
access directly. Use getter functions like :c:func:`PyFrame_GetCode` and
|
||||
:c:func:`PyFrame_GetBack`.
|
||||
|
||||
Debuggers and profilers can use the limited C API to access this structure.
|
||||
|
||||
.. versionchanged:: 3.11
|
||||
The structure moved to the internal C API headers.
|
||||
|
||||
|
||||
.. c:function:: PyObject* PyEval_EvalFrame(PyFrameObject *f)
|
||||
|
|
|
|||
|
|
@ -837,40 +837,40 @@ Porting to Python 3.11
|
|||
which are not available in the limited C API.
|
||||
(Contributed by Victor Stinner in :issue:`46007`.)
|
||||
|
||||
* Changes of the private :c:type:`PyFrameObject` structure members.
|
||||
* The :c:type:`PyFrameObject` structure member has been moved to the internal C
|
||||
API headers.
|
||||
|
||||
While the documentation notes that the :c:type:`PyFrameObject` fields are
|
||||
subject to change at any time, they have been stable for a long time and were
|
||||
used in several popular extensions.
|
||||
|
||||
While the documentation notes that the fields of ``PyFrameObject`` are
|
||||
subject to change at any time, they have been stable for a long time
|
||||
and were used in several popular extensions.
|
||||
In Python 3.11, the frame struct was reorganized to allow performance
|
||||
optimizations. Rather than reading the fields directly, extensions should
|
||||
use functions:
|
||||
optimizations. Some fields were removed entirely, as they were details of the
|
||||
old implementation.
|
||||
|
||||
* ``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 (see below), use :c:func:`PyFrame_GetBack`.
|
||||
* ``f_builtins``: removed,
|
||||
use ``PyObject_GetAttrString((PyObject*)frame, "f_builtins")``.
|
||||
* ``f_globals``: removed,
|
||||
use ``PyObject_GetAttrString((PyObject*)frame, "f_globals")``.
|
||||
* ``f_locals``: removed,
|
||||
use ``PyObject_GetAttrString((PyObject*)frame, "f_locals")``.
|
||||
* ``f_lasti``: removed,
|
||||
use ``PyObject_GetAttrString((PyObject*)frame, "f_lasti")``.
|
||||
Code using ``f_lasti`` with ``PyCode_Addr2Line()`` should use
|
||||
:c:type:`PyFrameObject` fields:
|
||||
|
||||
* ``f_back``: use :c:func:`PyFrame_GetBack`.
|
||||
* ``f_blockstack``: removed.
|
||||
* ``f_builtins``: use ``PyObject_GetAttrString((PyObject*)frame, "f_builtins")``.
|
||||
* ``f_code``: use :c:func:`PyFrame_GetCode`.
|
||||
* ``f_gen``: removed.
|
||||
* ``f_globals``: use ``PyObject_GetAttrString((PyObject*)frame, "f_globals")``.
|
||||
* ``f_iblock``: removed.
|
||||
* ``f_lasti``: use ``PyObject_GetAttrString((PyObject*)frame, "f_lasti")``.
|
||||
Code using ``f_lasti`` with ``PyCode_Addr2Line()`` must use
|
||||
:c:func:`PyFrame_GetLineNumber` instead.
|
||||
|
||||
The following fields were removed entirely, as they were details
|
||||
of the old implementation:
|
||||
|
||||
* ``f_valuesstack``
|
||||
* ``f_stackdepth``
|
||||
* ``f_gen``
|
||||
* ``f_iblock``
|
||||
* ``f_state``
|
||||
* ``f_blockstack``
|
||||
* ``f_localsplus``
|
||||
* ``f_lineno``: use :c:func:`PyFrame_GetLineNumber`
|
||||
* ``f_locals``: use ``PyObject_GetAttrString((PyObject*)frame, "f_locals")``.
|
||||
* ``f_stackdepth``: removed.
|
||||
* ``f_state``: no public API (renamed to ``f_frame.f_state``).
|
||||
* ``f_trace``: no public API.
|
||||
* ``f_trace_lines``: use ``PyObject_GetAttrString((PyObject*)frame, "f_trace_lines")``
|
||||
(it also be modified).
|
||||
* ``f_trace_opcodes``: use ``PyObject_GetAttrString((PyObject*)frame, "f_trace_opcodes")``
|
||||
(it also be modified).
|
||||
* ``f_localsplus``: no public API (renamed to ``f_frame.localsplus``).
|
||||
* ``f_valuestack``: 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
|
||||
|
|
@ -897,9 +897,9 @@ Porting to Python 3.11
|
|||
}
|
||||
#endif
|
||||
|
||||
Or use `the pythoncapi_compat project
|
||||
<https://github.com/pythoncapi/pythoncapi_compat>`__ to get these APIs
|
||||
on older Python versions.
|
||||
Or use the `pythoncapi_compat project
|
||||
<https://github.com/pythoncapi/pythoncapi_compat>`__ to get these two
|
||||
functions on older Python versions.
|
||||
|
||||
* Changes of the :c:type:`PyThreadState` structure members:
|
||||
|
||||
|
|
|
|||
|
|
@ -4,19 +4,6 @@
|
|||
# error "this header file must not be included directly"
|
||||
#endif
|
||||
|
||||
struct _frame {
|
||||
PyObject_HEAD
|
||||
PyFrameObject *f_back; /* previous frame, or NULL */
|
||||
struct _interpreter_frame *f_frame; /* points to the frame data */
|
||||
PyObject *f_trace; /* Trace function */
|
||||
int f_lineno; /* Current line number. Only valid if non-zero */
|
||||
char f_trace_lines; /* Emit per-line trace events? */
|
||||
char f_trace_opcodes; /* Emit per-opcode trace events? */
|
||||
char f_owns_frame; /* This frame owns the frame */
|
||||
/* The frame data, if this frame object owns the frame */
|
||||
PyObject *_f_frame_data[1];
|
||||
};
|
||||
|
||||
/* Standard object interface */
|
||||
|
||||
PyAPI_DATA(PyTypeObject) PyFrame_Type;
|
||||
|
|
|
|||
|
|
@ -6,6 +6,18 @@ extern "C" {
|
|||
|
||||
#include <stdbool.h>
|
||||
|
||||
struct _frame {
|
||||
PyObject_HEAD
|
||||
PyFrameObject *f_back; /* previous frame, or NULL */
|
||||
struct _interpreter_frame *f_frame; /* points to the frame data */
|
||||
PyObject *f_trace; /* Trace function */
|
||||
int f_lineno; /* Current line number. Only valid if non-zero */
|
||||
char f_trace_lines; /* Emit per-line trace events? */
|
||||
char f_trace_opcodes; /* Emit per-opcode trace events? */
|
||||
char f_owns_frame; /* This frame owns the frame */
|
||||
/* The frame data, if this frame object owns the frame */
|
||||
PyObject *_f_frame_data[1];
|
||||
};
|
||||
|
||||
/* runtime lifecycle */
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
Move the :c:type:`PyFrameObject` type definition (``struct _frame``) to the
|
||||
internal C API ``pycore_frame.h`` header file. Patch by Victor Stinner.
|
||||
Loading…
Add table
Add a link
Reference in a new issue