From 0c5c52fa8261e8a0fba8ebb4e5dac9b341ba4605 Mon Sep 17 00:00:00 2001 From: Matt Wozniski Date: Thu, 28 May 2026 00:09:35 -0400 Subject: [PATCH] Remove hardcoded offsets for Python 3.14 and 3.15 These offsets are no longer used for anything in the overwhelming majority of cases. The only way that they could be used is if a process running a modern version of Python managed to trash memory in a way that corrupted the `_Py_DebugOffsets` structure in memory. And unfortunately, even in that case, we would go on to behave incorrectly: the Python 3.14 debug offsets were wrong. Since these aren't being used and haven't been being well maintained, and since they're impossible to properly test, and since they're impossible to make work for multiple different interpreter flavors (GIL vs free-threading, JIT vs no-JIT, etc) and they could even change between two patch versions of the interpreter for the same flavor, let's just remove them and turn it into a hard failure if someone manages to trash memory so badly that the `_Py_DebugOffsets` structure can't be used. Signed-off-by: Matt Wozniski --- pyproject.toml | 1 + src/pystack/_pystack/cpython/code.h | 78 ----------- src/pystack/_pystack/cpython/frame.h | 18 --- src/pystack/_pystack/cpython/gc.h | 44 ------ src/pystack/_pystack/cpython/interpreter.h | 153 --------------------- src/pystack/_pystack/cpython/runtime.h | 30 ---- src/pystack/_pystack/cpython/string.h | 14 -- src/pystack/_pystack/cpython/thread.h | 140 ------------------- src/pystack/_pystack/process.cpp | 17 +++ src/pystack/_pystack/version.cpp | 150 +++++++++++++++----- 10 files changed, 136 insertions(+), 509 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index c7b951c8..b80cb06c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.14", + "Programming Language :: Python :: 3.15", "Programming Language :: Python :: Implementation :: CPython", "Topic :: Software Development :: Debuggers", ] diff --git a/src/pystack/_pystack/cpython/code.h b/src/pystack/_pystack/cpython/code.h index d837c66b..5069ffe7 100644 --- a/src/pystack/_pystack/cpython/code.h +++ b/src/pystack/_pystack/cpython/code.h @@ -197,82 +197,4 @@ typedef struct } PyCodeObject; } // namespace Python3_13 -namespace Python3_14 { -typedef uint16_t _Py_CODEUNIT; - -typedef struct -{ - PyObject_VAR_HEAD PyObject* co_consts; - PyObject* co_names; - PyObject* co_exceptiontable; - int co_flags; - int co_argcount; - int co_posonlyargcount; - int co_kwonlyargcount; - int co_stacksize; - int co_firstlineno; - int co_nlocalsplus; - int co_framesize; - int co_nlocals; - int co_ncellvars; - int co_nfreevars; - uint32_t co_version; - PyObject* co_localsplusnames; - PyObject* co_localspluskinds; - PyObject* co_filename; - PyObject* co_name; - PyObject* co_qualname; - PyObject* co_linetable; - PyObject* co_weakreflist; - void* co_executors; - void* _co_cached; - uintptr_t _co_instrumentation_version; - void* _co_monitoring; - Py_ssize_t _co_unique_id; - int _co_firsttraceable; - void* co_extra; - /* deal with co_tlbc somehow */ - char co_code_adaptive[1]; -} PyCodeObject; -} // namespace Python3_14 - -namespace Python3_15 { -typedef uint16_t _Py_CODEUNIT; - -typedef struct -{ - PyObject_VAR_HEAD PyObject* co_consts; - PyObject* co_names; - PyObject* co_exceptiontable; - int co_flags; - int co_argcount; - int co_posonlyargcount; - int co_kwonlyargcount; - int co_stacksize; - int co_firstlineno; - int co_nlocalsplus; - int co_framesize; - int co_nlocals; - int co_ncellvars; - int co_nfreevars; - uint32_t co_version; - PyObject* co_localsplusnames; - PyObject* co_localspluskinds; - PyObject* co_filename; - PyObject* co_name; - PyObject* co_qualname; - PyObject* co_linetable; - PyObject* co_weakreflist; - void* co_executors; - void* _co_cached; - uintptr_t _co_instrumentation_version; - void* _co_monitoring; - Py_ssize_t _co_unique_id; - int _co_firsttraceable; - void* co_extra; - /* deal with co_tlbc somehow */ - char co_code_adaptive[1]; -} PyCodeObject; -} // namespace Python3_15 - } // namespace pystack diff --git a/src/pystack/_pystack/cpython/frame.h b/src/pystack/_pystack/cpython/frame.h index a71f9dd8..0951a252 100644 --- a/src/pystack/_pystack/cpython/frame.h +++ b/src/pystack/_pystack/cpython/frame.h @@ -147,24 +147,6 @@ typedef union _PyStackRef { uintptr_t bits; } _PyStackRef; -typedef struct _interpreter_frame -{ - _PyStackRef f_executable; - void* previous; - void* f_funcobj; - PyObject* f_globals; - PyObject* f_builtins; - PyObject* f_locals; - PyObject* frame_obj; - _Py_CODEUNIT* instr_ptr; - _PyStackRef stackpointer; - /* int32_t tlbc_index; */ - uint16_t return_offset; - char owner; - uint8_t visited; - void* localsplus[1]; -} PyFrameObject; - } // namespace Python3_14 } // namespace pystack diff --git a/src/pystack/_pystack/cpython/gc.h b/src/pystack/_pystack/cpython/gc.h index 5ac0c941..85e6b8bd 100644 --- a/src/pystack/_pystack/cpython/gc.h +++ b/src/pystack/_pystack/cpython/gc.h @@ -83,48 +83,4 @@ struct _gc_runtime_state } // namespace Python3_8 -namespace Python3_14 { - -struct _gc_runtime_state -{ - PyObject* trash_delete_later; - int trash_delete_nesting; - int enabled; - int debug; - struct Python3_8::gc_generation young; - struct Python3_8::gc_generation old[2]; - struct Python3_8::gc_generation permanent_generation; - struct gc_generation_stats generation_stats[NUM_GENERATIONS]; - int collecting; - PyObject* garbage; - PyObject* callbacks; - Py_ssize_t heap_size; - Py_ssize_t work_to_do; - int visited_space; - int phase; -}; - -} // namespace Python3_14 - -namespace Python3_15 { - -struct _gc_runtime_state -{ - int enabled; - int debug; - struct Python3_8::gc_generation young; - struct Python3_8::gc_generation old[2]; - struct Python3_8::gc_generation permanent_generation; - struct gc_generation_stats generation_stats[NUM_GENERATIONS]; - int collecting; - struct _PyInterpreterFrame* frame; - PyObject* garbage; - PyObject* callbacks; - Py_ssize_t heap_size; - Py_ssize_t long_lived_total; - Py_ssize_t long_lived_pending; -}; - -} // namespace Python3_15 - } // namespace pystack diff --git a/src/pystack/_pystack/cpython/interpreter.h b/src/pystack/_pystack/cpython/interpreter.h index bc2f1742..31382998 100644 --- a/src/pystack/_pystack/cpython/interpreter.h +++ b/src/pystack/_pystack/cpython/interpreter.h @@ -339,157 +339,4 @@ typedef struct _is } PyInterpreterState; } // namespace Python3_13 -namespace Python3_14 { - -struct _pythreadstate; - -typedef struct -{ - Python3_13::PyMutex mutex; - unsigned long long thread; - size_t level; -} _PyRecursiveMutex; - -struct _import_state -{ - PyObject* modules; - PyObject* modules_by_index; - PyObject* importlib; - int override_frozen_modules; - int override_multi_interp_extensions_check; - PyObject* import_func; - _PyRecursiveMutex lock; - /* diagnostic info in PyImport_ImportModuleLevelObject() */ - struct - { - int import_level; - int64_t accumulated; - int header; - } find_and_load; -}; - -struct _gil_runtime_state -{ - unsigned long interval; - struct _pythreadstate* last_holder; - int locked; - unsigned long switch_number; - pthread_cond_t cond; - pthread_cond_t mutex; -#ifdef FORCE_SWITCHING - pthread_cond_t switch_cond; - pthread_cond_t switch_mutex; -#endif -}; - -typedef struct _is -{ - struct _ceval_state ceval; - void* _malloced; - struct _is* next; - int64_t id; - Py_ssize_t id_refcount; - int requires_idref; - long _whence; - int _initialized; - int _ready; - int finalizing; - uintptr_t last_restart_version; - struct pythreads - { - uint64_t next_unique_id; - struct _pythreadstate* head; - struct _pythreadstate* preallocated; - struct _pythreadstate* main; - Py_ssize_t count; - size_t stacksize; - } threads; - void* runtime; - struct _pythreadstate* _finalizing; - unsigned long _finalizing_id; - struct _gc_runtime_state gc; - PyObject* sysdict; - PyObject* builtins; - struct _import_state imports; - struct _gil_runtime_state _gil; -} PyInterpreterState; - -} // namespace Python3_14 - -namespace Python3_15 { - -struct _pythreadstate; - -typedef struct -{ - Python3_13::PyMutex mutex; - unsigned long long thread; - size_t level; -} _PyRecursiveMutex; - -struct _import_state -{ - PyObject* modules; - PyObject* modules_by_index; - PyObject* importlib; - int override_frozen_modules; - int override_multi_interp_extensions_check; - PyObject* import_func; - _PyRecursiveMutex lock; - /* diagnostic info in PyImport_ImportModuleLevelObject() */ - struct - { - int import_level; - int64_t accumulated; - int header; - } find_and_load; -}; - -struct _gil_runtime_state -{ - unsigned long interval; - struct _pythreadstate* last_holder; - int locked; - unsigned long switch_number; - pthread_cond_t cond; - pthread_cond_t mutex; -#ifdef FORCE_SWITCHING - pthread_cond_t switch_cond; - pthread_cond_t switch_mutex; -#endif -}; - -typedef struct _is -{ - struct _ceval_state ceval; - struct _is* next; - int64_t id; - Py_ssize_t id_refcount; - int requires_idref; - long _whence; - int _initialized; - int _ready; - int finalizing; - uintptr_t last_restart_version; - struct pythreads - { - uint64_t next_unique_id; - struct _pythreadstate* head; - struct _pythreadstate* preallocated; - struct _pythreadstate* main; - Py_ssize_t count; - size_t stacksize; - } threads; - void* runtime; - struct _pythreadstate* _finalizing; - unsigned long _finalizing_id; - struct _gc_runtime_state gc; - PyObject* sysdict; - PyObject* builtins; - struct _import_state imports; - struct _gil_runtime_state _gil; -} PyInterpreterState; - -} // namespace Python3_15 - } // namespace pystack diff --git a/src/pystack/_pystack/cpython/runtime.h b/src/pystack/_pystack/cpython/runtime.h index 9ba3153f..26f1821a 100644 --- a/src/pystack/_pystack/cpython/runtime.h +++ b/src/pystack/_pystack/cpython/runtime.h @@ -619,21 +619,6 @@ typedef struct _Py_DebugOffsets typedef struct pyruntimestate { _Py_DebugOffsets debug_offsets; - int _initialized; - int preinitializing; - int preinitialized; - int core_initialized; - int initialized; - struct _pythreadstate* finalizing; - unsigned long _finalizing_id; - - struct pyinterpreters - { - Python3_13::PyMutex mutex; - PyInterpreterState* head; - PyInterpreterState* main; - int64_t next_id; - } interpreters; } PyRuntimeState; } // namespace Python3_14 @@ -859,21 +844,6 @@ typedef struct _Py_DebugOffsets typedef struct pyruntimestate { _Py_DebugOffsets debug_offsets; - int _initialized; - int preinitializing; - int preinitialized; - int core_initialized; - int initialized; - struct _pythreadstate* finalizing; - unsigned long _finalizing_id; - - struct pyinterpreters - { - Python3_13::PyMutex mutex; - PyInterpreterState* head; - PyInterpreterState* main; - int64_t next_id; - } interpreters; } PyRuntimeState; } // namespace Python3_15 diff --git a/src/pystack/_pystack/cpython/string.h b/src/pystack/_pystack/cpython/string.h index 17d02fe0..b6618c3c 100644 --- a/src/pystack/_pystack/cpython/string.h +++ b/src/pystack/_pystack/cpython/string.h @@ -122,23 +122,9 @@ struct _PyUnicode_State } // namespace Python3_14t -namespace Python3_15t { - -struct _PyUnicode_State -{ - unsigned char interned; - unsigned int kind : 3; - unsigned int compact : 1; - unsigned int ascii : 1; - unsigned int statically_allocated : 1; -}; - -} // namespace Python3_15t - union AnyPyUnicodeState { Python3::_PyUnicode_State python3; Python3_14t::_PyUnicode_State python3_14t; - Python3_15t::_PyUnicode_State python3_15t; }; } // namespace pystack diff --git a/src/pystack/_pystack/cpython/thread.h b/src/pystack/_pystack/cpython/thread.h index 091481ec..c9b5da8d 100644 --- a/src/pystack/_pystack/cpython/thread.h +++ b/src/pystack/_pystack/cpython/thread.h @@ -295,144 +295,4 @@ typedef struct _pythreadstate } PyThreadState; } // namespace Python3_13 -namespace Python3_14 { - -typedef struct _remote_debugger_support -{ - int32_t debugger_pending_call; - char debugger_script_path[512]; -} _PyRemoteDebuggerSupport; - -typedef struct _pythreadstate -{ - struct _pythreadstate* prev; - struct _pythreadstate* next; - PyInterpreterState* interp; - uintptr_t eval_breaker; - struct - { - unsigned int initialized : 1; - unsigned int bound : 1; - unsigned int unbound : 1; - unsigned int bound_gilstate : 1; - unsigned int active : 1; - unsigned int finalizing : 1; - unsigned int cleared : 1; - unsigned int finalized : 1; - unsigned int : 24; - } _status; - int holds_gil; - int _whence; - int state; - int py_recursion_remaining; - int py_recursion_limit; - int recursion_headroom; - int tracing; - int what_event; - struct _PyInterpreterFrame* current_frame; - Py_tracefunc c_profilefunc; - Py_tracefunc c_tracefunc; - PyObject* c_profileobj; - PyObject* c_traceobj; - PyObject* current_exception; - Python3_13::_PyErr_StackItem* exc_info; - PyObject* dict; - int gilstate_counter; - PyObject* async_exc; - unsigned long thread_id; - unsigned long native_thread_id; - PyObject* delete_later; - uintptr_t critical_section; - int coroutine_origin_tracking_depth; - PyObject* async_gen_firstiter; - PyObject* async_gen_finalizer; - PyObject* context; - uint64_t context_ver; - uint64_t id; - void* datastack_chunk; - PyObject** datastack_top; - PyObject** datastack_limit; - Python3_13::_PyErr_StackItem exc_state; - PyObject* current_executor; - uint64_t dict_global_version; - PyObject* threading_local_key; - PyObject* threading_local_sentinel; - _PyRemoteDebuggerSupport remote_debugger_support; -} PyThreadState; - -} // namespace Python3_14 - -namespace Python3_15 { - -typedef struct _remote_debugger_support -{ - int32_t debugger_pending_call; - char debugger_script_path[512]; -} _PyRemoteDebuggerSupport; - -typedef struct _pythreadstate -{ - struct _pythreadstate* prev; - struct _pythreadstate* next; - PyInterpreterState* interp; - uintptr_t eval_breaker; - struct - { - unsigned int initialized : 1; - unsigned int bound : 1; - unsigned int unbound : 1; - unsigned int bound_gilstate : 1; - unsigned int active : 1; - unsigned int finalizing : 1; - unsigned int cleared : 1; - unsigned int finalized : 1; - unsigned int : 24; - } _status; - int holds_gil; - int gil_requested; - int _whence; - int state; - int py_recursion_remaining; - int py_recursion_limit; - int recursion_headroom; - int tracing; - int what_event; - struct _PyInterpreterFrame* current_frame; - struct _PyInterpreterFrame* base_frame; - struct _PyInterpreterFrame* last_profiled_frame; - - Py_tracefunc c_profilefunc; - Py_tracefunc c_tracefunc; - PyObject* c_profileobj; - PyObject* c_traceobj; - PyObject* current_exception; - Python3_13::_PyErr_StackItem* exc_info; - PyObject* dict; - int gilstate_counter; - PyObject* async_exc; - unsigned long thread_id; - unsigned long native_thread_id; - PyObject* delete_later; - uintptr_t critical_section; - int coroutine_origin_tracking_depth; - PyObject* async_gen_firstiter; - PyObject* async_gen_finalizer; - PyObject* context; - uint64_t context_ver; - uint64_t id; - void* datastack_chunk; - PyObject** datastack_top; - PyObject** datastack_limit; - void* datastack_cached_chunk; - Python3_13::_PyErr_StackItem exc_state; - PyObject* current_executor; - uint64_t dict_global_version; - PyObject* threading_local_key; - PyObject* threading_local_sentinel; - _PyRemoteDebuggerSupport remote_debugger_support; - -} PyThreadState; - -} // namespace Python3_15 - } // namespace pystack diff --git a/src/pystack/_pystack/process.cpp b/src/pystack/_pystack/process.cpp index d351eecd..9aac1b2c 100644 --- a/src/pystack/_pystack/process.cpp +++ b/src/pystack/_pystack/process.cpp @@ -821,6 +821,11 @@ AbstractProcessManager::setPythonVersion(const std::pair& version) void AbstractProcessManager::warnIfOffsetsAreMismatched(remote_addr_t runtime_addr) const { + if (versionIsAtLeast(3, 14)) { + // From 3.14 onwards, we don't have static offsets to compare to. + return; + } + Structure py_runtime(shared_from_this(), runtime_addr); if (0 != memcmp(py_runtime.getField(&py_runtime_v::o_dbg_off_cookie), "xdebugpy", 8)) { @@ -1455,6 +1460,12 @@ ProcessManager::initializeVersion(pid_t pid, const ProcessMemoryMapInfo& map_inf } setPythonVersion(python_version); + + if (!d_debug_offsets && versionIsAtLeast(3, 14)) { + throw std::runtime_error( + "The process runs Python " + std::to_string(d_major) + "." + std::to_string(d_minor) + + ", but we've failed to locate its _Py_DebugOffsets structure in memory."); + } } const std::vector& @@ -1539,6 +1550,12 @@ CoreFileProcessManager::initializeVersion( } setPythonVersion(python_version); + + if (!d_debug_offsets && versionIsAtLeast(3, 14)) { + throw std::runtime_error( + "The process runs Python " + std::to_string(d_major) + "." + std::to_string(d_minor) + + ", but we've failed to locate its _Py_DebugOffsets structure in memory."); + } } const std::vector& diff --git a/src/pystack/_pystack/version.cpp b/src/pystack/_pystack/version.cpp index 975b5446..9f0733d6 100644 --- a/src/pystack/_pystack/version.cpp +++ b/src/pystack/_pystack/version.cpp @@ -351,6 +351,92 @@ py_runtimev313() }; } +template +constexpr py_runtime_v +py_runtimev314() +{ + return { + sizeof(T), + {}, + {}, + {}, + {}, + {offsetof(T, debug_offsets.cookie)}, + {offsetof(T, debug_offsets.version)}, + {offsetof(T, debug_offsets.free_threaded)}, + {offsetof(T, debug_offsets.runtime_state.size)}, + {offsetof(T, debug_offsets.runtime_state.finalizing)}, + {offsetof(T, debug_offsets.runtime_state.interpreters_head)}, + {offsetof(T, debug_offsets.interpreter_state.size)}, + {offsetof(T, debug_offsets.interpreter_state.id)}, + {offsetof(T, debug_offsets.interpreter_state.next)}, + {offsetof(T, debug_offsets.interpreter_state.threads_head)}, + {offsetof(T, debug_offsets.interpreter_state.gc)}, + {offsetof(T, debug_offsets.interpreter_state.imports_modules)}, + {offsetof(T, debug_offsets.interpreter_state.sysdict)}, + {offsetof(T, debug_offsets.interpreter_state.builtins)}, + {offsetof(T, debug_offsets.interpreter_state.ceval_gil)}, + {offsetof(T, debug_offsets.interpreter_state.gil_runtime_state)}, + {offsetof(T, debug_offsets.interpreter_state.gil_runtime_state_enabled)}, + {offsetof(T, debug_offsets.interpreter_state.gil_runtime_state_locked)}, + {offsetof(T, debug_offsets.interpreter_state.gil_runtime_state_holder)}, + {offsetof(T, debug_offsets.thread_state.size)}, + {offsetof(T, debug_offsets.thread_state.prev)}, + {offsetof(T, debug_offsets.thread_state.next)}, + {offsetof(T, debug_offsets.thread_state.interp)}, + {offsetof(T, debug_offsets.thread_state.current_frame)}, + {offsetof(T, debug_offsets.thread_state.thread_id)}, + {offsetof(T, debug_offsets.thread_state.native_thread_id)}, + {offsetof(T, debug_offsets.thread_state.datastack_chunk)}, + {offsetof(T, debug_offsets.thread_state.status)}, + {offsetof(T, debug_offsets.interpreter_frame.size)}, + {offsetof(T, debug_offsets.interpreter_frame.previous)}, + {offsetof(T, debug_offsets.interpreter_frame.executable)}, + {offsetof(T, debug_offsets.interpreter_frame.instr_ptr)}, + {offsetof(T, debug_offsets.interpreter_frame.localsplus)}, + {offsetof(T, debug_offsets.interpreter_frame.owner)}, + {offsetof(T, debug_offsets.code_object.size)}, + {offsetof(T, debug_offsets.code_object.filename)}, + {offsetof(T, debug_offsets.code_object.name)}, + {offsetof(T, debug_offsets.code_object.qualname)}, + {offsetof(T, debug_offsets.code_object.linetable)}, + {offsetof(T, debug_offsets.code_object.firstlineno)}, + {offsetof(T, debug_offsets.code_object.argcount)}, + {offsetof(T, debug_offsets.code_object.localsplusnames)}, + {offsetof(T, debug_offsets.code_object.localspluskinds)}, + {offsetof(T, debug_offsets.code_object.co_code_adaptive)}, + {offsetof(T, debug_offsets.pyobject.size)}, + {offsetof(T, debug_offsets.pyobject.ob_type)}, + {offsetof(T, debug_offsets.type_object.size)}, + {offsetof(T, debug_offsets.type_object.tp_name)}, + {offsetof(T, debug_offsets.type_object.tp_repr)}, + {offsetof(T, debug_offsets.type_object.tp_flags)}, + {offsetof(T, debug_offsets.tuple_object.size)}, + {offsetof(T, debug_offsets.tuple_object.ob_item)}, + {offsetof(T, debug_offsets.tuple_object.ob_size)}, + {offsetof(T, debug_offsets.list_object.size)}, + {offsetof(T, debug_offsets.list_object.ob_item)}, + {offsetof(T, debug_offsets.list_object.ob_size)}, + {offsetof(T, debug_offsets.dict_object.size)}, + {offsetof(T, debug_offsets.dict_object.ma_keys)}, + {offsetof(T, debug_offsets.dict_object.ma_values)}, + {offsetof(T, debug_offsets.float_object.size)}, + {offsetof(T, debug_offsets.float_object.ob_fval)}, + {offsetof(T, debug_offsets.long_object.size)}, + {offsetof(T, debug_offsets.long_object.lv_tag)}, + {offsetof(T, debug_offsets.long_object.ob_digit)}, + {offsetof(T, debug_offsets.bytes_object.size)}, + {offsetof(T, debug_offsets.bytes_object.ob_size)}, + {offsetof(T, debug_offsets.bytes_object.ob_sval)}, + {offsetof(T, debug_offsets.unicode_object.size)}, + {offsetof(T, debug_offsets.unicode_object.state)}, + {offsetof(T, debug_offsets.unicode_object.length)}, + {offsetof(T, debug_offsets.unicode_object.asciiobject_size)}, + {offsetof(T, debug_offsets.gc.size)}, + {offsetof(T, debug_offsets.gc.collecting)}, + }; +} + template constexpr py_type_v py_type() @@ -723,25 +809,25 @@ python_v python_v3_13 = { // ---- Python 3.14 ------------------------------------------------------------ python_v python_v3_14 = { - py_tuple(), - py_list(), - py_dict(), + {}, + {}, + {}, py_dictkeys(), py_dictvalues(), - py_float(), - py_long<_PyLongObject>(), - py_bytes(), - py_unicode(), - py_object(), - py_type(), - py_codev311(), - py_framev314(), - py_threadv313(), - py_isv312(), - py_runtimev313(), - py_gc(), + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + py_runtimev314(), + {}, py_cframe(), - py_gilruntimestate(), + {}, }; // ----------------------------------------------------------------------------- @@ -749,25 +835,25 @@ python_v python_v3_14 = { // ---- Python 3.15 ------------------------------------------------------------ python_v python_v3_15 = { - py_tuple(), - py_list(), - py_dict(), + {}, + {}, + {}, py_dictkeys(), py_dictvalues(), - py_float(), - py_long<_PyLongObject>(), - py_bytes(), - py_unicode(), - py_object(), - py_type(), - py_codev311(), - py_framev314(), - py_threadv313(), - py_isv312(), - py_runtimev313(), - py_gc(), + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + py_runtimev314(), + {}, py_cframe(), - py_gilruntimestate(), + {}, }; // -----------------------------------------------------------------------------