Python 3.14 has moved some functionality into the public API, use the updated names even with older Python versions. Also resolve an error caused by variable reuse with delayed annotation evaluation for TextureProperties_MixIn on startup. Resolve #140695.
64 lines
1.8 KiB
C++
64 lines
1.8 KiB
C++
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
/** \file
|
|
* \ingroup pygen
|
|
*
|
|
* This file contains wrapper functions related to global interpreter lock.
|
|
* these functions are slightly different from the original Python API,
|
|
* don't throw SIGABRT even if the thread state is nullptr. */
|
|
|
|
#include <Python.h>
|
|
|
|
#include "python_compat.hh" /* IWYU pragma: keep. */
|
|
|
|
#include "../BPY_extern.hh"
|
|
|
|
BPy_ThreadStatePtr BPY_thread_save()
|
|
{
|
|
/* Use `_PyThreadState_UncheckedGet()` instead of `PyThreadState_Get()`, to avoid a fatal error
|
|
* issued when a thread state is nullptr (the thread state can be nullptr when quitting Blender).
|
|
*
|
|
* `PyEval_SaveThread()` will release the GIL, so this thread has to have the GIL to begin with
|
|
* or badness will ensue. */
|
|
if (PyThreadState_GetUnchecked() && PyGILState_Check()) {
|
|
return (BPy_ThreadStatePtr)PyEval_SaveThread();
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
void BPY_thread_restore(BPy_ThreadStatePtr tstate)
|
|
{
|
|
if (tstate) {
|
|
PyEval_RestoreThread((PyThreadState *)tstate);
|
|
}
|
|
}
|
|
|
|
void BPY_thread_backtrace_print()
|
|
{
|
|
PyThreadState *tstate = PyGILState_GetThisThreadState();
|
|
|
|
if (tstate) {
|
|
PyFrameObject *frame = PyThreadState_GetFrame(tstate);
|
|
|
|
printf(frame ? "Python stack trace:\n" : "No Python stack trace available.\n");
|
|
|
|
while (frame) {
|
|
PyCodeObject *frame_co = PyFrame_GetCode(frame);
|
|
int line = PyFrame_GetLineNumber(frame);
|
|
const char *filename = PyUnicode_AsUTF8(frame_co->co_filename);
|
|
const char *funcname = PyUnicode_AsUTF8(frame_co->co_name);
|
|
printf(" %s:%d %s\n", filename, line, funcname);
|
|
Py_DECREF(frame_co);
|
|
PyFrameObject *frame_back = PyFrame_GetBack(frame);
|
|
Py_DECREF(frame);
|
|
frame = frame_back;
|
|
}
|
|
printf("\n");
|
|
}
|
|
else {
|
|
printf("No Python thread state available.\n");
|
|
}
|
|
}
|