Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * This is a new part of Blender. 00019 * 00020 * Contributor(s): Willian P. Germano, Campbell Barton 00021 * 00022 * ***** END GPL LICENSE BLOCK ***** 00023 */ 00024 00036 #include <Python.h> 00037 #include <stddef.h> 00038 00039 #include "bpy_internal_import.h" 00040 00041 #include "MEM_guardedalloc.h" 00042 00043 #include "DNA_text_types.h" 00044 00045 #include "BLI_listbase.h" 00046 #include "BLI_path_util.h" 00047 #include "BLI_string.h" 00048 #include "BLI_utildefines.h" 00049 00050 /* UNUSED */ 00051 #include "BKE_text.h" /* txt_to_buf */ 00052 #include "BKE_main.h" 00053 00054 static Main *bpy_import_main = NULL; 00055 00056 /* 'builtins' is most likely PyEval_GetBuiltins() */ 00057 void bpy_import_init(PyObject *builtins) 00058 { 00059 PyObject *item; 00060 PyObject *mod; 00061 00062 PyDict_SetItemString(builtins, "__import__", item = PyCFunction_New(&bpy_import_meth, NULL)); Py_DECREF(item); 00063 00064 /* move reload here 00065 * XXX, use import hooks */ 00066 mod = PyImport_ImportModuleLevel((char *)"imp", NULL, NULL, NULL, 0); 00067 if (mod) { 00068 PyDict_SetItemString(PyModule_GetDict(mod), "reload", item = PyCFunction_New(&bpy_reload_meth, NULL)); Py_DECREF(item); 00069 Py_DECREF(mod); 00070 } 00071 else { 00072 BLI_assert(!"unable to load 'imp' module."); 00073 } 00074 } 00075 00076 00077 static void free_compiled_text(Text *text) 00078 { 00079 if (text->compiled) { 00080 Py_DECREF((PyObject *)text->compiled); 00081 } 00082 text->compiled = NULL; 00083 } 00084 00085 struct Main *bpy_import_main_get(void) 00086 { 00087 return bpy_import_main; 00088 } 00089 00090 void bpy_import_main_set(struct Main *maggie) 00091 { 00092 bpy_import_main = maggie; 00093 } 00094 00095 /* returns a dummy filename for a textblock so we can tell what file a text block comes from */ 00096 void bpy_text_filename_get(char *fn, size_t fn_len, Text *text) 00097 { 00098 BLI_snprintf(fn, fn_len, "%s%c%s", ID_BLEND_PATH(bpy_import_main, &text->id), SEP, text->id.name + 2); 00099 } 00100 00101 PyObject *bpy_text_import(Text *text) 00102 { 00103 char *buf = NULL; 00104 char modulename[MAX_ID_NAME+2]; 00105 int len; 00106 00107 if (!text->compiled) { 00108 char fn_dummy[256]; 00109 bpy_text_filename_get(fn_dummy, sizeof(fn_dummy), text); 00110 00111 buf = txt_to_buf(text); 00112 text->compiled = Py_CompileString(buf, fn_dummy, Py_file_input); 00113 MEM_freeN(buf); 00114 00115 if (PyErr_Occurred()) { 00116 PyErr_Print(); 00117 PyErr_Clear(); 00118 PySys_SetObject("last_traceback", NULL); 00119 free_compiled_text(text); 00120 return NULL; 00121 } 00122 } 00123 00124 len = strlen(text->id.name + 2); 00125 BLI_strncpy(modulename, text->id.name + 2, len); 00126 modulename[len - 3] = '\0'; /* remove .py */ 00127 return PyImport_ExecCodeModule(modulename, text->compiled); 00128 } 00129 00130 PyObject *bpy_text_import_name(const char *name, int *found) 00131 { 00132 Text *text; 00133 char txtname[MAX_ID_NAME - 2]; 00134 int namelen = strlen(name); 00135 //XXX Main *maggie = bpy_import_main ? bpy_import_main:G.main; 00136 Main *maggie = bpy_import_main; 00137 00138 *found = 0; 00139 00140 if (!maggie) { 00141 printf("ERROR: bpy_import_main_set() was not called before running python. this is a bug.\n"); 00142 return NULL; 00143 } 00144 00145 /* we know this cant be importable, the name is too long for blender! */ 00146 if (namelen >= (MAX_ID_NAME - 2) - 3) return NULL; 00147 00148 memcpy(txtname, name, namelen); 00149 memcpy(&txtname[namelen], ".py", 4); 00150 00151 text = BLI_findstring(&maggie->text, txtname, offsetof(ID, name) + 2); 00152 00153 if (!text) 00154 return NULL; 00155 else 00156 *found = 1; 00157 00158 return bpy_text_import(text); 00159 } 00160 00161 00162 /* 00163 * find in-memory module and recompile 00164 */ 00165 00166 PyObject *bpy_text_reimport(PyObject *module, int *found) 00167 { 00168 Text *text; 00169 const char *name; 00170 char *filepath; 00171 char *buf = NULL; 00172 //XXX Main *maggie = bpy_import_main ? bpy_import_main:G.main; 00173 Main *maggie = bpy_import_main; 00174 00175 if (!maggie) { 00176 printf("ERROR: bpy_import_main_set() was not called before running python. this is a bug.\n"); 00177 return NULL; 00178 } 00179 00180 *found = 0; 00181 00182 /* get name, filename from the module itself */ 00183 if ((name = PyModule_GetName(module)) == NULL) 00184 return NULL; 00185 00186 if ((filepath = (char *)PyModule_GetFilename(module)) == NULL) 00187 return NULL; 00188 00189 /* look up the text object */ 00190 text = BLI_findstring(&maggie->text, BLI_path_basename(filepath), offsetof(ID, name) + 2); 00191 00192 /* uh-oh.... didn't find it */ 00193 if (!text) 00194 return NULL; 00195 else 00196 *found = 1; 00197 00198 /* if previously compiled, free the object */ 00199 /* (can't see how could be NULL, but check just in case) */ 00200 if (text->compiled) { 00201 Py_DECREF((PyObject *)text->compiled); 00202 } 00203 00204 /* compile the buffer */ 00205 buf = txt_to_buf(text); 00206 text->compiled = Py_CompileString(buf, text->id.name + 2, Py_file_input); 00207 MEM_freeN(buf); 00208 00209 /* if compile failed.... return this error */ 00210 if (PyErr_Occurred()) { 00211 PyErr_Print(); 00212 PyErr_Clear(); 00213 PySys_SetObject("last_traceback", NULL); 00214 free_compiled_text(text); 00215 return NULL; 00216 } 00217 00218 /* make into a module */ 00219 return PyImport_ExecCodeModule((char *)name, text->compiled); 00220 } 00221 00222 00223 static PyObject *blender_import(PyObject *UNUSED(self), PyObject *args, PyObject *kw) 00224 { 00225 PyObject *exception, *err, *tb; 00226 char *name; 00227 int found = 0; 00228 PyObject *globals = NULL, *locals = NULL, *fromlist = NULL; 00229 int level = -1; /* relative imports */ 00230 00231 PyObject *newmodule; 00232 //PyObject_Print(args, stderr, 0); 00233 static const char *kwlist[] = {"name", "globals", "locals", "fromlist", "level", NULL}; 00234 00235 if (!PyArg_ParseTupleAndKeywords(args, kw, "s|OOOi:bpy_import_meth", (char **)kwlist, 00236 &name, &globals, &locals, &fromlist, &level)) 00237 { 00238 return NULL; 00239 } 00240 00241 /* import existing builtin modules or modules that have been imported already */ 00242 newmodule = PyImport_ImportModuleLevel(name, globals, locals, fromlist, level); 00243 00244 if (newmodule) 00245 return newmodule; 00246 00247 PyErr_Fetch(&exception, &err, &tb); /* get the python error incase we cant import as blender text either */ 00248 00249 /* importing from existing modules failed, see if we have this module as blender text */ 00250 newmodule = bpy_text_import_name(name, &found); 00251 00252 if (newmodule) {/* found module as blender text, ignore above exception */ 00253 PyErr_Clear(); 00254 Py_XDECREF(exception); 00255 Py_XDECREF(err); 00256 Py_XDECREF(tb); 00257 /* printf("imported from text buffer...\n"); */ 00258 } 00259 else if (found == 1) { /* blender text module failed to execute but was found, use its error message */ 00260 Py_XDECREF(exception); 00261 Py_XDECREF(err); 00262 Py_XDECREF(tb); 00263 return NULL; 00264 } 00265 else { 00266 /* no blender text was found that could import the module 00267 * rause the original error from PyImport_ImportModuleEx */ 00268 PyErr_Restore(exception, err, tb); 00269 } 00270 return newmodule; 00271 } 00272 00273 00274 /* 00275 * our reload() module, to handle reloading in-memory scripts 00276 */ 00277 00278 static PyObject *blender_reload(PyObject *UNUSED(self), PyObject *module) 00279 { 00280 PyObject *exception, *err, *tb; 00281 PyObject *newmodule = NULL; 00282 int found = 0; 00283 00284 /* try reimporting from file */ 00285 newmodule = PyImport_ReloadModule(module); 00286 if (newmodule) 00287 return newmodule; 00288 00289 /* no file, try importing from memory */ 00290 PyErr_Fetch(&exception, &err, &tb); /*restore for probable later use */ 00291 00292 newmodule = bpy_text_reimport(module, &found); 00293 if (newmodule) {/* found module as blender text, ignore above exception */ 00294 PyErr_Clear(); 00295 Py_XDECREF(exception); 00296 Py_XDECREF(err); 00297 Py_XDECREF(tb); 00298 /* printf("imported from text buffer...\n"); */ 00299 } 00300 else if (found == 1) { /* blender text module failed to execute but was found, use its error message */ 00301 Py_XDECREF(exception); 00302 Py_XDECREF(err); 00303 Py_XDECREF(tb); 00304 return NULL; 00305 } 00306 else { 00307 /* no blender text was found that could import the module 00308 * reuse the original error from PyImport_ImportModuleEx */ 00309 PyErr_Restore(exception, err, tb); 00310 } 00311 00312 return newmodule; 00313 } 00314 00315 PyMethodDef bpy_import_meth = {"bpy_import_meth", (PyCFunction)blender_import, METH_VARARGS | METH_KEYWORDS, "blenders import"}; 00316 PyMethodDef bpy_reload_meth = {"bpy_reload_meth", (PyCFunction)blender_reload, METH_O, "blenders reload"};