summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2022-02-25 11:53:19 (GMT)
committerGitHub <noreply@github.com>2022-02-25 11:53:19 (GMT)
commit18b5dd68c6b616257ae243c0b6bb965ffc885a23 (patch)
tree5d7248f7ff003e8f51b1883eb23018bd61ef5750
parent4657bf701670215ce69b89401b2307022a3b0a7d (diff)
downloadcpython-18b5dd68c6b616257ae243c0b6bb965ffc885a23.zip
cpython-18b5dd68c6b616257ae243c0b6bb965ffc885a23.tar.gz
cpython-18b5dd68c6b616257ae243c0b6bb965ffc885a23.tar.bz2
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.
-rw-r--r--Doc/c-api/veryhigh.rst12
-rw-r--r--Doc/whatsnew/3.11.rst68
-rw-r--r--Include/cpython/frameobject.h13
-rw-r--r--Include/internal/pycore_frame.h12
-rw-r--r--Misc/NEWS.d/next/C API/2022-02-23-16-13-17.bpo-46836.ZYyPF_.rst2
5 files changed, 58 insertions, 49 deletions
diff --git a/Doc/c-api/veryhigh.rst b/Doc/c-api/veryhigh.rst
index 5b8735d..2f5720d 100644
--- a/Doc/c-api/veryhigh.rst
+++ b/Doc/c-api/veryhigh.rst
@@ -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)
diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst
index 0556a44..3f73bdf 100644
--- a/Doc/whatsnew/3.11.rst
+++ b/Doc/whatsnew/3.11.rst
@@ -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 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:
+ 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.
- * ``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
+ In Python 3.11, the frame struct was reorganized to allow performance
+ optimizations. Some fields were removed entirely, as they were details of the
+ old implementation.
+
+ :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:
diff --git a/Include/cpython/frameobject.h b/Include/cpython/frameobject.h
index 3d862d9..e692096 100644
--- a/Include/cpython/frameobject.h
+++ b/Include/cpython/frameobject.h
@@ -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;
diff --git a/Include/internal/pycore_frame.h b/Include/internal/pycore_frame.h
index 1ad1562..09d4122 100644
--- a/Include/internal/pycore_frame.h
+++ b/Include/internal/pycore_frame.h
@@ -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 */
diff --git a/Misc/NEWS.d/next/C API/2022-02-23-16-13-17.bpo-46836.ZYyPF_.rst b/Misc/NEWS.d/next/C API/2022-02-23-16-13-17.bpo-46836.ZYyPF_.rst
new file mode 100644
index 0000000..2867bfd
--- /dev/null
+++ b/Misc/NEWS.d/next/C API/2022-02-23-16-13-17.bpo-46836.ZYyPF_.rst
@@ -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.