Drop support for python 3.1.
[blender.git] / source / blender / python / generic / bpy_internal_import.c
1 /* 
2  * $Id$
3  * ***** BEGIN GPL LICENSE BLOCK *****
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  *
19  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
20  * All rights reserved.
21  *
22  * This is a new part of Blender.
23  *
24  * Contributor(s): Willian P. Germano
25  *
26  * ***** END GPL LICENSE BLOCK *****
27 */
28
29 /** \file blender/python/generic/bpy_internal_import.c
30  *  \ingroup pygen
31  */
32
33
34 #include <Python.h>
35 #include <stddef.h>
36
37 #include "compile.h"    /* for the PyCodeObject */
38 #include "eval.h"               /* for PyEval_EvalCode */
39
40 #include "bpy_internal_import.h"
41
42 #include "MEM_guardedalloc.h"
43
44 #include "DNA_text_types.h"
45
46 #include "BLI_listbase.h"
47 #include "BLI_path_util.h"
48 #include "BLI_string.h"
49 #include "BLI_utildefines.h"
50
51  /* UNUSED */   
52 #include "BKE_text.h" /* txt_to_buf */  
53 #include "BKE_main.h"
54 #include "BKE_global.h" /* grr, only for G.main->name */
55
56 static Main *bpy_import_main= NULL;
57
58 static void free_compiled_text(Text *text)
59 {
60         if(text->compiled) {
61                 Py_DECREF(( PyObject * )text->compiled);
62         }
63         text->compiled= NULL;
64 }
65
66 struct Main *bpy_import_main_get(void)
67 {
68         return bpy_import_main;
69 }
70
71 void bpy_import_main_set(struct Main *maggie)
72 {
73         bpy_import_main= maggie;
74 }
75
76 /* returns a dummy filename for a textblock so we can tell what file a text block comes from */
77 void bpy_text_filename_get(char *fn, size_t fn_len, Text *text)
78 {
79         BLI_snprintf(fn, fn_len, "%s%c%s", text->id.lib ? text->id.lib->filepath : G.main->name, SEP, text->id.name+2);
80 }
81
82 PyObject *bpy_text_import(Text *text)
83 {
84         char *buf = NULL;
85         char modulename[24];
86         int len;
87
88         if( !text->compiled ) {
89                 char fn_dummy[256];
90                 bpy_text_filename_get(fn_dummy, sizeof(fn_dummy), text);
91
92                 buf = txt_to_buf( text );
93                 text->compiled = Py_CompileString( buf, fn_dummy, Py_file_input );
94                 MEM_freeN( buf );
95
96                 if( PyErr_Occurred(  ) ) {
97                         PyErr_Print(  );
98                         PyErr_Clear(  );
99                         PySys_SetObject("last_traceback", NULL);
100                         free_compiled_text( text );
101                         return NULL;
102                 }
103         }
104
105         len= strlen(text->id.name+2);
106         strncpy(modulename, text->id.name+2, len);
107         modulename[len - 3]= '\0'; /* remove .py */
108         return PyImport_ExecCodeModule(modulename, text->compiled);
109 }
110
111 PyObject *bpy_text_import_name( char *name, int *found )
112 {
113         Text *text;
114         char txtname[22]; /* 21+NULL */
115         int namelen = strlen( name );
116 //XXX   Main *maggie= bpy_import_main ? bpy_import_main:G.main;
117         Main *maggie= bpy_import_main;
118         
119         *found= 0;
120
121         if(!maggie) {
122                 printf("ERROR: bpy_import_main_set() was not called before running python. this is a bug.\n");
123                 return NULL;
124         }
125         
126         if (namelen>21-3) return NULL; /* we know this cant be importable, the name is too long for blender! */
127         
128         memcpy( txtname, name, namelen );
129         memcpy( &txtname[namelen], ".py", 4 );
130
131         text= BLI_findstring(&maggie->text, txtname, offsetof(ID, name) + 2);
132
133         if( !text )
134                 return NULL;
135         else
136                 *found = 1;
137         
138         return bpy_text_import(text);
139 }
140
141
142 /*
143  * find in-memory module and recompile
144  */
145
146 PyObject *bpy_text_reimport( PyObject *module, int *found )
147 {
148         Text *text;
149         const char *name;
150         char *filepath;
151         char *buf = NULL;
152 //XXX   Main *maggie= bpy_import_main ? bpy_import_main:G.main;
153         Main *maggie= bpy_import_main;
154         
155         if(!maggie) {
156                 printf("ERROR: bpy_import_main_set() was not called before running python. this is a bug.\n");
157                 return NULL;
158         }
159         
160         *found= 0;
161         
162         /* get name, filename from the module itself */
163         if((name= PyModule_GetName(module)) == NULL)
164                 return NULL;
165
166         if((filepath= (char *)PyModule_GetFilename(module)) == NULL)
167                 return NULL;
168
169         /* look up the text object */
170         text= BLI_findstring(&maggie->text, BLI_path_basename(filepath), offsetof(ID, name) + 2);
171
172         /* uh-oh.... didn't find it */
173         if( !text )
174                 return NULL;
175         else
176                 *found = 1;
177
178         /* if previously compiled, free the object */
179         /* (can't see how could be NULL, but check just in case) */ 
180         if( text->compiled ){
181                 Py_DECREF( (PyObject *)text->compiled );
182         }
183
184         /* compile the buffer */
185         buf = txt_to_buf( text );
186         text->compiled = Py_CompileString( buf, text->id.name+2, Py_file_input );
187         MEM_freeN( buf );
188
189         /* if compile failed.... return this error */
190         if( PyErr_Occurred(  ) ) {
191                 PyErr_Print(  );
192                 PyErr_Clear(  );
193                 PySys_SetObject("last_traceback", NULL);
194                 free_compiled_text( text );
195                 return NULL;
196         }
197
198         /* make into a module */
199         return PyImport_ExecCodeModule( (char *)name, text->compiled );
200 }
201
202
203 static PyObject *blender_import(PyObject *UNUSED(self), PyObject *args,  PyObject * kw)
204 {
205         PyObject *exception, *err, *tb;
206         char *name;
207         int found= 0;
208         PyObject *globals = NULL, *locals = NULL, *fromlist = NULL;
209         int level= -1; /* relative imports */
210         
211         PyObject *newmodule;
212         //PyObject_Print(args, stderr, 0);
213         static const char *kwlist[] = {"name", "globals", "locals", "fromlist", "level", NULL};
214         
215         if( !PyArg_ParseTupleAndKeywords(args, kw, "s|OOOi:bpy_import_meth", (char **)kwlist,
216                                    &name, &globals, &locals, &fromlist, &level) )
217                 return NULL;
218
219         /* import existing builtin modules or modules that have been imported already */
220         newmodule= PyImport_ImportModuleLevel(name, globals, locals, fromlist, level);
221         
222         if(newmodule)
223                 return newmodule;
224         
225         PyErr_Fetch( &exception, &err, &tb );   /* get the python error incase we cant import as blender text either */
226         
227         /* importing from existing modules failed, see if we have this module as blender text */
228         newmodule = bpy_text_import_name( name, &found );
229         
230         if( newmodule ) {/* found module as blender text, ignore above exception */
231                 PyErr_Clear(  );
232                 Py_XDECREF( exception );
233                 Py_XDECREF( err );
234                 Py_XDECREF( tb );
235                 /* printf( "imported from text buffer...\n" ); */
236         }
237         else if (found==1) { /* blender text module failed to execute but was found, use its error message */
238                 Py_XDECREF( exception );
239                 Py_XDECREF( err );
240                 Py_XDECREF( tb );
241                 return NULL;
242         }
243         else {
244                 /* no blender text was found that could import the module
245                  * rause the original error from PyImport_ImportModuleEx */
246                 PyErr_Restore( exception, err, tb );
247         }
248         return newmodule;
249 }
250
251
252 /*
253  * our reload() module, to handle reloading in-memory scripts
254  */
255
256 static PyObject *blender_reload(PyObject *UNUSED(self), PyObject * module)
257 {
258         PyObject *exception, *err, *tb;
259         PyObject *newmodule = NULL;
260         int found= 0;
261
262         /* try reimporting from file */
263         newmodule = PyImport_ReloadModule( module );
264         if( newmodule )
265                 return newmodule;
266
267         /* no file, try importing from memory */
268         PyErr_Fetch( &exception, &err, &tb );   /*restore for probable later use */
269
270         newmodule = bpy_text_reimport( module, &found );
271         if( newmodule ) {/* found module as blender text, ignore above exception */
272                 PyErr_Clear(  );
273                 Py_XDECREF( exception );
274                 Py_XDECREF( err );
275                 Py_XDECREF( tb );
276                 /* printf( "imported from text buffer...\n" ); */
277         }
278         else if (found==1) { /* blender text module failed to execute but was found, use its error message */
279                 Py_XDECREF( exception );
280                 Py_XDECREF( err );
281                 Py_XDECREF( tb );
282                 return NULL;
283         }
284         else {
285                 /* no blender text was found that could import the module
286                  * rause the original error from PyImport_ImportModuleEx */
287                 PyErr_Restore( exception, err, tb );
288         }
289
290         return newmodule;
291 }
292
293 PyMethodDef bpy_import_meth = {"bpy_import_meth", (PyCFunction)blender_import, METH_VARARGS | METH_KEYWORDS, "blenders import"};
294 PyMethodDef bpy_reload_meth = {"bpy_reload_meth", (PyCFunction)blender_reload, METH_O, "blenders reload"};
295
296
297 /* Clear user modules.
298  * This is to clear any modules that could be defined from running scripts in blender.
299  * 
300  * Its also needed for the BGE Python api so imported scripts are not used between levels
301  * 
302  * This clears every modules that has a __file__ attribute (is not a builtin)
303  *
304  * Note that clearing external python modules is important for the BGE otherwise
305  * it wont reload scripts between loading different blend files or while making the game.
306  * - use 'clear_all' arg in this case.
307  *
308  * Since pythons bultins include a full path even for win32.
309  * even if we remove a python module a reimport will bring it back again.
310  */
311
312 #if 0 // not used anymore but may still come in handy later
313
314 #if defined(WIN32) || defined(WIN64)
315 #define SEPSTR "\\"
316 #else
317 #define SEPSTR "/"
318 #endif
319
320
321 void bpy_text_clear_modules(int clear_all)
322 {
323         PyObject *modules= PyImport_GetModuleDict();
324         
325         char *fname;
326         char *file_extension;
327         
328         /* looping over the dict */
329         PyObject *key, *value;
330         int pos = 0;
331         
332         /* new list */
333         PyObject *list;
334
335         if (modules==NULL)
336                 return; /* should never happen but just incase */
337
338         list= PyList_New(0);
339
340         /* go over sys.modules and remove anything with a 
341          * sys.modukes[x].__file__ thats ends with a .py and has no path
342          */
343         while (PyDict_Next(modules, &pos, &key, &value)) {
344                 fname= PyModule_GetFilename(value);
345                 if(fname) {
346                         if (clear_all || ((strstr(fname, SEPSTR))==0)) { /* no path ? */
347                                 file_extension = strstr(fname, ".py");
348                                 if(file_extension && (*(file_extension + 3) == '\0' || *(file_extension + 4) == '\0')) { /* .py or pyc extension? */
349                                         /* now we can be fairly sure its a python import from the blendfile */
350                                         PyList_Append(list, key); /* free'd with the list */
351                                 }
352                         }
353                 }
354                 else {
355                         PyErr_Clear();
356                 }
357         }
358         
359         /* remove all our modules */
360         for(pos=0; pos < PyList_Size(list); pos++) {
361                 /* PyObject_Print(key, stderr, 0); */
362                 key= PyList_GET_ITEM(list, pos);
363                 PyDict_DelItem(modules, key);
364         }
365         
366         Py_DECREF(list); /* removes all references from append */
367 }
368 #endif