Mathutils doc improvements + other small things
[blender-staging.git] / source / blender / python / intern / bpy_interface.c
1 /**
2  * $Id:
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * Contributor(s): Michel Selten, Willian P. Germano, Stephen Swaney,
21  * Chris Keith, Chris Want, Ken Hughes, Campbell Barton
22  *
23  * ***** END GPL LICENSE BLOCK *****
24  */
25  
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <sys/stat.h>
30
31
32 /* grr, python redefines */
33 #ifdef _POSIX_C_SOURCE
34 #undef _POSIX_C_SOURCE
35 #endif
36
37 #include <Python.h>
38 #include "compile.h"            /* for the PyCodeObject */
39 #include "eval.h"               /* for PyEval_EvalCode */
40
41 #include "bpy_rna.h"
42 #include "bpy_props.h"
43 #include "bpy_operator.h"
44 #include "bpy_util.h"
45
46 #ifndef WIN32
47 #include <dirent.h>
48 #else
49 #include "BLI_winstuff.h"
50 #endif
51
52 #include "DNA_space_types.h"
53 #include "DNA_text_types.h"
54
55 #include "MEM_guardedalloc.h"
56
57 #include "BLI_path_util.h"
58 #include "BLI_storage.h"
59 #include "BLI_fileops.h"
60 #include "BLI_string.h"
61
62 #include "BKE_context.h"
63 #include "BKE_text.h"
64 #include "BKE_context.h"
65 #include "BKE_main.h"
66
67 #include "BPY_extern.h"
68
69 #include "../generic/bpy_internal_import.h" // our own imports
70 /* external util modules */
71
72 #include "../generic/Mathutils.h"
73 #include "../generic/Geometry.h"
74 #include "../generic/BGL.h"
75 #include "../generic/IDProp.h"
76
77 /* for internal use, when starting and ending python scripts */
78
79 /* incase a python script triggers another python call, stop bpy_context_clear from invalidating */
80 static int py_call_level= 0;
81
82
83 // only for tests
84 #define TIME_PY_RUN
85
86 #ifdef TIME_PY_RUN
87 #include "PIL_time.h"
88 static int              bpy_timer_count = 0;
89 static double   bpy_timer; /* time since python starts */
90 static double   bpy_timer_run; /* time for each python script run */
91 static double   bpy_timer_run_tot; /* accumulate python runs */
92 #endif
93
94 void bpy_context_set(bContext *C, PyGILState_STATE *gilstate)
95 {
96         py_call_level++;
97
98         if(gilstate)
99                 *gilstate = PyGILState_Ensure();
100
101         if(py_call_level==1) {
102
103                 if(C) { // XXX - should always be true.
104                         BPy_SetContext(C);
105                         bpy_import_main_set(CTX_data_main(C));
106                 }
107                 else {
108                         fprintf(stderr, "ERROR: Python context called with a NULL Context. this should not happen!\n");
109                 }
110
111                 BPY_update_modules(); /* can give really bad results if this isnt here */
112
113 #ifdef TIME_PY_RUN
114                 if(bpy_timer_count==0) {
115                         /* record time from the beginning */
116                         bpy_timer= PIL_check_seconds_timer();
117                         bpy_timer_run = bpy_timer_run_tot = 0.0;
118                 }
119                 bpy_timer_run= PIL_check_seconds_timer();
120
121
122                 bpy_timer_count++;
123 #endif
124         }
125 }
126
127 void bpy_context_clear(bContext *C, PyGILState_STATE *gilstate)
128 {
129         py_call_level--;
130
131         if(gilstate)
132                 PyGILState_Release(*gilstate);
133
134         if(py_call_level < 0) {
135                 fprintf(stderr, "ERROR: Python context internal state bug. this should not happen!\n");
136         }
137         else if(py_call_level==0) {
138                 // XXX - Calling classes currently wont store the context :\, cant set NULL because of this. but this is very flakey still.
139                 //BPy_SetContext(NULL);
140                 //bpy_import_main_set(NULL);
141
142 #ifdef TIME_PY_RUN
143                 bpy_timer_run_tot += PIL_check_seconds_timer() - bpy_timer_run;
144                 bpy_timer_count++;
145 #endif
146
147         }
148 }
149
150 static void bpy_import_test(char *modname)
151 {
152         PyObject *mod= PyImport_ImportModuleLevel(modname, NULL, NULL, NULL, 0);
153         if(mod) {
154                 Py_DECREF(mod);
155         }
156         else {
157                 PyErr_Print();
158                 PyErr_Clear();
159         }       
160 }
161
162 void BPY_free_compiled_text( struct Text *text )
163 {
164         if( text->compiled ) {
165                 Py_DECREF( ( PyObject * ) text->compiled );
166                 text->compiled = NULL;
167         }
168 }
169
170 /*****************************************************************************
171 * Description: Creates the bpy module and adds it to sys.modules for importing
172 *****************************************************************************/
173 static BPy_StructRNA *bpy_context_module= NULL; /* for fast access */
174 static void bpy_init_modules( void )
175 {
176         PyObject *mod;
177
178         /* Needs to be first since this dir is needed for future modules */
179         char *modpath= BLI_gethome_folder("scripts/modules", BLI_GETHOME_ALL);
180         if(modpath) {
181                 PyObject *sys_path= PySys_GetObject("path"); /* borrow */
182                 PyObject *py_modpath= PyUnicode_FromString(modpath);
183                 PyList_Insert(sys_path, 0, py_modpath); /* add first */
184                 Py_DECREF(py_modpath);
185         }
186         
187         /* stand alone utility modules not related to blender directly */
188         Geometry_Init();
189         Mathutils_Init();
190         BGL_Init();
191         IDProp_Init_Types();
192
193
194         mod = PyModule_New("_bpy");
195
196         /* add the module so we can import it */
197         PyDict_SetItemString(PySys_GetObject("modules"), "_bpy", mod);
198         Py_DECREF(mod);
199
200         /* run first, initializes rna types */
201         BPY_rna_init();
202
203         PyModule_AddObject( mod, "types", BPY_rna_types() ); /* needs to be first so bpy_types can run */
204         bpy_import_test("bpy_types");
205         PyModule_AddObject( mod, "data", BPY_rna_module() ); /* imports bpy_types by running this */
206         bpy_import_test("bpy_types");
207         /* PyModule_AddObject( mod, "doc", BPY_rna_doc() ); */
208         PyModule_AddObject( mod, "props", BPY_rna_props() );
209         PyModule_AddObject( mod, "ops", BPY_operator_module() ); /* ops is now a python module that does the conversion from SOME_OT_foo -> some.foo */
210         PyModule_AddObject( mod, "app", BPY_app_struct() );
211
212         /* bpy context */
213         {
214                 bpy_context_module= ( BPy_StructRNA * ) PyObject_NEW( BPy_StructRNA, &pyrna_struct_Type );
215
216                 RNA_pointer_create(NULL, &RNA_Context, NULL, &bpy_context_module->ptr);
217                 bpy_context_module->freeptr= 0;
218
219                 PyModule_AddObject(mod, "context", (PyObject *)bpy_context_module);
220         }
221
222         /* add our own modules dir, this is a python package */
223         bpy_import_test("bpy");
224 }
225
226 void BPY_update_modules( void )
227 {
228 #if 0 // slow, this runs all the time poll, draw etc 100's of time a sec.
229         PyObject *mod= PyImport_ImportModuleLevel("bpy", NULL, NULL, NULL, 0);
230         PyModule_AddObject( mod, "data", BPY_rna_module() );
231         PyModule_AddObject( mod, "types", BPY_rna_types() ); // atm this does not need updating
232 #endif
233
234         /* refreshes the main struct */
235         BPY_update_rna_module();
236         bpy_context_module->ptr.data= (void *)BPy_GetContext();
237 }
238
239 /*****************************************************************************
240 * Description: This function creates a new Python dictionary object.
241 *****************************************************************************/
242 static PyObject *CreateGlobalDictionary( bContext *C, const char *filename )
243 {
244         PyObject *mod;
245         PyObject *item;
246         PyObject *dict = PyDict_New(  );
247         PyDict_SetItemString( dict, "__builtins__", PyEval_GetBuiltins(  ) );
248
249         item = PyUnicode_FromString( "__main__" );
250         PyDict_SetItemString( dict, "__name__", item );
251         Py_DECREF(item);
252         
253         /* __file__ only for nice UI'ness */
254         if(filename) {
255                 PyObject *item = PyUnicode_FromString( filename );
256                 PyDict_SetItemString( dict, "__file__", item );
257                 Py_DECREF(item);
258         }
259
260         /* add bpy to global namespace */
261         mod= PyImport_ImportModuleLevel("bpy", NULL, NULL, NULL, 0);
262         PyDict_SetItemString( dict, "bpy", mod );
263         Py_DECREF(mod);
264         
265         return dict;
266 }
267
268 /* must be called before Py_Initialize */
269 void BPY_start_python_path(void)
270 {
271         char *py_path_bundle= BLI_gethome_folder("python", BLI_GETHOME_ALL);
272
273         if(py_path_bundle==NULL)
274                 return;
275
276         /* set the environment path */
277         printf("found bundled python: %s\n", py_path_bundle);
278
279 #ifdef __APPLE__
280         /* OSX allow file/directory names to contain : character (represented as / in the Finder)
281          but current Python lib (release 3.1.1) doesn't handle these correctly */
282         if(strchr(py_path_bundle, ':'))
283                 printf("Warning : Blender application is located in a path containing : or / chars\
284                            \nThis may make python import function fail\n");
285 #endif
286         
287 #ifdef _WIN32
288         /* cmake/MSVC debug build crashes without this, why only
289            in this case is unknown.. */
290         {
291                 char *envpath = getenv("PYTHONPATH");
292
293                 if(envpath && envpath[0]) {
294                         char *newenvpath = BLI_sprintfN("%s;%s", py_path_bundle, envpath);
295                         BLI_setenv("PYTHONPATH", newenvpath);
296                         MEM_freeN(newenvpath);
297                 }
298                 else
299                         BLI_setenv("PYTHONPATH", py_path_bundle);       
300         }
301 #endif
302
303         {
304                 static wchar_t py_path_bundle_wchar[FILE_MAXDIR];
305
306                 mbstowcs(py_path_bundle_wchar, py_path_bundle, FILE_MAXDIR);
307                 Py_SetPythonHome(py_path_bundle_wchar);
308         }
309 }
310
311
312
313 void BPY_set_context(bContext *C)
314 {
315         BPy_SetContext(C);
316 }
317
318 /* call BPY_set_context first */
319 void BPY_start_python( int argc, char **argv )
320 {
321         PyThreadState *py_tstate = NULL;
322         
323         BPY_start_python_path(); /* allow to use our own included python */
324
325         Py_Initialize(  );
326         
327         // PySys_SetArgv( argc, argv); // broken in py3, not a huge deal
328         /* sigh, why do python guys not have a char** version anymore? :( */
329         {
330                 int i;
331 #if 0
332                 PyObject *py_argv= PyList_New(argc);
333                 for (i=0; i<argc; i++)
334                         PyList_SET_ITEM(py_argv, i, PyUnicode_FromString(argv[i]));
335
336 #else   // should fix bug #20021 - utf path name problems
337                 PyObject *py_argv= PyList_New(0);
338                 for (i=0; i<argc; i++) {
339                         PyObject *item= PyUnicode_Decode(argv[i], strlen(argv[i]), Py_FileSystemDefaultEncoding, NULL);
340                         if(item==NULL) { // should never happen
341                                 PyErr_Print();
342                                 PyErr_Clear();
343                         }
344                         else {
345                                 PyList_Append(py_argv, item);
346                                 Py_DECREF(item);
347                         }
348                 }
349 #endif
350                 PySys_SetObject("argv", py_argv);
351                 Py_DECREF(py_argv);
352         }
353         
354         /* Initialize thread support (also acquires lock) */
355         PyEval_InitThreads();
356         
357         
358         /* bpy.* and lets us import it */
359         bpy_init_modules(); 
360
361         { /* our own import and reload functions */
362                 PyObject *item;
363                 //PyObject *m = PyImport_AddModule("__builtin__");
364                 //PyObject *d = PyModule_GetDict(m);
365                 PyObject *d = PyEval_GetBuiltins(  );
366                 PyDict_SetItemString(d, "reload",               item=PyCFunction_New(bpy_reload_meth, NULL));   Py_DECREF(item);
367                 PyDict_SetItemString(d, "__import__",   item=PyCFunction_New(bpy_import_meth, NULL));   Py_DECREF(item);
368         }
369         
370         pyrna_alloc_types();
371
372         py_tstate = PyGILState_GetThisThreadState();
373         PyEval_ReleaseThread(py_tstate);
374 }
375
376 void BPY_end_python( void )
377 {
378         // fprintf(stderr, "Ending Python!\n");
379
380         PyGILState_Ensure(); /* finalizing, no need to grab the state */
381         
382         // free other python data.
383         pyrna_free_types();
384
385         /* clear all python data from structs */
386         
387         Py_Finalize(  );
388         
389 #ifdef TIME_PY_RUN
390         // measure time since py started
391         bpy_timer = PIL_check_seconds_timer() - bpy_timer;
392
393         printf("*bpy stats* - ");
394         printf("tot exec: %d,  ", bpy_timer_count);
395         printf("tot run: %.4fsec,  ", bpy_timer_run_tot);
396         if(bpy_timer_count>0)
397                 printf("average run: %.6fsec,  ", (bpy_timer_run_tot/bpy_timer_count));
398
399         if(bpy_timer>0.0)
400                 printf("tot usage %.4f%%", (bpy_timer_run_tot/bpy_timer)*100.0);
401
402         printf("\n");
403
404         // fprintf(stderr, "Ending Python Done!\n");
405
406 #endif
407
408 }
409
410 /* Can run a file or text block */
411 int BPY_run_python_script( bContext *C, const char *fn, struct Text *text, struct ReportList *reports)
412 {
413         PyObject *py_dict, *py_result= NULL;
414         PyGILState_STATE gilstate;
415         
416         if (fn==NULL && text==NULL) {
417                 return 0;
418         }
419         
420         bpy_context_set(C, &gilstate);
421         
422         py_dict = CreateGlobalDictionary(C, text?text->id.name+2:fn);
423
424         if (text) {
425                 
426                 if( !text->compiled ) { /* if it wasn't already compiled, do it now */
427                         char *buf = txt_to_buf( text );
428
429                         text->compiled =
430                                 Py_CompileString( buf, text->id.name+2, Py_file_input );
431
432                         MEM_freeN( buf );
433
434                         if( PyErr_Occurred(  ) ) {
435                                 BPY_free_compiled_text( text );
436                         }
437                 }
438                 if(text->compiled)
439                         py_result =  PyEval_EvalCode( text->compiled, py_dict, py_dict );
440                 
441         } else {
442                 FILE *fp= fopen(fn, "r");               
443                 if(fp) {
444 #ifdef _WIN32
445                         /* Previously we used PyRun_File to run directly the code on a FILE 
446                          * object, but as written in the Python/C API Ref Manual, chapter 2,
447                          * 'FILE structs for different C libraries can be different and 
448                          * incompatible'.
449                          * So now we load the script file data to a buffer */
450                         char *pystring;
451
452                         fclose(fp);
453
454                         pystring= malloc(strlen(fn) + 32);
455                         pystring[0]= '\0';
456                         sprintf(pystring, "exec(open(r'%s').read())", fn);
457                         py_result = PyRun_String( pystring, Py_file_input, py_dict, py_dict );
458                         free(pystring);
459 #else
460                         py_result = PyRun_File(fp, fn, Py_file_input, py_dict, py_dict);
461                         fclose(fp);
462 #endif
463                 }
464                 else {
465                         PyErr_Format(PyExc_SystemError, "Python file \"%s\" could not be opened: %s", fn, strerror(errno));
466                         py_result= NULL;
467                 }
468         }
469         
470         if (!py_result) {
471                 BPy_errors_to_report(reports);
472         } else {
473                 Py_DECREF( py_result );
474         }
475         
476         Py_DECREF(py_dict);
477         
478         bpy_context_clear(C, &gilstate);
479
480         return py_result ? 1:0;
481 }
482
483
484 /* TODO - move into bpy_space.c ? */
485 /* GUI interface routines */
486
487 /* Copied from Draw.c */
488 static void exit_pydraw( SpaceScript * sc, short err )
489 {
490         Script *script = NULL;
491
492         if( !sc || !sc->script )
493                 return;
494
495         script = sc->script;
496
497         if( err ) {
498                 BPy_errors_to_report(NULL); // TODO, reports
499                 script->flags = 0;      /* mark script struct for deletion */
500                 SCRIPT_SET_NULL(script);
501                 script->scriptname[0] = '\0';
502                 script->scriptarg[0] = '\0';
503 // XXX 2.5              error_pyscript();
504 // XXX 2.5              scrarea_queue_redraw( sc->area );
505         }
506
507 #if 0 // XXX 2.5
508         BPy_Set_DrawButtonsList(sc->but_refs);
509         BPy_Free_DrawButtonsList(); /*clear all temp button references*/
510 #endif
511
512         sc->but_refs = NULL;
513         
514         Py_XDECREF( ( PyObject * ) script->py_draw );
515         Py_XDECREF( ( PyObject * ) script->py_event );
516         Py_XDECREF( ( PyObject * ) script->py_button );
517
518         script->py_draw = script->py_event = script->py_button = NULL;
519 }
520
521 static int bpy_run_script_init(bContext *C, SpaceScript * sc)
522 {
523         if (sc->script==NULL) 
524                 return 0;
525         
526         if (sc->script->py_draw==NULL && sc->script->scriptname[0] != '\0')
527                 BPY_run_python_script(C, sc->script->scriptname, NULL, NULL);
528                 
529         if (sc->script->py_draw==NULL)
530                 return 0;
531         
532         return 1;
533 }
534
535 int BPY_run_script_space_draw(const struct bContext *C, SpaceScript * sc)
536 {
537         if (bpy_run_script_init( (bContext *)C, sc)) {
538                 PyGILState_STATE gilstate = PyGILState_Ensure();
539                 PyObject *result = PyObject_CallObject( sc->script->py_draw, NULL );
540                 
541                 if (result==NULL)
542                         exit_pydraw(sc, 1);
543                         
544                 PyGILState_Release(gilstate);
545         }
546         return 1;
547 }
548
549 // XXX - not used yet, listeners dont get a context
550 int BPY_run_script_space_listener(bContext *C, SpaceScript * sc)
551 {
552         if (bpy_run_script_init(C, sc)) {
553                 PyGILState_STATE gilstate = PyGILState_Ensure();
554                 
555                 PyObject *result = PyObject_CallObject( sc->script->py_draw, NULL );
556                 
557                 if (result==NULL)
558                         exit_pydraw(sc, 1);
559                         
560                 PyGILState_Release(gilstate);
561         }
562         return 1;
563 }
564
565 void BPY_DECREF(void *pyob_ptr)
566 {
567         PyGILState_STATE gilstate = PyGILState_Ensure();
568         Py_DECREF((PyObject *)pyob_ptr);
569         PyGILState_Release(gilstate);
570 }
571
572 #if 0
573 /* called from the the scripts window, assume context is ok */
574 int BPY_run_python_script_space(const char *modulename, const char *func)
575 {
576         PyObject *py_dict, *py_result= NULL;
577         char pystring[512];
578         PyGILState_STATE gilstate;
579         
580         /* for calling the module function */
581         PyObject *py_func, 
582         
583         gilstate = PyGILState_Ensure();
584         
585         py_dict = CreateGlobalDictionary(C);
586         
587         PyObject *module = PyImport_ImportModule(scpt->script.filename);
588         if (module==NULL) {
589                 PyErr_SetFormat(PyExc_SystemError, "could not import '%s'", scpt->script.filename);
590         }
591         else {
592                 py_func = PyObject_GetAttrString(modulename, func);
593                 if (py_func==NULL) {
594                         PyErr_SetFormat(PyExc_SystemError, "module has no function '%s.%s'\n", scpt->script.filename, func);
595                 }
596                 else {
597                         Py_DECREF(py_func);
598                         if (!PyCallable_Check(py_func)) {
599                                 PyErr_SetFormat(PyExc_SystemError, "module item is not callable '%s.%s'\n", scpt->script.filename, func);
600                         }
601                         else {
602                                 py_result= PyObject_CallObject(py_func, NULL); // XXX will need args eventually
603                         }
604                 }
605         }
606         
607         if (!py_result) {
608                 BPy_errors_to_report(NULL); // TODO - reports
609         } else
610                 Py_DECREF( py_result );
611         
612         Py_XDECREF(module);
613         
614         Py_DECREF(py_dict);
615         
616         PyGILState_Release(gilstate);
617         return 1;
618 }
619 #endif
620
621 // #define TIME_REGISTRATION
622
623 #ifdef TIME_REGISTRATION
624 #include "PIL_time.h"
625 #endif
626
627
628 int BPY_button_eval(bContext *C, char *expr, double *value)
629 {
630         PyGILState_STATE gilstate;
631         PyObject *dict, *mod, *retval;
632         int error_ret = 0;
633         
634         if (!value || !expr || expr[0]=='\0') return -1;
635         
636         bpy_context_set(C, &gilstate);
637         
638         dict= CreateGlobalDictionary(C, NULL);
639         
640         /* import some modules: builtins,math*/
641         PyDict_SetItemString(dict, "__builtins__", PyEval_GetBuiltins());
642
643         mod = PyImport_ImportModule("math");
644         if (mod) {
645                 PyDict_Merge(dict, PyModule_GetDict(mod), 0); /* 0 - dont overwrite existing values */
646                 
647                 /* Only keep for backwards compat! - just import all math into root, they are standard */
648                 PyDict_SetItemString(dict, "math", mod);
649                 PyDict_SetItemString(dict, "m", mod);
650                 Py_DECREF(mod);
651         } 
652         
653         retval = PyRun_String(expr, Py_eval_input, dict, dict);
654         
655         if (retval == NULL) {
656                 error_ret= -1;
657         }
658         else {
659                 double val;
660
661                 if(PyTuple_Check(retval)) {
662                         /* Users my have typed in 10km, 2m
663                          * add up all values */
664                         int i;
665                         val= 0.0;
666
667                         for(i=0; i<PyTuple_GET_SIZE(retval); i++) {
668                                 val+= PyFloat_AsDouble(PyTuple_GET_ITEM(retval, i));
669                         }
670                 }
671                 else {
672                         val = PyFloat_AsDouble(retval);
673                 }
674                 Py_DECREF(retval);
675                 
676                 if(val==-1 && PyErr_Occurred()) {
677                         error_ret= -1;
678                 }
679                 else {
680                         *value= val;
681                 }
682         }
683         
684         if(error_ret) {
685                 BPy_errors_to_report(CTX_wm_reports(C));
686         }
687         
688         Py_DECREF(dict);
689         bpy_context_clear(C, &gilstate);
690         
691         return error_ret;
692 }
693
694 void BPY_load_user_modules(bContext *C)
695 {
696         PyGILState_STATE gilstate;
697         Main *bmain= CTX_data_main(C);
698         Text *text;
699
700         /* can happen on file load */
701         if(bmain==NULL)
702                 return;
703
704         bpy_context_set(C, &gilstate);
705
706         for(text=CTX_data_main(C)->text.first; text; text= text->id.next) {
707                 if(text->flags & TXT_ISSCRIPT && BLI_testextensie(text->id.name+2, ".py")) {
708                         PyObject *module= bpy_text_import(text);
709
710                         if (module==NULL) {
711                                 PyErr_Print();
712                                 PyErr_Clear();
713                         }
714                         else {
715                                 Py_DECREF(module);
716                         }
717                 }
718         }
719         bpy_context_clear(C, &gilstate);
720 }
721
722 int BPY_context_get(bContext *C, const char *member, bContextDataResult *result)
723 {
724         PyObject *pyctx= (PyObject *)CTX_py_dict_get(C);
725         PyObject *item= PyDict_GetItemString(pyctx, member);
726         PointerRNA *ptr= NULL;
727         int done= 0;
728
729         if(item==NULL) {
730                 /* pass */
731         }
732         else if(item==Py_None) {
733                 /* pass */
734         }
735         else if(BPy_StructRNA_Check(item)) {
736                 ptr= &(((BPy_StructRNA *)item)->ptr);
737
738                 //result->ptr= ((BPy_StructRNA *)item)->ptr;
739                 CTX_data_pointer_set(result, ptr->id.data, ptr->type, ptr->data);
740                 done= 1;
741         }
742         else if (PySequence_Check(item)) {
743                 PyObject *seq_fast= PySequence_Fast(item, "bpy_context_get sequence conversion");
744                 if (seq_fast==NULL) {
745                         PyErr_Print();
746                         PyErr_Clear();
747                 }
748                 else {
749                         int len= PySequence_Fast_GET_SIZE(seq_fast);
750                         int i;
751                         for(i = 0; i < len; i++) {
752                                 PyObject *list_item= PySequence_Fast_GET_ITEM(seq_fast, i);
753
754                                 if(BPy_StructRNA_Check(list_item)) {
755                                         /*
756                                         CollectionPointerLink *link= MEM_callocN(sizeof(CollectionPointerLink), "bpy_context_get");
757                                         link->ptr= ((BPy_StructRNA *)item)->ptr;
758                                         BLI_addtail(&result->list, link);
759                                         */
760                                         ptr= &(((BPy_StructRNA *)list_item)->ptr);
761                                         CTX_data_list_add(result, ptr->id.data, ptr->type, ptr->data);
762                                 }
763                                 else {
764                                         printf("List item not a valid type\n");
765                                 }
766
767                         }
768                         Py_DECREF(seq_fast);
769
770                         done= 1;
771                 }
772         }
773
774         if(done==0) {
775                 if (item)       printf("Context '%s' not a valid type\n", member);
776                 else            printf("Context '%s' not found\n", member);
777         }
778         else {
779                 printf("Context '%s' found\n", member);
780         }
781
782         return done;
783 }
784