1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 2
5 * of the License, or (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software Foundation,
14 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15 *
16 * Chris Keith, Chris Want, Ken Hughes, Campbell Barton
17 */
18
19 /** \file
20 * \ingroup pythonintern
21 *
22 * This file deals with embedding the python interpreter within blender,
23 * starting and stopping python and exposing blender/python modules so they can
24 * be accesses from scripts.
25 */
26
27 #include <Python.h>
28 #include <frameobject.h>
29
30 #include "MEM_guardedalloc.h"
31
32 #include "CLG_log.h"
33
34 #include "BLI_fileops.h"
35 #include "BLI_listbase.h"
36 #include "BLI_path_util.h"
37 #include "BLI_string.h"
38 #include "BLI_string_utf8.h"
39 #include "BLI_threads.h"
40 #include "BLI_utildefines.h"
41
42 #include "RNA_types.h"
43
44 #include "bpy.h"
45 #include "bpy_capi_utils.h"
46 #include "bpy_intern_string.h"
47 #include "bpy_path.h"
48 #include "bpy_rna.h"
49 #include "bpy_traceback.h"
50
51 #include "bpy_app_translations.h"
52
53 #include "DNA_text_types.h"
54
55 #include "BKE_appdir.h"
56 #include "BKE_context.h"
57 #include "BKE_global.h" /* only for script checking */
58 #include "BKE_main.h"
59 #include "BKE_text.h"
60
61 #ifdef WITH_CYCLES
62 # include "CCL_api.h"
63 #endif
64
65 #include "BPY_extern.h"
66 #include "BPY_extern_python.h"
67 #include "BPY_extern_run.h"
68
69 #include "../generic/py_capi_utils.h"
70
71 /* inittab initialization functions */
72 #include "../bmesh/bmesh_py_api.h"
73 #include "../generic/bgl.h"
74 #include "../generic/bl_math_py_api.h"
75 #include "../generic/blf_py_api.h"
76 #include "../generic/idprop_py_api.h"
77 #include "../generic/imbuf_py_api.h"
78 #include "../gpu/gpu_py_api.h"
79 #include "../mathutils/mathutils.h"
80
81 /* Logging types to use anywhere in the Python modules. */
82 CLG_LOGREF_DECLARE_GLOBAL(BPY_LOG_CONTEXT, "bpy.context");
83 CLG_LOGREF_DECLARE_GLOBAL(BPY_LOG_RNA, "bpy.rna");
84
85 /* for internal use, when starting and ending python scripts */
86
87 /* In case a python script triggers another python call,
88 * stop bpy_context_clear from invalidating. */
89 static int py_call_level = 0;
90
91 /* Set by command line arguments before Python starts. */
92 static bool py_use_system_env = false;
93
94 // #define TIME_PY_RUN /* simple python tests. prints on exit. */
95
96 #ifdef TIME_PY_RUN
97 # include "PIL_time.h"
98 static int bpy_timer_count = 0;
99 static double bpy_timer; /* time since python starts */
100 static double bpy_timer_run; /* time for each python script run */
101 static double bpy_timer_run_tot; /* accumulate python runs */
102 #endif
103
104 /* use for updating while a python script runs - in case of file load */
BPY_context_update(bContext * C)105 void BPY_context_update(bContext *C)
106 {
107 /* don't do this from a non-main (e.g. render) thread, it can cause a race
108 * condition on C->data.recursion. ideal solution would be to disable
109 * context entirely from non-main threads, but that's more complicated */
110 if (!BLI_thread_is_main()) {
111 return;
112 }
113
114 BPY_context_set(C);
115 BPY_modules_update(); /* can give really bad results if this isn't here */
116 }
117
bpy_context_set(bContext * C,PyGILState_STATE * gilstate)118 void bpy_context_set(bContext *C, PyGILState_STATE *gilstate)
119 {
120 py_call_level++;
121
122 if (gilstate) {
123 *gilstate = PyGILState_Ensure();
124 }
125
126 if (py_call_level == 1) {
127 BPY_context_update(C);
128
129 #ifdef TIME_PY_RUN
130 if (bpy_timer_count == 0) {
131 /* record time from the beginning */
132 bpy_timer = PIL_check_seconds_timer();
133 bpy_timer_run = bpy_timer_run_tot = 0.0;
134 }
135 bpy_timer_run = PIL_check_seconds_timer();
136
137 bpy_timer_count++;
138 #endif
139 }
140 }
141
142 /* context should be used but not now because it causes some bugs */
bpy_context_clear(bContext * UNUSED (C),const PyGILState_STATE * gilstate)143 void bpy_context_clear(bContext *UNUSED(C), const PyGILState_STATE *gilstate)
144 {
145 py_call_level--;
146
147 if (gilstate) {
148 PyGILState_Release(*gilstate);
149 }
150
151 if (py_call_level < 0) {
152 fprintf(stderr, "ERROR: Python context internal state bug. this should not happen!\n");
153 }
154 else if (py_call_level == 0) {
155 /* XXX - Calling classes currently wont store the context :\,
156 * cant set NULL because of this. but this is very flakey still. */
157 #if 0
158 BPY_context_set(NULL);
159 #endif
160
161 #ifdef TIME_PY_RUN
162 bpy_timer_run_tot += PIL_check_seconds_timer() - bpy_timer_run;
163 bpy_timer_count++;
164 #endif
165 }
166 }
167
168 /**
169 * Use for `CTX_*_set(..)` functions need to set values which are later read back as expected.
170 * In this case we don't want the Python context to override the values as it causes problems
171 * see T66256.
172 *
173 * \param dict_p: A pointer to #bContext.data.py_context so we can assign a new value.
174 * \param dict_orig: The value of #bContext.data.py_context_orig to check if we need to copy.
175 *
176 * \note Typically accessed via #BPY_context_dict_clear_members macro.
177 */
BPY_context_dict_clear_members_array(void ** dict_p,void * dict_orig,const char * context_members[],uint context_members_len)178 void BPY_context_dict_clear_members_array(void **dict_p,
179 void *dict_orig,
180 const char *context_members[],
181 uint context_members_len)
182 {
183 PyGILState_STATE gilstate;
184 const bool use_gil = !PyC_IsInterpreterActive();
185
186 if (use_gil) {
187 gilstate = PyGILState_Ensure();
188 }
189
190 /* Copy on write. */
191 if (*dict_p == dict_orig) {
192 *dict_p = PyDict_Copy(dict_orig);
193 }
194
195 PyObject *dict = *dict_p;
196 BLI_assert(PyDict_Check(dict));
197 for (uint i = 0; i < context_members_len; i++) {
198 if (PyDict_DelItemString(dict, context_members[i])) {
199 PyErr_Clear();
200 }
201 }
202
203 if (use_gil) {
204 PyGILState_Release(gilstate);
205 }
206 }
207
BPY_text_free_code(Text * text)208 void BPY_text_free_code(Text *text)
209 {
210 if (text->compiled) {
211 PyGILState_STATE gilstate;
212 const bool use_gil = !PyC_IsInterpreterActive();
213
214 if (use_gil) {
215 gilstate = PyGILState_Ensure();
216 }
217
218 Py_DECREF((PyObject *)text->compiled);
219 text->compiled = NULL;
220
221 if (use_gil) {
222 PyGILState_Release(gilstate);
223 }
224 }
225 }
226
227 /**
228 * Needed so the #Main pointer in `bpy.data` doesn't become out of date.
229 */
BPY_modules_update(void)230 void BPY_modules_update(void)
231 {
232 #if 0 /* slow, this runs all the time poll, draw etc 100's of time a sec. */
233 PyObject *mod = PyImport_ImportModuleLevel("bpy", NULL, NULL, NULL, 0);
234 PyModule_AddObject(mod, "data", BPY_rna_module());
235 PyModule_AddObject(mod, "types", BPY_rna_types()); /* atm this does not need updating */
236 #endif
237
238 /* refreshes the main struct */
239 BPY_update_rna_module();
240 }
241
BPY_context_get(void)242 bContext *BPY_context_get(void)
243 {
244 return bpy_context_module->ptr.data;
245 }
246
BPY_context_set(bContext * C)247 void BPY_context_set(bContext *C)
248 {
249 bpy_context_module->ptr.data = (void *)C;
250 }
251
252 #ifdef WITH_FLUID
253 /* defined in manta module */
254 extern PyObject *Manta_initPython(void);
255 #endif
256
257 #ifdef WITH_AUDASPACE
258 /* defined in AUD_C-API.cpp */
259 extern PyObject *AUD_initPython(void);
260 #endif
261
262 #ifdef WITH_CYCLES
263 /* defined in cycles module */
CCL_initPython(void)264 static PyObject *CCL_initPython(void)
265 {
266 return (PyObject *)CCL_python_module_init();
267 }
268 #endif
269
270 static struct _inittab bpy_internal_modules[] = {
271 {"mathutils", PyInit_mathutils},
272 #if 0
273 {"mathutils.geometry", PyInit_mathutils_geometry},
274 {"mathutils.noise", PyInit_mathutils_noise},
275 {"mathutils.kdtree", PyInit_mathutils_kdtree},
276 #endif
277 {"_bpy_path", BPyInit__bpy_path},
278 {"bgl", BPyInit_bgl},
279 {"blf", BPyInit_blf},
280 {"bl_math", BPyInit_bl_math},
281 {"imbuf", BPyInit_imbuf},
282 {"bmesh", BPyInit_bmesh},
283 #if 0
284 {"bmesh.types", BPyInit_bmesh_types},
285 {"bmesh.utils", BPyInit_bmesh_utils},
286 {"bmesh.utils", BPyInit_bmesh_geometry},
287 #endif
288 #ifdef WITH_FLUID
289 {"manta", Manta_initPython},
290 #endif
291 #ifdef WITH_AUDASPACE
292 {"aud", AUD_initPython},
293 #endif
294 #ifdef WITH_CYCLES
295 {"_cycles", CCL_initPython},
296 #endif
297 {"gpu", BPyInit_gpu},
298 {"idprop", BPyInit_idprop},
299 {NULL, NULL},
300 };
301
302 /* call BPY_context_set first */
BPY_python_start(bContext * C,int argc,const char ** argv)303 void BPY_python_start(bContext *C, int argc, const char **argv)
304 {
305 #ifndef WITH_PYTHON_MODULE
306 PyThreadState *py_tstate = NULL;
307 const char *py_path_bundle = BKE_appdir_folder_id(BLENDER_SYSTEM_PYTHON, NULL);
308
309 /* Needed for Python's initialization for portable Python installations.
310 * We could use #Py_SetPath, but this overrides Python's internal logic
311 * for calculating it's own module search paths.
312 *
313 * `sys.executable` is overwritten after initialization to the Python binary. */
314 {
315 const char *program_path = BKE_appdir_program_path();
316 wchar_t program_path_wchar[FILE_MAX];
317 BLI_strncpy_wchar_from_utf8(program_path_wchar, program_path, ARRAY_SIZE(program_path_wchar));
318 Py_SetProgramName(program_path_wchar);
319 }
320
321 /* must run before python initializes */
322 PyImport_ExtendInittab(bpy_internal_modules);
323
324 /* allow to use our own included python */
325 PyC_SetHomePath(py_path_bundle);
326
327 /* Without this the `sys.stdout` may be set to 'ascii'
328 * (it is on my system at least), where printing unicode values will raise
329 * an error, this is highly annoying, another stumbling block for developers,
330 * so use a more relaxed error handler and enforce utf-8 since the rest of
331 * Blender is utf-8 too - campbell */
332 Py_SetStandardStreamEncoding("utf-8", "surrogateescape");
333
334 /* Suppress error messages when calculating the module search path.
335 * While harmless, it's noisy. */
336 Py_FrozenFlag = 1;
337
338 /* Only use the systems environment variables and site when explicitly requested.
339 * Since an incorrect 'PYTHONPATH' causes difficult to debug errors, see: T72807. */
340 Py_IgnoreEnvironmentFlag = !py_use_system_env;
341 Py_NoUserSiteDirectory = !py_use_system_env;
342
343 /* Initialize Python (also acquires lock). */
344 Py_Initialize();
345
346 // PySys_SetArgv(argc, argv); /* broken in py3, not a huge deal */
347 /* sigh, why do python guys not have a (char **) version anymore? */
348 {
349 int i;
350 PyObject *py_argv = PyList_New(argc);
351 for (i = 0; i < argc; i++) {
352 /* should fix bug T20021 - utf path name problems, by replacing
353 * PyUnicode_FromString, with this one */
354 PyList_SET_ITEM(py_argv, i, PyC_UnicodeFromByte(argv[i]));
355 }
356
357 PySys_SetObject("argv", py_argv);
358 Py_DECREF(py_argv);
359 }
360
361 /* Setting the program name is important so the 'multiprocessing' module
362 * can launch new Python instances. */
363 {
364 const char *sys_variable = "executable";
365 char program_path[FILE_MAX];
366 if (BKE_appdir_program_python_search(
367 program_path, sizeof(program_path), PY_MAJOR_VERSION, PY_MINOR_VERSION)) {
368 PyObject *py_program_path = PyC_UnicodeFromByte(program_path);
369 PySys_SetObject(sys_variable, py_program_path);
370 Py_DECREF(py_program_path);
371 }
372 else {
373 fprintf(stderr,
374 "Unable to find the python binary, "
375 "the multiprocessing module may not be functional!\n");
376 PySys_SetObject(sys_variable, Py_None);
377 }
378 }
379
380 # ifdef WITH_FLUID
381 /* Required to prevent assertion error, see:
382 * https://stackoverflow.com/questions/27844676 */
383 Py_DECREF(PyImport_ImportModule("threading"));
384 # endif
385
386 #else
387 (void)argc;
388 (void)argv;
389
390 /* must run before python initializes */
391 /* broken in py3.3, load explicitly below */
392 // PyImport_ExtendInittab(bpy_internal_modules);
393 #endif
394
395 bpy_intern_string_init();
396
397 #ifdef WITH_PYTHON_MODULE
398 {
399 /* Manually load all modules */
400 struct _inittab *inittab_item;
401 PyObject *sys_modules = PyImport_GetModuleDict();
402
403 for (inittab_item = bpy_internal_modules; inittab_item->name; inittab_item++) {
404 PyObject *mod = inittab_item->initfunc();
405 if (mod) {
406 PyDict_SetItemString(sys_modules, inittab_item->name, mod);
407 }
408 else {
409 PyErr_Print();
410 PyErr_Clear();
411 }
412 // Py_DECREF(mod); /* ideally would decref, but in this case we never want to free */
413 }
414 }
415 #endif
416
417 /* bpy.* and lets us import it */
418 BPy_init_modules(C);
419
420 pyrna_alloc_types();
421
422 #ifndef WITH_PYTHON_MODULE
423 /* py module runs atexit when bpy is freed */
424 BPY_atexit_register(); /* this can init any time */
425
426 py_tstate = PyGILState_GetThisThreadState();
427 PyEval_ReleaseThread(py_tstate);
428 #endif
429 }
430
BPY_python_end(void)431 void BPY_python_end(void)
432 {
433 // fprintf(stderr, "Ending Python!\n");
434 PyGILState_STATE gilstate;
435
436 /* finalizing, no need to grab the state, except when we are a module */
437 gilstate = PyGILState_Ensure();
438
439 /* free other python data. */
440 pyrna_free_types();
441
442 /* clear all python data from structs */
443
444 bpy_intern_string_exit();
445
446 /* bpy.app modules that need cleanup */
447 BPY_app_translations_end();
448
449 #ifndef WITH_PYTHON_MODULE
450 BPY_atexit_unregister(); /* without this we get recursive calls to WM_exit */
451
452 Py_Finalize();
453
454 (void)gilstate;
455 #else
456 PyGILState_Release(gilstate);
457 #endif
458
459 #ifdef TIME_PY_RUN
460 /* measure time since py started */
461 bpy_timer = PIL_check_seconds_timer() - bpy_timer;
462
463 printf("*bpy stats* - ");
464 printf("tot exec: %d, ", bpy_timer_count);
465 printf("tot run: %.4fsec, ", bpy_timer_run_tot);
466 if (bpy_timer_count > 0) {
467 printf("average run: %.6fsec, ", (bpy_timer_run_tot / bpy_timer_count));
468 }
469
470 if (bpy_timer > 0.0) {
471 printf("tot usage %.4f%%", (bpy_timer_run_tot / bpy_timer) * 100.0);
472 }
473
474 printf("\n");
475
476 // fprintf(stderr, "Ending Python Done!\n");
477
478 #endif
479 }
480
BPY_python_reset(bContext * C)481 void BPY_python_reset(bContext *C)
482 {
483 /* unrelated security stuff */
484 G.f &= ~(G_FLAG_SCRIPT_AUTOEXEC_FAIL | G_FLAG_SCRIPT_AUTOEXEC_FAIL_QUIET);
485 G.autoexec_fail[0] = '\0';
486
487 BPY_driver_reset();
488 BPY_app_handlers_reset(false);
489 BPY_modules_load_user(C);
490 }
491
BPY_python_use_system_env(void)492 void BPY_python_use_system_env(void)
493 {
494 BLI_assert(!Py_IsInitialized());
495 py_use_system_env = true;
496 }
497
BPY_python_backtrace(FILE * fp)498 void BPY_python_backtrace(FILE *fp)
499 {
500 fputs("\n# Python backtrace\n", fp);
501 PyThreadState *tstate = PyGILState_GetThisThreadState();
502 if (tstate != NULL && tstate->frame != NULL) {
503 PyFrameObject *frame = tstate->frame;
504 do {
505 const int line = PyCode_Addr2Line(frame->f_code, frame->f_lasti);
506 const char *filename = _PyUnicode_AsString(frame->f_code->co_filename);
507 const char *funcname = _PyUnicode_AsString(frame->f_code->co_name);
508 fprintf(fp, " File \"%s\", line %d in %s\n", filename, line, funcname);
509 } while ((frame = frame->f_back));
510 }
511 }
512
BPY_DECREF(void * pyob_ptr)513 void BPY_DECREF(void *pyob_ptr)
514 {
515 const PyGILState_STATE gilstate = PyGILState_Ensure();
516 Py_DECREF((PyObject *)pyob_ptr);
517 PyGILState_Release(gilstate);
518 }
519
BPY_DECREF_RNA_INVALIDATE(void * pyob_ptr)520 void BPY_DECREF_RNA_INVALIDATE(void *pyob_ptr)
521 {
522 const PyGILState_STATE gilstate = PyGILState_Ensure();
523 const int do_invalidate = (Py_REFCNT((PyObject *)pyob_ptr) > 1);
524 Py_DECREF((PyObject *)pyob_ptr);
525 if (do_invalidate) {
526 pyrna_invalidate(pyob_ptr);
527 }
528 PyGILState_Release(gilstate);
529 }
530
BPY_modules_load_user(bContext * C)531 void BPY_modules_load_user(bContext *C)
532 {
533 PyGILState_STATE gilstate;
534 Main *bmain = CTX_data_main(C);
535 Text *text;
536
537 /* can happen on file load */
538 if (bmain == NULL) {
539 return;
540 }
541
542 /* update pointers since this can run from a nested script
543 * on file load */
544 if (py_call_level) {
545 BPY_context_update(C);
546 }
547
548 bpy_context_set(C, &gilstate);
549
550 for (text = bmain->texts.first; text; text = text->id.next) {
551 if (text->flags & TXT_ISSCRIPT && BLI_path_extension_check(text->id.name + 2, ".py")) {
552 if (!(G.f & G_FLAG_SCRIPT_AUTOEXEC)) {
553 if (!(G.f & G_FLAG_SCRIPT_AUTOEXEC_FAIL_QUIET)) {
554 G.f |= G_FLAG_SCRIPT_AUTOEXEC_FAIL;
555 BLI_snprintf(G.autoexec_fail, sizeof(G.autoexec_fail), "Text '%s'", text->id.name + 2);
556
557 printf("scripts disabled for \"%s\", skipping '%s'\n",
558 BKE_main_blendfile_path(bmain),
559 text->id.name + 2);
560 }
561 }
562 else {
563 BPY_run_text(C, text, NULL, false);
564
565 /* Check if the script loaded a new file. */
566 if (bmain != CTX_data_main(C)) {
567 break;
568 }
569 }
570 }
571 }
572 bpy_context_clear(C, &gilstate);
573 }
574
BPY_context_member_get(bContext * C,const char * member,bContextDataResult * result)575 int BPY_context_member_get(bContext *C, const char *member, bContextDataResult *result)
576 {
577 PyGILState_STATE gilstate;
578 const bool use_gil = !PyC_IsInterpreterActive();
579
580 PyObject *pyctx;
581 PyObject *item;
582 PointerRNA *ptr = NULL;
583 bool done = false;
584
585 if (use_gil) {
586 gilstate = PyGILState_Ensure();
587 }
588
589 pyctx = (PyObject *)CTX_py_dict_get(C);
590 item = PyDict_GetItemString(pyctx, member);
591
592 if (item == NULL) {
593 /* pass */
594 }
595 else if (item == Py_None) {
596 done = true;
597 }
598 else if (BPy_StructRNA_Check(item)) {
599 ptr = &(((BPy_StructRNA *)item)->ptr);
600
601 // result->ptr = ((BPy_StructRNA *)item)->ptr;
602 CTX_data_pointer_set(result, ptr->owner_id, ptr->type, ptr->data);
603 CTX_data_type_set(result, CTX_DATA_TYPE_POINTER);
604 done = true;
605 }
606 else if (PySequence_Check(item)) {
607 PyObject *seq_fast = PySequence_Fast(item, "bpy_context_get sequence conversion");
608 if (seq_fast == NULL) {
609 PyErr_Print();
610 PyErr_Clear();
611 }
612 else {
613 const int len = PySequence_Fast_GET_SIZE(seq_fast);
614 PyObject **seq_fast_items = PySequence_Fast_ITEMS(seq_fast);
615 int i;
616
617 for (i = 0; i < len; i++) {
618 PyObject *list_item = seq_fast_items[i];
619
620 if (BPy_StructRNA_Check(list_item)) {
621 #if 0
622 CollectionPointerLink *link = MEM_callocN(sizeof(CollectionPointerLink),
623 "bpy_context_get");
624 link->ptr = ((BPy_StructRNA *)item)->ptr;
625 BLI_addtail(&result->list, link);
626 #endif
627 ptr = &(((BPy_StructRNA *)list_item)->ptr);
628 CTX_data_list_add(result, ptr->owner_id, ptr->type, ptr->data);
629 }
630 else {
631 CLOG_INFO(BPY_LOG_CONTEXT,
632 1,
633 "'%s' list item not a valid type in sequence type '%s'",
634 member,
635 Py_TYPE(item)->tp_name);
636 }
637 }
638 Py_DECREF(seq_fast);
639 CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
640 done = true;
641 }
642 }
643
644 if (done == false) {
645 if (item) {
646 CLOG_INFO(BPY_LOG_CONTEXT, 1, "'%s' not a valid type", member);
647 }
648 else {
649 CLOG_INFO(BPY_LOG_CONTEXT, 1, "'%s' not found\n", member);
650 }
651 }
652 else {
653 CLOG_INFO(BPY_LOG_CONTEXT, 2, "'%s' found", member);
654 }
655
656 if (use_gil) {
657 PyGILState_Release(gilstate);
658 }
659
660 return done;
661 }
662
663 #ifdef WITH_PYTHON_MODULE
664 /* TODO, reloading the module isn't functional at the moment. */
665
666 static void bpy_module_free(void *mod);
667
668 /* Defined in 'creator.c' when building as a Python module. */
669 extern int main_python_enter(int argc, const char **argv);
670 extern void main_python_exit(void);
671
672 static struct PyModuleDef bpy_proxy_def = {
673 PyModuleDef_HEAD_INIT,
674 "bpy", /* m_name */
675 NULL, /* m_doc */
676 0, /* m_size */
677 NULL, /* m_methods */
678 NULL, /* m_reload */
679 NULL, /* m_traverse */
680 NULL, /* m_clear */
681 bpy_module_free, /* m_free */
682 };
683
684 typedef struct {
685 PyObject_HEAD
686 /* Type-specific fields go here. */
687 PyObject *mod;
688 } dealloc_obj;
689
690 /* call once __file__ is set */
bpy_module_delay_init(PyObject * bpy_proxy)691 static void bpy_module_delay_init(PyObject *bpy_proxy)
692 {
693 const int argc = 1;
694 const char *argv[2];
695
696 /* updating the module dict below will lose the reference to __file__ */
697 PyObject *filename_obj = PyModule_GetFilenameObject(bpy_proxy);
698
699 const char *filename_rel = _PyUnicode_AsString(filename_obj); /* can be relative */
700 char filename_abs[1024];
701
702 BLI_strncpy(filename_abs, filename_rel, sizeof(filename_abs));
703 BLI_path_abs_from_cwd(filename_abs, sizeof(filename_abs));
704 Py_DECREF(filename_obj);
705
706 argv[0] = filename_abs;
707 argv[1] = NULL;
708
709 // printf("module found %s\n", argv[0]);
710
711 main_python_enter(argc, argv);
712
713 /* initialized in BPy_init_modules() */
714 PyDict_Update(PyModule_GetDict(bpy_proxy), PyModule_GetDict(bpy_package_py));
715 }
716
717 static void dealloc_obj_dealloc(PyObject *self);
718
719 static PyTypeObject dealloc_obj_Type;
720
721 /* use our own dealloc so we can free a property if we use one */
dealloc_obj_dealloc(PyObject * self)722 static void dealloc_obj_dealloc(PyObject *self)
723 {
724 bpy_module_delay_init(((dealloc_obj *)self)->mod);
725
726 /* Note, for subclassed PyObjects we cant just call PyObject_DEL() directly or it will crash */
727 dealloc_obj_Type.tp_free(self);
728 }
729
730 PyMODINIT_FUNC PyInit_bpy(void);
731
PyInit_bpy(void)732 PyMODINIT_FUNC PyInit_bpy(void)
733 {
734 PyObject *bpy_proxy = PyModule_Create(&bpy_proxy_def);
735
736 /* Problem:
737 * 1) this init function is expected to have a private member defined - 'md_def'
738 * but this is only set for C defined modules (not py packages)
739 * so we cant return 'bpy_package_py' as is.
740 *
741 * 2) there is a 'bpy' C module for python to load which is basically all of blender,
742 * and there is scripts/bpy/__init__.py,
743 * we may end up having to rename this module so there is no naming conflict here eg:
744 * 'from blender import bpy'
745 *
746 * 3) we don't know the filename at this point, workaround by assigning a dummy value
747 * which calls back when its freed so the real loading can take place.
748 */
749
750 /* assign an object which is freed after __file__ is assigned */
751 dealloc_obj *dob;
752
753 /* assign dummy type */
754 dealloc_obj_Type.tp_name = "dealloc_obj";
755 dealloc_obj_Type.tp_basicsize = sizeof(dealloc_obj);
756 dealloc_obj_Type.tp_dealloc = dealloc_obj_dealloc;
757 dealloc_obj_Type.tp_flags = Py_TPFLAGS_DEFAULT;
758
759 if (PyType_Ready(&dealloc_obj_Type) < 0) {
760 return NULL;
761 }
762
763 dob = (dealloc_obj *)dealloc_obj_Type.tp_alloc(&dealloc_obj_Type, 0);
764 dob->mod = bpy_proxy; /* borrow */
765 PyModule_AddObject(bpy_proxy, "__file__", (PyObject *)dob); /* borrow */
766
767 return bpy_proxy;
768 }
769
bpy_module_free(void * UNUSED (mod))770 static void bpy_module_free(void *UNUSED(mod))
771 {
772 main_python_exit();
773 }
774
775 #endif
776
777 /**
778 * Avoids duplicating keyword list.
779 */
BPY_string_is_keyword(const char * str)780 bool BPY_string_is_keyword(const char *str)
781 {
782 /* list is from...
783 * ", ".join(['"%s"' % kw for kw in __import__("keyword").kwlist])
784 */
785 const char *kwlist[] = {
786 "False", "None", "True", "and", "as", "assert", "async", "await", "break",
787 "class", "continue", "def", "del", "elif", "else", "except", "finally", "for",
788 "from", "global", "if", "import", "in", "is", "lambda", "nonlocal", "not",
789 "or", "pass", "raise", "return", "try", "while", "with", "yield", NULL,
790 };
791
792 for (int i = 0; kwlist[i]; i++) {
793 if (STREQ(str, kwlist[i])) {
794 return true;
795 }
796 }
797
798 return false;
799 }
800
801 /* EVIL, define text.c functions here... */
802 /* BKE_text.h */
text_check_identifier_unicode(const uint ch)803 int text_check_identifier_unicode(const uint ch)
804 {
805 return (ch < 255 && text_check_identifier((char)ch)) || Py_UNICODE_ISALNUM(ch);
806 }
807
text_check_identifier_nodigit_unicode(const uint ch)808 int text_check_identifier_nodigit_unicode(const uint ch)
809 {
810 return (ch < 255 && text_check_identifier_nodigit((char)ch)) || Py_UNICODE_ISALPHA(ch);
811 }
812