1212#include " include/PyEventLoop.hh"
1313
1414#include < Python.h>
15+ #include < stdint.h>
1516
1617/* *
1718 * @brief Wrapper to decrement the counter of queueing event-loop jobs after the job finishes
@@ -153,6 +154,42 @@ PyEventLoop PyEventLoop::_getLoopOnThread(PyThreadState *tstate) {
153154 {
154155 // Every `PyThreadState` is actually allocated with extra fields as a `_PyThreadStateImpl` struct
155156 // See https://github.com/python/cpython/blob/v3.13.0rc1/Include/internal/pycore_tstate.h#L17-L24
157+ #if PY_VERSION_HEX >= 0x030f0000 // Python version is greater than 3.14
158+ // Python 3.15 embeds a frame and adds stack fields before asyncio_running_loop.
159+ using PyThreadStateHolder = struct { // _PyThreadStateImpl
160+ PyThreadState base;
161+ struct { // _PyInterpreterFrame
162+ uintptr_t f_executable;
163+ void *previous;
164+ uintptr_t f_funcobj;
165+ PyObject *f_globals;
166+ PyObject *f_builtins;
167+ PyObject *f_locals;
168+ PyObject *frame_obj;
169+ void *instr_ptr;
170+ uintptr_t *stackpointer;
171+ #ifdef Py_GIL_DISABLED
172+ int32_t tlbc_index;
173+ #endif
174+ uint16_t return_offset;
175+ char owner;
176+ #ifdef Py_DEBUG
177+ uint8_t visited : 1 ;
178+ uint8_t lltrace : 7 ;
179+ #else
180+ uint8_t visited;
181+ #endif
182+ uintptr_t localsplus[1 ];
183+ } base_frame;
184+ Py_ssize_t refcount;
185+ uintptr_t c_stack_top;
186+ uintptr_t c_stack_soft_limit;
187+ uintptr_t c_stack_hard_limit;
188+ uintptr_t c_stack_init_base;
189+ uintptr_t c_stack_init_top;
190+ PyObject *asyncio_running_loop;
191+ };
192+ #else
156193 using PyThreadStateHolder = struct { // _PyThreadStateImpl
157194 PyThreadState base;
158195 #if PY_VERSION_HEX >= 0x030e0000 // Python version is greater than 3.14
@@ -164,6 +201,7 @@ PyEventLoop PyEventLoop::_getLoopOnThread(PyThreadState *tstate) {
164201 #endif
165202 PyObject *asyncio_running_loop; // we only need the first few fields of `_PyThreadStateImpl`
166203 };
204+ #endif
167205
168206 // Modified from https://github.com/python/cpython/blob/v3.13.0rc1/Modules/_asynciomodule.c#L3205-L3210
169207 PyObject *loop = ((PyThreadStateHolder *)tstate)->asyncio_running_loop ;
0 commit comments