Blender  V3.3
bpy_interface.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
11 #include <Python.h>
12 #include <frameobject.h>
13 
14 #include "MEM_guardedalloc.h"
15 
16 #include "CLG_log.h"
17 
18 #include "BLI_fileops.h"
19 #include "BLI_listbase.h"
20 #include "BLI_path_util.h"
21 #include "BLI_string.h"
22 #include "BLI_string_utf8.h"
23 #include "BLI_threads.h"
24 #include "BLI_utildefines.h"
25 
26 #include "RNA_types.h"
27 
28 #include "bpy.h"
29 #include "bpy_capi_utils.h"
30 #include "bpy_intern_string.h"
31 #include "bpy_path.h"
32 #include "bpy_props.h"
33 #include "bpy_rna.h"
34 #include "bpy_traceback.h"
35 
36 #include "bpy_app_translations.h"
37 
38 #include "DNA_text_types.h"
39 
40 #include "BKE_appdir.h"
41 #include "BKE_context.h"
42 #include "BKE_global.h" /* only for script checking */
43 #include "BKE_main.h"
44 #include "BKE_text.h"
45 
46 #ifdef WITH_CYCLES
47 # include "CCL_api.h"
48 #endif
49 
50 #include "BPY_extern.h"
51 #include "BPY_extern_python.h"
52 #include "BPY_extern_run.h"
53 
54 #include "../generic/py_capi_utils.h"
55 
56 /* inittab initialization functions */
57 #include "../bmesh/bmesh_py_api.h"
58 #include "../generic/bgl.h"
59 #include "../generic/bl_math_py_api.h"
60 #include "../generic/blf_py_api.h"
61 #include "../generic/idprop_py_api.h"
62 #include "../generic/imbuf_py_api.h"
63 #include "../gpu/gpu_py_api.h"
64 #include "../mathutils/mathutils.h"
65 
66 /* Logging types to use anywhere in the Python modules. */
67 
71 
72 /* for internal use, when starting and ending python scripts */
73 
74 /* In case a python script triggers another python call,
75  * stop bpy_context_clear from invalidating. */
76 static int py_call_level = 0;
77 
78 /* Set by command line arguments before Python starts. */
79 static bool py_use_system_env = false;
80 
81 // #define TIME_PY_RUN /* simple python tests. prints on exit. */
82 
83 #ifdef TIME_PY_RUN
84 # include "PIL_time.h"
85 static int bpy_timer_count = 0;
86 static double bpy_timer; /* time since python starts */
87 static double bpy_timer_run; /* time for each python script run */
88 static double bpy_timer_run_tot; /* accumulate python runs */
89 #endif
90 
92 {
93  /* don't do this from a non-main (e.g. render) thread, it can cause a race
94  * condition on C->data.recursion. ideal solution would be to disable
95  * context entirely from non-main threads, but that's more complicated */
96  if (!BLI_thread_is_main()) {
97  return;
98  }
99 
101  BPY_modules_update(); /* can give really bad results if this isn't here */
102 }
103 
104 void bpy_context_set(bContext *C, PyGILState_STATE *gilstate)
105 {
106  py_call_level++;
107 
108  if (gilstate) {
109  *gilstate = PyGILState_Ensure();
110  }
111 
112  if (py_call_level == 1) {
114 
115 #ifdef TIME_PY_RUN
116  if (bpy_timer_count == 0) {
117  /* record time from the beginning */
118  bpy_timer = PIL_check_seconds_timer();
119  bpy_timer_run = bpy_timer_run_tot = 0.0;
120  }
121  bpy_timer_run = PIL_check_seconds_timer();
122 
123  bpy_timer_count++;
124 #endif
125  }
126 }
127 
128 void bpy_context_clear(bContext *UNUSED(C), const PyGILState_STATE *gilstate)
129 {
130  py_call_level--;
131 
132  if (gilstate) {
133  PyGILState_Release(*gilstate);
134  }
135 
136  if (py_call_level < 0) {
137  fprintf(stderr, "ERROR: Python context internal state bug. this should not happen!\n");
138  }
139  else if (py_call_level == 0) {
140  /* XXX: Calling classes currently won't store the context :\,
141  * can't set NULL because of this. but this is very flaky still. */
142 #if 0
144 #endif
145 
146 #ifdef TIME_PY_RUN
147  bpy_timer_run_tot += PIL_check_seconds_timer() - bpy_timer_run;
148  bpy_timer_count++;
149 #endif
150  }
151 }
152 
154 {
155  if (UNLIKELY(C == NULL)) {
156  return;
157  }
159 }
160 
162  void *dict_orig,
163  const char *context_members[],
164  uint context_members_len)
165 {
166  PyGILState_STATE gilstate;
167  const bool use_gil = !PyC_IsInterpreterActive();
168 
169  if (use_gil) {
170  gilstate = PyGILState_Ensure();
171  }
172 
173  /* Copy on write. */
174  if (*dict_p == dict_orig) {
175  *dict_p = PyDict_Copy(dict_orig);
176  }
177 
178  PyObject *dict = *dict_p;
179  BLI_assert(PyDict_Check(dict));
180 
181  /* Use #PyDict_Pop instead of #PyDict_DelItemString to avoid setting the exception,
182  * while supported it's good to avoid for low level functions like this that run often. */
183  for (uint i = 0; i < context_members_len; i++) {
184  PyObject *key = PyUnicode_FromString(context_members[i]);
185  PyObject *item = _PyDict_Pop(dict, key, Py_None);
186  Py_DECREF(key);
187  Py_DECREF(item);
188  }
189 
190  if (use_gil) {
191  PyGILState_Release(gilstate);
192  }
193 }
194 
196 {
197  if (text->compiled) {
198  PyGILState_STATE gilstate;
199  const bool use_gil = !PyC_IsInterpreterActive();
200 
201  if (use_gil) {
202  gilstate = PyGILState_Ensure();
203  }
204 
205  Py_DECREF((PyObject *)text->compiled);
206  text->compiled = NULL;
207 
208  if (use_gil) {
209  PyGILState_Release(gilstate);
210  }
211  }
212 }
213 
215 {
216 #if 0 /* slow, this runs all the time poll, draw etc 100's of time a sec. */
217  PyObject *mod = PyImport_ImportModuleLevel("bpy", NULL, NULL, NULL, 0);
218  PyModule_AddObject(mod, "data", BPY_rna_module());
219  PyModule_AddObject(mod, "types", BPY_rna_types()); /* This does not need updating. */
220 #endif
221 
222  /* refreshes the main struct */
224 }
225 
227 {
228  return bpy_context_module->ptr.data;
229 }
230 
232 {
233  bpy_context_module->ptr.data = (void *)C;
234 }
235 
236 #ifdef WITH_FLUID
237 /* defined in manta module */
238 extern PyObject *Manta_initPython(void);
239 #endif
240 
241 #ifdef WITH_AUDASPACE_PY
242 /* defined in AUD_C-API.cpp */
243 extern PyObject *AUD_initPython(void);
244 #endif
245 
246 #ifdef WITH_CYCLES
247 /* defined in cycles module */
248 static PyObject *CCL_initPython(void)
249 {
250  return (PyObject *)CCL_python_module_init();
251 }
252 #endif
253 
254 static struct _inittab bpy_internal_modules[] = {
255  {"mathutils", PyInit_mathutils},
256 #if 0
257  {"mathutils.geometry", PyInit_mathutils_geometry},
258  {"mathutils.noise", PyInit_mathutils_noise},
259  {"mathutils.kdtree", PyInit_mathutils_kdtree},
260 #endif
261  {"_bpy_path", BPyInit__bpy_path},
262  {"bgl", BPyInit_bgl},
263  {"blf", BPyInit_blf},
264  {"bl_math", BPyInit_bl_math},
265  {"imbuf", BPyInit_imbuf},
266  {"bmesh", BPyInit_bmesh},
267 #if 0
268  {"bmesh.types", BPyInit_bmesh_types},
269  {"bmesh.utils", BPyInit_bmesh_utils},
270  {"bmesh.utils", BPyInit_bmesh_geometry},
271 #endif
272 #ifdef WITH_FLUID
273  {"manta", Manta_initPython},
274 #endif
275 #ifdef WITH_AUDASPACE_PY
276  {"aud", AUD_initPython},
277 #endif
278 #ifdef WITH_CYCLES
279  {"_cycles", CCL_initPython},
280 #endif
281  {"gpu", BPyInit_gpu},
282  {"idprop", BPyInit_idprop},
283  {NULL, NULL},
284 };
285 
286 #ifndef WITH_PYTHON_MODULE
296 static void pystatus_exit_on_error(PyStatus status)
297 {
298  if (UNLIKELY(PyStatus_Exception(status))) {
299  fputs("Internal error initializing Python!\n", stderr);
300  /* This calls `exit`. */
301  Py_ExitStatusException(status);
302  }
303 }
304 #endif
305 
306 void BPY_python_start(bContext *C, int argc, const char **argv)
307 {
308 #ifndef WITH_PYTHON_MODULE
309 
310  /* #PyPreConfig (early-configuration). */
311  {
312  PyPreConfig preconfig;
313  PyStatus status;
314 
315  /* To narrow down reports where the systems Python is inexplicably used, see: T98131. */
316  CLOG_INFO(
318  2,
319  "Initializing %s support for the systems Python environment such as 'PYTHONPATH' and "
320  "the user-site directory.",
321  py_use_system_env ? "*with*" : "*without*");
322 
323  if (py_use_system_env) {
324  PyPreConfig_InitPythonConfig(&preconfig);
325  }
326  else {
327  /* Only use the systems environment variables and site when explicitly requested.
328  * Since an incorrect 'PYTHONPATH' causes difficult to debug errors, see: T72807.
329  * An alternative to setting `preconfig.use_environment = 0` */
330  PyPreConfig_InitIsolatedConfig(&preconfig);
331  }
332 
333  /* Force `utf-8` on all platforms, since this is what's used for Blender's internal strings,
334  * providing consistent encoding behavior across all Blender installations.
335  *
336  * This also uses the `surrogateescape` error handler ensures any unexpected bytes are escaped
337  * instead of raising an error.
338  *
339  * Without this `sys.getfilesystemencoding()` and `sys.stdout` for example may be set to ASCII
340  * or some other encoding - where printing some `utf-8` values will raise an error.
341  *
342  * This can cause scripts to fail entirely on some systems.
343  *
344  * This assignment is the equivalent of enabling the `PYTHONUTF8` environment variable.
345  * See `PEP-540` for details on exactly what this changes. */
346  preconfig.utf8_mode = true;
347 
348  /* Note that there is no reason to call #Py_PreInitializeFromBytesArgs here
349  * as this is only used so that command line arguments can be handled by Python itself,
350  * not for setting `sys.argv` (handled below). */
351  status = Py_PreInitialize(&preconfig);
352  pystatus_exit_on_error(status);
353  }
354 
355  /* Must run before python initializes, but after #PyPreConfig. */
356  PyImport_ExtendInittab(bpy_internal_modules);
357 
358  /* #PyConfig (initialize Python). */
359  {
360  PyConfig config;
361  PyStatus status;
362  bool has_python_executable = false;
363 
364  PyConfig_InitPythonConfig(&config);
365 
366  /* Suppress error messages when calculating the module search path.
367  * While harmless, it's noisy. */
368  config.pathconfig_warnings = 0;
369 
370  /* When using the system's Python, allow the site-directory as well. */
371  config.user_site_directory = py_use_system_env;
372 
373  /* While `sys.argv` is set, we don't want Python to interpret it. */
374  config.parse_argv = 0;
375  status = PyConfig_SetBytesArgv(&config, argc, (char *const *)argv);
376  pystatus_exit_on_error(status);
377 
378  /* Needed for Python's initialization for portable Python installations.
379  * We could use #Py_SetPath, but this overrides Python's internal logic
380  * for calculating its own module search paths.
381  *
382  * `sys.executable` is overwritten after initialization to the Python binary. */
383  {
384  const char *program_path = BKE_appdir_program_path();
385  status = PyConfig_SetBytesString(&config, &config.program_name, program_path);
386  pystatus_exit_on_error(status);
387  }
388 
389  /* Setting the program name is important so the 'multiprocessing' module
390  * can launch new Python instances. */
391  {
392  char program_path[FILE_MAX];
394  program_path, sizeof(program_path), PY_MAJOR_VERSION, PY_MINOR_VERSION)) {
395  status = PyConfig_SetBytesString(&config, &config.executable, program_path);
396  pystatus_exit_on_error(status);
397  has_python_executable = true;
398  }
399  else {
400  /* Set to `sys.executable = None` below (we can't do before Python is initialized). */
401  fprintf(stderr,
402  "Unable to find the python binary, "
403  "the multiprocessing module may not be functional!\n");
404  }
405  }
406 
407  /* Allow to use our own included Python. `py_path_bundle` may be NULL. */
408  {
409  const char *py_path_bundle = BKE_appdir_folder_id(BLENDER_SYSTEM_PYTHON, NULL);
410  if (py_path_bundle != NULL) {
411 
412 # ifdef __APPLE__
413  /* Mac-OS allows file/directory names to contain `:` character
414  * (represented as `/` in the Finder) but current Python lib (as of release 3.1.1)
415  * doesn't handle these correctly. */
416  if (strchr(py_path_bundle, ':')) {
417  fprintf(stderr,
418  "Warning! Blender application is located in a path containing ':' or '/' chars\n"
419  "This may make python import function fail\n");
420  }
421 # endif /* __APPLE__ */
422 
423  status = PyConfig_SetBytesString(&config, &config.home, py_path_bundle);
424  pystatus_exit_on_error(status);
425  }
426  else {
427  /* Common enough to use the system Python on Linux/Unix, warn on other systems. */
428 # if defined(__APPLE__) || defined(_WIN32)
429  fprintf(stderr,
430  "Bundled Python not found and is expected on this platform "
431  "(the 'install' target may have not been built)\n");
432 # endif
433  }
434  }
435 
436  /* Initialize Python (also acquires lock). */
437  status = Py_InitializeFromConfig(&config);
438  pystatus_exit_on_error(status);
439 
440  if (!has_python_executable) {
441  PySys_SetObject("executable", Py_None);
442  }
443  }
444 
445 # ifdef WITH_FLUID
446  /* Required to prevent assertion error, see:
447  * https://stackoverflow.com/questions/27844676 */
448  Py_DECREF(PyImport_ImportModule("threading"));
449 # endif
450 
451 #else
452  (void)argc;
453  (void)argv;
454 
455  /* must run before python initializes */
456  /* broken in py3.3, load explicitly below */
457  // PyImport_ExtendInittab(bpy_internal_modules);
458 #endif
459 
461 
462 #ifdef WITH_PYTHON_MODULE
463  {
464  /* Manually load all modules */
465  struct _inittab *inittab_item;
466  PyObject *sys_modules = PyImport_GetModuleDict();
467 
468  for (inittab_item = bpy_internal_modules; inittab_item->name; inittab_item++) {
469  PyObject *mod = inittab_item->initfunc();
470  if (mod) {
471  PyDict_SetItemString(sys_modules, inittab_item->name, mod);
472  }
473  else {
474  PyErr_Print();
475  PyErr_Clear();
476  }
477  // Py_DECREF(mod); /* ideally would decref, but in this case we never want to free */
478  }
479  }
480 #endif
481 
482  /* Run first, initializes RNA types. */
483  BPY_rna_init();
484 
485  /* Defines `bpy.*` and lets us import it. */
487 
489 
490 #ifndef WITH_PYTHON_MODULE
491  /* py module runs atexit when bpy is freed */
492  BPY_atexit_register(); /* this can init any time */
493 
494  /* Free the lock acquired (implicitly) when Python is initialized. */
495  PyEval_ReleaseThread(PyGILState_GetThisThreadState());
496 
497 #endif
498 
499 #ifdef WITH_PYTHON_MODULE
500  /* Disable all add-ons at exit, not essential, it just avoids resource leaks, see T71362. */
502  (const char *[]){"atexit", "addon_utils", NULL},
503  "atexit.register(addon_utils.disable_all)");
504 #endif
505 }
506 
507 void BPY_python_end(void)
508 {
509  // fprintf(stderr, "Ending Python!\n");
510  PyGILState_STATE gilstate;
511 
512  /* finalizing, no need to grab the state, except when we are a module */
513  gilstate = PyGILState_Ensure();
514 
515  /* Frees the python-driver name-space & cached data. */
516  BPY_driver_exit();
517 
518  /* Clear Python values in the context so freeing the context after Python exits doesn't crash. */
520 
521  /* Decrement user counts of all callback functions. */
523 
524  /* free other python data. */
526 
527  BPY_rna_exit();
528 
529  /* clear all python data from structs */
530 
532 
533  /* bpy.app modules that need cleanup */
535 
536 #ifndef WITH_PYTHON_MODULE
537  BPY_atexit_unregister(); /* without this we get recursive calls to WM_exit */
538 
539  Py_Finalize();
540 
541  (void)gilstate;
542 #else
543  PyGILState_Release(gilstate);
544 #endif
545 
546 #ifdef TIME_PY_RUN
547  /* measure time since py started */
548  bpy_timer = PIL_check_seconds_timer() - bpy_timer;
549 
550  printf("*bpy stats* - ");
551  printf("tot exec: %d, ", bpy_timer_count);
552  printf("tot run: %.4fsec, ", bpy_timer_run_tot);
553  if (bpy_timer_count > 0) {
554  printf("average run: %.6fsec, ", (bpy_timer_run_tot / bpy_timer_count));
555  }
556 
557  if (bpy_timer > 0.0) {
558  printf("tot usage %.4f%%", (bpy_timer_run_tot / bpy_timer) * 100.0);
559  }
560 
561  printf("\n");
562 
563  // fprintf(stderr, "Ending Python Done!\n");
564 
565 #endif
566 }
567 
569 {
570  /* unrelated security stuff */
572  G.autoexec_fail[0] = '\0';
573 
575  BPY_app_handlers_reset(false);
577 }
578 
580 {
581  BLI_assert(!Py_IsInitialized());
582  py_use_system_env = true;
583 }
584 
585 void BPY_python_backtrace(FILE *fp)
586 {
587  fputs("\n# Python backtrace\n", fp);
588 
589  /* Can happen in rare cases. */
590  if (!_PyThreadState_UncheckedGet()) {
591  return;
592  }
593  PyFrameObject *frame;
594  if (!(frame = PyEval_GetFrame())) {
595  return;
596  }
597  do {
598  PyCodeObject *code = PyFrame_GetCode(frame);
599  const int line = PyFrame_GetLineNumber(frame);
600  const char *filepath = PyUnicode_AsUTF8(code->co_filename);
601  const char *funcname = PyUnicode_AsUTF8(code->co_name);
602  fprintf(fp, " File \"%s\", line %d in %s\n", filepath, line, funcname);
603  } while ((frame = PyFrame_GetBack(frame)));
604 }
605 
606 void BPY_DECREF(void *pyob_ptr)
607 {
608  const PyGILState_STATE gilstate = PyGILState_Ensure();
609  Py_DECREF((PyObject *)pyob_ptr);
610  PyGILState_Release(gilstate);
611 }
612 
613 void BPY_DECREF_RNA_INVALIDATE(void *pyob_ptr)
614 {
615  const PyGILState_STATE gilstate = PyGILState_Ensure();
616  const bool do_invalidate = (Py_REFCNT((PyObject *)pyob_ptr) > 1);
617  Py_DECREF((PyObject *)pyob_ptr);
618  if (do_invalidate) {
619  pyrna_invalidate(pyob_ptr);
620  }
621  PyGILState_Release(gilstate);
622 }
623 
625 {
626  PyGILState_STATE gilstate;
627  Main *bmain = CTX_data_main(C);
628  Text *text;
629 
630  /* can happen on file load */
631  if (bmain == NULL) {
632  return;
633  }
634 
635  /* update pointers since this can run from a nested script
636  * on file load */
637  if (py_call_level) {
639  }
640 
641  bpy_context_set(C, &gilstate);
642 
643  for (text = bmain->texts.first; text; text = text->id.next) {
644  if (text->flags & TXT_ISSCRIPT) {
645  if (!(G.f & G_FLAG_SCRIPT_AUTOEXEC)) {
648  BLI_snprintf(G.autoexec_fail, sizeof(G.autoexec_fail), "Text '%s'", text->id.name + 2);
649 
650  printf("scripts disabled for \"%s\", skipping '%s'\n",
652  text->id.name + 2);
653  }
654  }
655  else {
656  BPY_run_text(C, text, NULL, false);
657 
658  /* Check if the script loaded a new file. */
659  if (bmain != CTX_data_main(C)) {
660  break;
661  }
662  }
663  }
664  }
665  bpy_context_clear(C, &gilstate);
666 }
667 
669 {
670  PyGILState_STATE gilstate;
671  const bool use_gil = !PyC_IsInterpreterActive();
672 
673  PyObject *pyctx;
674  PyObject *item;
675  PointerRNA *ptr = NULL;
676  bool done = false;
677 
678  if (use_gil) {
679  gilstate = PyGILState_Ensure();
680  }
681 
682  pyctx = (PyObject *)CTX_py_dict_get(C);
683  item = PyDict_GetItemString(pyctx, member);
684 
685  if (item == NULL) {
686  /* pass */
687  }
688  else if (item == Py_None) {
689  done = true;
690  }
691  else if (BPy_StructRNA_Check(item)) {
692  ptr = &(((BPy_StructRNA *)item)->ptr);
693 
694  // result->ptr = ((BPy_StructRNA *)item)->ptr;
697  done = true;
698  }
699  else if (PySequence_Check(item)) {
700  PyObject *seq_fast = PySequence_Fast(item, "bpy_context_get sequence conversion");
701  if (seq_fast == NULL) {
702  PyErr_Print();
703  PyErr_Clear();
704  }
705  else {
706  const int len = PySequence_Fast_GET_SIZE(seq_fast);
707  PyObject **seq_fast_items = PySequence_Fast_ITEMS(seq_fast);
708  int i;
709 
710  for (i = 0; i < len; i++) {
711  PyObject *list_item = seq_fast_items[i];
712 
713  if (BPy_StructRNA_Check(list_item)) {
714 #if 0
716  "bpy_context_get");
717  link->ptr = ((BPy_StructRNA *)item)->ptr;
718  BLI_addtail(&result->list, link);
719 #endif
720  ptr = &(((BPy_StructRNA *)list_item)->ptr);
722  }
723  else {
725  1,
726  "'%s' list item not a valid type in sequence type '%s'",
727  member,
728  Py_TYPE(item)->tp_name);
729  }
730  }
731  Py_DECREF(seq_fast);
733  done = true;
734  }
735  }
736 
737  if (done == false) {
738  if (item) {
739  CLOG_INFO(BPY_LOG_CONTEXT, 1, "'%s' not a valid type", member);
740  }
741  else {
742  CLOG_INFO(BPY_LOG_CONTEXT, 1, "'%s' not found", member);
743  }
744  }
745  else {
746  CLOG_INFO(BPY_LOG_CONTEXT, 2, "'%s' found", member);
747  }
748 
749  if (use_gil) {
750  PyGILState_Release(gilstate);
751  }
752 
753  return done;
754 }
755 
756 #ifdef WITH_PYTHON_MODULE
757 /* TODO: reloading the module isn't functional at the moment. */
758 
759 static void bpy_module_free(void *mod);
760 
761 /* Defined in 'creator.c' when building as a Python module. */
762 extern int main_python_enter(int argc, const char **argv);
763 extern void main_python_exit(void);
764 
765 static struct PyModuleDef bpy_proxy_def = {
766  PyModuleDef_HEAD_INIT,
767  "bpy", /* m_name */
768  NULL, /* m_doc */
769  0, /* m_size */
770  NULL, /* m_methods */
771  NULL, /* m_reload */
772  NULL, /* m_traverse */
773  NULL, /* m_clear */
774  bpy_module_free, /* m_free */
775 };
776 
777 typedef struct {
778  PyObject_HEAD
779  /* Type-specific fields go here. */
780  PyObject *mod;
781 } dealloc_obj;
782 
783 /* call once __file__ is set */
784 static void bpy_module_delay_init(PyObject *bpy_proxy)
785 {
786  const int argc = 1;
787  const char *argv[2];
788 
789  /* updating the module dict below will lose the reference to __file__ */
790  PyObject *filepath_obj = PyModule_GetFilenameObject(bpy_proxy);
791 
792  const char *filepath_rel = PyUnicode_AsUTF8(filepath_obj); /* can be relative */
793  char filepath_abs[1024];
794 
795  BLI_strncpy(filepath_abs, filepath_rel, sizeof(filepath_abs));
796  BLI_path_abs_from_cwd(filepath_abs, sizeof(filepath_abs));
797  Py_DECREF(filepath_obj);
798 
799  argv[0] = filepath_abs;
800  argv[1] = NULL;
801 
802  // printf("module found %s\n", argv[0]);
803 
804  main_python_enter(argc, argv);
805 
806  /* initialized in BPy_init_modules() */
807  PyDict_Update(PyModule_GetDict(bpy_proxy), PyModule_GetDict(bpy_package_py));
808 }
809 
810 static void dealloc_obj_dealloc(PyObject *self);
811 
812 static PyTypeObject dealloc_obj_Type;
813 
814 /* use our own dealloc so we can free a property if we use one */
815 static void dealloc_obj_dealloc(PyObject *self)
816 {
817  bpy_module_delay_init(((dealloc_obj *)self)->mod);
818 
819  /* NOTE: for subclassed PyObjects we can't just call PyObject_DEL() directly or it will crash. */
820  dealloc_obj_Type.tp_free(self);
821 }
822 
823 PyMODINIT_FUNC PyInit_bpy(void);
824 
825 PyMODINIT_FUNC PyInit_bpy(void)
826 {
827  PyObject *bpy_proxy = PyModule_Create(&bpy_proxy_def);
828 
829  /* Problem:
830  * 1) this init function is expected to have a private member defined - `md_def`
831  * but this is only set for C defined modules (not py packages)
832  * so we can't return 'bpy_package_py' as is.
833  *
834  * 2) there is a 'bpy' C module for python to load which is basically all of blender,
835  * and there is `scripts/bpy/__init__.py`,
836  * we may end up having to rename this module so there is no naming conflict here eg:
837  * 'from blender import bpy'
838  *
839  * 3) we don't know the filepath at this point, workaround by assigning a dummy value
840  * which calls back when its freed so the real loading can take place.
841  */
842 
843  /* assign an object which is freed after __file__ is assigned */
844  dealloc_obj *dob;
845 
846  /* assign dummy type */
847  dealloc_obj_Type.tp_name = "dealloc_obj";
848  dealloc_obj_Type.tp_basicsize = sizeof(dealloc_obj);
849  dealloc_obj_Type.tp_dealloc = dealloc_obj_dealloc;
850  dealloc_obj_Type.tp_flags = Py_TPFLAGS_DEFAULT;
851 
852  if (PyType_Ready(&dealloc_obj_Type) < 0) {
853  return NULL;
854  }
855 
856  dob = (dealloc_obj *)dealloc_obj_Type.tp_alloc(&dealloc_obj_Type, 0);
857  dob->mod = bpy_proxy; /* borrow */
858  PyModule_AddObject(bpy_proxy, "__file__", (PyObject *)dob); /* borrow */
859 
860  return bpy_proxy;
861 }
862 
863 static void bpy_module_free(void *UNUSED(mod))
864 {
865  main_python_exit();
866 }
867 
868 #endif
869 
870 bool BPY_string_is_keyword(const char *str)
871 {
872  /* list is from...
873  * ", ".join(['"%s"' % kw for kw in __import__("keyword").kwlist])
874  */
875  const char *kwlist[] = {
876  "False", "None", "True", "and", "as", "assert", "async", "await", "break",
877  "class", "continue", "def", "del", "elif", "else", "except", "finally", "for",
878  "from", "global", "if", "import", "in", "is", "lambda", "nonlocal", "not",
879  "or", "pass", "raise", "return", "try", "while", "with", "yield", NULL,
880  };
881 
882  for (int i = 0; kwlist[i]; i++) {
883  if (STREQ(str, kwlist[i])) {
884  return true;
885  }
886  }
887 
888  return false;
889 }
890 
891 /* EVIL: define `text.c` functions here (declared in `BKE_text.h`). */
893 {
894  return (ch < 255 && text_check_identifier((char)ch)) || Py_UNICODE_ISALNUM(ch);
895 }
896 
898 {
899  return (ch < 255 && text_check_identifier_nodigit((char)ch)) || Py_UNICODE_ISALPHA(ch);
900 }
PyObject * AUD_initPython(void)
Definition: AUD_PyInit.cpp:50
const char * BKE_appdir_folder_id(int folder_id, const char *subfolder)
Definition: appdir.c:672
const char * BKE_appdir_program_path(void)
Definition: appdir.c:867
@ BLENDER_SYSTEM_PYTHON
Definition: BKE_appdir.h:165
bool BKE_appdir_program_python_search(char *fullpath, size_t fullpath_len, int version_major, int version_minor)
Definition: appdir.c:879
void * CTX_py_dict_get(const bContext *C)
Definition: context.c:242
@ CTX_DATA_TYPE_POINTER
Definition: BKE_context.h:232
@ CTX_DATA_TYPE_COLLECTION
Definition: BKE_context.h:233
void CTX_data_type_set(struct bContextDataResult *result, short type)
Definition: context.c:701
void CTX_data_list_add_ptr(bContextDataResult *result, const PointerRNA *ptr)
Definition: context.c:675
void CTX_data_pointer_set_ptr(bContextDataResult *result, const PointerRNA *ptr)
Definition: context.c:654
void CTX_wm_operator_poll_msg_clear(struct bContext *C)
Definition: context.c:1030
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1074
@ G_FLAG_SCRIPT_AUTOEXEC_FAIL_QUIET
Definition: BKE_global.h:158
@ G_FLAG_SCRIPT_AUTOEXEC_FAIL
Definition: BKE_global.h:157
@ G_FLAG_SCRIPT_AUTOEXEC
Definition: BKE_global.h:154
const char * BKE_main_blendfile_path(const struct Main *bmain) ATTR_NONNULL()
bool text_check_identifier_nodigit(char ch)
Definition: text.c:2343
bool text_check_identifier(char ch)
Definition: text.c:2320
#define BLI_assert(a)
Definition: BLI_assert.h:46
File and directory operations.
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:80
#define FILE_MAX
bool BLI_path_abs_from_cwd(char *path, size_t maxlen) ATTR_NONNULL()
Definition: path_util.c:1015
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
Definition: string.c:64
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
unsigned int uint
Definition: BLI_sys_types.h:67
int BLI_thread_is_main(void)
Definition: threads.cc:207
#define UNUSED(x)
#define UNLIKELY(x)
#define STREQ(a, b)
void BPY_driver_exit(void)
Definition: bpy_driver.c:237
void BPY_driver_reset(void)
Definition: bpy_driver.c:260
void BPY_app_handlers_reset(bool do_all)
struct CLG_LogRef * BPY_LOG_RNA
struct CLG_LogRef * BPY_LOG_CONTEXT
bool bool BPY_run_text(struct bContext *C, struct Text *text, struct ReportList *reports, bool do_jump) ATTR_NONNULL(1
bool BPY_run_string_eval(struct bContext *C, const char *imports[], const char *expr)
void * CCL_python_module_init(void)
Definition: python.cpp:986
#define CLOG_INFO(clg_ref, level,...)
Definition: CLG_log.h:187
@ TXT_ISSCRIPT
Read Guarded memory(de)allocation.
Platform independent time functions.
#define C
Definition: RandGen.cpp:25
PyObject * BPyInit_bgl(void)
Definition: bgl.c:2599
PyMODINIT_FUNC BPyInit_bl_math(void)
PyObject * BPyInit_blf(void)
Definition: blf_py_api.c:474
PyObject * BPyInit_bmesh(void)
Definition: bmesh_py_api.c:169
PyObject * BPyInit_bmesh_geometry(void)
PyObject * BPyInit_bmesh_types(void)
PyObject * BPyInit_bmesh_utils(void)
void BPy_init_modules(struct bContext *C)
Definition: bpy.c:589
PyObject * bpy_package_py
Definition: bpy.c:59
void BPY_atexit_register(void)
struct CLG_LogRef * BPY_LOG_INTERFACE
void BPY_atexit_unregister(void)
void BPY_app_translations_end(void)
int text_check_identifier_nodigit_unicode(const uint ch)
bContext * BPY_context_get(void)
bool BPY_string_is_keyword(const char *str)
void BPY_context_dict_clear_members_array(void **dict_p, void *dict_orig, const char *context_members[], uint context_members_len)
int text_check_identifier_unicode(const uint ch)
int BPY_context_member_get(bContext *C, const char *member, bContextDataResult *result)
void bpy_context_set(bContext *C, PyGILState_STATE *gilstate)
void BPY_context_set(bContext *C)
void BPY_DECREF_RNA_INVALIDATE(void *pyob_ptr)
static void pystatus_exit_on_error(PyStatus status)
void BPY_python_backtrace(FILE *fp)
void BPY_python_use_system_env(void)
static int py_call_level
Definition: bpy_interface.c:76
static void bpy_context_end(bContext *C)
void BPY_modules_update(void)
CLG_LOGREF_DECLARE_GLOBAL(BPY_LOG_CONTEXT, "bpy.context")
void BPY_python_reset(bContext *C)
static bool py_use_system_env
Definition: bpy_interface.c:79
void BPY_context_update(bContext *C)
Definition: bpy_interface.c:91
void BPY_python_end(void)
static struct _inittab bpy_internal_modules[]
void BPY_text_free_code(Text *text)
void bpy_context_clear(bContext *UNUSED(C), 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_init(void)
void bpy_intern_string_exit(void)
PyObject * BPyInit__bpy_path(void)
Definition: bpy_path.c:35
void BPY_rna_props_clear_all(void)
Definition: bpy_props.c:4676
void pyrna_invalidate(BPy_DummyPointerRNA *self)
Definition: bpy_rna.c:123
void BPY_rna_init(void)
Definition: bpy_rna.c:7673
void pyrna_alloc_types(void)
Definition: bpy_rna.c:8853
void pyrna_free_types(void)
Definition: bpy_rna.c:8885
void BPY_update_rna_module(void)
Definition: bpy_rna.c:7762
PyObject * BPY_rna_module(void)
Definition: bpy_rna.c:7749
void BPY_rna_exit(void)
Definition: bpy_rna.c:7726
PyObject * BPY_rna_types(void)
Definition: bpy_rna.c:7877
BPy_StructRNA * bpy_context_module
Definition: bpy_rna.c:87
#define BPy_StructRNA_Check(v)
Definition: bpy_rna.h:66
SyclQueue void void size_t num_bytes void
int len
Definition: draw_manager.c:108
#define str(s)
PyObject * BPyInit_gpu(void)
Definition: gpu_py_api.c:39
PyObject * BPyInit_idprop(void)
PyObject * BPyInit_imbuf(void)
Definition: imbuf_py_api.c:579
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
PyObject * Manta_initPython(void)
PyMODINIT_FUNC PyInit_mathutils(void)
Definition: mathutils.c:746
PyMODINIT_FUNC PyInit_mathutils_geometry(void)
PyMODINIT_FUNC PyInit_mathutils_kdtree(void)
PyMODINIT_FUNC PyInit_mathutils_noise(void)
#define G(x, y, z)
bool PyC_IsInterpreterActive(void)
PyObject_HEAD PointerRNA ptr
Definition: bpy_rna.h:111
void * next
Definition: DNA_ID.h:369
char name[66]
Definition: DNA_ID.h:378
void * first
Definition: DNA_listBase.h:31
Definition: BKE_main.h:121
ListBase texts
Definition: BKE_main.h:185
void * data
Definition: RNA_types.h:38
int flags
void * compiled
double PIL_check_seconds_timer(void)
Definition: time.c:64
ccl_device_inline int mod(int x, int m)
Definition: util/math.h:490
PointerRNA * ptr
Definition: wm_files.c:3480