]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-46836: Move PyFrameObject to pycore_frame.h (GH-31530)
authorVictor Stinner <vstinner@python.org>
Fri, 25 Feb 2022 11:53:19 +0000 (12:53 +0100)
committerGitHub <noreply@github.com>
Fri, 25 Feb 2022 11:53:19 +0000 (12:53 +0100)
Move the PyFrameObject type definition (struct _frame) to the
internal C API pycore_frame.h header file.

Doc/c-api/veryhigh.rst
Doc/whatsnew/3.11.rst
Include/cpython/frameobject.h
Include/internal/pycore_frame.h
Misc/NEWS.d/next/C API/2022-02-23-16-13-17.bpo-46836.ZYyPF_.rst [new file with mode: 0644]

index 5b8735de75e9d025009ec7382e9df78ea37be457..2f5720d493d7982894a287581b3982676ce296ef 100644 (file)
@@ -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)
index 0556a44d4c7d4c015ba63c6c72aac5045cb19e1d..3f73bdfa3020f20eb37e57cfb16edcac13ee51a8 100644 (file)
@@ -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:
 
index 3d862d9deb000f6d8c1b3e77e1f8bc58e9c19ec0..e69209686bee02697fd54534d0074474ea861621 100644 (file)
@@ -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;
index 1ad156290a55e947ec565346bf7deeb636414021..09d41222b61fc9de7c6f67ea4782773ba33aca28 100644 (file)
@@ -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 (file)
index 0000000..2867bfd
--- /dev/null
@@ -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.