14#include <frameobject.h>
17#ifdef WITH_PYTHON_MODULE
18# include "pylifecycle.h"
29#ifdef WITH_PYTHON_MODULE
93static int bpy_timer_count = 0;
95static double bpy_timer;
97static double bpy_timer_run;
99static double bpy_timer_run_tot;
122 *gilstate = PyGILState_Ensure();
129 if (bpy_timer_count == 0) {
132 bpy_timer_run = bpy_timer_run_tot = 0.0;
146 PyGILState_Release(*gilstate);
150 fprintf(stderr,
"ERROR: Python context internal state bug. this should not happen!\n");
176 const char *context_members[],
177 uint context_members_len)
179 PyGILState_STATE gilstate;
182 gilstate = PyGILState_Ensure();
186 if (*dict_p == dict_orig) {
187 *dict_p = PyDict_Copy(
static_cast<PyObject *
>(dict_orig));
190 PyObject *dict =
static_cast<PyObject *
>(*dict_p);
195 for (
uint i = 0;
i < context_members_len;
i++) {
196 PyObject *key = PyUnicode_FromString(context_members[
i]);
199#if PY_VERSION_HEX >= 0x030d0000
200 switch (PyDict_Pop(dict, key, &item)) {
213 item = _PyDict_Pop(dict, key, Py_None);
221 PyGILState_Release(gilstate);
228 PyGILState_STATE gilstate;
232 gilstate = PyGILState_Ensure();
239 PyGILState_Release(gilstate);
249 PyObject *
mod = PyImport_ImportModuleLevel(
"bpy",
nullptr,
nullptr,
nullptr, 0);
273#ifdef WITH_AUDASPACE_PY
280static PyObject *CCL_initPython()
311#ifdef WITH_AUDASPACE_PY
315 {
"_cycles", CCL_initPython},
325#ifndef WITH_PYTHON_MODULE
338 fputs(
"Internal error initializing Python!\n", stderr);
340 Py_ExitStatusException(
status);
347#ifndef WITH_PYTHON_MODULE
348 BLI_assert_msg(Py_IsInitialized() == 0,
"Python has already been initialized");
352 PyPreConfig preconfig;
358 "Initializing %s support for the systems Python environment such as 'PYTHONPATH' and "
359 "the user-site directory.",
363 PyPreConfig_InitPythonConfig(&preconfig);
369 PyPreConfig_InitIsolatedConfig(&preconfig);
385 preconfig.utf8_mode =
true;
390 status = Py_PreInitialize(&preconfig);
401 bool has_python_executable =
false;
404 PyConfig_InitPythonConfig(&config);
409 PyConfig_InitIsolatedConfig(&config);
414 config.install_signal_handlers = 1;
419 config.pathconfig_warnings = 0;
425 bool show_python_warnings =
false;
432 show_python_warnings =
true;
435 if (show_python_warnings) {
441 PyWideStringList_Append(&config.warnoptions,
L"default");
456 config.parse_argv = 0;
457 status = PyConfig_SetBytesArgv(&config, argc, (
char *
const *)argv);
467 status = PyConfig_SetBytesString(&config, &config.program_name, program_path);
476 program_path,
sizeof(program_path), PY_MAJOR_VERSION, PY_MINOR_VERSION))
478 status = PyConfig_SetBytesString(&config, &config.executable, program_path);
480 has_python_executable =
true;
485 "Unable to find the Python binary, "
486 "the multiprocessing module may not be functional!\n");
494 if (py_path_bundle.has_value()) {
500 if (strchr(py_path_bundle->c_str(),
':')) {
502 "Warning! Blender application is located in a path containing ':' or '/' chars\n"
503 "This may make Python import function fail\n");
507 status = PyConfig_SetBytesString(&config, &config.home, py_path_bundle->c_str());
510# ifdef PYTHON_SSL_CERT_FILE
512 const char *ssl_cert_file_env =
"SSL_CERT_FILE";
513 if (
BLI_getenv(ssl_cert_file_env) ==
nullptr) {
514 const char *ssl_cert_file_suffix = PYTHON_SSL_CERT_FILE;
517 ssl_cert_file,
sizeof(ssl_cert_file), py_path_bundle->c_str(), ssl_cert_file_suffix);
524# if defined(__APPLE__) || defined(_WIN32)
526 "Bundled Python not found and is expected on this platform "
527 "(the 'install' target may have not been built)\n");
533 status = Py_InitializeFromConfig(&config);
534 PyConfig_Clear(&config);
538 if (!has_python_executable) {
539 PySys_SetObject(
"executable", Py_None);
546 Py_DECREF(PyImport_ImportModule(
"threading"));
564#ifdef WITH_PYTHON_MODULE
567 struct _inittab *inittab_item;
568 PyObject *sys_modules = PyImport_GetModuleDict();
571 PyObject *
mod = inittab_item->initfunc();
573 PyDict_SetItemString(sys_modules, inittab_item->name,
mod);
591#ifndef WITH_PYTHON_MODULE
596 PyEval_ReleaseThread(PyGILState_GetThisThreadState());
600#ifdef WITH_PYTHON_MODULE
602 const char *imports[] = {
"atexit",
"addon_utils",
nullptr};
609#ifndef WITH_PYTHON_MODULE
610 BLI_assert_msg(Py_IsInitialized() != 0,
"Python must be initialized");
614 PyGILState_STATE gilstate = PyGILState_Ensure();
637#ifndef WITH_PYTHON_MODULE
641 if (do_python_exit) {
646 PyGILState_Release(gilstate);
647 (void)do_python_exit;
655 printf(
"tot exec: %d, ", bpy_timer_count);
656 printf(
"tot run: %.4fsec, ", bpy_timer_run_tot);
657 if (bpy_timer_count > 0) {
658 printf(
"average run: %.6fsec, ", (bpy_timer_run_tot / bpy_timer_count));
661 if (bpy_timer > 0.0) {
662 printf(
"tot usage %.4f%%", (bpy_timer_run_tot / bpy_timer) * 100.0);
671 BLI_assert_msg(Py_IsInitialized() != 0,
"Python must be initialized");
675 G.autoexec_fail[0] =
'\0';
695 fputs(
"\n# Python backtrace\n", fp);
701 PyFrameObject *frame = PyEval_GetFrame();
702 if (frame ==
nullptr) {
706 PyCodeObject *code = PyFrame_GetCode(frame);
707 const int line = PyFrame_GetLineNumber(frame);
708 const char *filepath = PyUnicode_AsUTF8(code->co_filename);
709 const char *funcname = PyUnicode_AsUTF8(code->co_name);
710 fprintf(fp,
" File \"%s\", line %d in %s\n", filepath, line, funcname);
711 }
while ((frame = PyFrame_GetBack(frame)));
716 const PyGILState_STATE gilstate = PyGILState_Ensure();
718 PyGILState_Release(gilstate);
723 const PyGILState_STATE gilstate = PyGILState_Ensure();
724 const bool do_invalidate = (Py_REFCNT((PyObject *)pyob_ptr) > 1);
729 PyGILState_Release(gilstate);
734 PyGILState_STATE gilstate;
739 if (bmain ==
nullptr) {
759 printf(
"scripts disabled for \"%s\", skipping '%s'\n",
782 if (!(use_logging_info || use_logging_member)) {
787 const char *location = python_location ? python_location->c_str() :
"unknown:0";
789 if (use_logging_info) {
792 else if (use_logging_member) {
802 PyGILState_STATE gilstate;
805 gilstate = PyGILState_Ensure();
814 item = PyDict_GetItemString(pyctx, member);
816 if (item ==
nullptr) {
819 else if (item == Py_None) {
830 else if (PySequence_Check(item)) {
831 PyObject *seq_fast = PySequence_Fast(item,
"bpy_context_get sequence conversion");
832 if (seq_fast ==
nullptr) {
836 const int len = PySequence_Fast_GET_SIZE(seq_fast);
837 PyObject **seq_fast_items = PySequence_Fast_ITEMS(seq_fast);
840 for (
i = 0;
i <
len;
i++) {
841 PyObject *list_item = seq_fast_items[
i];
849 std::string message = std::string(
"'") + member +
850 "' list item not a valid type in sequence type '" +
851 Py_TYPE(list_item)->tp_name +
"'";
864 std::string message = std::string(
"'") + member +
"' not a valid type";
870 PyGILState_Release(gilstate);
882 if (!Py_IsInitialized()) {
886 PyGILState_STATE gilstate;
888 std::optional<std::string>
result = std::nullopt;
890 gilstate = PyGILState_Ensure();
893 const char *filename =
nullptr;
898 result = std::string(filename) +
":" + std::to_string(lineno);
902 PyGILState_Release(gilstate);
907#ifdef WITH_PYTHON_MODULE
922static void main_python_exit_ensure();
924static void bpy_detect_exit_singleton_cleanup(PyObject * )
926 main_python_exit_ensure();
929static void bpy_detect_exit_singleton_add_to_module(PyObject *
mod)
931 static PyObject *singleton =
nullptr;
938 const char *bpy_detect_exit_singleton_id =
"_bpy_detect_exit_singleton";
939 if (singleton ==
nullptr) {
942 void *pointer =
reinterpret_cast<void *
>(
uintptr_t(-1));
943 singleton = PyCapsule_New(
944 pointer, bpy_detect_exit_singleton_id, bpy_detect_exit_singleton_cleanup);
948 Py_INCREF(singleton);
950 PyModule_AddObject(
mod, bpy_detect_exit_singleton_id, singleton);
957static void bpy_module_free(
void *
mod);
960extern int main_python_enter(
int argc,
const char **argv);
961extern void main_python_exit();
963static void main_python_exit_ensure()
965 static bool exit =
false;
973static struct PyModuleDef bpy_proxy_def = {
992static void bpy_module_delay_init(PyObject *bpy_proxy)
998 PyObject *filepath_obj = PyModule_GetFilenameObject(bpy_proxy);
1001 const char *filepath_rel = PyUnicode_AsUTF8(filepath_obj);
1002 char filepath_abs[1024];
1004 STRNCPY(filepath_abs, filepath_rel);
1008 argv[0] = filepath_abs;
1011 main_python_enter(argc, argv);
1014 PyDict_Update(PyModule_GetDict(bpy_proxy), PyModule_GetDict(
bpy_package_py));
1023 const char *bpy_modules_array[] = {
1030 PyObject *sys_modules = PyImport_GetModuleDict();
1032 PyObject *
mod = PyDict_GetItemString(sys_modules, bpy_modules_array[
i]);
1034 bpy_detect_exit_singleton_add_to_module(
mod);
1043static bool bpy_module_ensure_compatible_version()
1049 const uint version_runtime = Py_Version;
1051 uint version_compile_major = PY_VERSION_HEX >> 24;
1052 uint version_compile_minor = ((PY_VERSION_HEX & 0x00ff0000) >> 16);
1053 uint version_runtime_major = version_runtime >> 24;
1054 uint version_runtime_minor = ((version_runtime & 0x00ff0000) >> 16);
1055 if ((version_compile_major != version_runtime_major) ||
1056 (version_compile_minor != version_runtime_minor))
1058 PyErr_Format(PyExc_ImportError,
1059 "The version of \"bpy\" was compiled with: "
1060 "(%u.%u) is incompatible with: (%u.%u) used by the interpreter!",
1061 version_compile_major,
1062 version_compile_minor,
1063 version_runtime_major,
1064 version_runtime_minor);
1070static void dealloc_obj_dealloc(PyObject *
self);
1072static PyTypeObject dealloc_obj_Type;
1075static void dealloc_obj_dealloc(PyObject *
self)
1077 bpy_module_delay_init(((dealloc_obj *)
self)->
mod);
1081 dealloc_obj_Type.tp_free(
self);
1084PyMODINIT_FUNC PyInit_bpy();
1086PyMODINIT_FUNC PyInit_bpy()
1088 if (!bpy_module_ensure_compatible_version()) {
1092 PyObject *bpy_proxy = PyModule_Create(&bpy_proxy_def);
1112 dealloc_obj_Type.tp_name =
"dealloc_obj";
1113 dealloc_obj_Type.tp_basicsize =
sizeof(dealloc_obj);
1114 dealloc_obj_Type.tp_dealloc = dealloc_obj_dealloc;
1115 dealloc_obj_Type.tp_flags = Py_TPFLAGS_DEFAULT;
1117 if (PyType_Ready(&dealloc_obj_Type) < 0) {
1121 dob = (dealloc_obj *)dealloc_obj_Type.tp_alloc(&dealloc_obj_Type, 0);
1122 dob->mod = bpy_proxy;
1123 PyModule_AddObject(bpy_proxy,
"__file__", (PyObject *)dob);
1128static void bpy_module_free(
void * )
1130 main_python_exit_ensure();
1138 const char *kwlist[] = {
1139 "False",
"None",
"True",
"and",
"as",
"assert",
"async",
"await",
"break",
1140 "class",
"continue",
"def",
"del",
"elif",
"else",
"except",
"finally",
"for",
1141 "from",
"global",
"if",
"import",
"in",
"is",
"lambda",
"nonlocal",
"not",
1142 "or",
"pass",
"raise",
"return",
"try",
"while",
"with",
"yield",
nullptr,
1145 for (
int i = 0; kwlist[
i];
i++) {
PyObject * AUD_initPython(void)
const char * BKE_appdir_program_path() ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL
bool BKE_appdir_program_python_search(char *program_filepath, size_t program_filepath_maxncpy, int version_major, int version_minor) ATTR_NONNULL(1)
std::optional< std::string > BKE_appdir_folder_id(int folder_id, const char *subfolder) ATTR_WARN_UNUSED_RESULT
void CTX_data_type_set(bContextDataResult *result, ContextDataType type)
void CTX_wm_operator_poll_msg_clear(bContext *C)
Main * CTX_data_main(const bContext *C)
void CTX_data_list_add_ptr(bContextDataResult *result, const PointerRNA *ptr)
void CTX_data_pointer_set_ptr(bContextDataResult *result, const PointerRNA *ptr)
bool CTX_member_logging_get(const bContext *C)
void * CTX_py_dict_get(const bContext *C)
@ G_FLAG_SCRIPT_AUTOEXEC_FAIL_QUIET
@ G_FLAG_SCRIPT_AUTOEXEC_FAIL
const char * BKE_main_blendfile_path(const Main *bmain) ATTR_NONNULL()
bool text_check_identifier_nodigit(char ch)
bool text_check_identifier(char ch)
#define BLI_assert_unreachable()
#define BLI_assert_msg(a, msg)
void BLI_setenv(const char *env, const char *val) ATTR_NONNULL(1)
#define BLI_path_join(...)
const char * BLI_getenv(const char *env) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT
bool BLI_path_abs_from_cwd(char *path, size_t path_maxncpy) ATTR_NONNULL(1)
char * STRNCPY(char(&dst)[N], const char *src)
#define SNPRINTF_UTF8(dst, format,...)
int BLI_thread_is_main(void)
Platform independent time functions.
double BLI_time_now_seconds(void)
void BPY_app_handlers_reset(bool do_all)
struct CLG_LogRef * BPY_LOG_RNA
bool bool BPY_run_text(bContext *C, Text *text, ReportList *reports, bool do_jump) ATTR_NONNULL(1
bool BPY_run_string_eval(bContext *C, const char *imports[], const char *expr)
void * CCL_python_module_init(void)
#define CLOG_DEBUG(clg_ref,...)
#define CLOG_AT_LEVEL_NOCHECK(clg_ref, verbose_level,...)
#define CLOG_CHECK(clg_ref, verbose_level,...)
#define CLG_LOGREF_DECLARE_GLOBAL(var, id)
#define CLOG_INFO(clg_ref,...)
PyMODINIT_FUNC BPyInit_bl_math()
PyObject * BPyInit_bmesh()
PyObject * BPyInit_bmesh_geometry()
PyObject * BPyInit_bmesh_types()
PyObject * BPyInit_bmesh_utils()
PyObject * bpy_package_py
void BPy_init_modules(bContext *C)
void BPY_atexit_unregister()
void BPY_atexit_register()
struct CLG_LogRef * BPY_LOG_INTERFACE
void BPY_app_translations_end()
int text_check_identifier_nodigit_unicode(const uint ch)
bool BPY_string_is_keyword(const char *str)
void BPY_python_use_system_env()
void BPY_context_dict_clear_members_array(void **dict_p, void *dict_orig, const char *context_members[], uint context_members_len)
CLG_LogRef * BKE_LOG_CONTEXT
int text_check_identifier_unicode(const uint ch)
std::optional< std::string > BPY_python_current_file_and_line()
void BPY_modules_update()
bContext * BPY_context_get()
void bpy_context_set(bContext *C, PyGILState_STATE *gilstate)
void BPY_context_set(bContext *C)
static void pystatus_exit_on_error(const PyStatus &status)
void BPY_DECREF_RNA_INVALIDATE(void *pyob_ptr)
void BPY_python_backtrace(FILE *fp)
static void bpy_context_end(bContext *C)
void BPY_python_reset(bContext *C)
static bool py_use_system_env
void BPY_context_update(bContext *C)
void BPY_python_end(const bool do_python_exit)
static _inittab bpy_internal_modules[]
bool BPY_python_use_system_env_get()
bool BPY_context_member_get(bContext *C, const char *member, bContextDataResult *result)
void BPY_text_free_code(Text *text)
static void bpy_context_log_member_error(const bContext *C, const char *message)
void bpy_context_clear(bContext *, const PyGILState_STATE *gilstate)
void BPY_modules_load_user(bContext *C)
void BPY_python_start(bContext *C, int argc, const char **argv)
void BPY_DECREF(void *pyob_ptr)
void bpy_intern_string_exit()
void bpy_intern_string_init()
PyObject * BPyInit__bpy_path()
void BPY_rna_props_clear_all()
void pyrna_invalidate(BPy_DummyPointerRNA *self)
PyObject * BPY_rna_module()
PyObject * BPY_rna_types()
void BPY_update_rna_module()
BPy_StructRNA * bpy_context_module
#define BPy_StructRNA_Check(v)
VecBase< float, D > constexpr mod(VecOp< float, D >, VecOp< float, D >) RET
PyObject * BPyInit_idprop()
PyObject * BPyInit_imbuf()
PyObject * Manta_initPython(void)
PyMODINIT_FUNC PyInit_mathutils()
PyMODINIT_FUNC PyInit_mathutils_geometry()
PyMODINIT_FUNC PyInit_mathutils_kdtree()
PyMODINIT_FUNC PyInit_mathutils_noise()
_W64 unsigned int uintptr_t
bool PyC_IsInterpreterActive()
void PyC_FileAndNum_Safe(const char **r_filename, int *r_lineno)
PyObject * BPyInit_hydra()
header-only compatibility defines.
#define PyThreadState_GetUnchecked