| 
									
										
										
										
											2011-02-23 10:52:22 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2009-08-26 06:15:43 +00:00
										 |  |  |  * This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  |  * as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  |  * of the License, or (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  * along with this program; if not, write to the Free Software Foundation, | 
					
						
							| 
									
										
										
										
											2010-02-12 13:34:04 +00:00
										 |  |  |  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							| 
									
										
										
										
											2009-08-26 06:15:43 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Chris Keith, Chris Want, Ken Hughes, Campbell Barton | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2011-02-27 20:10:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-18 08:08:12 +11:00
										 |  |  | /** \file
 | 
					
						
							|  |  |  |  * \ingroup pythonintern | 
					
						
							| 
									
										
										
										
											2011-11-05 08:21:12 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * This file deals with embedding the python interpreter within blender, | 
					
						
							|  |  |  |  * starting and stopping python and exposing blender/python modules so they can | 
					
						
							|  |  |  |  * be accesses from scripts. | 
					
						
							| 
									
										
										
										
											2011-02-27 20:10:08 +00:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-27 06:05:22 +00:00
										 |  |  | #include <Python.h>
 | 
					
						
							| 
									
										
										
										
											2020-08-17 17:21:11 +10:00
										 |  |  | #include <frameobject.h>
 | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-07 18:36:47 +00:00
										 |  |  | #include "MEM_guardedalloc.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-02 11:05:15 +02:00
										 |  |  | #include "CLG_log.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-07 05:26:12 +00:00
										 |  |  | #include "BLI_fileops.h"
 | 
					
						
							|  |  |  | #include "BLI_listbase.h"
 | 
					
						
							| 
									
										
										
										
											2020-03-19 09:33:03 +01:00
										 |  |  | #include "BLI_path_util.h"
 | 
					
						
							| 
									
										
										
										
											2013-01-07 05:26:12 +00:00
										 |  |  | #include "BLI_string.h"
 | 
					
						
							|  |  |  | #include "BLI_string_utf8.h"
 | 
					
						
							|  |  |  | #include "BLI_threads.h"
 | 
					
						
							| 
									
										
										
										
											2020-03-19 09:33:03 +01:00
										 |  |  | #include "BLI_utildefines.h"
 | 
					
						
							| 
									
										
										
										
											2013-01-07 05:26:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-02 04:51:43 +00:00
										 |  |  | #include "RNA_types.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-11 14:08:22 +00:00
										 |  |  | #include "bpy.h"
 | 
					
						
							| 
									
										
										
										
											2017-11-29 21:11:29 +11:00
										 |  |  | #include "bpy_capi_utils.h"
 | 
					
						
							| 
									
										
										
										
											2011-06-18 08:45:45 +00:00
										 |  |  | #include "bpy_intern_string.h"
 | 
					
						
							| 
									
										
										
										
											2020-03-19 09:33:03 +01:00
										 |  |  | #include "bpy_path.h"
 | 
					
						
							|  |  |  | #include "bpy_rna.h"
 | 
					
						
							|  |  |  | #include "bpy_traceback.h"
 | 
					
						
							| 
									
										
										
										
											2009-02-28 13:27:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-01 09:34:01 +02:00
										 |  |  | #include "bpy_app_translations.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-04 13:26:33 +00:00
										 |  |  | #include "DNA_text_types.h"
 | 
					
						
							| 
									
										
										
										
											2009-04-11 02:18:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-23 14:37:13 +01:00
										 |  |  | #include "BKE_appdir.h"
 | 
					
						
							| 
									
										
										
										
											2009-04-11 02:18:24 +00:00
										 |  |  | #include "BKE_context.h"
 | 
					
						
							| 
									
										
										
										
											2010-02-27 01:27:22 +00:00
										 |  |  | #include "BKE_global.h" /* only for script checking */
 | 
					
						
							| 
									
										
										
										
											2018-11-07 15:37:31 +01:00
										 |  |  | #include "BKE_main.h"
 | 
					
						
							|  |  |  | #include "BKE_text.h"
 | 
					
						
							| 
									
										
										
										
											2009-04-11 02:18:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-16 13:57:03 +02:00
										 |  |  | #ifdef WITH_CYCLES
 | 
					
						
							|  |  |  | #  include "CCL_api.h"
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2012-01-09 16:58:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
											
												2.5
More cleanup!
- removed old UI font completely, including from uiBeginBlock
- emboss hints for uiBlock only have three types now;
  Regular, Pulldown, or "Nothing" (only icon/text)
- removed old font path from Userdef
- removed all old button theme hinting
- removed old "auto block" to merge buttons in groups
  (was only in use for radiosity buttons)
And went over all warnings. One hooray for make giving clean output :)
Well, we need uniform definitions for warnings, so people at least fix
them... here's the real bad bugs I found:
- in mesh code, a call to editmesh mixed *em and *me
- in armature, ED_util.h was not included, so no warnings for wrong call
  to ED_undo_push()
- The extern Py api .h was not included in the bpy_interface.c, showing
  a several calls using different args.
Further just added the missing includes, and removed unused vars.
											
										 
											2009-04-14 15:59:52 +00:00
										 |  |  | #include "BPY_extern.h"
 | 
					
						
							| 
									
										
										
										
											2020-08-17 17:20:12 +10:00
										 |  |  | #include "BPY_extern_python.h"
 | 
					
						
							| 
									
										
										
										
											2020-08-17 17:46:06 +10:00
										 |  |  | #include "BPY_extern_run.h"
 | 
					
						
							| 
									
										
										
											
												2.5
More cleanup!
- removed old UI font completely, including from uiBeginBlock
- emboss hints for uiBlock only have three types now;
  Regular, Pulldown, or "Nothing" (only icon/text)
- removed old font path from Userdef
- removed all old button theme hinting
- removed old "auto block" to merge buttons in groups
  (was only in use for radiosity buttons)
And went over all warnings. One hooray for make giving clean output :)
Well, we need uniform definitions for warnings, so people at least fix
them... here's the real bad bugs I found:
- in mesh code, a call to editmesh mixed *em and *me
- in armature, ED_util.h was not included, so no warnings for wrong call
  to ED_undo_push()
- The extern Py api .h was not included in the bpy_interface.c, showing
  a several calls using different args.
