Integrated unit testing framework with scons on Linux.
[blender.git] / source / blender / python / intern / bpy_interface.c
1
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <sys/stat.h>
6
7 #ifndef WIN32
8 #include <dirent.h>
9 #else
10 #include "BLI_winstuff.h"
11 #endif
12
13 #include <Python.h>
14 #include "compile.h"            /* for the PyCodeObject */
15 #include "eval.h"               /* for PyEval_EvalCode */
16
17 #include "bpy_compat.h"
18
19 #include "bpy_rna.h"
20 #include "bpy_operator.h"
21 #include "bpy_ui.h"
22 #include "bpy_sys.h"
23 #include "bpy_util.h"
24
25 #include "DNA_anim_types.h"
26 #include "DNA_space_types.h"
27 #include "DNA_text_types.h"
28
29 #include "MEM_guardedalloc.h"
30
31 #include "BLI_util.h"
32 #include "BLI_string.h"
33
34 #include "BKE_context.h"
35 #include "BKE_fcurve.h"
36 #include "BKE_text.h"
37
38 #include "BPY_extern.h"
39
40 #include "../generic/bpy_internal_import.h" // our own imports
41 /* external util modukes */
42
43 #include "../generic/Mathutils.h"
44 #include "../generic/Geometry.h"
45 #include "../generic/BGL.h"
46
47
48 void BPY_free_compiled_text( struct Text *text )
49 {
50         if( text->compiled ) {
51                 Py_DECREF( ( PyObject * ) text->compiled );
52                 text->compiled = NULL;
53         }
54 }
55
56 /*****************************************************************************
57 * Description: Creates the bpy module and adds it to sys.modules for importing
58 *****************************************************************************/
59 static void bpy_init_modules( void )
60 {
61         PyObject *mod;
62         
63         mod = PyModule_New("bpy");
64         
65         PyModule_AddObject( mod, "data", BPY_rna_module() );
66         /* PyModule_AddObject( mod, "doc", BPY_rna_doc() ); */
67         PyModule_AddObject( mod, "types", BPY_rna_types() );
68         PyModule_AddObject( mod, "props", BPY_rna_props() );
69         PyModule_AddObject( mod, "ops", BPY_operator_module() );
70         PyModule_AddObject( mod, "ui", BPY_ui_module() ); // XXX very experimental, consider this a test, especially PyCObject is not meant to be permanent
71         
72         /* add the module so we can import it */
73         PyDict_SetItemString(PySys_GetObject("modules"), "bpy", mod);
74         Py_DECREF(mod);
75
76
77         /* stand alone utility modules not related to blender directly */
78         Geometry_Init("Geometry");
79         Mathutils_Init("Mathutils");
80         BGL_Init("BGL");
81 }
82
83 #if (PY_VERSION_HEX < 0x02050000)
84 PyObject *PyImport_ImportModuleLevel(char *name, void *a, void *b, void *c, int d)
85 {
86         return PyImport_ImportModule(name);
87 }
88 #endif
89
90 void BPY_update_modules( void )
91 {
92         PyObject *mod= PyImport_ImportModuleLevel("bpy", NULL, NULL, NULL, 0);
93         PyModule_AddObject( mod, "data", BPY_rna_module() );
94         PyModule_AddObject( mod, "types", BPY_rna_types() );
95         PyModule_AddObject( mod, "util", BPY_util_module() );
96
97         /* XXX this will move to bpy.util */
98         PyModule_AddObject( mod, "sys", BPY_sys_module() );
99 }
100
101 /*****************************************************************************
102 * Description: This function creates a new Python dictionary object.
103 *****************************************************************************/
104 static PyObject *CreateGlobalDictionary( bContext *C )
105 {
106         PyObject *mod;
107         PyObject *dict = PyDict_New(  );
108         PyObject *item = PyUnicode_FromString( "__main__" );
109         PyDict_SetItemString( dict, "__builtins__", PyEval_GetBuiltins(  ) );
110         PyDict_SetItemString( dict, "__name__", item );
111         Py_DECREF(item);
112         
113         // XXX - evil, need to access context
114         BPy_SetContext(C);
115         
116         // XXX - put somewhere more logical
117         {
118                 PyMethodDef *ml;
119                 static PyMethodDef bpy_prop_meths[] = {
120                         {"FloatProperty", (PyCFunction)BPy_FloatProperty, METH_VARARGS|METH_KEYWORDS, ""},
121                         {"IntProperty", (PyCFunction)BPy_IntProperty, METH_VARARGS|METH_KEYWORDS, ""},
122                         {"BoolProperty", (PyCFunction)BPy_BoolProperty, METH_VARARGS|METH_KEYWORDS, ""},
123                         {"StringProperty", (PyCFunction)BPy_StringProperty, METH_VARARGS|METH_KEYWORDS, ""},
124                         {NULL, NULL, 0, NULL}
125                 };
126                 
127                 for(ml = bpy_prop_meths; ml->ml_name; ml++) {
128                         PyDict_SetItemString( dict, ml->ml_name, PyCFunction_New(ml, NULL));
129                 }
130         }
131         
132         /* add bpy to global namespace */
133         mod= PyImport_ImportModuleLevel("bpy", NULL, NULL, NULL, 0);
134         PyDict_SetItemString( dict, "bpy", mod );
135         Py_DECREF(mod);
136         
137         return dict;
138 }
139
140 void BPY_start_python( int argc, char **argv )
141 {
142         PyThreadState *py_tstate = NULL;
143         
144         Py_Initialize(  );
145         
146         //PySys_SetArgv( argc_copy, argv_copy );
147         
148         /* Initialize thread support (also acquires lock) */
149         PyEval_InitThreads();
150         
151         
152         /* bpy.* and lets us import it */
153         bpy_init_modules(); 
154
155         { /* our own import and reload functions */
156                 PyObject *item;
157                 //PyObject *m = PyImport_AddModule("__builtin__");
158                 //PyObject *d = PyModule_GetDict(m);
159                 PyObject *d = PyEval_GetBuiltins(  );
160                 PyDict_SetItemString(d, "reload",               item=PyCFunction_New(bpy_reload_meth, NULL));   Py_DECREF(item);
161                 PyDict_SetItemString(d, "__import__",   item=PyCFunction_New(bpy_import_meth, NULL));   Py_DECREF(item);
162         }
163         
164         py_tstate = PyGILState_GetThisThreadState();
165         PyEval_ReleaseThread(py_tstate);
166 }
167
168 void BPY_end_python( void )
169 {
170         PyGILState_Ensure(); /* finalizing, no need to grab the state */
171         
172         // free other python data.
173         //BPY_rna_free_types();
174         
175         Py_Finalize(  );
176         
177         return;
178 }
179
180 /* Can run a file or text block */
181 int BPY_run_python_script( bContext *C, const char *fn, struct Text *text, struct ReportList *reports)
182 {
183         PyObject *py_dict, *py_result;
184         PyGILState_STATE gilstate;
185         
186         if (fn==NULL && text==NULL) {
187                 return 0;
188         }
189         
190         //BPY_start_python();
191         
192         gilstate = PyGILState_Ensure();
193
194         BPY_update_modules(); /* can give really bad results if this isnt here */
195         bpy_import_main_set(CTX_data_main(C));
196         
197         py_dict = CreateGlobalDictionary(C);
198
199         if (text) {
200                 
201                 if( !text->compiled ) { /* if it wasn't already compiled, do it now */
202                         char *buf = txt_to_buf( text );
203
204                         text->compiled =
205                                 Py_CompileString( buf, text->id.name+2, Py_file_input );
206
207                         MEM_freeN( buf );
208
209                         if( PyErr_Occurred(  ) ) {
210                                 BPy_errors_to_report(reports);
211                                 BPY_free_compiled_text( text );
212                                 PyGILState_Release(gilstate);
213                                 return 0;
214                         }
215                 }
216                 py_result =  PyEval_EvalCode( text->compiled, py_dict, py_dict );
217                 
218         } else {
219                 char pystring[512];
220                 /* TODO - look into a better way to run a file */
221                 sprintf(pystring, "exec(open(r'%s').read())", fn);      
222                 py_result = PyRun_String( pystring, Py_file_input, py_dict, py_dict );                  
223         }
224         
225         if (!py_result) {
226                 BPy_errors_to_report(reports);
227         } else {
228                 Py_DECREF( py_result );
229         }
230         
231         Py_DECREF(py_dict);
232         PyGILState_Release(gilstate);
233         bpy_import_main_set(NULL);
234         
235         //BPY_end_python();
236         return py_result ? 1:0;
237 }
238
239
240 /* TODO - move into bpy_space.c ? */
241 /* GUI interface routines */
242
243 /* Copied from Draw.c */
244 static void exit_pydraw( SpaceScript * sc, short err )
245 {
246         Script *script = NULL;
247
248         if( !sc || !sc->script )
249                 return;
250
251         script = sc->script;
252
253         if( err ) {
254                 BPy_errors_to_report(NULL); // TODO, reports
255                 script->flags = 0;      /* mark script struct for deletion */
256                 SCRIPT_SET_NULL(script);
257                 script->scriptname[0] = '\0';
258                 script->scriptarg[0] = '\0';
259 // XXX 2.5              error_pyscript();
260 // XXX 2.5              scrarea_queue_redraw( sc->area );
261         }
262
263 #if 0 // XXX 2.5
264         BPy_Set_DrawButtonsList(sc->but_refs);
265         BPy_Free_DrawButtonsList(); /*clear all temp button references*/
266 #endif
267
268         sc->but_refs = NULL;
269         
270         Py_XDECREF( ( PyObject * ) script->py_draw );
271         Py_XDECREF( ( PyObject * ) script->py_event );
272         Py_XDECREF( ( PyObject * ) script->py_button );
273
274         script->py_draw = script->py_event = script->py_button = NULL;
275 }
276
277 static int bpy_run_script_init(bContext *C, SpaceScript * sc)
278 {
279         if (sc->script==NULL) 
280                 return 0;
281         
282         if (sc->script->py_draw==NULL && sc->script->scriptname[0] != '\0')
283                 BPY_run_python_script(C, sc->script->scriptname, NULL, NULL);
284                 
285         if (sc->script->py_draw==NULL)
286                 return 0;
287         
288         return 1;
289 }
290
291 int BPY_run_script_space_draw(struct bContext *C, SpaceScript * sc)
292 {
293         if (bpy_run_script_init(C, sc)) {
294                 PyGILState_STATE gilstate = PyGILState_Ensure();
295                 PyObject *result = PyObject_CallObject( sc->script->py_draw, NULL );
296                 
297                 if (result==NULL)
298                         exit_pydraw(sc, 1);
299                         
300                 PyGILState_Release(gilstate);
301         }
302         return 1;
303 }
304
305 // XXX - not used yet, listeners dont get a context
306 int BPY_run_script_space_listener(bContext *C, SpaceScript * sc)
307 {
308         if (bpy_run_script_init(C, sc)) {
309                 PyGILState_STATE gilstate = PyGILState_Ensure();
310                 
311                 PyObject *result = PyObject_CallObject( sc->script->py_draw, NULL );
312                 
313                 if (result==NULL)
314                         exit_pydraw(sc, 1);
315                         
316                 PyGILState_Release(gilstate);
317         }
318         return 1;
319 }
320
321 void BPY_DECREF(void *pyob_ptr)
322 {
323         Py_DECREF((PyObject *)pyob_ptr);
324 }
325
326 #if 0
327 /* called from the the scripts window, assume context is ok */
328 int BPY_run_python_script_space(const char *modulename, const char *func)
329 {
330         PyObject *py_dict, *py_result= NULL;
331         char pystring[512];
332         PyGILState_STATE gilstate;
333         
334         /* for calling the module function */
335         PyObject *py_func, 
336         
337         gilstate = PyGILState_Ensure();
338         
339         py_dict = CreateGlobalDictionary(C);
340         
341         PyObject *module = PyImport_ImportModule(scpt->script.filename);
342         if (module==NULL) {
343                 PyErr_SetFormat(PyExc_SystemError, "could not import '%s'", scpt->script.filename);
344         }
345         else {
346                 py_func = PyObject_GetAttrString(modulename, func);
347                 if (py_func==NULL) {
348                         PyErr_SetFormat(PyExc_SystemError, "module has no function '%s.%s'\n", scpt->script.filename, func);
349                 }
350                 else {
351                         Py_DECREF(py_func);
352                         if (!PyCallable_Check(py_func)) {
353                                 PyErr_SetFormat(PyExc_SystemError, "module item is not callable '%s.%s'\n", scpt->script.filename, func);
354                         }
355                         else {
356                                 py_result= PyObject_CallObject(py_func, NULL); // XXX will need args eventually
357                         }
358                 }
359         }
360         
361         if (!py_result) {
362                 BPy_errors_to_report(NULL); // TODO - reports
363         } else
364                 Py_DECREF( py_result );
365         
366         Py_XDECREF(module);
367         
368         Py_DECREF(py_dict);
369         
370         PyGILState_Release(gilstate);
371         return 1;
372 }
373 #endif
374
375 // #define TIME_REGISTRATION
376
377 #ifdef TIME_REGISTRATION
378 #include "PIL_time.h"
379 #endif
380
381 /* XXX this is temporary, need a proper script registration system for 2.5 */
382 void BPY_run_ui_scripts(bContext *C, int reload)
383 {
384 #ifdef TIME_REGISTRATION
385         double time = PIL_check_seconds_timer();
386 #endif
387         DIR *dir; 
388         struct dirent *de;
389         char *file_extension;
390         char *dirname;
391         char path[FILE_MAX];
392         char *dirs[] = {"io", "ui", NULL};
393         int a, filelen; /* filename length */
394         
395         PyGILState_STATE gilstate;
396         PyObject *mod;
397         PyObject *sys_path_orig;
398         PyObject *sys_path_new;
399
400         gilstate = PyGILState_Ensure();
401         
402         // XXX - evil, need to access context
403         BPy_SetContext(C);
404         bpy_import_main_set(CTX_data_main(C));
405
406         for(a=0; dirs[a]; a++) {
407                 dirname= BLI_gethome_folder(dirs[a]);
408
409                 if(!dirname)
410                         continue;
411
412                 dir = opendir(dirname);
413
414                 if(!dir)
415                         continue;
416
417                 /* backup sys.path */
418                 sys_path_orig= PySys_GetObject("path");
419                 Py_INCREF(sys_path_orig); /* dont free it */
420                 
421                 sys_path_new= PyList_New(1);
422                 PyList_SET_ITEM(sys_path_new, 0, PyUnicode_FromString(dirname));
423                 PySys_SetObject("path", sys_path_new);
424                 Py_DECREF(sys_path_new);
425                         
426                 while((de = readdir(dir)) != NULL) {
427                         /* We could stat the file but easier just to let python
428                          * import it and complain if theres a problem */
429                         
430                         file_extension = strstr(de->d_name, ".py");
431                         
432                         if(file_extension && *(file_extension + 3) == '\0') {
433                                 filelen = strlen(de->d_name);
434                                 BLI_strncpy(path, de->d_name, filelen-2); /* cut off the .py on copy */
435                                 
436                                 mod= PyImport_ImportModuleLevel(path, NULL, NULL, NULL, 0);
437                                 if (mod) {
438                                         if (reload) {
439                                                 PyObject *mod_orig= mod;
440                                                 mod= PyImport_ReloadModule(mod);
441                                                 Py_DECREF(mod_orig);
442                                         }
443                                 }
444                                 
445                                 if(mod) {
446                                         Py_DECREF(mod); /* could be NULL from reloading */
447                                 } else {
448                                         BPy_errors_to_report(NULL); // TODO - reports
449                                         fprintf(stderr, "unable to import \"%s\"  %s/%s\n", path, dirname, de->d_name);
450                                 }
451
452                         }
453                 }
454
455                 closedir(dir);
456
457                 PySys_SetObject("path", sys_path_orig);
458                 Py_DECREF(sys_path_orig);
459         }
460         
461         bpy_import_main_set(NULL);
462         
463         PyGILState_Release(gilstate);
464 #ifdef TIME_REGISTRATION
465         printf("script time %f\n", (PIL_check_seconds_timer()-time));
466 #endif
467 }
468
469 /* ****************************************** */
470 /* Drivers - PyExpression Evaluation */
471
472 /* for pydrivers (drivers using one-line Python expressions to express relationships between targets) */
473 PyObject *bpy_pydriver_Dict = NULL;
474
475 /* For faster execution we keep a special dictionary for pydrivers, with
476  * the needed modules and aliases. 
477  */
478 static int bpy_pydriver_create_dict(void)
479 {
480         PyObject *d, *mod;
481         
482         /* validate namespace for driver evaluation */
483         if (bpy_pydriver_Dict) return -1;
484
485         d = PyDict_New();
486         if (d == NULL) 
487                 return -1;
488         else
489                 bpy_pydriver_Dict = d;
490
491         /* import some modules: builtins, bpy, math, (Blender.noise )*/
492         PyDict_SetItemString(d, "__builtins__", PyEval_GetBuiltins());
493
494         mod = PyImport_ImportModule("math");
495         if (mod) {
496                 PyDict_Merge(d, PyModule_GetDict(mod), 0); /* 0 - dont overwrite existing values */
497                 
498                 /* Only keep for backwards compat! - just import all math into root, they are standard */
499                 PyDict_SetItemString(d, "math", mod);
500                 PyDict_SetItemString(d, "m", mod);
501                 Py_DECREF(mod);
502         } 
503         
504         /* add bpy to global namespace */
505         mod= PyImport_ImportModuleLevel("bpy", NULL, NULL, NULL, 0);
506         if (mod) {
507                 PyDict_SetItemString(bpy_pydriver_Dict, "bpy", mod);
508                 Py_DECREF(mod);
509         }
510         
511         
512 #if 0 // non existant yet
513         mod = PyImport_ImportModule("Blender.Noise");
514         if (mod) {
515                 PyDict_SetItemString(d, "noise", mod);
516                 PyDict_SetItemString(d, "n", mod);
517                 Py_DECREF(mod);
518         } else {
519                 PyErr_Clear();
520         }
521         
522         /* If there's a Blender text called pydrivers.py, import it.
523          * Users can add their own functions to this module. 
524          */
525         if (G.f & G_DOSCRIPTLINKS) {
526                 mod = importText("pydrivers"); /* can also use PyImport_Import() */
527                 if (mod) {
528                         PyDict_SetItemString(d, "pydrivers", mod);
529                         PyDict_SetItemString(d, "p", mod);
530                         Py_DECREF(mod);
531                 } else {
532                         PyErr_Clear();
533                 }
534         }
535 #endif // non existant yet
536         
537         return 0;
538 }
539
540 /* Update function, it gets rid of pydrivers global dictionary, forcing
541  * BPY_pydriver_eval to recreate it. This function is used to force
542  * reloading the Blender text module "pydrivers.py", if available, so
543  * updates in it reach pydriver evaluation. 
544  */
545 void BPY_pydriver_update(void)
546 {
547         PyGILState_STATE gilstate = PyGILState_Ensure();
548
549         if (bpy_pydriver_Dict) { /* free the global dict used by pydrivers */
550                 PyDict_Clear(bpy_pydriver_Dict);
551                 Py_DECREF(bpy_pydriver_Dict);
552                 bpy_pydriver_Dict = NULL;
553         }
554
555         PyGILState_Release(gilstate);
556
557         return;
558 }
559
560 /* error return function for BPY_eval_pydriver */
561 static float pydriver_error(ChannelDriver *driver) 
562 {
563         if (bpy_pydriver_Dict) { /* free the global dict used by pydrivers */
564                 PyDict_Clear(bpy_pydriver_Dict);
565                 Py_DECREF(bpy_pydriver_Dict);
566                 bpy_pydriver_Dict = NULL;
567         }
568
569         driver->flag |= DRIVER_FLAG_INVALID; /* py expression failed */
570         fprintf(stderr, "\nError in Driver: The following Python expression failed:\n\t'%s'\n\n", driver->expression);
571         
572         BPy_errors_to_report(NULL); // TODO - reports
573
574         return 0.0f;
575 }
576
577 /* This evals py driver expressions, 'expr' is a Python expression that
578  * should evaluate to a float number, which is returned. 
579  */
580 float BPY_pydriver_eval (ChannelDriver *driver)
581 {
582         PyObject *driver_vars=NULL;
583         PyObject *retval;
584         PyGILState_STATE gilstate;
585         
586         DriverTarget *dtar;
587         float result = 0.0f; /* default return */
588         char *expr = NULL;
589         short targets_ok= 1;
590         
591         /* sanity checks - should driver be executed? */
592         if ((driver == NULL) /*|| (G.f & G_DOSCRIPTLINKS)==0*/) 
593                 return result;
594         
595         /* get the py expression to be evaluated */
596         expr = driver->expression; 
597         if ((expr == NULL) || (expr[0]=='\0')) 
598                 return result;
599
600         gilstate = PyGILState_Ensure();
601         
602         /* init global dictionary for py-driver evaluation settings */
603         if (!bpy_pydriver_Dict) {
604                 if (bpy_pydriver_create_dict() != 0) {
605                         fprintf(stderr, "Pydriver error: couldn't create Python dictionary");
606                         PyGILState_Release(gilstate);
607                         return result;
608                 }
609         }
610         
611         /* add target values to a dict that will be used as '__locals__' dict */
612         driver_vars = PyDict_New(); // XXX do we need to decref this?
613         for (dtar= driver->targets.first; dtar; dtar= dtar->next) {
614                 PyObject *driver_arg = NULL;
615                 float tval = 0.0f;
616                 
617                 /* try to get variable value */
618                 tval= driver_get_target_value(driver, dtar);
619                 driver_arg= PyFloat_FromDouble((double)tval);
620                 
621                 /* try to add to dictionary */
622                 if (PyDict_SetItemString(driver_vars, dtar->name, driver_arg)) {
623                         /* this target failed - bad name */
624                         if (targets_ok) {
625                                 /* first one - print some extra info for easier identification */
626                                 fprintf(stderr, "\nBPY_pydriver_eval() - Error while evaluating PyDriver:\n");
627                                 targets_ok= 0;
628                         }
629                         
630                         fprintf(stderr, "\tBPY_pydriver_eval() - couldn't add variable '%s' to namespace \n", dtar->name);
631                         BPy_errors_to_report(NULL); // TODO - reports
632                 }
633         }
634         
635         /* execute expression to get a value */
636         retval = PyRun_String(expr, Py_eval_input, bpy_pydriver_Dict, driver_vars);
637         
638         /* decref the driver vars first...  */
639         Py_DECREF(driver_vars);
640         
641         /* process the result */
642         if (retval == NULL) {
643                 result = pydriver_error(driver);
644                 PyGILState_Release(gilstate);
645                 return result;
646         }
647
648         result = (float)PyFloat_AsDouble(retval);
649         Py_DECREF(retval);
650         
651         if ((result == -1) && PyErr_Occurred()) {
652                 result = pydriver_error(driver);
653                 PyGILState_Release(gilstate);
654                 return result;
655         }
656         
657         /* all fine, make sure the "invalid expression" flag is cleared */
658         driver->flag &= ~DRIVER_FLAG_INVALID;
659
660         PyGILState_Release(gilstate);
661
662         return result;
663 }