Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 124227c

Browse files
authored
bpo-44800: Document internal frame naming conventions (GH-32281)
The fact interpreter frames were split out from full frame objects rather than always being part of the eval loop implementation means that it's tricky to infer the expected naming conventions simply from looking at the code. Documenting the de facto conventions in pycore_frame.h means future readers of the code will have a clear explanation of the rationale for those conventions (i.e. minimising non-functional code churn).
1 parent 4f5d56f commit 124227c

File tree

1 file changed

+69
-0
lines changed

1 file changed

+69
-0
lines changed

Include/internal/pycore_frame.h

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,75 @@ extern "C" {
77
#include <stdbool.h>
88
#include <stddef.h>
99

10+
/* Starting in CPython 3.11, CPython separates the frame state between the
11+
* full frame objects exposed by the Python and C runtime state introspection
12+
* APIs, and internal lighter weight interpreter frames, which are simple C
13+
* structures owned by either the interpreter eval loop (while executing
14+
* ordinary functions), by a generator or coroutine object (for frames that
15+
* are able to be suspended), or by their corresponding full frame object (if
16+
* a state instrospection API has been invoked and the full frame object has
17+
* taken responsibility for the lifecycle of the interpreter frame).
18+
*
19+
* This split storage eliminates a lot of allocation and deallocation of full
20+
* Python objects during code execution, providing a significant speed gain
21+
* over the previous approach of using full Python objects for both
22+
* introspection and code execution.
23+
*
24+
* Struct names:
25+
*
26+
* * PyFrameObject: the full Python frame object
27+
* * _PyInterpreterFrame: the lightweight frame struct used by the eval loop
28+
* * _PyCFrame: a struct that lives on the C stack and allows Python level
29+
* recursive evaluation to be decoupled from recursive C level invocation
30+
* of the bytecode eval loop
31+
* * See pystate.h for more details on this struct
32+
*
33+
* Field naming conventions:
34+
*
35+
* * full frame object fields have an "f_*" (or "_f_*") prefix
36+
* * new interpreter frame fields have no prefix
37+
* * Several interpreter frame fields have the "f_*" prefix as a result of
38+
* trying to keep diffs as small as was feasible when splitting the original
39+
* frame struct definition in two. The following are all interpreter frame
40+
* fields, NOT full frame object fields:
41+
* * f_func
42+
* * f_globals
43+
* * f_builtins
44+
* * f_locals
45+
* * f_code
46+
* * f_lasti
47+
* * f_state
48+
* * Renaming those fields was considered but ultimately deemed too disruptive
49+
* to key third party projects that were trying to keep up with the Python
50+
* 3.11 code evaluation changes during the alpha release cycle
51+
* (see bpo-44800 for details)
52+
*
53+
* Naming conventions for local variables, function parameters and fields in other structs:
54+
*
55+
* * "frame" and "f" may refer to either full frame objects or interpreter frames
56+
* * the context of use or the field naming conventions usually make the
57+
* type being referenced unambiguous in code reviews
58+
* * the following alternative names are used when more clarity is needed:
59+
* * full frame objects: "frame_obj" (and variants like "frameobj" or "fobj")
60+
* * interpreter frame structs: "frame_data" or "iframe"
61+
* * "current frame" should NOT be abbreviated as "cframe", as the latter now
62+
* typically refers to _PyCFrame structs
63+
*
64+
* Function/macro parameter types:
65+
*
66+
* * "PyFrame_*" functions and other public C API functions that relate to
67+
* frames accept full frame object pointers
68+
* * "_PyFrame_*" functions and other private C API functions that relate to
69+
* frames accept either full frame object or interpreter frame pointers.
70+
* Check the specific function signatures for details.
71+
*
72+
* Function return types:
73+
*
74+
* * Public C API functions will only ever return full frame object pointers
75+
* * Private C API functions with an underscore prefix may return interpreter
76+
* frame pointers instead. Check the specific function signatures for details.
77+
*/
78+
1079
struct _frame {
1180
PyObject_HEAD
1281
PyFrameObject *f_back; /* previous frame, or NULL */

0 commit comments

Comments
 (0)