This looks like a lot but its a few small changes.
[blender.git] / source / blender / python / BPY_interface.c
1 /* 
2  *
3  * ***** BEGIN GPL/BL DUAL 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. The Blender
9  * Foundation also sells licenses for use in proprietary software under
10  * the Blender License.  See http://www.blender.org/BL/ for information
11  * about this.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  *
22  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
23  * All rights reserved.
24  *
25  * This is a new part of Blender.
26  *
27  * Contributor(s): Michel Selten, Willian P. Germano, Stephen Swaney
28  *
29  * ***** END GPL/BL DUAL LICENSE BLOCK *****
30 */
31 #ifdef HAVE_CONFIG_H
32 #include <config.h>
33 #endif
34
35 #include <Python.h>
36 #include "compile.h" /* for the PyCodeObject */
37 #include "eval.h" /* for PyEval_EvalCode */
38
39 #include <stdio.h>
40
41 #include <MEM_guardedalloc.h>
42
43 #include <BLI_blenlib.h> /* for BLI_last_slash() */
44
45 #include <BKE_global.h>
46 #include <BKE_main.h>
47 #include <BKE_text.h>
48 #include <DNA_camera_types.h>
49 #include <DNA_ID.h>
50 #include <DNA_lamp_types.h>
51 #include <DNA_material_types.h>
52 #include <DNA_object_types.h>
53 #include <DNA_scene_types.h>
54 #include <DNA_scriptlink_types.h>
55 #include <DNA_space_types.h>
56 #include <DNA_text_types.h>
57 #include <DNA_world_types.h>
58
59 #include <DNA_userdef_types.h> /* for U.pythondir */
60
61 #include "BPY_extern.h"
62 #include "api2_2x/EXPP_interface.h"
63
64 /* bpy_registryDict is declared in api2_2x/Registry.h and defined
65  * here.  This Python dictionary will be used to store data that scripts
66  * choose to preserve after they are executed, so user changes can be
67  * restored next time the script is used.  Check the Blender.Registry module. */
68 extern PyObject *bpy_registryDict;
69
70 /*****************************************************************************/
71 /* Structure definitions                                                     */
72 /*****************************************************************************/
73 #define FILENAME_LENGTH 24
74 typedef struct _ScriptError {
75   char filename[FILENAME_LENGTH];
76   int lineno;
77 } ScriptError;
78
79 /*****************************************************************************/
80 /* Global variables                                                          */
81 /*****************************************************************************/
82 ScriptError g_script_error;
83 short EXPP_releaseGlobalDict = 1;
84
85 /*****************************************************************************/
86 /* Function prototypes                                                       */
87 /*****************************************************************************/
88 PyObject *RunPython(Text *text, PyObject *globaldict);
89 char     *GetName(Text *text);
90 PyObject *CreateGlobalDictionary (void);
91 void      ReleaseGlobalDictionary (PyObject * dict);
92 void      DoAllScriptsFromList (ListBase * list, short event);
93 PyObject *importText(char *name);
94 void init_ourImport(void);
95 PyObject *blender_import(PyObject *self, PyObject *args);
96
97 /*****************************************************************************/
98 /* Description: This function will initialise Python and all the implemented */
99 /*              api variations.                                              */
100 /* Notes:       Currently only the api for 2.2x will be initialised.         */
101 /*****************************************************************************/
102 void BPY_start_python(void)
103 {
104   bpy_registryDict = PyDict_New(); /* check comment at start of this file */
105
106   if (!bpy_registryDict)
107     printf("Error: Couldn't create the Registry Python Dictionary!");
108
109 /* TODO: Shouldn't "blender" be replaced by PACKAGE ?? (config.h) */
110   Py_SetProgramName("blender");
111
112   Py_Initialize ();
113
114   init_ourImport ();
115
116   initBlenderApi2_2x ();
117
118   init_syspath();
119
120   return;
121 }
122
123 /*****************************************************************************/
124 /* Description: This function will terminate the Python interpreter          */
125 /*****************************************************************************/
126 void BPY_end_python(void)
127 {
128   if (bpy_registryDict) {
129     Py_DECREF (bpy_registryDict);
130     bpy_registryDict = NULL;
131   }
132
133   Py_Finalize();
134   return;
135 }
136
137 void syspath_append(PyObject *dir)
138 {
139   PyObject *mod_sys, *dict, *path;
140
141   PyErr_Clear();
142
143   mod_sys = PyImport_ImportModule("sys"); /* new ref */
144   dict = PyModule_GetDict(mod_sys);       /* borrowed ref */
145   path = PyDict_GetItemString(dict, "path"); /* borrowed ref */
146
147   if (!PyList_Check(path)) return;
148
149   PyList_Append(path, dir);
150
151   if (PyErr_Occurred()) Py_FatalError("could not build sys.path");
152
153   Py_DECREF(mod_sys);
154 }
155
156 void init_syspath(void)
157 {
158   PyObject *path;
159   PyObject *mod, *d;
160   PyObject *p;
161   char *c, *progname;
162   char execdir[FILE_MAXDIR + FILE_MAXFILE];/*defines from DNA_space_types.h*/
163
164   int n;
165
166   path = Py_BuildValue("s", bprogname);
167
168   mod = PyImport_ImportModule("Blender.sys");
169
170   if (mod) {
171     d = PyModule_GetDict(mod);
172     PyDict_SetItemString(d, "progname", path);
173     Py_DECREF(mod);
174   }
175   else
176     printf("Warning: could not set Blender.sys.progname\n");
177
178   progname = BLI_last_slash(bprogname); /* looks for the last dir separator */
179
180   c = Py_GetPath(); /* get python system path */
181   PySys_SetPath(c); /* initialize */
182
183   n = progname - bprogname;
184   if (n > 0) {
185     strncpy(execdir, bprogname, n);
186     if (execdir[n-1] == '.') n--; /*fix for when run as ./blender */
187     execdir[n] = '\0';
188
189     p = Py_BuildValue("s", execdir);
190     syspath_append(p);  /* append to module search path */
191
192     /* set Blender.sys.progname */
193   }
194   else
195     printf ("Warning: could not determine argv[0] path\n");
196
197   if (U.pythondir) {
198     p = Py_BuildValue("s", U.pythondir);
199     syspath_append(p);  /* append to module search path */
200   }
201
202   /* 
203    * bring in the site module so we can add 
204    * site-package dirs to sys.path 
205    */
206
207   mod = PyImport_ImportModule("site"); /* new ref */
208
209   if (mod) {
210     PyObject* item;
211     int size = 0;
212     int index;
213
214     /* get the value of 'sitedirs' from the module */
215
216     /* the ref man says GetDict() never fails!!! */
217     d = PyModule_GetDict (mod); /* borrowed ref */
218     p = PyDict_GetItemString (d, "sitedirs");  /* borrowed ref */
219
220     if( p ) {  /* we got our string */
221       /* append each item in sitedirs list to path */
222       size = PyList_Size (p);
223
224       for (index = 0; index < size; index++) {
225         item  = PySequence_GetItem (p, index);  /* new ref */
226         if( item )
227           syspath_append (item);
228       }
229     }
230     Py_DECREF(mod);
231   }
232   else {  /* import 'site' failed */
233     PyErr_Clear();
234     printf("sys_init:warning - no sitedirs added from site module.\n");
235   }
236
237   /* 
238    * initialize the sys module
239    * set sys.executable to the Blender exe 
240    * set argv[0] to the Blender exe
241    */
242
243   mod = PyImport_ImportModule("sys"); /* new ref */
244
245   if (mod) {
246     d = PyModule_GetDict(mod); /* borrowed ref */
247     PyDict_SetItemString(d, "executable", Py_BuildValue("s", bprogname));
248     /* in the future this can be extended to have more argv's if needed: */
249     PyDict_SetItemString(d, "argv", Py_BuildValue("[s]", bprogname));
250     Py_DECREF(mod);
251   }
252 }
253
254 /*****************************************************************************/
255 /* Description: This function adds the user defined folder for Python        */
256 /*              scripts to sys.path.  This is done in init_syspath, too, but */
257 /*              when Blender's main() runs BPY_start_python(), U.pythondir   */
258 /*              isn't set yet, so we provide this function to be executed    */
259 /*              after U.pythondir is defined.                                */
260 /*****************************************************************************/
261 void BPY_syspath_append_pythondir(void)
262 {
263   syspath_append(Py_BuildValue("s", U.pythondir));
264 }
265
266 /*****************************************************************************/
267 /* Description: This function will return the linenumber on which an error   */
268 /*              has occurred in the Python script.                           */
269 /*****************************************************************************/
270 int BPY_Err_getLinenumber(void)
271 {
272   return g_script_error.lineno;
273 }
274
275 /*****************************************************************************/
276 /* Description: This function will return the filename of the python script. */
277 /*****************************************************************************/
278 const char *BPY_Err_getFilename(void)
279 {
280   return g_script_error.filename;
281 }
282
283 /*****************************************************************************/
284 /* Description: Return PyString filename from a traceback object             */
285 /*****************************************************************************/
286 PyObject *traceback_getFilename(PyObject *tb)
287 {
288   PyObject *v;
289
290 /* co_filename is in f_code, which is in tb_frame, which is in tb */
291
292   v = PyObject_GetAttrString(tb, "tb_frame"); Py_XDECREF(v);
293   v = PyObject_GetAttrString(v, "f_code"); Py_XDECREF(v);
294   v = PyObject_GetAttrString(v, "co_filename");
295
296   return v;
297 }
298
299 /*****************************************************************************/
300 /* Description: Blender Python error handler. This catches the error and     */
301 /* stores filename and line number in a global                               */
302 /*****************************************************************************/
303 void BPY_Err_Handle(Text *text)
304 {
305   PyObject *exception, *err, *tb, *v;
306
307   PyErr_Fetch(&exception, &err, &tb);
308
309   if (!exception && !tb) {
310     printf("FATAL: spurious exception\n");
311     return;
312   }
313
314   strcpy(g_script_error.filename, GetName(text));
315
316   if (exception && PyErr_GivenExceptionMatches(exception, PyExc_SyntaxError)) {
317     /* no traceback available when SyntaxError */
318     PyErr_Restore(exception, err, tb); /* takes away reference! */
319     PyErr_Print();
320     v = PyObject_GetAttrString(err, "lineno");
321     g_script_error.lineno = PyInt_AsLong(v);
322     Py_XDECREF(v);
323     /* this avoids an abort in Python 2.3's garbage collecting: */
324     PyErr_Clear(); 
325     return;
326   } else {
327     PyErr_NormalizeException(&exception, &err, &tb);
328     PyErr_Restore(exception, err, tb); // takes away reference!
329     PyErr_Print();
330     tb = PySys_GetObject("last_traceback");
331
332     if (!tb) {
333       printf("\nCan't get traceback\n");
334       return;
335     }
336
337     Py_INCREF(tb);
338
339 /* From old bpython BPY_main.c:
340  * 'check traceback objects and look for last traceback in the
341  *  same text file. This is used to jump to the line of where the
342  *  error occured. "If the error occured in another text file or module,
343  *  the last frame in the current file is adressed."' */
344
345     while (1) { 
346       v = PyObject_GetAttrString(tb, "tb_next");
347
348       if (v == Py_None || strcmp(PyString_AsString(traceback_getFilename(v)),
349                               GetName(text))) {
350         break;
351       }
352
353       Py_DECREF(tb);
354       tb = v;
355     }
356
357     v = PyObject_GetAttrString(tb, "tb_lineno");
358     g_script_error.lineno = PyInt_AsLong(v);
359     Py_XDECREF(v);
360     v = traceback_getFilename(tb);
361     strncpy(g_script_error.filename, PyString_AsString(v), FILENAME_LENGTH);
362     Py_XDECREF(v);
363     Py_DECREF(tb);
364   }
365
366   return;
367 }
368
369 /*****************************************************************************/
370 /* Description: This function executes the script passed by st.              */
371 /* Notes:       It is called by blender/src/drawtext.c when a Blender user   */
372 /*              presses ALT+PKEY in the script's text window.                */
373 /*****************************************************************************/
374 struct _object *BPY_txt_do_python(struct SpaceText* st)
375 {
376   PyObject *dict, *ret;
377   PyObject *main_dict = PyModule_GetDict(PyImport_AddModule("__main__"));
378
379   if (!st->text) return NULL;
380
381 /* The EXPP_releaseGlobalDict global variable controls whether we should run
382  * the script with a clean global dictionary or should keep the current one,
383  * possibly already "polluted" by other calls to the Python Interpreter.
384  * The default is to use a clean one.  To change this the script writer must
385  * call Blender.ReleaseGlobalDict(bool), with bool == 0, in the script. */
386
387   if (EXPP_releaseGlobalDict) {
388     printf("Using a clean Global Dictionary.\n");
389     st->flags |= ST_CLEAR_NAMESPACE;
390     dict = CreateGlobalDictionary();
391   }
392   else
393     dict = main_dict; /* must be careful not to free the main_dict */
394
395   clearScriptLinks ();
396
397   ret = RunPython (st->text, dict); /* Run the script */
398
399   if (!ret) { /* Failed execution of the script */
400
401     if (EXPP_releaseGlobalDict && (dict != main_dict))
402       ReleaseGlobalDictionary(dict);
403
404     BPY_Err_Handle(st->text);
405     BPY_end_python();
406     BPY_start_python();
407
408     return NULL;
409   }
410
411   else Py_DECREF (ret);
412
413 /* Scripts that use the GUI rely on the persistent global namespace, so
414  * they need a workaround: The namespace is released when the GUI is exit.'
415  * See api2_2x/Draw.c: Method_Register() */
416
417 /* Block below: The global dict should only be released if:
418  * - a script didn't defined it to be persistent and
419  * - Draw.Register() is not in use (no GUI) and
420  * - it is not the real __main__ dict (if it is, restart to clean it) */
421
422   if (EXPP_releaseGlobalDict) {
423     if (st->flags & ST_CLEAR_NAMESPACE) { /* False if the GUI is in use */
424
425       if (dict != main_dict) ReleaseGlobalDictionary(dict);
426
427       else {
428         BPY_end_python(); /* restart to get a fresh __main__ dict */
429         BPY_start_python();
430       }
431
432     }
433   }
434   else if (dict != main_dict) PyDict_Update (main_dict, dict);
435
436 /* Line above: if it should be kept and it's not already the __main__ dict,
437  * merge it into the __main__ one.  This happens when to release is the
438  * current behavior and the script changes that with
439  * Blender.ReleaseGlobalDict(0). */
440
441 /* Edited from old BPY_main.c:
442  * 'The return value is the global namespace dictionary of the script
443  *  context.  This may be stored in the SpaceText instance to give control
444  *  over namespace persistence.  Remember that the same script may be
445  *  executed in several windows ...  Namespace persistence is desired for
446  *  scripts that use the GUI and store callbacks to the current script.' */
447
448   return dict;
449 }
450
451 /*****************************************************************************/
452 /* Description:                                                              */
453 /* Notes:                                                                    */
454 /*****************************************************************************/
455 void BPY_free_compiled_text(struct Text* text)
456 {
457   if (!text->compiled) return;
458   Py_DECREF((PyObject*) text->compiled);
459   text->compiled = NULL;
460
461   return;
462 }
463
464 /*****************************************************************************/
465 /* ScriptLinks                                                               */
466 /*****************************************************************************/
467
468 /*****************************************************************************/
469 /* Description:                                                              */
470 /* Notes:       Not implemented yet                                          */
471 /*****************************************************************************/
472 void BPY_clear_bad_scriptlinks(struct Text *byebye)
473 {
474 /*
475   BPY_clear_bad_scriptlist(getObjectList(), byebye);
476   BPY_clear_bad_scriptlist(getLampList(), byebye);
477   BPY_clear_bad_scriptlist(getCameraList(), byebye);
478   BPY_clear_bad_scriptlist(getMaterialList(), byebye);
479   BPY_clear_bad_scriptlist(getWorldList(),  byebye);
480   BPY_clear_bad_scriptlink(&scene_getCurrent()->id, byebye);
481
482   allqueue(REDRAWBUTSSCRIPT, 0);
483 */
484   return;
485 }
486
487 /*****************************************************************************/
488 /* Description: Loop through all scripts of a list of object types, and      */
489 /*              execute these scripts.                                       */
490 /*              For the scene, only the current active scene the scripts are */
491 /*              executed (if any).                                           */
492 /*****************************************************************************/
493 void BPY_do_all_scripts(short event)
494 {
495   DoAllScriptsFromList (&(G.main->object), event);
496   DoAllScriptsFromList (&(G.main->lamp), event);
497   DoAllScriptsFromList (&(G.main->camera), event);
498   DoAllScriptsFromList (&(G.main->mat), event);
499   DoAllScriptsFromList (&(G.main->world), event);
500
501   BPY_do_pyscript (&(G.scene->id), event);
502
503   return;
504 }
505
506 /*****************************************************************************/
507 /* Description: Execute a Python script when an event occurs. The following  */
508 /*              events are possible: frame changed, load script and redraw.  */
509 /*              Only events happening to one of the following object types   */
510 /*              are handled: Object, Lamp, Camera, Material, World and       */
511 /*              Scene.                                                       */
512 /*****************************************************************************/
513 void BPY_do_pyscript(struct ID *id, short event)
514 {
515   ScriptLink  * scriptlink;
516   int           index;
517   PyObject    * dict;
518   PyObject    * ret;
519
520   scriptlink = setScriptLinks (id, event);
521
522   if (scriptlink == NULL) return;
523
524   for (index = 0; index < scriptlink->totscript; index++)
525   {
526     if ((scriptlink->flag[index] == event) &&
527         (scriptlink->scripts[index] != NULL))
528     {
529       dict = CreateGlobalDictionary();
530       ret = RunPython ((Text*) scriptlink->scripts[index], dict);
531       ReleaseGlobalDictionary (dict);
532       if (!ret)
533       {
534           /* Failed execution of the script */
535           BPY_Err_Handle ((Text*) scriptlink->scripts[index]);
536           BPY_end_python ();
537           BPY_start_python ();
538       }
539       else
540       {
541           Py_DECREF (ret);
542       }
543     }
544   }
545
546   return;
547 }
548
549 /*****************************************************************************/
550 /* Description:                                                              */
551 /* Notes:                                                                    */
552 /*****************************************************************************/
553 void BPY_free_scriptlink(struct ScriptLink *slink)
554 {
555   if (slink->totscript) {
556     if(slink->flag) MEM_freeN(slink->flag);
557     if(slink->scripts) MEM_freeN(slink->scripts); 
558   }
559
560   return;
561 }
562
563 /*****************************************************************************/
564 /* Description:                                                              */
565 /* Notes:                                                                    */
566 /*****************************************************************************/
567 void BPY_copy_scriptlink(struct ScriptLink *scriptlink)
568 {
569   void *tmp;
570
571   if (scriptlink->totscript) {
572
573     tmp = scriptlink->scripts;
574     scriptlink->scripts =
575       MEM_mallocN(sizeof(ID*)*scriptlink->totscript, "scriptlistL");
576     memcpy(scriptlink->scripts, tmp, sizeof(ID*)*scriptlink->totscript);
577
578     tmp = scriptlink->flag;
579     scriptlink->flag =
580       MEM_mallocN(sizeof(short)*scriptlink->totscript, "scriptlistF");
581     memcpy(scriptlink->flag, tmp, sizeof(short)*scriptlink->totscript);
582   }
583
584   return;
585 }
586
587 /*****************************************************************************/
588 /* Description:                                                              */
589 /* Notes:       Not implemented yet                                          */
590 /*****************************************************************************/
591 int BPY_call_importloader(char *name)
592 { /* XXX Should this function go away from Blender? */
593   printf ("In BPY_call_importloader(name=%s)\n",name);
594   return (0);
595 }
596
597 /*****************************************************************************/
598 /* Private functions                                                         */
599 /*****************************************************************************/
600
601 /*****************************************************************************/
602 /* Description: This function executes the python script passed by text.     */
603 /*              The Python dictionary containing global variables needs to   */
604 /*              be passed in globaldict.                                     */
605 /*****************************************************************************/
606 PyObject * RunPython(Text *text, PyObject *globaldict)
607 {
608   char *buf = NULL;
609
610 /* The script text is compiled to Python bytecode and saved at text->compiled
611  * to speed-up execution if the user executes the script multiple times */
612
613   if (!text->compiled) { /* if it wasn't already compiled, do it now */
614     buf = txt_to_buf(text);
615
616     text->compiled = Py_CompileString(buf, GetName(text), Py_file_input);
617
618     MEM_freeN(buf);
619
620     if (PyErr_Occurred()) {
621       BPY_free_compiled_text(text);
622       return NULL;
623     }
624
625   }
626
627   return PyEval_EvalCode(text->compiled, globaldict, globaldict);
628 }
629
630 /*****************************************************************************/
631 /* Description: This function returns the value of the name field of the     */
632 /*              given Text struct.                                           */
633 /*****************************************************************************/
634 char * GetName(Text *text)
635 {
636   return (text->id.name+2);
637 }
638
639 /*****************************************************************************/
640 /* Description: This function creates a new Python dictionary object.        */
641 /*****************************************************************************/
642 PyObject * CreateGlobalDictionary (void)
643 {
644   PyObject *dict = PyDict_New();
645
646   PyDict_SetItemString (dict, "__builtins__", PyEval_GetBuiltins());
647   PyDict_SetItemString (dict, "__name__", PyString_FromString("__main__"));
648
649   return dict;
650 }
651
652 /*****************************************************************************/
653 /* Description: This function deletes a given Python dictionary object.      */
654 /*****************************************************************************/
655 void ReleaseGlobalDictionary (PyObject * dict)
656 {
657   PyDict_Clear (dict);
658   Py_DECREF (dict);   /* Release dictionary. */
659
660   return;
661 }
662
663 /*****************************************************************************/
664 /* Description: This function runs all scripts (if any) present in the       */
665 /*              list argument. The event by which the function has been      */
666 /*              called, is passed in the event argument.                     */
667 /*****************************************************************************/
668 void DoAllScriptsFromList (ListBase *list, short event)
669 {
670   ID *id;
671
672   id = list->first;
673
674   while (id != NULL) {
675     BPY_do_pyscript (id, event);
676     id = id->next;
677   }
678
679   return;
680 }
681
682 PyObject *importText(char *name)
683 {
684   Text *text;
685   char *txtname;
686   char *buf = NULL;
687   int namelen = strlen(name);
688
689   txtname = malloc(namelen+3+1);
690   if (!txtname) return NULL;
691
692   memcpy(txtname, name, namelen);
693   memcpy(&txtname[namelen], ".py", 4);
694
695   text = (Text*) &(G.main->text.first);
696
697   while(text) {
698     if (!strcmp (txtname, GetName(text)))
699       break;
700     text = text->id.next;
701   }
702
703   if (!text) {
704     free(txtname);
705     return NULL;
706   }
707
708   if (!text->compiled) {
709     buf = txt_to_buf(text);
710     text->compiled = Py_CompileString(buf, GetName(text), Py_file_input);
711     MEM_freeN(buf);
712
713     if (PyErr_Occurred()) {
714       PyErr_Print();
715       BPY_free_compiled_text(text);
716       free(txtname);
717       return NULL;
718     }
719   }
720
721   free(txtname);
722   return PyImport_ExecCodeModule(name, text->compiled);
723 }
724
725 static PyMethodDef bimport[] = {
726   { "blimport", blender_import, METH_VARARGS, "our own import"}
727 };
728
729 PyObject *blender_import(PyObject *self, PyObject *args)
730 {
731   PyObject *exception, *err, *tb;
732   char *name;
733   PyObject *globals = NULL, *locals = NULL, *fromlist = NULL;
734   PyObject *m;
735
736   if (!PyArg_ParseTuple(args, "s|OOO:bimport",
737           &name, &globals, &locals, &fromlist))
738       return NULL;
739
740   m = PyImport_ImportModuleEx(name, globals, locals, fromlist);
741
742   if (m) 
743     return m;
744   else
745     PyErr_Fetch(&exception, &err, &tb); /*restore for probable later use*/
746   
747   m = importText(name);
748   if (m) { /* found module, ignore above exception*/
749     PyErr_Clear();
750     Py_XDECREF(exception); Py_XDECREF(err); Py_XDECREF(tb);
751     printf("imported from text buffer...\n");
752   } else {
753     PyErr_Restore(exception, err, tb);
754   }
755   return m;
756 }
757
758 void init_ourImport(void)
759 {
760   PyObject *m, *d;
761   PyObject *import = PyCFunction_New(bimport, NULL);
762
763   m = PyImport_AddModule("__builtin__");
764   d = PyModule_GetDict(m);
765   PyDict_SetItemString(d, "__import__", import);
766 }