|
Blender
V2.59
|
00001 /* 00002 * $Id: bpy_internal_import.c 37088 2011-06-02 08:29:16Z campbellbarton $ 00003 * ***** BEGIN GPL LICENSE BLOCK ***** 00004 * 00005 * This program is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU General Public License 00007 * as published by the Free Software Foundation; either version 2 00008 * of the License, or (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program; if not, write to the Free Software Foundation, 00017 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00018 * 00019 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00020 * All rights reserved. 00021 * 00022 * This is a new part of Blender. 00023 * 00024 * Contributor(s): Willian P. Germano 00025 * 00026 * ***** END GPL LICENSE BLOCK ***** 00027 */ 00028 00034 #include <Python.h> 00035 #include <stddef.h> 00036 00037 #include "bpy_internal_import.h" 00038 00039 #include "MEM_guardedalloc.h" 00040 00041 #include "DNA_text_types.h" 00042 00043 #include "BLI_listbase.h" 00044 #include "BLI_path_util.h" 00045 #include "BLI_string.h" 00046 #include "BLI_utildefines.h" 00047 00048 /* UNUSED */ 00049 #include "BKE_text.h" /* txt_to_buf */ 00050 #include "BKE_main.h" 00051 00052 static Main *bpy_import_main= NULL; 00053 00054 /* 'builtins' is most likely PyEval_GetBuiltins() */ 00055 void bpy_import_init(PyObject *builtins) 00056 { 00057 PyObject *item; 00058 PyObject *mod; 00059 00060 PyDict_SetItemString(builtins, "__import__", item=PyCFunction_New(&bpy_import_meth, NULL)); Py_DECREF(item); 00061 00062 /* move reload here 00063 * XXX, use import hooks */ 00064 mod= PyImport_ImportModuleLevel((char *)"imp", NULL, NULL, NULL, 0); 00065 if(mod) { 00066 PyDict_SetItemString(PyModule_GetDict(mod), "reload", item=PyCFunction_New(&bpy_reload_meth, NULL)); Py_DECREF(item); 00067 Py_DECREF(mod); 00068 } 00069 else { 00070 BLI_assert(!"unable to load 'imp' module."); 00071 } 00072 } 00073 00074 00075 static void free_compiled_text(Text *text) 00076 { 00077 if(text->compiled) { 00078 Py_DECREF((PyObject *)text->compiled); 00079 } 00080 text->compiled= NULL; 00081 } 00082 00083 struct Main *bpy_import_main_get(void) 00084 { 00085 return bpy_import_main; 00086 } 00087 00088 void bpy_import_main_set(struct Main *maggie) 00089 { 00090 bpy_import_main= maggie; 00091 } 00092 00093 /* returns a dummy filename for a textblock so we can tell what file a text block comes from */ 00094 void bpy_text_filename_get(char *fn, size_t fn_len, Text *text) 00095 { 00096 BLI_snprintf(fn, fn_len, "%s%c%s", text->id.lib ? text->id.lib->filepath : bpy_import_main->name, SEP, text->id.name+2); 00097 } 00098 00099 PyObject *bpy_text_import(Text *text) 00100 { 00101 char *buf= NULL; 00102 char modulename[24]; 00103 int len; 00104 00105 if(!text->compiled) { 00106 char fn_dummy[256]; 00107 bpy_text_filename_get(fn_dummy, sizeof(fn_dummy), text); 00108 00109 buf= txt_to_buf(text); 00110 text->compiled= Py_CompileString(buf, fn_dummy, Py_file_input); 00111 MEM_freeN(buf); 00112 00113 if(PyErr_Occurred()) { 00114 PyErr_Print(); 00115 PyErr_Clear(); 00116 PySys_SetObject("last_traceback", NULL); 00117 free_compiled_text(text); 00118 return NULL; 00119 } 00120 } 00121 00122 len= strlen(text->id.name+2); 00123 strncpy(modulename, text->id.name+2, len); 00124 modulename[len - 3]= '\0'; /* remove .py */ 00125 return PyImport_ExecCodeModule(modulename, text->compiled); 00126 } 00127 00128 PyObject *bpy_text_import_name(char *name, int *found) 00129 { 00130 Text *text; 00131 char txtname[MAX_ID_NAME-2]; 00132 int namelen= strlen(name); 00133 //XXX Main *maggie= bpy_import_main ? bpy_import_main:G.main; 00134 Main *maggie= bpy_import_main; 00135 00136 *found= 0; 00137 00138 if(!maggie) { 00139 printf("ERROR: bpy_import_main_set() was not called before running python. this is a bug.\n"); 00140 return NULL; 00141 } 00142 00143 if (namelen >= (MAX_ID_NAME-2) - 3) return NULL; /* we know this cant be importable, the name is too long for blender! */ 00144 00145 memcpy(txtname, name, namelen); 00146 memcpy(&txtname[namelen], ".py", 4); 00147 00148 text= BLI_findstring(&maggie->text, txtname, offsetof(ID, name) + 2); 00149 00150 if(!text) 00151 return NULL; 00152 else 00153 *found= 1; 00154 00155 return bpy_text_import(text); 00156 } 00157 00158 00159 /* 00160 * find in-memory module and recompile 00161 */ 00162 00163 PyObject *bpy_text_reimport(PyObject *module, int *found) 00164 { 00165 Text *text; 00166 const char *name; 00167 char *filepath; 00168 char *buf= NULL; 00169 //XXX Main *maggie= bpy_import_main ? bpy_import_main:G.main; 00170 Main *maggie= bpy_import_main; 00171 00172 if(!maggie) { 00173 printf("ERROR: bpy_import_main_set() was not called before running python. this is a bug.\n"); 00174 return NULL; 00175 } 00176 00177 *found= 0; 00178 00179 /* get name, filename from the module itself */ 00180 if((name= PyModule_GetName(module)) == NULL) 00181 return NULL; 00182 00183 if((filepath= (char *)PyModule_GetFilename(module)) == NULL) 00184 return NULL; 00185 00186 /* look up the text object */ 00187 text= BLI_findstring(&maggie->text, BLI_path_basename(filepath), offsetof(ID, name) + 2); 00188 00189 /* uh-oh.... didn't find it */ 00190 if(!text) 00191 return NULL; 00192 else 00193 *found= 1; 00194 00195 /* if previously compiled, free the object */ 00196 /* (can't see how could be NULL, but check just in case) */ 00197 if(text->compiled){ 00198 Py_DECREF((PyObject *)text->compiled); 00199 } 00200 00201 /* compile the buffer */ 00202 buf= txt_to_buf(text); 00203 text->compiled= Py_CompileString(buf, text->id.name+2, Py_file_input); 00204 MEM_freeN(buf); 00205 00206 /* if compile failed.... return this error */ 00207 if(PyErr_Occurred()) { 00208 PyErr_Print(); 00209 PyErr_Clear(); 00210 PySys_SetObject("last_traceback", NULL); 00211 free_compiled_text(text); 00212 return NULL; 00213 } 00214 00215 /* make into a module */ 00216 return PyImport_ExecCodeModule((char *)name, text->compiled); 00217 } 00218 00219 00220 static PyObject *blender_import(PyObject *UNUSED(self), PyObject *args, PyObject *kw) 00221 { 00222 PyObject *exception, *err, *tb; 00223 char *name; 00224 int found= 0; 00225 PyObject *globals= NULL, *locals= NULL, *fromlist= NULL; 00226 int level= -1; /* relative imports */ 00227 00228 PyObject *newmodule; 00229 //PyObject_Print(args, stderr, 0); 00230 static const char *kwlist[]= {"name", "globals", "locals", "fromlist", "level", NULL}; 00231 00232 if(!PyArg_ParseTupleAndKeywords(args, kw, "s|OOOi:bpy_import_meth", (char **)kwlist, 00233 &name, &globals, &locals, &fromlist, &level)) 00234 return NULL; 00235 00236 /* import existing builtin modules or modules that have been imported already */ 00237 newmodule= PyImport_ImportModuleLevel(name, globals, locals, fromlist, level); 00238 00239 if(newmodule) 00240 return newmodule; 00241 00242 PyErr_Fetch(&exception, &err, &tb); /* get the python error incase we cant import as blender text either */ 00243 00244 /* importing from existing modules failed, see if we have this module as blender text */ 00245 newmodule= bpy_text_import_name(name, &found); 00246 00247 if(newmodule) {/* found module as blender text, ignore above exception */ 00248 PyErr_Clear(); 00249 Py_XDECREF(exception); 00250 Py_XDECREF(err); 00251 Py_XDECREF(tb); 00252 /* printf("imported from text buffer...\n"); */ 00253 } 00254 else if (found==1) { /* blender text module failed to execute but was found, use its error message */ 00255 Py_XDECREF(exception); 00256 Py_XDECREF(err); 00257 Py_XDECREF(tb); 00258 return NULL; 00259 } 00260 else { 00261 /* no blender text was found that could import the module 00262 * rause the original error from PyImport_ImportModuleEx */ 00263 PyErr_Restore(exception, err, tb); 00264 } 00265 return newmodule; 00266 } 00267 00268 00269 /* 00270 * our reload() module, to handle reloading in-memory scripts 00271 */ 00272 00273 static PyObject *blender_reload(PyObject *UNUSED(self), PyObject *module) 00274 { 00275 PyObject *exception, *err, *tb; 00276 PyObject *newmodule= NULL; 00277 int found= 0; 00278 00279 /* try reimporting from file */ 00280 newmodule= PyImport_ReloadModule(module); 00281 if(newmodule) 00282 return newmodule; 00283 00284 /* no file, try importing from memory */ 00285 PyErr_Fetch(&exception, &err, &tb); /*restore for probable later use */ 00286 00287 newmodule= bpy_text_reimport(module, &found); 00288 if(newmodule) {/* found module as blender text, ignore above exception */ 00289 PyErr_Clear(); 00290 Py_XDECREF(exception); 00291 Py_XDECREF(err); 00292 Py_XDECREF(tb); 00293 /* printf("imported from text buffer...\n"); */ 00294 } 00295 else if (found==1) { /* blender text module failed to execute but was found, use its error message */ 00296 Py_XDECREF(exception); 00297 Py_XDECREF(err); 00298 Py_XDECREF(tb); 00299 return NULL; 00300 } 00301 else { 00302 /* no blender text was found that could import the module 00303 * reuse the original error from PyImport_ImportModuleEx */ 00304 PyErr_Restore(exception, err, tb); 00305 } 00306 00307 return newmodule; 00308 } 00309 00310 PyMethodDef bpy_import_meth= {"bpy_import_meth", (PyCFunction)blender_import, METH_VARARGS | METH_KEYWORDS, "blenders import"}; 00311 PyMethodDef bpy_reload_meth= {"bpy_reload_meth", (PyCFunction)blender_reload, METH_O, "blenders reload"}; 00312 00313 00314 /* Clear user modules. 00315 * This is to clear any modules that could be defined from running scripts in blender. 00316 * 00317 * Its also needed for the BGE Python api so imported scripts are not used between levels 00318 * 00319 * This clears every modules that has a __file__ attribute (is not a builtin) 00320 * 00321 * Note that clearing external python modules is important for the BGE otherwise 00322 * it wont reload scripts between loading different blend files or while making the game. 00323 * - use 'clear_all' arg in this case. 00324 * 00325 * Since pythons built-ins include a full path even for win32. 00326 * even if we remove a python module a re-import will bring it back again. 00327 */ 00328 00329 #if 0 // not used anymore but may still come in handy later 00330 00331 #if defined(WIN32) || defined(WIN64) 00332 #define SEPSTR "\\" 00333 #else 00334 #define SEPSTR "/" 00335 #endif 00336 00337 00338 void bpy_text_clear_modules(int clear_all) 00339 { 00340 PyObject *modules= PyImport_GetModuleDict(); 00341 00342 char *fname; 00343 char *file_extension; 00344 00345 /* looping over the dict */ 00346 PyObject *key, *value; 00347 int pos= 0; 00348 00349 /* new list */ 00350 PyObject *list; 00351 00352 if (modules==NULL) 00353 return; /* should never happen but just incase */ 00354 00355 list= PyList_New(0); 00356 00357 /* go over sys.modules and remove anything with a 00358 * sys.modukes[x].__file__ thats ends with a .py and has no path 00359 */ 00360 while (PyDict_Next(modules, &pos, &key, &value)) { 00361 fname= PyModule_GetFilename(value); 00362 if(fname) { 00363 if (clear_all || ((strstr(fname, SEPSTR))==0)) { /* no path ? */ 00364 file_extension= strstr(fname, ".py"); 00365 if(file_extension && (*(file_extension + 3) == '\0' || *(file_extension + 4) == '\0')) { /* .py or pyc extension? */ 00366 /* now we can be fairly sure its a python import from the blendfile */ 00367 PyList_Append(list, key); /* free'd with the list */ 00368 } 00369 } 00370 } 00371 else { 00372 PyErr_Clear(); 00373 } 00374 } 00375 00376 /* remove all our modules */ 00377 for(pos=0; pos < PyList_Size(list); pos++) { 00378 /* PyObject_Print(key, stderr, 0); */ 00379 key= PyList_GET_ITEM(list, pos); 00380 PyDict_DelItem(modules, key); 00381 } 00382 00383 Py_DECREF(list); /* removes all references from append */ 00384 } 00385 #endif