Skip to content

Commit dec747c

Browse files
CopilotXmader
andauthored
Fix asyncio loop lookup on Python 3.15
Co-authored-by: Xmader <16057139+Xmader@users.noreply.github.com>
1 parent 42d60f2 commit dec747c

1 file changed

Lines changed: 38 additions & 0 deletions

File tree

‎src/PyEventLoop.cc‎

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
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

Comments
 (0)