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