https://github.com/python/cpython/commit/61317074d450f72fa121ceb1c7b0c52698a71106
commit: 61317074d450f72fa121ceb1c7b0c52698a71106
branch: main
author: Victor Stinner <vstin...@python.org>
committer: vstinner <vstin...@python.org>
date: 2025-03-21T17:19:47Z
summary:

gh-131238: Add pycore_interpframe_structs.h header (#131553)

Add an explicit include to pycore_interpframe_structs.h in
pycore_runtime_structs.h to fix a dependency cycle.

files:
A Include/internal/pycore_interpframe_structs.h
M Include/internal/pycore_genobject.h
M Include/internal/pycore_interpframe.h
M Include/internal/pycore_runtime_structs.h
M Objects/genobject.c
M Python/pylifecycle.c
M Python/pystate.c

diff --git a/Include/internal/pycore_genobject.h 
b/Include/internal/pycore_genobject.h
index e99ffcba64e66f..2947dde71fd676 100644
--- a/Include/internal/pycore_genobject.h
+++ b/Include/internal/pycore_genobject.h
@@ -9,42 +9,9 @@ extern "C" {
 #endif
 
 #include "pycore_interpframe.h"   // _PyInterpreterFrame
+#include "pycore_interpframe_structs.h" // _PyGenObject
 
 
-/* _PyGenObject_HEAD defines the initial segment of generator
-   and coroutine objects. */
-#define _PyGenObject_HEAD(prefix)                                           \
-    PyObject_HEAD                                                           \
-    /* List of weak reference. */                                           \
-    PyObject *prefix##_weakreflist;                                         \
-    /* Name of the generator. */                                            \
-    PyObject *prefix##_name;                                                \
-    /* Qualified name of the generator. */                                  \
-    PyObject *prefix##_qualname;                                            \
-    _PyErr_StackItem prefix##_exc_state;                                    \
-    PyObject *prefix##_origin_or_finalizer;                                 \
-    char prefix##_hooks_inited;                                             \
-    char prefix##_closed;                                                   \
-    char prefix##_running_async;                                            \
-    /* The frame */                                                         \
-    int8_t prefix##_frame_state;                                            \
-    _PyInterpreterFrame prefix##_iframe;                                    \
-
-struct _PyGenObject {
-    /* The gi_ prefix is intended to remind of generator-iterator. */
-    _PyGenObject_HEAD(gi)
-};
-
-struct _PyCoroObject {
-    _PyGenObject_HEAD(cr)
-};
-
-struct _PyAsyncGenObject {
-    _PyGenObject_HEAD(ag)
-};
-
-#undef _PyGenObject_HEAD
-
 static inline
 PyGenObject *_PyGen_GetGeneratorFromFrame(_PyInterpreterFrame *frame)
 {
diff --git a/Include/internal/pycore_interpframe.h 
b/Include/internal/pycore_interpframe.h
index f513dbe5cbbdb3..41acd877aee873 100644
--- a/Include/internal/pycore_interpframe.h
+++ b/Include/internal/pycore_interpframe.h
@@ -1,7 +1,3 @@
-/* See InternalDocs/frames.md for an explanation of the frame stack
- * including explanation of the PyFrameObject and _PyInterpreterFrame
- * structs. */
-
 #ifndef Py_INTERNAL_INTERP_FRAME_H
 #define Py_INTERNAL_INTERP_FRAME_H
 
@@ -10,50 +6,14 @@
 #endif
 
 #include "pycore_code.h"          // _PyCode_CODE()
+#include "pycore_interpframe_structs.h" // _PyInterpreterFrame
 #include "pycore_stackref.h"      // PyStackRef_AsPyObjectBorrow()
 #include "pycore_stats.h"         // CALL_STAT_INC()
-#include "pycore_structs.h"       // _PyStackRef
-#include "pycore_typedefs.h"      // _PyInterpreterFrame
-
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-enum _frameowner {
-    FRAME_OWNED_BY_THREAD = 0,
-    FRAME_OWNED_BY_GENERATOR = 1,
-    FRAME_OWNED_BY_FRAME_OBJECT = 2,
-    FRAME_OWNED_BY_INTERPRETER = 3,
-    FRAME_OWNED_BY_CSTACK = 4,
-};
-
-struct _PyInterpreterFrame {
-    _PyStackRef f_executable; /* Deferred or strong reference (code object or 
None) */
-    struct _PyInterpreterFrame *previous;
-    _PyStackRef f_funcobj; /* Deferred or strong reference. Only valid if not 
on C stack */
-    PyObject *f_globals; /* Borrowed reference. Only valid if not on C stack */
-    PyObject *f_builtins; /* Borrowed reference. Only valid if not on C stack 
*/
-    PyObject *f_locals; /* Strong reference, may be NULL. Only valid if not on 
C stack */
-    PyFrameObject *frame_obj; /* Strong reference, may be NULL. Only valid if 
not on C stack */
-    _Py_CODEUNIT *instr_ptr; /* Instruction currently executing (or about to 
begin) */
-    _PyStackRef *stackpointer;
-#ifdef Py_GIL_DISABLED
-    /* Index of thread-local bytecode containing instr_ptr. */
-    int32_t tlbc_index;
-#endif
-    uint16_t return_offset;  /* Only relevant during a function call */
-    char owner;
-#ifdef Py_DEBUG
-    uint8_t visited:1;
-    uint8_t lltrace:7;
-#else
-    uint8_t visited;
-#endif
-    /* Locals and stack */
-    _PyStackRef localsplus[1];
-};
-
 #define _PyInterpreterFrame_LASTI(IF) \
     ((int)((IF)->instr_ptr - _PyFrame_GetBytecode((IF))))
 
diff --git a/Include/internal/pycore_interpframe_structs.h 
b/Include/internal/pycore_interpframe_structs.h
new file mode 100644
index 00000000000000..835b8e58194863
--- /dev/null
+++ b/Include/internal/pycore_interpframe_structs.h
@@ -0,0 +1,95 @@
+/* Structures used by pycore_debug_offsets.h.
+ *
+ * See InternalDocs/frames.md for an explanation of the frame stack
+ * including explanation of the PyFrameObject and _PyInterpreterFrame
+ * structs.
+ */
+
+#ifndef Py_INTERNAL_INTERP_FRAME_STRUCTS_H
+#define Py_INTERNAL_INTERP_FRAME_STRUCTS_H
+
+#ifndef Py_BUILD_CORE
+#  error "this header requires Py_BUILD_CORE define"
+#endif
+
+#include "pycore_structs.h"       // _PyStackRef
+#include "pycore_typedefs.h"      // _PyInterpreterFrame
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum _frameowner {
+    FRAME_OWNED_BY_THREAD = 0,
+    FRAME_OWNED_BY_GENERATOR = 1,
+    FRAME_OWNED_BY_FRAME_OBJECT = 2,
+    FRAME_OWNED_BY_INTERPRETER = 3,
+    FRAME_OWNED_BY_CSTACK = 4,
+};
+
+struct _PyInterpreterFrame {
+    _PyStackRef f_executable; /* Deferred or strong reference (code object or 
None) */
+    struct _PyInterpreterFrame *previous;
+    _PyStackRef f_funcobj; /* Deferred or strong reference. Only valid if not 
on C stack */
+    PyObject *f_globals; /* Borrowed reference. Only valid if not on C stack */
+    PyObject *f_builtins; /* Borrowed reference. Only valid if not on C stack 
*/
+    PyObject *f_locals; /* Strong reference, may be NULL. Only valid if not on 
C stack */
+    PyFrameObject *frame_obj; /* Strong reference, may be NULL. Only valid if 
not on C stack */
+    _Py_CODEUNIT *instr_ptr; /* Instruction currently executing (or about to 
begin) */
+    _PyStackRef *stackpointer;
+#ifdef Py_GIL_DISABLED
+    /* Index of thread-local bytecode containing instr_ptr. */
+    int32_t tlbc_index;
+#endif
+    uint16_t return_offset;  /* Only relevant during a function call */
+    char owner;
+#ifdef Py_DEBUG
+    uint8_t visited:1;
+    uint8_t lltrace:7;
+#else
+    uint8_t visited;
+#endif
+    /* Locals and stack */
+    _PyStackRef localsplus[1];
+};
+
+
+/* _PyGenObject_HEAD defines the initial segment of generator
+   and coroutine objects. */
+#define _PyGenObject_HEAD(prefix)                                           \
+    PyObject_HEAD                                                           \
+    /* List of weak reference. */                                           \
+    PyObject *prefix##_weakreflist;                                         \
+    /* Name of the generator. */                                            \
+    PyObject *prefix##_name;                                                \
+    /* Qualified name of the generator. */                                  \
+    PyObject *prefix##_qualname;                                            \
+    _PyErr_StackItem prefix##_exc_state;                                    \
+    PyObject *prefix##_origin_or_finalizer;                                 \
+    char prefix##_hooks_inited;                                             \
+    char prefix##_closed;                                                   \
+    char prefix##_running_async;                                            \
+    /* The frame */                                                         \
+    int8_t prefix##_frame_state;                                            \
+    _PyInterpreterFrame prefix##_iframe;                                    \
+
+struct _PyGenObject {
+    /* The gi_ prefix is intended to remind of generator-iterator. */
+    _PyGenObject_HEAD(gi)
+};
+
+struct _PyCoroObject {
+    _PyGenObject_HEAD(cr)
+};
+
+struct _PyAsyncGenObject {
+    _PyGenObject_HEAD(ag)
+};
+
+#undef _PyGenObject_HEAD
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif  // !Py_INTERNAL_INTERP_FRAME_STRUCTS_H
diff --git a/Include/internal/pycore_runtime_structs.h 
b/Include/internal/pycore_runtime_structs.h
index a062de39f4eb40..6bf3aae7175a97 100644
--- a/Include/internal/pycore_runtime_structs.h
+++ b/Include/internal/pycore_runtime_structs.h
@@ -64,6 +64,7 @@ struct _fileutils_state {
     int force_ascii;
 };
 
+#include "pycore_interpframe_structs.h" // _PyInterpreterFrame
 #include "pycore_debug_offsets.h" // _Py_DebugOffsets
 #include "pycore_signal.h"        // struct _signals_runtime_state
 #include "pycore_faulthandler.h"  // struct _faulthandler_runtime_state
diff --git a/Objects/genobject.c b/Objects/genobject.c
index 308d45701d296f..13f2bf7808c309 100644
--- a/Objects/genobject.c
+++ b/Objects/genobject.c
@@ -3,13 +3,12 @@
 #define _PY_INTERPRETER
 
 #include "Python.h"
-#include "pycore_genobject.h"
-
 #include "pycore_call.h"          // _PyObject_CallNoArgs()
 #include "pycore_ceval.h"         // _PyEval_EvalFrame()
 #include "pycore_frame.h"         // _PyInterpreterFrame
 #include "pycore_freelist.h"      // _Py_FREELIST_FREE(), _Py_FREELIST_POP()
 #include "pycore_gc.h"            // _PyGC_CLEAR_FINALIZED()
+#include "pycore_genobject.h"
 #include "pycore_modsupport.h"    // _PyArg_CheckPositional()
 #include "pycore_object.h"        // _PyObject_GC_UNTRACK()
 #include "pycore_opcode_utils.h"  // RESUME_AFTER_YIELD_FROM
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index ed21fce335c99d..484583e1c79579 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -1,8 +1,6 @@
 /* Python interpreter top-level routines, including init/exit */
 
 #include "Python.h"
-#include "pycore_genobject.h"     // included first to break dependency cycle
-
 #include "pycore_audit.h"         // _PySys_ClearAuditHooks()
 #include "pycore_call.h"          // _PyObject_CallMethod()
 #include "pycore_ceval.h"         // _PyEval_FiniGIL()
diff --git a/Python/pystate.c b/Python/pystate.c
index 7d1ca0d33ef4d8..ee35f0fa945f8b 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -2,8 +2,6 @@
 /* Thread and interpreter state structures and their interfaces */
 
 #include "Python.h"
-#include "pycore_genobject.h"     // included first to break dependency cycle
-
 #include "pycore_abstract.h"      // _PyIndex_Check()
 #include "pycore_audit.h"         // _Py_AuditHookEntry
 #include "pycore_ceval.h"         // _PyEval_AcquireLock()

_______________________________________________
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com

Reply via email to