|
Blender
V2.59
|
00001 /* 00002 * $Id: bpy_interface.c 38409 2011-07-15 04:01:47Z campbellbarton $ 00003 * 00004 * ***** BEGIN GPL LICENSE BLOCK ***** 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software Foundation, 00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 * 00020 * Contributor(s): Michel Selten, Willian P. Germano, Stephen Swaney, 00021 * Chris Keith, Chris Want, Ken Hughes, Campbell Barton 00022 * 00023 * ***** END GPL LICENSE BLOCK ***** 00024 */ 00025 00031 /* grr, python redefines */ 00032 #ifdef _POSIX_C_SOURCE 00033 #undef _POSIX_C_SOURCE 00034 #endif 00035 00036 #include <Python.h> 00037 00038 #include "MEM_guardedalloc.h" 00039 00040 #include "RNA_types.h" 00041 00042 #include "bpy.h" 00043 #include "bpy_rna.h" 00044 #include "bpy_util.h" 00045 #include "bpy_traceback.h" 00046 #include "bpy_intern_string.h" 00047 00048 #include "DNA_space_types.h" 00049 #include "DNA_text_types.h" 00050 00051 #include "BLI_path_util.h" 00052 #include "BLI_math_base.h" 00053 #include "BLI_string.h" 00054 #include "BLI_utildefines.h" 00055 00056 00057 #include "BKE_context.h" 00058 #include "BKE_text.h" 00059 #include "BKE_font.h" /* only for utf8towchar */ 00060 #include "BKE_main.h" 00061 #include "BKE_global.h" /* only for script checking */ 00062 00063 #include "BPY_extern.h" 00064 00065 #include "../generic/bpy_internal_import.h" // our own imports 00066 #include "../generic/py_capi_utils.h" 00067 00068 /* inittab initialization functions */ 00069 #include "../generic/bgl.h" 00070 #include "../generic/blf_py_api.h" 00071 #include "../generic/noise_py_api.h" 00072 #include "../mathutils/mathutils.h" 00073 00074 /* for internal use, when starting and ending python scripts */ 00075 00076 /* incase a python script triggers another python call, stop bpy_context_clear from invalidating */ 00077 static int py_call_level= 0; 00078 BPy_StructRNA *bpy_context_module= NULL; /* for fast access */ 00079 00080 // #define TIME_PY_RUN // simple python tests. prints on exit. 00081 00082 #ifdef TIME_PY_RUN 00083 #include "PIL_time.h" 00084 static int bpy_timer_count= 0; 00085 static double bpy_timer; /* time since python starts */ 00086 static double bpy_timer_run; /* time for each python script run */ 00087 static double bpy_timer_run_tot; /* accumulate python runs */ 00088 #endif 00089 00090 void bpy_context_set(bContext *C, PyGILState_STATE *gilstate) 00091 { 00092 py_call_level++; 00093 00094 if(gilstate) 00095 *gilstate= PyGILState_Ensure(); 00096 00097 if(py_call_level==1) { 00098 00099 if(C) { // XXX - should always be true. 00100 BPy_SetContext(C); 00101 bpy_import_main_set(CTX_data_main(C)); 00102 } 00103 else { 00104 fprintf(stderr, "ERROR: Python context called with a NULL Context. this should not happen!\n"); 00105 } 00106 00107 BPY_modules_update(C); /* can give really bad results if this isnt here */ 00108 00109 #ifdef TIME_PY_RUN 00110 if(bpy_timer_count==0) { 00111 /* record time from the beginning */ 00112 bpy_timer= PIL_check_seconds_timer(); 00113 bpy_timer_run= bpy_timer_run_tot= 0.0; 00114 } 00115 bpy_timer_run= PIL_check_seconds_timer(); 00116 00117 00118 bpy_timer_count++; 00119 #endif 00120 } 00121 } 00122 00123 /* context should be used but not now because it causes some bugs */ 00124 void bpy_context_clear(bContext *UNUSED(C), PyGILState_STATE *gilstate) 00125 { 00126 py_call_level--; 00127 00128 if(gilstate) 00129 PyGILState_Release(*gilstate); 00130 00131 if(py_call_level < 0) { 00132 fprintf(stderr, "ERROR: Python context internal state bug. this should not happen!\n"); 00133 } 00134 else if(py_call_level==0) { 00135 // XXX - Calling classes currently wont store the context :\, cant set NULL because of this. but this is very flakey still. 00136 //BPy_SetContext(NULL); 00137 //bpy_import_main_set(NULL); 00138 00139 #ifdef TIME_PY_RUN 00140 bpy_timer_run_tot += PIL_check_seconds_timer() - bpy_timer_run; 00141 bpy_timer_count++; 00142 #endif 00143 00144 } 00145 } 00146 00147 void BPY_text_free_code(Text *text) 00148 { 00149 if(text->compiled) { 00150 Py_DECREF((PyObject *)text->compiled); 00151 text->compiled= NULL; 00152 } 00153 } 00154 00155 void BPY_modules_update(bContext *C) 00156 { 00157 #if 0 // slow, this runs all the time poll, draw etc 100's of time a sec. 00158 PyObject *mod= PyImport_ImportModuleLevel("bpy", NULL, NULL, NULL, 0); 00159 PyModule_AddObject(mod, "data", BPY_rna_module()); 00160 PyModule_AddObject(mod, "types", BPY_rna_types()); // atm this does not need updating 00161 #endif 00162 00163 /* refreshes the main struct */ 00164 BPY_update_rna_module(); 00165 bpy_context_module->ptr.data= (void *)C; 00166 } 00167 00168 void BPY_context_set(bContext *C) 00169 { 00170 BPy_SetContext(C); 00171 } 00172 00173 /* defined in AUD_C-API.cpp */ 00174 extern PyObject *AUD_initPython(void); 00175 00176 static struct _inittab bpy_internal_modules[]= { 00177 {(char *)"noise", BPyInit_noise}, 00178 {(char *)"mathutils", PyInit_mathutils}, 00179 // {(char *)"mathutils.geometry", PyInit_mathutils_geometry}, 00180 {(char *)"bgl", BPyInit_bgl}, 00181 {(char *)"blf", BPyInit_blf}, 00182 #ifdef WITH_AUDASPACE 00183 {(char *)"aud", AUD_initPython}, 00184 #endif 00185 {NULL, NULL} 00186 }; 00187 00188 /* call BPY_context_set first */ 00189 void BPY_python_start(int argc, const char **argv) 00190 { 00191 #ifndef WITH_PYTHON_MODULE 00192 PyThreadState *py_tstate= NULL; 00193 00194 /* not essential but nice to set our name */ 00195 static wchar_t bprogname_wchar[FILE_MAXDIR+FILE_MAXFILE]; /* python holds a reference */ 00196 utf8towchar(bprogname_wchar, bprogname); 00197 Py_SetProgramName(bprogname_wchar); 00198 00199 /* must run before python initializes */ 00200 PyImport_ExtendInittab(bpy_internal_modules); 00201 00202 /* allow to use our own included python */ 00203 PyC_SetHomePath(BLI_get_folder(BLENDER_SYSTEM_PYTHON, NULL)); 00204 00205 /* Python 3.2 now looks for '2.58/python/include/python3.2d/pyconfig.h' to parse 00206 * from the 'sysconfig' module which is used by 'site', so for now disable site. 00207 * alternatively we could copy the file. */ 00208 Py_NoSiteFlag= 1; 00209 00210 Py_Initialize(); 00211 00212 // PySys_SetArgv(argc, argv); // broken in py3, not a huge deal 00213 /* sigh, why do python guys not have a char** version anymore? :( */ 00214 { 00215 int i; 00216 PyObject *py_argv= PyList_New(argc); 00217 for (i=0; i<argc; i++) 00218 PyList_SET_ITEM(py_argv, i, PyC_UnicodeFromByte(argv[i])); /* should fix bug #20021 - utf path name problems, by replacing PyUnicode_FromString */ 00219 00220 PySys_SetObject("argv", py_argv); 00221 Py_DECREF(py_argv); 00222 } 00223 00224 /* Initialize thread support (also acquires lock) */ 00225 PyEval_InitThreads(); 00226 #else 00227 (void)argc; 00228 (void)argv; 00229 00230 /* must run before python initializes */ 00231 PyImport_ExtendInittab(bpy_internal_modules); 00232 #endif 00233 00234 bpy_intern_string_init(); 00235 00236 /* bpy.* and lets us import it */ 00237 BPy_init_modules(); 00238 00239 bpy_import_init(PyEval_GetBuiltins()); 00240 00241 pyrna_alloc_types(); 00242 00243 #ifndef WITH_PYTHON_MODULE 00244 py_tstate= PyGILState_GetThisThreadState(); 00245 PyEval_ReleaseThread(py_tstate); 00246 #endif 00247 } 00248 00249 void BPY_python_end(void) 00250 { 00251 // fprintf(stderr, "Ending Python!\n"); 00252 00253 PyGILState_Ensure(); /* finalizing, no need to grab the state */ 00254 00255 // free other python data. 00256 pyrna_free_types(); 00257 00258 /* clear all python data from structs */ 00259 00260 bpy_intern_string_exit(); 00261 00262 Py_Finalize(); 00263 00264 #ifdef TIME_PY_RUN 00265 // measure time since py started 00266 bpy_timer= PIL_check_seconds_timer() - bpy_timer; 00267 00268 printf("*bpy stats* - "); 00269 printf("tot exec: %d, ", bpy_timer_count); 00270 printf("tot run: %.4fsec, ", bpy_timer_run_tot); 00271 if(bpy_timer_count>0) 00272 printf("average run: %.6fsec, ", (bpy_timer_run_tot/bpy_timer_count)); 00273 00274 if(bpy_timer>0.0) 00275 printf("tot usage %.4f%%", (bpy_timer_run_tot/bpy_timer)*100.0); 00276 00277 printf("\n"); 00278 00279 // fprintf(stderr, "Ending Python Done!\n"); 00280 00281 #endif 00282 00283 } 00284 00285 static void python_script_error_jump_text(struct Text *text) 00286 { 00287 int lineno; 00288 int offset; 00289 python_script_error_jump(text->id.name+2, &lineno, &offset); 00290 if(lineno != -1) { 00291 /* select the line with the error */ 00292 txt_move_to(text, lineno - 1, INT_MAX, FALSE); 00293 txt_move_to(text, lineno - 1, offset, TRUE); 00294 } 00295 } 00296 00297 /* super annoying, undo _PyModule_Clear(), bug [#23871] */ 00298 #define PYMODULE_CLEAR_WORKAROUND 00299 00300 #ifdef PYMODULE_CLEAR_WORKAROUND 00301 /* bad!, we should never do this, but currently only safe way I could find to keep namespace. 00302 * from being cleared. - campbell */ 00303 typedef struct { 00304 PyObject_HEAD 00305 PyObject *md_dict; 00306 /* ommit other values, we only want the dict. */ 00307 } PyModuleObject; 00308 #endif 00309 00310 static int python_script_exec(bContext *C, const char *fn, struct Text *text, struct ReportList *reports, const short do_jump) 00311 { 00312 PyObject *main_mod= NULL; 00313 PyObject *py_dict= NULL, *py_result= NULL; 00314 PyGILState_STATE gilstate; 00315 00316 BLI_assert(fn || text); 00317 00318 if (fn==NULL && text==NULL) { 00319 return 0; 00320 } 00321 00322 bpy_context_set(C, &gilstate); 00323 00324 PyC_MainModule_Backup(&main_mod); 00325 00326 if (text) { 00327 char fn_dummy[FILE_MAXDIR]; 00328 bpy_text_filename_get(fn_dummy, sizeof(fn_dummy), text); 00329 00330 if(text->compiled == NULL) { /* if it wasn't already compiled, do it now */ 00331 char *buf= txt_to_buf(text); 00332 00333 text->compiled= Py_CompileString(buf, fn_dummy, Py_file_input); 00334 00335 MEM_freeN(buf); 00336 00337 if(PyErr_Occurred()) { 00338 if(do_jump) { 00339 python_script_error_jump_text(text); 00340 } 00341 BPY_text_free_code(text); 00342 } 00343 } 00344 00345 if(text->compiled) { 00346 py_dict= PyC_DefaultNameSpace(fn_dummy); 00347 py_result= PyEval_EvalCode(text->compiled, py_dict, py_dict); 00348 } 00349 00350 } 00351 else { 00352 FILE *fp= fopen(fn, "r"); 00353 00354 if(fp) { 00355 py_dict= PyC_DefaultNameSpace(fn); 00356 00357 #ifdef _WIN32 00358 /* Previously we used PyRun_File to run directly the code on a FILE 00359 * object, but as written in the Python/C API Ref Manual, chapter 2, 00360 * 'FILE structs for different C libraries can be different and 00361 * incompatible'. 00362 * So now we load the script file data to a buffer */ 00363 { 00364 char *pystring; 00365 00366 fclose(fp); 00367 00368 pystring= MEM_mallocN(strlen(fn) + 32, "pystring"); 00369 pystring[0]= '\0'; 00370 sprintf(pystring, "exec(open(r'%s').read())", fn); 00371 py_result= PyRun_String(pystring, Py_file_input, py_dict, py_dict); 00372 MEM_freeN(pystring); 00373 } 00374 #else 00375 py_result= PyRun_File(fp, fn, Py_file_input, py_dict, py_dict); 00376 fclose(fp); 00377 #endif 00378 } 00379 else { 00380 PyErr_Format(PyExc_IOError, 00381 "Python file \"%s\" could not be opened: %s", 00382 fn, strerror(errno)); 00383 py_result= NULL; 00384 } 00385 } 00386 00387 if (!py_result) { 00388 if(text) { 00389 if(do_jump) { 00390 python_script_error_jump_text(text); 00391 } 00392 } 00393 BPy_errors_to_report(reports); 00394 } 00395 else { 00396 Py_DECREF(py_result); 00397 } 00398 00399 if(py_dict) { 00400 #ifdef PYMODULE_CLEAR_WORKAROUND 00401 PyModuleObject *mmod= (PyModuleObject *)PyDict_GetItemString(PyThreadState_GET()->interp->modules, "__main__"); 00402 PyObject *dict_back= mmod->md_dict; 00403 /* freeing the module will clear the namespace, 00404 * gives problems running classes defined in this namespace being used later. */ 00405 mmod->md_dict= NULL; 00406 Py_DECREF(dict_back); 00407 #endif 00408 00409 #undef PYMODULE_CLEAR_WORKAROUND 00410 } 00411 00412 PyC_MainModule_Restore(main_mod); 00413 00414 bpy_context_clear(C, &gilstate); 00415 00416 return (py_result != NULL); 00417 } 00418 00419 /* Can run a file or text block */ 00420 int BPY_filepath_exec(bContext *C, const char *filepath, struct ReportList *reports) 00421 { 00422 return python_script_exec(C, filepath, NULL, reports, FALSE); 00423 } 00424 00425 00426 int BPY_text_exec(bContext *C, struct Text *text, struct ReportList *reports, const short do_jump) 00427 { 00428 return python_script_exec(C, NULL, text, reports, do_jump); 00429 } 00430 00431 void BPY_DECREF(void *pyob_ptr) 00432 { 00433 PyGILState_STATE gilstate= PyGILState_Ensure(); 00434 Py_DECREF((PyObject *)pyob_ptr); 00435 PyGILState_Release(gilstate); 00436 } 00437 00438 /* return -1 on error, else 0 */ 00439 int BPY_button_exec(bContext *C, const char *expr, double *value, const short verbose) 00440 { 00441 PyGILState_STATE gilstate; 00442 PyObject *py_dict, *mod, *retval; 00443 int error_ret= 0; 00444 PyObject *main_mod= NULL; 00445 00446 if (!value || !expr) return -1; 00447 00448 if(expr[0]=='\0') { 00449 *value= 0.0; 00450 return error_ret; 00451 } 00452 00453 bpy_context_set(C, &gilstate); 00454 00455 PyC_MainModule_Backup(&main_mod); 00456 00457 py_dict= PyC_DefaultNameSpace("<blender button>"); 00458 00459 mod= PyImport_ImportModule("math"); 00460 if (mod) { 00461 PyDict_Merge(py_dict, PyModule_GetDict(mod), 0); /* 0 - dont overwrite existing values */ 00462 Py_DECREF(mod); 00463 } 00464 else { /* highly unlikely but possibly */ 00465 PyErr_Print(); 00466 PyErr_Clear(); 00467 } 00468 00469 retval= PyRun_String(expr, Py_eval_input, py_dict, py_dict); 00470 00471 if (retval == NULL) { 00472 error_ret= -1; 00473 } 00474 else { 00475 double val; 00476 00477 if(PyTuple_Check(retval)) { 00478 /* Users my have typed in 10km, 2m 00479 * add up all values */ 00480 int i; 00481 val= 0.0; 00482 00483 for(i=0; i<PyTuple_GET_SIZE(retval); i++) { 00484 val+= PyFloat_AsDouble(PyTuple_GET_ITEM(retval, i)); 00485 } 00486 } 00487 else { 00488 val= PyFloat_AsDouble(retval); 00489 } 00490 Py_DECREF(retval); 00491 00492 if(val==-1 && PyErr_Occurred()) { 00493 error_ret= -1; 00494 } 00495 else if (!finite(val)) { 00496 *value= 0.0; 00497 } 00498 else { 00499 *value= val; 00500 } 00501 } 00502 00503 if(error_ret) { 00504 if(verbose) { 00505 BPy_errors_to_report(CTX_wm_reports(C)); 00506 } 00507 else { 00508 PyErr_Clear(); 00509 } 00510 } 00511 00512 PyC_MainModule_Backup(&main_mod); 00513 00514 bpy_context_clear(C, &gilstate); 00515 00516 return error_ret; 00517 } 00518 00519 int BPY_string_exec(bContext *C, const char *expr) 00520 { 00521 PyGILState_STATE gilstate; 00522 PyObject *main_mod= NULL; 00523 PyObject *py_dict, *retval; 00524 int error_ret= 0; 00525 Main *bmain_back; /* XXX, quick fix for release (Copy Settings crash), needs further investigation */ 00526 00527 if (!expr) return -1; 00528 00529 if(expr[0]=='\0') { 00530 return error_ret; 00531 } 00532 00533 bpy_context_set(C, &gilstate); 00534 00535 PyC_MainModule_Backup(&main_mod); 00536 00537 py_dict= PyC_DefaultNameSpace("<blender string>"); 00538 00539 bmain_back= bpy_import_main_get(); 00540 bpy_import_main_set(CTX_data_main(C)); 00541 00542 retval= PyRun_String(expr, Py_eval_input, py_dict, py_dict); 00543 00544 bpy_import_main_set(bmain_back); 00545 00546 if (retval == NULL) { 00547 error_ret= -1; 00548 00549 BPy_errors_to_report(CTX_wm_reports(C)); 00550 } 00551 else { 00552 Py_DECREF(retval); 00553 } 00554 00555 PyC_MainModule_Restore(main_mod); 00556 00557 bpy_context_clear(C, &gilstate); 00558 00559 return error_ret; 00560 } 00561 00562 00563 void BPY_modules_load_user(bContext *C) 00564 { 00565 PyGILState_STATE gilstate; 00566 Main *bmain= CTX_data_main(C); 00567 Text *text; 00568 00569 /* can happen on file load */ 00570 if(bmain==NULL) 00571 return; 00572 00573 bpy_context_set(C, &gilstate); 00574 00575 for(text=CTX_data_main(C)->text.first; text; text= text->id.next) { 00576 if(text->flags & TXT_ISSCRIPT && BLI_testextensie(text->id.name+2, ".py")) { 00577 if(!(G.f & G_SCRIPT_AUTOEXEC)) { 00578 printf("scripts disabled for \"%s\", skipping '%s'\n", bmain->name, text->id.name+2); 00579 } 00580 else { 00581 PyObject *module= bpy_text_import(text); 00582 00583 if (module==NULL) { 00584 PyErr_Print(); 00585 PyErr_Clear(); 00586 } 00587 else { 00588 Py_DECREF(module); 00589 } 00590 } 00591 } 00592 } 00593 bpy_context_clear(C, &gilstate); 00594 } 00595 00596 int BPY_context_member_get(bContext *C, const char *member, bContextDataResult *result) 00597 { 00598 PyObject *pyctx= (PyObject *)CTX_py_dict_get(C); 00599 PyObject *item= PyDict_GetItemString(pyctx, member); 00600 PointerRNA *ptr= NULL; 00601 int done= 0; 00602 00603 if(item==NULL) { 00604 /* pass */ 00605 } 00606 else if(item==Py_None) { 00607 /* pass */ 00608 } 00609 else if(BPy_StructRNA_Check(item)) { 00610 ptr= &(((BPy_StructRNA *)item)->ptr); 00611 00612 //result->ptr= ((BPy_StructRNA *)item)->ptr; 00613 CTX_data_pointer_set(result, ptr->id.data, ptr->type, ptr->data); 00614 done= 1; 00615 } 00616 else if (PySequence_Check(item)) { 00617 PyObject *seq_fast= PySequence_Fast(item, "bpy_context_get sequence conversion"); 00618 if (seq_fast==NULL) { 00619 PyErr_Print(); 00620 PyErr_Clear(); 00621 } 00622 else { 00623 int len= PySequence_Fast_GET_SIZE(seq_fast); 00624 int i; 00625 for(i= 0; i < len; i++) { 00626 PyObject *list_item= PySequence_Fast_GET_ITEM(seq_fast, i); 00627 00628 if(BPy_StructRNA_Check(list_item)) { 00629 /* 00630 CollectionPointerLink *link= MEM_callocN(sizeof(CollectionPointerLink), "bpy_context_get"); 00631 link->ptr= ((BPy_StructRNA *)item)->ptr; 00632 BLI_addtail(&result->list, link); 00633 */ 00634 ptr= &(((BPy_StructRNA *)list_item)->ptr); 00635 CTX_data_list_add(result, ptr->id.data, ptr->type, ptr->data); 00636 } 00637 else { 00638 printf("List item not a valid type\n"); 00639 } 00640 00641 } 00642 Py_DECREF(seq_fast); 00643 00644 done= 1; 00645 } 00646 } 00647 00648 if(done==0) { 00649 if (item) printf("PyContext '%s' not a valid type\n", member); 00650 else printf("PyContext '%s' not found\n", member); 00651 } 00652 else { 00653 if(G.f & G_DEBUG) { 00654 printf("PyContext '%s' found\n", member); 00655 } 00656 } 00657 00658 return done; 00659 } 00660 00661 00662 #ifdef WITH_PYTHON_MODULE 00663 #include "BLI_storage.h" 00664 /* TODO, reloading the module isnt functional at the moment. */ 00665 00666 static void bpy_module_free(void *mod); 00667 extern int main_python_enter(int argc, const char **argv); 00668 extern void main_python_exit(void); 00669 static struct PyModuleDef bpy_proxy_def= { 00670 PyModuleDef_HEAD_INIT, 00671 "bpy", /* m_name */ 00672 NULL, /* m_doc */ 00673 0, /* m_size */ 00674 NULL, /* m_methods */ 00675 NULL, /* m_reload */ 00676 NULL, /* m_traverse */ 00677 NULL, /* m_clear */ 00678 bpy_module_free, /* m_free */ 00679 }; 00680 00681 typedef struct { 00682 PyObject_HEAD 00683 /* Type-specific fields go here. */ 00684 PyObject *mod; 00685 } dealloc_obj; 00686 00687 /* call once __file__ is set */ 00688 void bpy_module_delay_init(PyObject *bpy_proxy) 00689 { 00690 const int argc= 1; 00691 const char *argv[2]; 00692 PyObject *filename_obj= PyModule_GetFilenameObject(bpy_proxy); /* updating the module dict below will loose the reference to __file__ */ 00693 const char *filename_rel= _PyUnicode_AsString(filename_obj); /* can be relative */ 00694 char filename_abs[1024]; 00695 00696 BLI_strncpy(filename_abs, filename_rel, sizeof(filename_abs)); 00697 BLI_path_cwd(filename_abs); 00698 00699 argv[0]= filename_abs; 00700 argv[1]= NULL; 00701 00702 // printf("module found %s\n", argv[0]); 00703 00704 main_python_enter(argc, argv); 00705 00706 /* initialized in BPy_init_modules() */ 00707 PyDict_Update(PyModule_GetDict(bpy_proxy), PyModule_GetDict(bpy_package_py)); 00708 } 00709 00710 static void dealloc_obj_dealloc(PyObject *self); 00711 00712 static PyTypeObject dealloc_obj_Type= {{{0}}}; 00713 00714 /* use our own dealloc so we can free a property if we use one */ 00715 static void dealloc_obj_dealloc(PyObject *self) 00716 { 00717 bpy_module_delay_init(((dealloc_obj *)self)->mod); 00718 00719 /* Note, for subclassed PyObjects we cant just call PyObject_DEL() directly or it will crash */ 00720 dealloc_obj_Type.tp_free(self); 00721 } 00722 00723 PyMODINIT_FUNC 00724 PyInit_bpy(void) 00725 { 00726 PyObject *bpy_proxy= PyModule_Create(&bpy_proxy_def); 00727 00728 /* Problem: 00729 * 1) this init function is expected to have a private member defined - 'md_def' 00730 * but this is only set for C defined modules (not py packages) 00731 * so we cant return 'bpy_package_py' as is. 00732 * 00733 * 2) there is a 'bpy' C module for python to load which is basically all of blender, 00734 * and there is scripts/bpy/__init__.py, 00735 * we may end up having to rename this module so there is no naming conflict here eg: 00736 * 'from blender import bpy' 00737 * 00738 * 3) we dont know the filename at this point, workaround by assigning a dummy value 00739 * which calls back when its freed so the real loading can take place. 00740 */ 00741 00742 /* assign an object which is freed after __file__ is assigned */ 00743 dealloc_obj *dob; 00744 00745 /* assign dummy type */ 00746 dealloc_obj_Type.tp_name= "dealloc_obj"; 00747 dealloc_obj_Type.tp_basicsize= sizeof(dealloc_obj); 00748 dealloc_obj_Type.tp_dealloc= dealloc_obj_dealloc; 00749 dealloc_obj_Type.tp_flags= Py_TPFLAGS_DEFAULT; 00750 00751 if(PyType_Ready(&dealloc_obj_Type) < 0) 00752 return NULL; 00753 00754 dob= (dealloc_obj *) dealloc_obj_Type.tp_alloc(&dealloc_obj_Type, 0); 00755 dob->mod= bpy_proxy; /* borrow */ 00756 PyModule_AddObject(bpy_proxy, "__file__", (PyObject *)dob); /* borrow */ 00757 00758 return bpy_proxy; 00759 } 00760 00761 static void bpy_module_free(void *UNUSED(mod)) 00762 { 00763 main_python_exit(); 00764 } 00765 00766 #endif