Further just added the missing includes, and removed unused vars.
											
										 
											2009-04-14 15:59:52 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-18 15:30:03 +00:00
										 |  |  | #include "../generic/py_capi_utils.h"
 | 
					
						
							| 
									
										
										
										
											2009-06-17 20:33:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-14 04:15:25 +00:00
										 |  |  | /* inittab initialization functions */ | 
					
						
							| 
									
										
										
										
											2020-03-19 09:33:03 +01:00
										 |  |  | #include "../bmesh/bmesh_py_api.h"
 | 
					
						
							| 
									
										
										
										
											2011-02-14 04:15:25 +00:00
										 |  |  | #include "../generic/bgl.h"
 | 
					
						
							| 
									
										
										
										
											2020-07-04 13:20:59 +03:00
										 |  |  | #include "../generic/bl_math_py_api.h"
 | 
					
						
							| 
									
										
										
										
											2011-02-14 04:15:25 +00:00
										 |  |  | #include "../generic/blf_py_api.h"
 | 
					
						
							| 
									
										
										
										
											2012-04-15 14:54:15 +00:00
										 |  |  | #include "../generic/idprop_py_api.h"
 | 
					
						
							| 
									
										
										
										
											2018-06-07 07:41:49 +02:00
										 |  |  | #include "../generic/imbuf_py_api.h"
 | 
					
						
							| 
									
										
										
										
											2019-01-03 00:55:07 +11:00
										 |  |  | #include "../gpu/gpu_py_api.h"
 | 
					
						
							| 
									
										
										
										
											2011-07-15 04:01:47 +00:00
										 |  |  | #include "../mathutils/mathutils.h"
 | 
					
						
							| 
									
										
										
										
											2011-02-14 04:15:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-02 11:05:15 +02:00
										 |  |  | /* Logging types to use anywhere in the Python modules. */ | 
					
						
							|  |  |  | CLG_LOGREF_DECLARE_GLOBAL(BPY_LOG_CONTEXT, "bpy.context"); | 
					
						
							|  |  |  | CLG_LOGREF_DECLARE_GLOBAL(BPY_LOG_RNA, "bpy.rna"); | 
					
						
							| 
									
										
										
										
											2012-04-15 14:54:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-07 16:20:19 +00:00
										 |  |  | /* for internal use, when starting and ending python scripts */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-29 19:59:13 +10:00
										 |  |  | /* In case a python script triggers another python call,
 | 
					
						
							|  |  |  |  * stop bpy_context_clear from invalidating. */ | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  | static int py_call_level = 0; | 
					
						
							| 
									
										
										
										
											2009-08-09 13:20:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-16 21:11:05 +11:00
										 |  |  | /* Set by command line arguments before Python starts. */ | 
					
						
							|  |  |  | static bool py_use_system_env = false; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 18:19:55 +11:00
										 |  |  | // #define TIME_PY_RUN /* simple python tests. prints on exit. */
 | 
					
						
							| 
									
										
										
										
											2009-08-09 13:20:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef TIME_PY_RUN
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | #  include "PIL_time.h"
 | 
					
						
							|  |  |  | static int bpy_timer_count = 0; | 
					
						
							|  |  |  | static double bpy_timer;         /* time since python starts */ | 
					
						
							|  |  |  | static double bpy_timer_run;     /* time for each python script run */ | 
					
						
							|  |  |  | static double bpy_timer_run_tot; /* accumulate python runs */ | 
					
						
							| 
									
										
										
										
											2009-08-09 13:20:12 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-20 13:29:42 +00:00
										 |  |  | /* use for updating while a python script runs - in case of file load */ | 
					
						
							| 
									
										
										
										
											2012-05-08 22:07:06 +00:00
										 |  |  | void BPY_context_update(bContext *C) | 
					
						
							| 
									
										
										
										
											2011-08-20 13:29:42 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   /* don't do this from a non-main (e.g. render) thread, it can cause a race
 | 
					
						
							|  |  |  |    * condition on C->data.recursion. ideal solution would be to disable | 
					
						
							|  |  |  |    * context entirely from non-main threads, but that's more complicated */ | 
					
						
							|  |  |  |   if (!BLI_thread_is_main()) { | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   BPy_SetContext(C); | 
					
						
							|  |  |  |   BPY_modules_update(C); /* can give really bad results if this isn't here */ | 
					
						
							| 
									
										
										
										
											2011-08-20 13:29:42 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-07 16:20:19 +00:00
										 |  |  | void bpy_context_set(bContext *C, PyGILState_STATE *gilstate) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   py_call_level++; | 
					
						
							| 
									
										
										
										
											2009-08-07 16:20:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (gilstate) { | 
					
						
							|  |  |  |     *gilstate = PyGILState_Ensure(); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-08-07 16:20:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (py_call_level == 1) { | 
					
						
							|  |  |  |     BPY_context_update(C); | 
					
						
							| 
									
										
										
										
											2009-11-05 11:17:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-09 13:20:12 +00:00
										 |  |  | #ifdef TIME_PY_RUN
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     if (bpy_timer_count == 0) { | 
					
						
							|  |  |  |       /* record time from the beginning */ | 
					
						
							|  |  |  |       bpy_timer = PIL_check_seconds_timer(); | 
					
						
							|  |  |  |       bpy_timer_run = bpy_timer_run_tot = 0.0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     bpy_timer_run = PIL_check_seconds_timer(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bpy_timer_count++; | 
					
						
							| 
									
										
										
										
											2009-08-09 13:20:12 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-08-07 16:20:19 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-13 23:25:08 +00:00
										 |  |  | /* context should be used but not now because it causes some bugs */ | 
					
						
							| 
									
										
										
										
											2020-07-13 11:27:09 +02:00
										 |  |  | void bpy_context_clear(bContext *UNUSED(C), const PyGILState_STATE *gilstate) | 
					
						
							| 
									
										
										
										
											2009-08-07 16:20:19 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   py_call_level--; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (gilstate) { | 
					
						
							|  |  |  |     PyGILState_Release(*gilstate); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (py_call_level < 0) { | 
					
						
							|  |  |  |     fprintf(stderr, "ERROR: Python context internal state bug. this should not happen!\n"); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else if (py_call_level == 0) { | 
					
						
							|  |  |  |     /* XXX - Calling classes currently wont store the context :\,
 | 
					
						
							|  |  |  |      * cant set NULL because of this. but this is very flakey still. */ | 
					
						
							| 
									
										
										
										
											2011-11-26 15:18:30 +00:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     BPy_SetContext(NULL); | 
					
						
							| 
									
										
										
										
											2011-11-26 15:18:30 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2009-08-09 13:20:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef TIME_PY_RUN
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     bpy_timer_run_tot += PIL_check_seconds_timer() - bpy_timer_run; | 
					
						
							|  |  |  |     bpy_timer_count++; | 
					
						
							| 
									
										
										
										
											2009-08-09 13:20:12 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-08-07 16:20:19 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-17 18:23:12 +10:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2020-09-19 14:18:05 +10:00
										 |  |  |  * Use for `CTX_*_set(..)` functions need to set values which are later read back as expected. | 
					
						
							| 
									
										
										
										
											2020-09-17 18:23:12 +10:00
										 |  |  |  * In this case we don't want the Python context to override the values as it causes problems | 
					
						
							|  |  |  |  * see T66256. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * \param dict_p: A pointer to #bContext.data.py_context so we can assign a new value. | 
					
						
							|  |  |  |  * \param dict_orig: The value of #bContext.data.py_context_orig to check if we need to copy. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * \note Typically accessed via #BPY_context_dict_clear_members macro. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | void BPY_context_dict_clear_members_array(void **dict_p, | 
					
						
							|  |  |  |                                           void *dict_orig, | 
					
						
							|  |  |  |                                           const char *context_members[], | 
					
						
							|  |  |  |                                           uint context_members_len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   PyGILState_STATE gilstate; | 
					
						
							|  |  |  |   const bool use_gil = !PyC_IsInterpreterActive(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (use_gil) { | 
					
						
							|  |  |  |     gilstate = PyGILState_Ensure(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* Copy on write. */ | 
					
						
							|  |  |  |   if (*dict_p == dict_orig) { | 
					
						
							|  |  |  |     *dict_p = PyDict_Copy(dict_orig); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   PyObject *dict = *dict_p; | 
					
						
							|  |  |  |   BLI_assert(PyDict_Check(dict)); | 
					
						
							|  |  |  |   for (uint i = 0; i < context_members_len; i++) { | 
					
						
							| 
									
										
										
										
											2020-09-17 21:01:20 +10:00
										 |  |  |     if (PyDict_DelItemString(dict, context_members[i])) { | 
					
						
							|  |  |  |       PyErr_Clear(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-09-17 18:23:12 +10:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (use_gil) { | 
					
						
							|  |  |  |     PyGILState_Release(gilstate); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-05 02:08:54 +00:00
										 |  |  | void BPY_text_free_code(Text *text) | 
					
						
							| 
									
										
										
										
											2009-03-04 13:26:33 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (text->compiled) { | 
					
						
							|  |  |  |     PyGILState_STATE gilstate; | 
					
						
							| 
									
										
										
										
											2020-08-20 16:10:13 +10:00
										 |  |  |     const bool use_gil = !PyC_IsInterpreterActive(); | 
					
						
							| 
									
										
										
										
											2012-09-10 23:32:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     if (use_gil) { | 
					
						
							|  |  |  |       gilstate = PyGILState_Ensure(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2012-09-10 23:32:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     Py_DECREF((PyObject *)text->compiled); | 
					
						
							|  |  |  |     text->compiled = NULL; | 
					
						
							| 
									
										
										
										
											2012-09-10 23:32:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     if (use_gil) { | 
					
						
							|  |  |  |       PyGILState_Release(gilstate); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-03-04 13:26:33 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-05 02:08:54 +00:00
										 |  |  | void BPY_modules_update(bContext *C) | 
					
						
							| 
									
										
										
										
											2009-04-11 16:17:39 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | #if 0 /* slow, this runs all the time poll, draw etc 100's of time a sec. */
 | 
					
						
							|  |  |  |   PyObject *mod = PyImport_ImportModuleLevel("bpy", NULL, NULL, NULL, 0); | 
					
						
							|  |  |  |   PyModule_AddObject(mod, "data", BPY_rna_module()); | 
					
						
							| 
									
										
										
										
											2019-04-17 08:24:14 +02:00
										 |  |  |   PyModule_AddObject(mod, "types", BPY_rna_types()); /* atm this does not need updating */ | 
					
						
							| 
									
										
										
										
											2009-08-15 09:53:38 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   /* refreshes the main struct */ | 
					
						
							|  |  |  |   BPY_update_rna_module(); | 
					
						
							|  |  |  |   if (bpy_context_module) { | 
					
						
							|  |  |  |     bpy_context_module->ptr.data = (void *)C; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-04-11 16:17:39 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-05 02:08:54 +00:00
										 |  |  | void BPY_context_set(bContext *C) | 
					
						
							| 
									
										
										
										
											2009-11-13 09:28:05 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   BPy_SetContext(C); | 
					
						
							| 
									
										
										
										
											2009-11-13 09:28:05 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-16 15:50:14 +01:00
										 |  |  | #ifdef WITH_FLUID
 | 
					
						
							|  |  |  | /* defined in manta module */ | 
					
						
							|  |  |  | extern PyObject *Manta_initPython(void); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef WITH_AUDASPACE
 | 
					
						
							| 
									
										
										
										
											2011-02-14 04:15:25 +00:00
										 |  |  | /* defined in AUD_C-API.cpp */ | 
					
						
							| 
									
										
										
										
											2010-10-29 22:59:39 +00:00
										 |  |  | extern PyObject *AUD_initPython(void); | 
					
						
							| 
									
										
										
										
											2019-12-16 15:50:14 +01:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2012-01-09 16:58:01 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef WITH_CYCLES
 | 
					
						
							|  |  |  | /* defined in cycles module */ | 
					
						
							|  |  |  | static PyObject *CCL_initPython(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return (PyObject *)CCL_python_module_init(); | 
					
						
							| 
									
										
										
										
											2012-01-09 16:58:01 +00:00
										 |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-10-29 22:59:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  | static struct _inittab bpy_internal_modules[] = { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     {"mathutils", PyInit_mathutils}, | 
					
						
							| 
									
										
										
										
											2014-07-01 13:39:36 +10:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2019-04-17 08:24:14 +02:00
										 |  |  |     {"mathutils.geometry", PyInit_mathutils_geometry}, | 
					
						
							|  |  |  |     {"mathutils.noise", PyInit_mathutils_noise}, | 
					
						
							|  |  |  |     {"mathutils.kdtree", PyInit_mathutils_kdtree}, | 
					
						
							| 
									
										
										
										
											2014-07-01 13:39:36 +10:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     {"_bpy_path", BPyInit__bpy_path}, | 
					
						
							|  |  |  |     {"bgl", BPyInit_bgl}, | 
					
						
							|  |  |  |     {"blf", BPyInit_blf}, | 
					
						
							| 
									
										
										
										
											2020-07-04 13:20:59 +03:00
										 |  |  |     {"bl_math", BPyInit_bl_math}, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     {"imbuf", BPyInit_imbuf}, | 
					
						
							|  |  |  |     {"bmesh", BPyInit_bmesh}, | 
					
						
							| 
									
										
										
										
											2014-07-01 13:39:36 +10:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2019-04-17 08:24:14 +02:00
										 |  |  |     {"bmesh.types", BPyInit_bmesh_types}, | 
					
						
							|  |  |  |     {"bmesh.utils", BPyInit_bmesh_utils}, | 
					
						
							|  |  |  |     {"bmesh.utils", BPyInit_bmesh_geometry}, | 
					
						
							| 
									
										
										
										
											2014-07-01 13:39:36 +10:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-12-16 15:50:14 +01:00
										 |  |  | #ifdef WITH_FLUID
 | 
					
						
							|  |  |  |     {"manta", Manta_initPython}, | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2011-06-23 09:27:56 +00:00
										 |  |  | #ifdef WITH_AUDASPACE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     {"aud", AUD_initPython}, | 
					
						
							| 
									
										
										
										
											2011-08-16 16:15:34 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | #ifdef WITH_CYCLES
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     {"_cycles", CCL_initPython}, | 
					
						
							| 
									
										
										
										
											2011-06-23 09:27:56 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     {"gpu", BPyInit_gpu}, | 
					
						
							|  |  |  |     {"idprop", BPyInit_idprop}, | 
					
						
							|  |  |  |     {NULL, NULL}, | 
					
						
							| 
									
										
										
										
											2010-10-29 22:59:39 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-05 02:08:54 +00:00
										 |  |  | /* call BPY_context_set first */ | 
					
						
							| 
									
										
										
										
											2011-02-19 12:05:20 +00:00
										 |  |  | void BPY_python_start(int argc, const char **argv) | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-02-20 23:39:29 +00:00
										 |  |  | #ifndef WITH_PYTHON_MODULE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyThreadState *py_tstate = NULL; | 
					
						
							|  |  |  |   const char *py_path_bundle = BKE_appdir_folder_id(BLENDER_SYSTEM_PYTHON, NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-23 13:52:52 +10:00
										 |  |  |   /* Not essential but nice to set our name. */ | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     const char *program_path = BKE_appdir_program_path(); | 
					
						
							|  |  |  |     wchar_t program_path_wchar[FILE_MAX]; | 
					
						
							|  |  |  |     BLI_strncpy_wchar_from_utf8(program_path_wchar, program_path, ARRAY_SIZE(program_path_wchar)); | 
					
						
							|  |  |  |     Py_SetProgramName(program_path_wchar); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /* must run before python initializes */ | 
					
						
							|  |  |  |   PyImport_ExtendInittab(bpy_internal_modules); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* allow to use our own included python */ | 
					
						
							|  |  |  |   PyC_SetHomePath(py_path_bundle); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 17:12:48 +10:00
										 |  |  |   /* Without this the `sys.stdout` may be set to 'ascii'
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |    * (it is on my system at least), where printing unicode values will raise | 
					
						
							| 
									
										
										
										
											2020-07-19 17:12:48 +10:00
										 |  |  |    * an error, this is highly annoying, another stumbling block for developers, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |    * so use a more relaxed error handler and enforce utf-8 since the rest of | 
					
						
							| 
									
										
										
										
											2020-07-19 17:12:48 +10:00
										 |  |  |    * Blender is utf-8 too - campbell */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   Py_SetStandardStreamEncoding("utf-8", "surrogateescape"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-20 18:10:33 +11:00
										 |  |  |   /* Suppress error messages when calculating the module search path.
 | 
					
						
							|  |  |  |    * While harmless, it's noisy. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   Py_FrozenFlag = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-16 15:54:34 +02:00
										 |  |  |   /* Only use the systems environment variables and site when explicitly requested.
 | 
					
						
							| 
									
										
										
										
											2020-01-16 21:11:05 +11:00
										 |  |  |    * Since an incorrect 'PYTHONPATH' causes difficult to debug errors, see: T72807. */ | 
					
						
							|  |  |  |   Py_IgnoreEnvironmentFlag = !py_use_system_env; | 
					
						
							| 
									
										
										
										
											2020-04-16 15:54:34 +02:00
										 |  |  |   Py_NoUserSiteDirectory = !py_use_system_env; | 
					
						
							| 
									
										
										
										
											2020-01-16 21:11:05 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-17 19:00:23 +10:00
										 |  |  |   /* Initialize Python (also acquires lock). */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   Py_Initialize(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // PySys_SetArgv(argc, argv);  /* broken in py3, not a huge deal */
 | 
					
						
							|  |  |  |   /* sigh, why do python guys not have a (char **) version anymore? */ | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     int i; | 
					
						
							|  |  |  |     PyObject *py_argv = PyList_New(argc); | 
					
						
							|  |  |  |     for (i = 0; i < argc; i++) { | 
					
						
							| 
									
										
										
										
											2020-09-30 20:09:02 +10:00
										 |  |  |       /* should fix bug T20021 - utf path name problems, by replacing
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |        * PyUnicode_FromString, with this one */ | 
					
						
							|  |  |  |       PyList_SET_ITEM(py_argv, i, PyC_UnicodeFromByte(argv[i])); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     PySys_SetObject("argv", py_argv); | 
					
						
							|  |  |  |     Py_DECREF(py_argv); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-17 07:27:09 +11:00
										 |  |  | #  ifdef WITH_FLUID
 | 
					
						
							|  |  |  |   /* Required to prevent assertion error, see:
 | 
					
						
							|  |  |  |    * https://stackoverflow.com/questions/27844676 */
 | 
					
						
							| 
									
										
										
										
											2019-12-16 15:50:14 +01:00
										 |  |  |   Py_DECREF(PyImport_ImportModule("threading")); | 
					
						
							| 
									
										
										
										
											2019-12-17 07:27:09 +11:00
										 |  |  | #  endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-20 23:39:29 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   (void)argc; | 
					
						
							|  |  |  |   (void)argv; | 
					
						
							| 
									
										
										
										
											2011-03-25 01:55:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   /* must run before python initializes */ | 
					
						
							|  |  |  |   /* broken in py3.3, load explicitly below */ | 
					
						
							|  |  |  |   // PyImport_ExtendInittab(bpy_internal_modules);
 | 
					
						
							| 
									
										
										
										
											2011-02-20 23:39:29 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   bpy_intern_string_init(); | 
					
						
							| 
									
										
										
										
											2013-02-06 13:14:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef WITH_PYTHON_MODULE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |     /* Manually load all modules */ | 
					
						
							|  |  |  |     struct _inittab *inittab_item; | 
					
						
							|  |  |  |     PyObject *sys_modules = PyImport_GetModuleDict(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (inittab_item = bpy_internal_modules; inittab_item->name; inittab_item++) { | 
					
						
							|  |  |  |       PyObject *mod = inittab_item->initfunc(); | 
					
						
							|  |  |  |       if (mod) { | 
					
						
							|  |  |  |         PyDict_SetItemString(sys_modules, inittab_item->name, mod); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  |         PyErr_Print(); | 
					
						
							|  |  |  |         PyErr_Clear(); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       // Py_DECREF(mod); /* ideally would decref, but in this case we never want to free */
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2013-02-06 13:14:11 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   /* bpy.* and lets us import it */ | 
					
						
							|  |  |  |   BPy_init_modules(); | 
					
						
							| 
									
										
										
										
											2009-04-11 16:17:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   pyrna_alloc_types(); | 
					
						
							| 
									
										
										
										
											2009-08-15 09:53:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-17 15:19:11 +00:00
										 |  |  | #ifndef WITH_PYTHON_MODULE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   /* py module runs atexit when bpy is freed */ | 
					
						
							|  |  |  |   BPY_atexit_register(); /* this can init any time */ | 
					
						
							| 
									
										
										
										
											2011-09-20 12:22:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   py_tstate = PyGILState_GetThisThreadState(); | 
					
						
							|  |  |  |   PyEval_ReleaseThread(py_tstate); | 
					
						
							| 
									
										
										
										
											2011-02-20 23:39:29 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-05 02:08:54 +00:00
										 |  |  | void BPY_python_end(void) | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   // fprintf(stderr, "Ending Python!\n");
 | 
					
						
							|  |  |  |   PyGILState_STATE gilstate; | 
					
						
							| 
									
										
										
										
											2009-08-14 12:29:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   /* finalizing, no need to grab the state, except when we are a module */ | 
					
						
							|  |  |  |   gilstate = PyGILState_Ensure(); | 
					
						
							| 
									
										
										
										
											2018-06-04 08:54:17 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   /* free other python data. */ | 
					
						
							|  |  |  |   pyrna_free_types(); | 
					
						
							| 
									
										
										
										
											2009-08-14 12:29:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   /* clear all python data from structs */ | 
					
						
							| 
									
										
										
										
											2011-06-18 08:45:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   bpy_intern_string_exit(); | 
					
						
							| 
									
										
										
										
											2011-06-18 08:45:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   /* bpy.app modules that need cleanup */ | 
					
						
							|  |  |  |   BPY_app_translations_end(); | 
					
						
							| 
									
										
										
										
											2015-04-01 09:34:01 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-17 15:19:11 +00:00
										 |  |  | #ifndef WITH_PYTHON_MODULE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   BPY_atexit_unregister(); /* without this we get recursive calls to WM_exit */ | 
					
						
							| 
									
										
										
										
											2011-09-20 15:17:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   Py_Finalize(); | 
					
						
							| 
									
										
										
										
											2014-02-14 10:55:19 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   (void)gilstate; | 
					
						
							| 
									
										
										
										
											2014-02-13 06:53:42 +11:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyGILState_Release(gilstate); | 
					
						
							| 
									
										
										
										
											2014-02-13 06:53:42 +11:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-09 13:20:12 +00:00
										 |  |  | #ifdef TIME_PY_RUN
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   /* measure time since py started */ | 
					
						
							|  |  |  |   bpy_timer = PIL_check_seconds_timer() - bpy_timer; | 
					
						
							| 
									
										
										
										
											2009-08-09 13:20:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   printf("*bpy stats* - "); | 
					
						
							|  |  |  |   printf("tot exec: %d,  ", bpy_timer_count); | 
					
						
							|  |  |  |   printf("tot run: %.4fsec,  ", bpy_timer_run_tot); | 
					
						
							|  |  |  |   if (bpy_timer_count > 0) { | 
					
						
							|  |  |  |     printf("average run: %.6fsec,  ", (bpy_timer_run_tot / bpy_timer_count)); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-08-09 13:20:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (bpy_timer > 0.0) { | 
					
						
							|  |  |  |     printf("tot usage %.4f%%", (bpy_timer_run_tot / bpy_timer) * 100.0); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-08-09 13:20:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   printf("\n"); | 
					
						
							| 
									
										
										
										
											2009-08-09 13:20:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   // fprintf(stderr, "Ending Python Done!\n");
 | 
					
						
							| 
									
										
										
										
											2009-08-14 12:29:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-09 13:20:12 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-09 23:31:53 +00:00
										 |  |  | void BPY_python_reset(bContext *C) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   /* unrelated security stuff */ | 
					
						
							|  |  |  |   G.f &= ~(G_FLAG_SCRIPT_AUTOEXEC_FAIL | G_FLAG_SCRIPT_AUTOEXEC_FAIL_QUIET); | 
					
						
							|  |  |  |   G.autoexec_fail[0] = '\0'; | 
					
						
							| 
									
										
										
										
											2013-06-10 00:42:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   BPY_driver_reset(); | 
					
						
							|  |  |  |   BPY_app_handlers_reset(false); | 
					
						
							|  |  |  |   BPY_modules_load_user(C); | 
					
						
							| 
									
										
										
										
											2013-06-09 23:31:53 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-16 21:11:05 +11:00
										 |  |  | void BPY_python_use_system_env(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   BLI_assert(!Py_IsInitialized()); | 
					
						
							|  |  |  |   py_use_system_env = true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-17 17:21:11 +10:00
										 |  |  | void BPY_python_backtrace(FILE *fp) | 
					
						
							| 
									
										
										
										
											2020-08-06 15:34:55 +10:00
										 |  |  | { | 
					
						
							|  |  |  |   fputs("\n# Python backtrace\n", fp); | 
					
						
							| 
									
										
										
										
											2020-08-17 17:21:11 +10:00
										 |  |  |   PyThreadState *tstate = PyGILState_GetThisThreadState(); | 
					
						
							|  |  |  |   if (tstate != NULL && tstate->frame != NULL) { | 
					
						
							|  |  |  |     PyFrameObject *frame = tstate->frame; | 
					
						
							|  |  |  |     do { | 
					
						
							|  |  |  |       const int line = PyCode_Addr2Line(frame->f_code, frame->f_lasti); | 
					
						
							|  |  |  |       const char *filename = _PyUnicode_AsString(frame->f_code->co_filename); | 
					
						
							|  |  |  |       const char *funcname = _PyUnicode_AsString(frame->f_code->co_name); | 
					
						
							|  |  |  |       fprintf(fp, "  File \"%s\", line %d in %s\n", filename, line, funcname); | 
					
						
							|  |  |  |     } while ((frame = frame->f_back)); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-06 15:34:55 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-01 12:43:07 +00:00
										 |  |  | void BPY_DECREF(void *pyob_ptr) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-08-20 16:10:13 +10:00
										 |  |  |   const PyGILState_STATE gilstate = PyGILState_Ensure(); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   Py_DECREF((PyObject *)pyob_ptr); | 
					
						
							|  |  |  |   PyGILState_Release(gilstate); | 
					
						
							| 
									
										
										
										
											2009-04-01 12:43:07 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-26 10:54:02 +00:00
										 |  |  | void BPY_DECREF_RNA_INVALIDATE(void *pyob_ptr) | 
					
						
							| 
									
										
										
										
											2012-10-26 10:33:57 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-08-20 16:10:13 +10:00
										 |  |  |   const PyGILState_STATE gilstate = PyGILState_Ensure(); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   const int do_invalidate = (Py_REFCNT((PyObject *)pyob_ptr) > 1); | 
					
						
							|  |  |  |   Py_DECREF((PyObject *)pyob_ptr); | 
					
						
							|  |  |  |   if (do_invalidate) { | 
					
						
							|  |  |  |     pyrna_invalidate(pyob_ptr); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   PyGILState_Release(gilstate); | 
					
						
							| 
									
										
										
										
											2012-10-26 10:33:57 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-05 02:08:54 +00:00
										 |  |  | void BPY_modules_load_user(bContext *C) | 
					
						
							| 
									
										
										
										
											2009-11-20 15:01:09 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyGILState_STATE gilstate; | 
					
						
							|  |  |  |   Main *bmain = CTX_data_main(C); | 
					
						
							|  |  |  |   Text *text; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* can happen on file load */ | 
					
						
							|  |  |  |   if (bmain == NULL) { | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* update pointers since this can run from a nested script
 | 
					
						
							|  |  |  |    * on file load */ | 
					
						
							|  |  |  |   if (py_call_level) { | 
					
						
							|  |  |  |     BPY_context_update(C); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   bpy_context_set(C, &gilstate); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (text = bmain->texts.first; text; text = text->id.next) { | 
					
						
							|  |  |  |     if (text->flags & TXT_ISSCRIPT && BLI_path_extension_check(text->id.name + 2, ".py")) { | 
					
						
							|  |  |  |       if (!(G.f & G_FLAG_SCRIPT_AUTOEXEC)) { | 
					
						
							|  |  |  |         if (!(G.f & G_FLAG_SCRIPT_AUTOEXEC_FAIL_QUIET)) { | 
					
						
							|  |  |  |           G.f |= G_FLAG_SCRIPT_AUTOEXEC_FAIL; | 
					
						
							|  |  |  |           BLI_snprintf(G.autoexec_fail, sizeof(G.autoexec_fail), "Text '%s'", text->id.name + 2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           printf("scripts disabled for \"%s\", skipping '%s'\n", | 
					
						
							|  |  |  |                  BKE_main_blendfile_path(bmain), | 
					
						
							|  |  |  |                  text->id.name + 2); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							| 
									
										
										
										
											2020-08-17 17:46:06 +10:00
										 |  |  |         BPY_run_text(C, text, NULL, false); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-18 14:45:23 +02:00
										 |  |  |         /* Check if the script loaded a new file. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         if (bmain != CTX_data_main(C)) { | 
					
						
							|  |  |  |           break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   bpy_context_clear(C, &gilstate); | 
					
						
							| 
									
										
										
										
											2009-11-20 15:01:09 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-10-29 09:25:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-05 02:08:54 +00:00
										 |  |  | int BPY_context_member_get(bContext *C, const char *member, bContextDataResult *result) | 
					
						
							| 
									
										
										
										
											2009-10-29 09:25:11 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyGILState_STATE gilstate; | 
					
						
							| 
									
										
										
										
											2020-08-20 16:10:13 +10:00
										 |  |  |   const bool use_gil = !PyC_IsInterpreterActive(); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   PyObject *pyctx; | 
					
						
							|  |  |  |   PyObject *item; | 
					
						
							|  |  |  |   PointerRNA *ptr = NULL; | 
					
						
							|  |  |  |   bool done = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (use_gil) { | 
					
						
							|  |  |  |     gilstate = PyGILState_Ensure(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   pyctx = (PyObject *)CTX_py_dict_get(C); | 
					
						
							|  |  |  |   item = PyDict_GetItemString(pyctx, member); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (item == NULL) { | 
					
						
							|  |  |  |     /* pass */ | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else if (item == Py_None) { | 
					
						
							|  |  |  |     done = true; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else if (BPy_StructRNA_Check(item)) { | 
					
						
							|  |  |  |     ptr = &(((BPy_StructRNA *)item)->ptr); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-01 11:09:22 +10:00
										 |  |  |     // result->ptr = ((BPy_StructRNA *)item)->ptr;
 | 
					
						
							| 
									
										
										
										
											2019-08-23 09:52:12 +02:00
										 |  |  |     CTX_data_pointer_set(result, ptr->owner_id, ptr->type, ptr->data); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     CTX_data_type_set(result, CTX_DATA_TYPE_POINTER); | 
					
						
							|  |  |  |     done = true; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else if (PySequence_Check(item)) { | 
					
						
							|  |  |  |     PyObject *seq_fast = PySequence_Fast(item, "bpy_context_get sequence conversion"); | 
					
						
							|  |  |  |     if (seq_fast == NULL) { | 
					
						
							|  |  |  |       PyErr_Print(); | 
					
						
							|  |  |  |       PyErr_Clear(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2020-08-20 16:10:13 +10:00
										 |  |  |       const int len = PySequence_Fast_GET_SIZE(seq_fast); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       PyObject **seq_fast_items = PySequence_Fast_ITEMS(seq_fast); | 
					
						
							|  |  |  |       int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       for (i = 0; i < len; i++) { | 
					
						
							|  |  |  |         PyObject *list_item = seq_fast_items[i]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (BPy_StructRNA_Check(list_item)) { | 
					
						
							| 
									
										
										
										
											2012-03-03 20:36:09 +00:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2019-04-17 08:24:14 +02:00
										 |  |  |           CollectionPointerLink *link = MEM_callocN(sizeof(CollectionPointerLink), | 
					
						
							|  |  |  |                                                     "bpy_context_get"); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |           link->ptr = ((BPy_StructRNA *)item)->ptr; | 
					
						
							|  |  |  |           BLI_addtail(&result->list, link); | 
					
						
							| 
									
										
										
										
											2012-03-03 20:36:09 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |           ptr = &(((BPy_StructRNA *)list_item)->ptr); | 
					
						
							| 
									
										
										
										
											2019-08-23 09:52:12 +02:00
										 |  |  |           CTX_data_list_add(result, ptr->owner_id, ptr->type, ptr->data); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |           CLOG_INFO(BPY_LOG_CONTEXT, | 
					
						
							|  |  |  |                     1, | 
					
						
							|  |  |  |                     "'%s' list item not a valid type in sequence type '%s'", | 
					
						
							|  |  |  |                     member, | 
					
						
							|  |  |  |                     Py_TYPE(item)->tp_name); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       Py_DECREF(seq_fast); | 
					
						
							|  |  |  |       CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); | 
					
						
							|  |  |  |       done = true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (done == false) { | 
					
						
							|  |  |  |     if (item) { | 
					
						
							|  |  |  |       CLOG_INFO(BPY_LOG_CONTEXT, 1, "'%s' not a valid type", member); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       CLOG_INFO(BPY_LOG_CONTEXT, 1, "'%s' not found\n", member); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     CLOG_INFO(BPY_LOG_CONTEXT, 2, "'%s' found", member); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (use_gil) { | 
					
						
							|  |  |  |     PyGILState_Release(gilstate); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return done; | 
					
						
							| 
									
										
										
										
											2009-10-29 09:25:11 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-20 23:39:29 +00:00
										 |  |  | #ifdef WITH_PYTHON_MODULE
 | 
					
						
							| 
									
										
										
										
											2012-03-18 07:38:51 +00:00
										 |  |  | /* TODO, reloading the module isn't functional at the moment. */ | 
					
						
							| 
									
										
										
										
											2011-02-20 23:39:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-07-10 18:54:02 +00:00
										 |  |  | static void bpy_module_free(void *mod); | 
					
						
							| 
									
										
										
										
											2020-08-02 13:11:30 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* Defined in 'creator.c' when building as a Python module. */ | 
					
						
							| 
									
										
										
										
											2011-07-10 18:54:02 +00:00
										 |  |  | extern int main_python_enter(int argc, const char **argv); | 
					
						
							|  |  |  | extern void main_python_exit(void); | 
					
						
							| 
									
										
										
										
											2020-08-02 13:11:30 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  | static struct PyModuleDef bpy_proxy_def = { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     PyModuleDef_HEAD_INIT, | 
					
						
							|  |  |  |     "bpy",           /* m_name */ | 
					
						
							|  |  |  |     NULL,            /* m_doc */ | 
					
						
							|  |  |  |     0,               /* m_size */ | 
					
						
							|  |  |  |     NULL,            /* m_methods */ | 
					
						
							|  |  |  |     NULL,            /* m_reload */ | 
					
						
							|  |  |  |     NULL,            /* m_traverse */ | 
					
						
							|  |  |  |     NULL,            /* m_clear */ | 
					
						
							|  |  |  |     bpy_module_free, /* m_free */ | 
					
						
							| 
									
										
										
										
											2011-07-10 18:54:02 +00:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2011-02-20 23:39:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-22 14:19:09 +00:00
										 |  |  | typedef struct { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyObject_HEAD | 
					
						
							|  |  |  |       /* Type-specific fields go here. */ | 
					
						
							|  |  |  |       PyObject *mod; | 
					
						
							| 
									
										
										
										
											2011-02-22 14:19:09 +00:00
										 |  |  | } dealloc_obj; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* call once __file__ is set */ | 
					
						
							| 
									
										
										
										
											2013-01-02 16:15:45 +00:00
										 |  |  | static void bpy_module_delay_init(PyObject *bpy_proxy) | 
					
						
							| 
									
										
										
										
											2011-02-20 23:39:29 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   const int argc = 1; | 
					
						
							|  |  |  |   const char *argv[2]; | 
					
						
							| 
									
										
										
										
											2011-11-26 15:18:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   /* updating the module dict below will loose the reference to __file__ */ | 
					
						
							|  |  |  |   PyObject *filename_obj = PyModule_GetFilenameObject(bpy_proxy); | 
					
						
							| 
									
										
										
										
											2011-11-26 15:18:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   const char *filename_rel = _PyUnicode_AsString(filename_obj); /* can be relative */ | 
					
						
							|  |  |  |   char filename_abs[1024]; | 
					
						
							| 
									
										
										
										
											2011-02-22 14:19:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   BLI_strncpy(filename_abs, filename_rel, sizeof(filename_abs)); | 
					
						
							| 
									
										
										
										
											2020-04-08 16:35:13 +10:00
										 |  |  |   BLI_path_abs_from_cwd(filename_abs, sizeof(filename_abs)); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   Py_DECREF(filename_obj); | 
					
						
							| 
									
										
										
										
											2011-03-09 04:58:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   argv[0] = filename_abs; | 
					
						
							|  |  |  |   argv[1] = NULL; | 
					
						
							| 
									
										
										
										
											2018-06-04 08:54:17 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   // printf("module found %s\n", argv[0]);
 | 
					
						
							| 
									
										
										
										
											2011-02-21 13:13:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   main_python_enter(argc, argv); | 
					
						
							| 
									
										
										
										
											2011-02-20 23:39:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   /* initialized in BPy_init_modules() */ | 
					
						
							|  |  |  |   PyDict_Update(PyModule_GetDict(bpy_proxy), PyModule_GetDict(bpy_package_py)); | 
					
						
							| 
									
										
										
										
											2011-02-22 14:19:09 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void dealloc_obj_dealloc(PyObject *self); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-16 22:26:20 +10:00
										 |  |  | static PyTypeObject dealloc_obj_Type; | 
					
						
							| 
									
										
										
										
											2011-02-22 14:19:09 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* use our own dealloc so we can free a property if we use one */ | 
					
						
							|  |  |  | static void dealloc_obj_dealloc(PyObject *self) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   bpy_module_delay_init(((dealloc_obj *)self)->mod); | 
					
						
							| 
									
										
										
										
											2011-02-22 14:19:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   /* Note, for subclassed PyObjects we cant just call PyObject_DEL() directly or it will crash */ | 
					
						
							|  |  |  |   dealloc_obj_Type.tp_free(self); | 
					
						
							| 
									
										
										
										
											2011-02-22 14:19:09 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | PyMODINIT_FUNC PyInit_bpy(void); | 
					
						
							| 
									
										
										
										
											2013-01-02 16:15:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | PyMODINIT_FUNC PyInit_bpy(void) | 
					
						
							| 
									
										
										
										
											2011-02-22 14:19:09 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyObject *bpy_proxy = PyModule_Create(&bpy_proxy_def); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* Problem:
 | 
					
						
							|  |  |  |    * 1) this init function is expected to have a private member defined - 'md_def' | 
					
						
							|  |  |  |    *    but this is only set for C defined modules (not py packages) | 
					
						
							|  |  |  |    *    so we cant return 'bpy_package_py' as is. | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * 2) there is a 'bpy' C module for python to load which is basically all of blender, | 
					
						
							|  |  |  |    *    and there is scripts/bpy/__init__.py, | 
					
						
							|  |  |  |    *    we may end up having to rename this module so there is no naming conflict here eg: | 
					
						
							|  |  |  |    *    'from blender import bpy' | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * 3) we don't know the filename at this point, workaround by assigning a dummy value | 
					
						
							|  |  |  |    *    which calls back when its freed so the real loading can take place. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* assign an object which is freed after __file__ is assigned */ | 
					
						
							|  |  |  |   dealloc_obj *dob; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* assign dummy type */ | 
					
						
							|  |  |  |   dealloc_obj_Type.tp_name = "dealloc_obj"; | 
					
						
							|  |  |  |   dealloc_obj_Type.tp_basicsize = sizeof(dealloc_obj); | 
					
						
							|  |  |  |   dealloc_obj_Type.tp_dealloc = dealloc_obj_dealloc; | 
					
						
							|  |  |  |   dealloc_obj_Type.tp_flags = Py_TPFLAGS_DEFAULT; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (PyType_Ready(&dealloc_obj_Type) < 0) { | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   dob = (dealloc_obj *)dealloc_obj_Type.tp_alloc(&dealloc_obj_Type, 0); | 
					
						
							|  |  |  |   dob->mod = bpy_proxy;                                       /* borrow */ | 
					
						
							|  |  |  |   PyModule_AddObject(bpy_proxy, "__file__", (PyObject *)dob); /* borrow */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return bpy_proxy; | 
					
						
							| 
									
										
										
										
											2011-02-20 23:39:29 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2011-02-22 14:19:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-07-10 18:54:02 +00:00
										 |  |  | static void bpy_module_free(void *UNUSED(mod)) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   main_python_exit(); | 
					
						
							| 
									
										
										
										
											2011-07-10 18:54:02 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-20 23:39:29 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2013-02-19 16:13:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-01 09:43:11 +11:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Avoids duplicating keyword list. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | bool BPY_string_is_keyword(const char *str) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   /* list is from...
 | 
					
						
							|  |  |  |    * ", ".join(['"%s"' % kw for kw in  __import__("keyword").kwlist]) | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   const char *kwlist[] = { | 
					
						
							|  |  |  |       "False", "None",     "True",  "and",    "as",   "assert", "async",  "await",    "break", | 
					
						
							|  |  |  |       "class", "continue", "def",   "del",    "elif", "else",   "except", "finally",  "for", | 
					
						
							|  |  |  |       "from",  "global",   "if",    "import", "in",   "is",     "lambda", "nonlocal", "not", | 
					
						
							|  |  |  |       "or",    "pass",     "raise", "return", "try",  "while",  "with",   "yield",    NULL, | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (int i = 0; kwlist[i]; i++) { | 
					
						
							|  |  |  |     if (STREQ(str, kwlist[i])) { | 
					
						
							|  |  |  |       return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return false; | 
					
						
							| 
									
										
										
										
											2016-04-01 09:43:11 +11:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-19 16:13:41 +00:00
										 |  |  | /* EVIL, define text.c functions here... */ | 
					
						
							| 
									
										
										
										
											2013-03-11 20:27:38 +00:00
										 |  |  | /* BKE_text.h */ | 
					
						
							| 
									
										
										
										
											2020-02-20 15:38:58 +11:00
										 |  |  | int text_check_identifier_unicode(const uint ch) | 
					
						
							| 
									
										
										
										
											2013-02-19 16:13:41 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return (ch < 255 && text_check_identifier((char)ch)) || Py_UNICODE_ISALNUM(ch); | 
					
						
							| 
									
										
										
										
											2013-02-19 16:13:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-20 15:38:58 +11:00
										 |  |  | int text_check_identifier_nodigit_unicode(const uint ch) | 
					
						
							| 
									
										
										
										
											2013-02-19 16:13:41 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return (ch < 255 && text_check_identifier_nodigit((char)ch)) || Py_UNICODE_ISALPHA(ch); | 
					
						
							| 
									
										
										
										
											2013-02-19 16:13:41 +00:00
										 |  |  | } |