Blender V5.0
bpy_app.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
12
13#include <Python.h>
14
15#include "bpy_app.hh"
16
17#include "bpy_app_alembic.hh"
19#include "bpy_app_ffmpeg.hh"
20#include "bpy_app_ocio.hh"
21#include "bpy_app_oiio.hh"
22#include "bpy_app_opensubdiv.hh"
23#include "bpy_app_openvdb.hh"
24#include "bpy_app_sdl.hh"
25
26#include "bpy_app_usd.hh"
27
29
30#include "bpy_app_handlers.hh"
31#include "bpy_capi_utils.hh"
32#include "bpy_driver.hh"
33
34#include "BPY_extern_python.hh" /* For #BPY_python_app_help_text_fn. */
35
36/* modules */
37#include "bpy_app_icons.hh"
38#include "bpy_app_timers.hh"
39
40#include "BLI_utildefines.h"
41
42#include "BKE_appdir.hh"
43#include "BKE_blender_version.h"
44#include "BKE_global.hh"
45#include "BKE_main.hh"
46
47#include "GPU_shader.hh"
48
49#include "UI_interface_icons.hh"
50
51#include "ED_undo.hh"
52#include "MEM_guardedalloc.h"
53
54#include "RNA_enum_types.hh" /* For `rna_enum_wm_job_type_items`. */
55
56/* for notifiers */
57#include "WM_api.hh"
58#include "WM_types.hh"
59
62#include "../generic/python_compat.hh" /* IWYU pragma: keep. */
63
64#ifdef BUILD_DATE
65extern "C" char build_date[];
66extern "C" char build_time[];
68extern "C" char build_commit_date[];
69extern "C" char build_commit_time[];
70extern "C" char build_hash[];
71extern "C" char build_branch[];
72extern "C" char build_platform[];
73extern "C" char build_type[];
74extern "C" char build_cflags[];
75extern "C" char build_cxxflags[];
76extern "C" char build_linkflags[];
77extern "C" char build_system[];
78#endif
79
80static PyTypeObject BlenderAppType;
81
82static PyStructSequence_Field app_info_fields[] = {
83 {"version",
84 "The Blender version as a tuple of 3 numbers (major, minor, micro). eg. (4, 3, 1)\n"
85 "\n"
86 ":type: tuple[int, int, int]\n"},
87 {"version_file",
88 "The Blender File version, as a tuple of 3 numbers (major, minor, file sub-version), that "
89 "will be used to save a .blend file. The last item in this tuple indicates the file "
90 "sub-version, which is different from the release micro version (the last item of the "
91 "``bpy.app.version`` tuple). The file sub-version can be incremented multiple times while a "
92 "Blender version is under development. This value is, and should be, used for handling "
93 "compatibility changes between Blender versions\n"
94 "\n"
95 ":type: tuple[int, int, int]\n"},
96 {"version_string",
97 "The Blender version formatted as a string\n"
98 "\n"
99 ":type: str\n"},
100 {"version_cycle",
101 "The release status of this build alpha/beta/rc/release\n"
102 "\n"
103 ":type: str\n"},
104 {"background",
105 "Boolean, True when blender is running without a user interface (started with -b)\n"
106 "\n"
107 ":type: bool\n"},
108 {"module",
109 "Boolean, True when running Blender as a python module\n"
110 "\n"
111 ":type: bool\n"},
112 {"factory_startup",
113 "Boolean, True when blender is running with --factory-startup\n"
114 "\n"
115 ":type: bool\n"},
116 {"portable",
117 "Boolean, True unless blender was built to reference absolute paths (on UNIX).\n"
118 "\n"
119 ":type: bool\n"},
120
121 /* buildinfo */
122 {"build_date",
123 "The date this blender instance was built\n"
124 "\n"
125 ":type: bytes\n"},
126 {"build_time",
127 "The time this blender instance was built\n"
128 "\n"
129 ":type: bytes\n"},
130 {"build_commit_timestamp",
131 "The unix timestamp of commit this blender instance was built\n"
132 "\n"
133 ":type: int\n"},
134 {"build_commit_date",
135 "The date of commit this blender instance was built\n"
136 "\n"
137 ":type: bytes\n"},
138 {"build_commit_time",
139 "The time of commit this blender instance was built\n"
140 "\n"
141 ":type: bytes\n"},
142 {"build_hash",
143 "The commit hash this blender instance was built with\n"
144 "\n"
145 ":type: bytes\n"},
146 {"build_branch",
147 "The branch this blender instance was built from\n"
148 "\n"
149 ":type: bytes\n"},
150 {"build_platform",
151 "The platform this blender instance was built for\n"
152 "\n"
153 ":type: bytes\n"},
154 {"build_type",
155 "The type of build (Release, Debug)\n"
156 "\n"
157 ":type: bytes\n"},
158 {"build_cflags",
159 "C compiler flags\n"
160 "\n"
161 ":type: bytes\n"},
162 {"build_cxxflags",
163 "C++ compiler flags\n"
164 "\n"
165 ":type: bytes\n"},
166 {"build_linkflags",
167 "Binary linking flags\n"
168 "\n"
169 ":type: bytes\n"},
170 {"build_system",
171 "Build system used\n"
172 "\n"
173 ":type: bytes\n"},
174
175 /* submodules */
176 {"alembic", "Alembic library information backend"},
177 {"usd", "USD library information backend"},
178 {"ffmpeg", "FFmpeg library information backend"},
179 {"ocio", "OpenColorIO library information backend"},
180 {"oiio", "OpenImageIO library information backend"},
181 {"opensubdiv", "OpenSubdiv library information backend"},
182 {"openvdb", "OpenVDB library information backend"},
183 {"sdl", "SDL library information backend"},
184 {"build_options", "A set containing most important enabled optional build features"},
185 {"handlers", "Application handler callbacks"},
186 {"translations", "Application and addons internationalization API"},
187
188 /* Modules (not struct sequence). */
189 {"icons", "Manage custom icons"},
190 {"timers", "Manage timers"},
191 {nullptr},
192};
193
195 /* Wrap. */
196 bpy_app_doc,
197 "This module contains application values that remain unchanged during runtime.\n");
198static PyStructSequence_Desc app_info_desc = {
199 /*name*/ "bpy.app",
200 /*doc*/ bpy_app_doc,
201 /*fields*/ app_info_fields,
202 /*n_in_sequence*/ ARRAY_SIZE(app_info_fields) - 1,
203};
204
205static PyObject *make_app_info()
206{
207 PyObject *app_info;
208 int pos = 0;
209
210 app_info = PyStructSequence_New(&BlenderAppType);
211 if (app_info == nullptr) {
212 return nullptr;
213 }
214#define SetIntItem(flag) PyStructSequence_SET_ITEM(app_info, pos++, PyLong_FromLong(flag))
215#define SetStrItem(str) PyStructSequence_SET_ITEM(app_info, pos++, PyUnicode_FromString(str))
216#define SetBytesItem(str) PyStructSequence_SET_ITEM(app_info, pos++, PyBytes_FromString(str))
217#define SetObjItem(obj) PyStructSequence_SET_ITEM(app_info, pos++, obj)
218
224
226 SetObjItem(PyBool_FromLong(G.background));
227#ifdef WITH_PYTHON_MODULE
228 SetObjItem(Py_NewRef(Py_True));
229#else
230 SetObjItem(Py_NewRef(Py_False));
231#endif
232 SetObjItem(PyBool_FromLong(G.factory_startup));
233
234#ifdef WITH_INSTALL_PORTABLE
235 SetObjItem(Py_NewRef(Py_True));
236#else
237 SetObjItem(Py_NewRef(Py_False));
238#endif
239
240/* build info, use bytes since we can't assume _any_ encoding:
241 * see patch #30154 for issue */
242#ifdef BUILD_DATE
256#else
257 SetBytesItem("Unknown");
258 SetBytesItem("Unknown");
259 SetIntItem(0);
260 SetBytesItem("Unknown");
261 SetBytesItem("Unknown");
262 SetBytesItem("Unknown");
263 SetBytesItem("Unknown");
264 SetBytesItem("Unknown");
265 SetBytesItem("Unknown");
266 SetBytesItem("Unknown");
267 SetBytesItem("Unknown");
268 SetBytesItem("Unknown");
269 SetBytesItem("Unknown");
270#endif
271
283
284 /* modules */
287
288#undef SetIntItem
289#undef SetStrItem
290#undef SetBytesItem
291#undef SetObjItem
292
293 if (PyErr_Occurred()) {
294 Py_DECREF(app_info);
295 return nullptr;
296 }
297 return app_info;
298}
299
300/* a few getsets because it makes sense for them to be in bpy.app even though
301 * they are not static */
302
304 /* Wrap. */
305 bpy_app_debug_doc,
306 "Boolean, for debug info "
307 "(started with ``--debug`` / ``--debug-*`` matching this attribute name).\n"
308 "\n"
309 ":type: bool\n");
310static PyObject *bpy_app_debug_get(PyObject * /*self*/, void *closure)
311{
312 const int flag = POINTER_AS_INT(closure);
313 return PyBool_FromLong(G.debug & flag);
314}
315
316static int bpy_app_debug_set(PyObject * /*self*/, PyObject *value, void *closure)
317{
318 const int flag = POINTER_AS_INT(closure);
319 const int param = PyObject_IsTrue(value);
320
321 if (param == -1) {
322 PyErr_SetString(PyExc_TypeError, "bpy.app.debug can only be True/False");
323 return -1;
324 }
325
326 if (param) {
327 G.debug |= flag;
328 }
329 else {
330 G.debug &= ~flag;
331 }
332
333 return 0;
334}
335
337 /* Wrap. */
338 bpy_app_internet_offline_doc,
339 "Boolean, true when internet access is allowed by Blender & 3rd party scripts "
340 "(read-only).\n"
341 "\n"
342 ":type: bool\n");
344 /* Wrap. */
345 bpy_app_internet_offline_override_doc,
346 "Boolean, true when internet access preference is overridden by the command line "
347 "(read-only).\n"
348 "\n"
349 ":type: bool\n");
351 /* Wrap. */
352 bpy_app_global_flag_doc,
353 "Boolean, for application behavior "
354 "(started with ``--enable-*`` matching this attribute name)\n"
355 "\n"
356 ":type: bool\n");
357
359 /* Wrap. */
360 bpy_app_autoexec_fail_doc,
361 "Boolean, True when auto-execution of scripts failed (read-only).\n"
362 "\n"
363 ":type: bool\n");
365 /* Wrap. */
366 bpy_app_autoexec_fail_quiet_doc,
367 "Boolean, True when auto-execution failure should be quiet, set after the warning is shown "
368 "once for the current blend file (read-only).\n"
369 "\n"
370 ":type: bool\n");
371
372static PyObject *bpy_app_global_flag_get(PyObject * /*self*/, void *closure)
373{
374 const int flag = POINTER_AS_INT(closure);
375 return PyBool_FromLong(G.f & flag);
376}
377
378static int bpy_app_global_flag_set(PyObject * /*self*/, PyObject *value, void *closure)
379{
380 const int flag = POINTER_AS_INT(closure);
381 const int param = PyObject_IsTrue(value);
382
383 if (param == -1) {
384 PyErr_SetString(PyExc_TypeError, "bpy.app.use_* can only be True/False");
385 return -1;
386 }
387
388 if (param) {
389 G.f |= flag;
390 }
391 else {
392 G.f &= ~flag;
393 }
394
395 return 0;
396}
397
398static int bpy_app_global_flag_set__only_disable(PyObject * /*self*/,
399 PyObject *value,
400 void *closure)
401{
402 const int param = PyObject_IsTrue(value);
403 if (param == 1) {
404 PyErr_SetString(PyExc_ValueError, "This bpy.app.use_* option can only be disabled");
405 return -1;
406 }
407 return bpy_app_global_flag_set(nullptr, value, closure);
408}
409
411 /* Wrap. */
412 bpy_app_debug_value_doc,
413 "Short, number which can be set to non-zero values for testing purposes.\n"
414 "\n"
415 ":type: int\n");
416static PyObject *bpy_app_debug_value_get(PyObject * /*self*/, void * /*closure*/)
417{
418 return PyLong_FromLong(G.debug_value);
419}
420
421static int bpy_app_debug_value_set(PyObject * /*self*/, PyObject *value, void * /*closure*/)
422{
423 const short param = PyC_Long_AsI16(value);
424
425 if (param == -1 && PyErr_Occurred()) {
426 PyC_Err_SetString_Prefix(PyExc_TypeError,
427 "bpy.app.debug_value can only be set to a whole number");
428 return -1;
429 }
430
431 G.debug_value = param;
432
434
435 return 0;
436}
437
439 /* Wrap. */
440 bpy_app_tempdir_doc,
441 "String, the temp directory used by blender (read-only).\n"
442 "\n"
443 ":type: str\n");
444static PyObject *bpy_app_tempdir_get(PyObject * /*self*/, void * /*closure*/)
445{
447}
448
450 /* Wrap. */
451 bpy_app_driver_dict_doc,
452 "Dictionary for drivers namespace, editable in-place, reset on file load (read-only).\n"
453 "\n"
454 ":type: dict[str, Any]\n");
455static PyObject *bpy_app_driver_dict_get(PyObject * /*self*/, void * /*closure*/)
456{
457 if (bpy_pydriver_Dict == nullptr) {
458 if (bpy_pydriver_create_dict() != 0) {
459 PyErr_SetString(PyExc_RuntimeError, "bpy.app.driver_namespace failed to create dictionary");
460 return nullptr;
461 }
462 }
463
464 return Py_NewRef(bpy_pydriver_Dict);
465}
466
468 /* Wrap. */
469 bpy_app_preview_render_size_doc,
470 "Reference size for icon/preview renders (read-only).\n"
471 "\n"
472 ":type: int\n");
473static PyObject *bpy_app_preview_render_size_get(PyObject * /*self*/, void *closure)
474{
475 return PyLong_FromLong(
477}
478
480 /* Wrap. */
481 bpy_app_autoexec_fail_message_doc,
482 "String, message describing the auto-execution failure (read-only).\n"
483 "\n"
484 ":type: str\n");
485
486static PyObject *bpy_app_autoexec_fail_message_get(PyObject * /*self*/, void * /*closure*/)
487{
488 return PyC_UnicodeFromBytes(G.autoexec_fail);
489}
490
492 /* Wrap. */
493 bpy_app_python_args_doc,
494 "Leading arguments to use when calling Python directly (via ``sys.executable``). "
495 "These arguments match settings Blender uses to "
496 "ensure Python runs with a compatible environment (read-only).\n"
497 "\n"
498 ":type: tuple[str, ...]\n");
499static PyObject *bpy_app_python_args_get(PyObject * /*self*/, void * /*closure*/)
500{
501 const char *args[1];
502 int args_num = 0;
504 /* Isolated Python environment. */
505 args[args_num++] = "-I";
506 }
507 return PyC_Tuple_PackArray_String(args, args_num);
508}
509
511 /* Wrap. */
512 bpy_app_binary_path_doc,
513 "The location of Blender's executable, useful for utilities that open new instances. "
514 "Read-only unless Blender is built as a Python module - in this case the value is "
515 "an empty string which script authors may point to a Blender binary.\n"
516 "\n"
517 ":type: str\n");
518static PyObject *bpy_app_binary_path_get(PyObject * /*self*/, void * /*closure*/)
519{
521}
522
523static int bpy_app_binary_path_set(PyObject * /*self*/, PyObject *value, void * /*closure*/)
524{
525#ifndef WITH_PYTHON_MODULE
526 PyErr_SetString(PyExc_AttributeError,
527 "bpy.app.binary_path is only writable when built as a Python module");
528 return -1;
529#endif
530 PyObject *value_coerce = nullptr;
531 const char *filepath = PyC_UnicodeAsBytes(value, &value_coerce);
532 if (filepath == nullptr) {
533 PyErr_Format(PyExc_ValueError, "expected a string or bytes, got %s", Py_TYPE(value)->tp_name);
534 return -1;
535 }
537 Py_XDECREF(value_coerce);
538 return 0;
539}
540
541static PyGetSetDef bpy_app_getsets[] = {
542 {"debug", bpy_app_debug_get, bpy_app_debug_set, bpy_app_debug_doc, (void *)G_DEBUG},
543 {"debug_freestyle",
546 bpy_app_debug_doc,
547 (void *)G_DEBUG_FREESTYLE},
548 {"debug_python",
551 bpy_app_debug_doc,
552 (void *)G_DEBUG_PYTHON},
553 {"debug_events",
556 bpy_app_debug_doc,
557 (void *)G_DEBUG_EVENTS},
558 {"debug_handlers",
561 bpy_app_debug_doc,
562 (void *)G_DEBUG_HANDLERS},
563 {"debug_wm", bpy_app_debug_get, bpy_app_debug_set, bpy_app_debug_doc, (void *)G_DEBUG_WM},
564 {"debug_depsgraph",
567 bpy_app_debug_doc,
568 (void *)G_DEBUG_DEPSGRAPH},
569 {"debug_depsgraph_build",
572 bpy_app_debug_doc,
574 {"debug_depsgraph_eval",
577 bpy_app_debug_doc,
578 (void *)G_DEBUG_DEPSGRAPH_EVAL},
579 {"debug_depsgraph_tag",
582 bpy_app_debug_doc,
583 (void *)G_DEBUG_DEPSGRAPH_TAG},
584 {"debug_depsgraph_time",
587 bpy_app_debug_doc,
588 (void *)G_DEBUG_DEPSGRAPH_TIME},
589 {"debug_depsgraph_pretty",
592 bpy_app_debug_doc,
594 {"debug_simdata",
597 bpy_app_debug_doc,
598 (void *)G_DEBUG_SIMDATA},
599 {"debug_io", bpy_app_debug_get, bpy_app_debug_set, bpy_app_debug_doc, (void *)G_DEBUG_IO},
600
601 {"use_event_simulate",
604 bpy_app_global_flag_doc,
605 (void *)G_FLAG_EVENT_SIMULATE},
606
607 {"use_userpref_skip_save_on_exit",
610 bpy_app_global_flag_doc,
612
613 {"debug_value",
616 bpy_app_debug_value_doc,
617 nullptr},
618 {"tempdir", bpy_app_tempdir_get, nullptr, bpy_app_tempdir_doc, nullptr},
619 {"driver_namespace", bpy_app_driver_dict_get, nullptr, bpy_app_driver_dict_doc, nullptr},
620
621 {"render_icon_size",
623 nullptr,
624 bpy_app_preview_render_size_doc,
625 (void *)ICON_SIZE_ICON},
626 {"render_preview_size",
628 nullptr,
629 bpy_app_preview_render_size_doc,
630 (void *)ICON_SIZE_PREVIEW},
631
632 {"online_access",
634 nullptr,
635 bpy_app_internet_offline_doc,
636 (void *)G_FLAG_INTERNET_ALLOW},
637 {"online_access_override",
639 nullptr,
640 bpy_app_internet_offline_override_doc,
642
643 /* security */
644 {"autoexec_fail",
646 nullptr,
647 bpy_app_autoexec_fail_doc,
649 {"autoexec_fail_quiet",
651 nullptr,
652 bpy_app_autoexec_fail_quiet_doc,
654 {"autoexec_fail_message",
656 nullptr,
657 bpy_app_autoexec_fail_message_doc,
658 nullptr},
659
660 {"python_args", bpy_app_python_args_get, nullptr, bpy_app_python_args_doc, nullptr},
661
662 /* Support script authors setting the Blender binary path to use, otherwise this value
663 * is not known when built as a Python module. */
664 {"binary_path",
667 bpy_app_binary_path_doc,
668 nullptr},
669
670 {nullptr, nullptr, nullptr, nullptr, nullptr},
671};
672
674 /* Wrap. */
675 bpy_app_is_job_running_doc,
676 ".. staticmethod:: is_job_running(job_type)\n"
677 "\n"
678 " Check whether a job of the given type is running.\n"
679 "\n"
680 " :arg job_type: job type in :ref:`rna_enum_wm_job_type_items`.\n"
681 " :type job_type: str\n"
682 " :return: Whether a job of the given type is currently running.\n"
683 " :rtype: bool\n");
684static PyObject *bpy_app_is_job_running(PyObject * /*self*/, PyObject *args, PyObject *kwds)
685{
686 BPy_EnumProperty_Parse job_type_enum{};
687 job_type_enum.items = rna_enum_wm_job_type_items;
688 job_type_enum.value = 0;
689
690 static const char *_keywords[] = {"job_type", nullptr};
691 static _PyArg_Parser _parser = {
693 "O&" /* `job_type` */
694 ":is_job_running",
695 _keywords,
696 nullptr,
697 };
698 if (!_PyArg_ParseTupleAndKeywordsFast(
699 args, kwds, &_parser, pyrna_enum_value_parse_string, &job_type_enum))
700 {
701 return nullptr;
702 }
703 wmWindowManager *wm = static_cast<wmWindowManager *>(G_MAIN->wm.first);
704 if (job_type_enum.value == WM_JOB_TYPE_SHADER_COMPILATION) {
705 /* Shader compilation no longer uses the WM_job API, so we handle this as a special case
706 * to avoid breaking the Python API. */
707 return PyBool_FromLong(GPU_shader_batch_is_compiling());
708 }
709 return PyBool_FromLong(WM_jobs_has_running_type(wm, job_type_enum.value));
710}
711
712char *(*BPY_python_app_help_text_fn)(bool all) = nullptr;
713
715 /* Wrap. */
716 bpy_app_help_text_doc,
717 ".. staticmethod:: help_text(*, all=False)\n"
718 "\n"
719 " Return the help text as a string.\n"
720 "\n"
721 " :arg all: Return all arguments, "
722 "even those which aren't available for the current platform.\n"
723 " :type all: bool\n"
724 " :return: Help text.\n"
725 " :rtype: str\n");
726static PyObject *bpy_app_help_text(PyObject * /*self*/, PyObject *args, PyObject *kwds)
727{
728 bool all = false;
729 static const char *_keywords[] = {"all", nullptr};
730 static _PyArg_Parser _parser = {
732 "|$" /* Optional keyword only arguments. */
733 "O&" /* `all` */
734 ":help_text",
735 _keywords,
736 nullptr,
737 };
738 if (!_PyArg_ParseTupleAndKeywordsFast(args, kwds, &_parser, PyC_ParseBool, &all)) {
739 return nullptr;
740 }
741
742 char *buf = BPY_python_app_help_text_fn(all);
743 PyObject *result = PyUnicode_FromString(buf);
744 MEM_freeN(buf);
745 return result;
746}
747
748#ifdef __GNUC__
749# ifdef __clang__
750# pragma clang diagnostic push
751# pragma clang diagnostic ignored "-Wcast-function-type"
752# else
753# pragma GCC diagnostic push
754# pragma GCC diagnostic ignored "-Wcast-function-type"
755# endif
756#endif
758 /* Wrap. */
759 bpy_app_memory_usage_undo_doc,
760 ".. staticmethod:: memory_usage_undo()\n"
761 "\n"
762 " Get undo memory usage information.\n"
763 "\n"
764 " :return: Memory usage of the undo stack in bytes.\n"
765 " :rtype: int\n");
766
767static PyObject *bpy_app_memory_usage_undo(PyObject * /*self*/, PyObject * /*args*/)
768{
769 size_t total_memory = 0;
770 UndoStack *ustack = ED_undo_stack_get();
771 if (ustack) {
772 total_memory = ED_undosys_total_memory_calc(ustack);
773 }
774 return PyLong_FromSize_t(total_memory);
775}
776
777static PyMethodDef bpy_app_methods[] = {
778 {"is_job_running",
779 (PyCFunction)bpy_app_is_job_running,
780 METH_VARARGS | METH_KEYWORDS | METH_STATIC,
781 bpy_app_is_job_running_doc},
782 {"help_text",
783 (PyCFunction)bpy_app_help_text,
784 METH_VARARGS | METH_KEYWORDS | METH_STATIC,
785 bpy_app_help_text_doc},
786 {"memory_usage_undo",
787 (PyCFunction)bpy_app_memory_usage_undo,
788 METH_NOARGS | METH_STATIC,
789 bpy_app_memory_usage_undo_doc},
790 {nullptr, nullptr, 0, nullptr},
791};
792
793#ifdef __GNUC__
794# ifdef __clang__
795# pragma clang diagnostic pop
796# else
797# pragma GCC diagnostic pop
798# endif
799#endif
800
802{
803 /* tricky dynamic members, not to py-spec! */
804 for (PyGetSetDef *getset = bpy_app_getsets; getset->name; getset++) {
805 PyObject *item = PyDescr_NewGetSet(&BlenderAppType, getset);
806 PyDict_SetItem(BlenderAppType.tp_dict, PyDescr_NAME(item), item);
807 Py_DECREF(item);
808 }
809}
810
812{
813 for (PyMethodDef *method = bpy_app_methods; method->ml_name; method++) {
814 BLI_assert_msg(method->ml_flags & METH_STATIC, "Only static methods make sense for 'bpy.app'");
815 PyObject *item = PyCFunction_New(method, nullptr);
816 PyDict_SetItemString(BlenderAppType.tp_dict, method->ml_name, item);
817 Py_DECREF(item);
818 }
819}
820
821/* end dynamic bpy.app */
822
823PyObject *BPY_app_struct()
824{
825 PyObject *ret;
826
827 PyStructSequence_InitType(&BlenderAppType, &app_info_desc);
828
829 ret = make_app_info();
830
831 /* prevent user from creating new instances */
832 BlenderAppType.tp_init = nullptr;
833 BlenderAppType.tp_new = nullptr;
834 /* Without this we can't do `set(sys.modules)` #29635. */
835 BlenderAppType.tp_hash = (hashfunc)Py_HashPointer;
836
837 /* Kind of a hack on top of #PyStructSequence. */
840
841 return ret;
842}
const char * BKE_appdir_program_path() ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL
Definition appdir.cc:956
void BKE_appdir_program_path_init(const char *argv0) ATTR_NONNULL(1)
Definition appdir.cc:933
#define BLENDER_VERSION_PATCH
const char * BKE_blender_version_string(void)
Definition blender.cc:146
#define BLENDER_VERSION_CYCLE
#define BLENDER_FILE_SUBVERSION
#define BLENDER_VERSION
#define BLENDER_FILE_VERSION
@ G_FLAG_EVENT_SIMULATE
@ G_FLAG_SCRIPT_AUTOEXEC_FAIL_QUIET
@ G_FLAG_USERPREF_NO_SAVE_ON_EXIT
@ G_FLAG_SCRIPT_AUTOEXEC_FAIL
@ G_FLAG_INTERNET_ALLOW
@ G_DEBUG
@ G_DEBUG_HANDLERS
@ G_DEBUG_FREESTYLE
@ G_DEBUG_IO
@ G_DEBUG_SIMDATA
@ G_DEBUG_DEPSGRAPH_PRETTY
@ G_DEBUG_DEPSGRAPH_TIME
@ G_DEBUG_DEPSGRAPH
@ G_DEBUG_DEPSGRAPH_EVAL
@ G_DEBUG_DEPSGRAPH_TAG
@ G_DEBUG_WM
@ G_DEBUG_EVENTS
@ G_DEBUG_PYTHON
@ G_DEBUG_DEPSGRAPH_BUILD
#define G_MAIN
#define G_FLAG_INTERNET_OVERRIDE_PREF_ANY
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:53
unsigned long ulong
#define ARRAY_SIZE(arr)
#define STRINGIFY(x)
#define POINTER_AS_INT(i)
bool BPY_python_use_system_env_get()
eIconSizes
@ ICON_SIZE_PREVIEW
@ ICON_SIZE_ICON
UndoStack * ED_undo_stack_get()
Definition ed_undo.cc:442
size_t ED_undosys_total_memory_calc(UndoStack *ustack)
Definition ed_undo.cc:916
bool GPU_shader_batch_is_compiling()
Read Guarded memory(de)allocation.
int UI_icon_preview_to_render_size(enum eIconSizes size)
@ WM_JOB_TYPE_SHADER_COMPILATION
Definition WM_api.hh:1800
#define NC_WINDOW
Definition WM_types.hh:375
static int bpy_app_binary_path_set(PyObject *, PyObject *value, void *)
Definition bpy_app.cc:523
static PyObject * bpy_app_debug_value_get(PyObject *, void *)
Definition bpy_app.cc:416
char build_type[]
Definition bpy_app.cc:73
PyDoc_STRVAR(bpy_app_doc, "This module contains application values that remain unchanged during runtime.\n")
static void py_struct_seq_getset_init()
Definition bpy_app.cc:801
char build_cflags[]
Definition bpy_app.cc:74
static PyObject * bpy_app_autoexec_fail_message_get(PyObject *, void *)
Definition bpy_app.cc:486
char build_hash[]
Definition bpy_app.cc:70
static PyStructSequence_Field app_info_fields[]
Definition bpy_app.cc:82
static PyObject * bpy_app_tempdir_get(PyObject *, void *)
Definition bpy_app.cc:444
static int bpy_app_debug_value_set(PyObject *, PyObject *value, void *)
Definition bpy_app.cc:421
static PyObject * make_app_info()
Definition bpy_app.cc:205
char build_commit_date[]
Definition bpy_app.cc:68
static PyObject * bpy_app_preview_render_size_get(PyObject *, void *closure)
Definition bpy_app.cc:473
static int bpy_app_global_flag_set(PyObject *, PyObject *value, void *closure)
Definition bpy_app.cc:378
PyObject * BPY_app_struct()
Definition bpy_app.cc:823
#define SetBytesItem(str)
static PyGetSetDef bpy_app_getsets[]
Definition bpy_app.cc:541
static PyObject * bpy_app_global_flag_get(PyObject *, void *closure)
Definition bpy_app.cc:372
static int bpy_app_global_flag_set__only_disable(PyObject *, PyObject *value, void *closure)
Definition bpy_app.cc:398
ulong build_commit_timestamp
Definition bpy_app.cc:67
static PyObject * bpy_app_memory_usage_undo(PyObject *, PyObject *)
Definition bpy_app.cc:767
static int bpy_app_debug_set(PyObject *, PyObject *value, void *closure)
Definition bpy_app.cc:316
char build_commit_time[]
Definition bpy_app.cc:69
char build_linkflags[]
Definition bpy_app.cc:76
static PyObject * bpy_app_python_args_get(PyObject *, void *)
Definition bpy_app.cc:499
char build_system[]
Definition bpy_app.cc:77
char build_branch[]
Definition bpy_app.cc:71
#define SetIntItem(flag)
char build_date[]
Definition bpy_app.cc:65
char build_cxxflags[]
Definition bpy_app.cc:75
static PyObject * bpy_app_binary_path_get(PyObject *, void *)
Definition bpy_app.cc:518
#define SetStrItem(str)
char *(* BPY_python_app_help_text_fn)(bool all)
Definition bpy_app.cc:712
static void py_struct_seq_method_init()
Definition bpy_app.cc:811
static PyMethodDef bpy_app_methods[]
Definition bpy_app.cc:777
static PyStructSequence_Desc app_info_desc
Definition bpy_app.cc:198
static PyObject * bpy_app_driver_dict_get(PyObject *, void *)
Definition bpy_app.cc:455
static PyObject * bpy_app_debug_get(PyObject *, void *closure)
Definition bpy_app.cc:310
char build_time[]
Definition bpy_app.cc:66
static PyTypeObject BlenderAppType
Definition bpy_app.cc:80
char build_platform[]
Definition bpy_app.cc:72
static PyObject * bpy_app_help_text(PyObject *, PyObject *args, PyObject *kwds)
Definition bpy_app.cc:726
#define SetObjItem(obj)
static PyObject * bpy_app_is_job_running(PyObject *, PyObject *args, PyObject *kwds)
Definition bpy_app.cc:684
PyObject * BPY_app_alembic_struct()
PyObject * BPY_app_build_options_struct()
PyObject * BPY_app_ffmpeg_struct()
PyObject * BPY_app_handlers_struct()
PyObject * BPY_app_icons_module()
PyObject * BPY_app_ocio_struct()
PyObject * BPY_app_oiio_struct()
PyObject * BPY_app_opensubdiv_struct()
PyObject * BPY_app_openvdb_struct()
PyObject * BPY_app_sdl_struct()
PyObject * BPY_app_timers_module()
PyObject * BPY_app_translations_struct()
PyObject * BPY_app_usd_struct()
PyObject * bpy_pydriver_Dict
Definition bpy_driver.cc:52
int bpy_pydriver_create_dict()
Definition bpy_driver.cc:58
uint pos
bool all(VecOp< bool, D >) RET
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
#define G(x, y, z)
int pyrna_enum_value_parse_string(PyObject *o, void *p)
int16_t PyC_Long_AsI16(PyObject *value)
PyObject * PyC_Err_SetString_Prefix(PyObject *exception_type_prefix, const char *str)
PyObject * PyC_UnicodeFromBytes(const char *str)
PyObject * PyC_Tuple_PackArray_String(const char **array, uint len)
int PyC_ParseBool(PyObject *o, void *p)
const char * PyC_UnicodeAsBytes(PyObject *py_str, PyObject **r_coerce)
PyObject * PyC_Tuple_Pack_I32(const blender::Span< int > values)
header-only compatibility defines.
#define Py_HashPointer
Py_DECREF(oname)
#define PY_ARG_PARSER_HEAD_COMPAT()
return ret
const EnumPropertyItem rna_enum_wm_job_type_items[]
Definition rna_wm.cc:206
const EnumPropertyItem * items
void * BKE_tempdir_session
Definition stubs.c:38
void WM_main_add_notifier(uint type, void *reference)
bool WM_jobs_has_running_type(const wmWindowManager *wm, int job_type)
Definition wm_jobs.cc:782
uint8_t flag
Definition wm_window.cc:145