Revision: 22301 http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=22301 Author: campbellbarton Date: 2009-08-07 18:20:19 +0200 (Fri, 07 Aug 2009)
Log Message: ----------- bpy_context_set and bpy_context_clear to replace a number of functions (some were not always called causing bugs). fix for a leak when trying to run a text with a syntax error too. Modified Paths: -------------- branches/blender2.5/blender/source/blender/python/intern/bpy_interface.c branches/blender2.5/blender/source/blender/python/intern/bpy_operator_wrap.c branches/blender2.5/blender/source/blender/python/intern/bpy_rna.c branches/blender2.5/blender/source/blender/python/intern/bpy_util.h Modified: branches/blender2.5/blender/source/blender/python/intern/bpy_interface.c =================================================================== --- branches/blender2.5/blender/source/blender/python/intern/bpy_interface.c 2009-08-07 15:57:02 UTC (rev 22300) +++ branches/blender2.5/blender/source/blender/python/intern/bpy_interface.c 2009-08-07 16:20:19 UTC (rev 22301) @@ -45,6 +45,50 @@ #include "../generic/BGL.h" +/* for internal use, when starting and ending python scripts */ + +/* incase a python script triggers another python call, stop bpy_context_clear from invalidating */ +static int py_call_level= 0; + +void bpy_context_set(bContext *C, PyGILState_STATE *gilstate) +{ + py_call_level++; + + if(gilstate) + *gilstate = PyGILState_Ensure(); + + if(py_call_level==1) { + + BPY_update_modules(); /* can give really bad results if this isnt here */ + + if(C) { // XXX - should always be true. + BPy_SetContext(C); + bpy_import_main_set(CTX_data_main(C)); + } + else { + fprintf(stderr, "ERROR: Python context called with a NULL Context. this should not happen!\n"); + } + } +} + +void bpy_context_clear(bContext *C, PyGILState_STATE *gilstate) +{ + py_call_level--; + + if(gilstate) + PyGILState_Release(*gilstate); + + if(py_call_level < 0) { + fprintf(stderr, "ERROR: Python context internal state bug. this should not happen!\n"); + } + else if(py_call_level==0) { + // XXX - Calling classes currently wont store the context :\, cant set NULL because of this. but this is very flakey still. + //BPy_SetContext(NULL); + //bpy_import_main_set(NULL); + } +} + + void BPY_free_compiled_text( struct Text *text ) { if( text->compiled ) { @@ -106,9 +150,6 @@ PyDict_SetItemString( dict, "__name__", item ); Py_DECREF(item); - // XXX - evil, need to access context - BPy_SetContext(C); - // XXX - put somewhere more logical { PyMethodDef *ml; @@ -224,20 +265,15 @@ /* Can run a file or text block */ int BPY_run_python_script( bContext *C, const char *fn, struct Text *text, struct ReportList *reports) { - PyObject *py_dict, *py_result; + PyObject *py_dict, *py_result= NULL; PyGILState_STATE gilstate; if (fn==NULL && text==NULL) { return 0; } - //BPY_start_python(); + bpy_context_set(C, &gilstate); - gilstate = PyGILState_Ensure(); - - BPY_update_modules(); /* can give really bad results if this isnt here */ - bpy_import_main_set(CTX_data_main(C)); - py_dict = CreateGlobalDictionary(C); if (text) { @@ -251,13 +287,11 @@ MEM_freeN( buf ); if( PyErr_Occurred( ) ) { - BPy_errors_to_report(reports); BPY_free_compiled_text( text ); - PyGILState_Release(gilstate); - return 0; } } - py_result = PyEval_EvalCode( text->compiled, py_dict, py_dict ); + if(text->compiled) + py_result = PyEval_EvalCode( text->compiled, py_dict, py_dict ); } else { #if 0 @@ -287,10 +321,9 @@ } Py_DECREF(py_dict); - PyGILState_Release(gilstate); - bpy_import_main_set(NULL); - //BPY_end_python(); + bpy_context_clear(C, &gilstate); + return py_result ? 1:0; } @@ -473,13 +506,8 @@ PyGILState_STATE gilstate; PyObject *sys_path; - gilstate = PyGILState_Ensure(); - - // XXX - evil, need to access context - BPy_SetContext(C); - bpy_import_main_set(CTX_data_main(C)); + bpy_context_set(C, &gilstate); - sys_path= PySys_GetObject("path"); /* borrow */ PyList_Insert(sys_path, 0, Py_None); /* place holder, resizes the list */ @@ -537,9 +565,8 @@ PyList_SetSlice(sys_path, 0, 1, NULL); /* remove the first item */ - bpy_import_main_set(NULL); + bpy_context_clear(C, &gilstate); - PyGILState_Release(gilstate); #ifdef TIME_REGISTRATION printf("script time %f\n", (PIL_check_seconds_timer()-time)); #endif Modified: branches/blender2.5/blender/source/blender/python/intern/bpy_operator_wrap.c =================================================================== --- branches/blender2.5/blender/source/blender/python/intern/bpy_operator_wrap.c 2009-08-07 15:57:02 UTC (rev 22300) +++ branches/blender2.5/blender/source/blender/python/intern/bpy_operator_wrap.c 2009-08-07 16:20:19 UTC (rev 22301) @@ -93,11 +93,9 @@ PointerRNA ptr_event; PyObject *py_operator; - PyGILState_STATE gilstate = PyGILState_Ensure(); + PyGILState_STATE gilstate; - bpy_import_main_set(CTX_data_main(C)); - - BPY_update_modules(); // XXX - the RNA pointers can change so update before running, would like a nicer solutuon for this. + bpy_context_set(C, &gilstate); args = PyTuple_New(1); PyTuple_SET_ITEM(args, 0, PyObject_GetAttrString(py_class, "__rna__")); // need to use an rna instance as the first arg @@ -221,8 +219,7 @@ } #endif - PyGILState_Release(gilstate); - bpy_import_main_set(NULL); + bpy_context_clear(C, &gilstate); return ret_flag; } Modified: branches/blender2.5/blender/source/blender/python/intern/bpy_rna.c =================================================================== --- branches/blender2.5/blender/source/blender/python/intern/bpy_rna.c 2009-08-07 15:57:02 UTC (rev 22300) +++ branches/blender2.5/blender/source/blender/python/intern/bpy_rna.c 2009-08-07 16:20:19 UTC (rev 22301) @@ -2918,9 +2918,10 @@ void *retdata= NULL; int err= 0, i, flag; - PyGILState_STATE gilstate = PyGILState_Ensure(); + PyGILState_STATE gilstate; - BPY_update_modules(); // XXX - the RNA pointers can change so update before running, would like a nicer solution for this. + bContext *C= BPy_GetContext(); // XXX - NEEDS FIXING, QUITE BAD. + bpy_context_set(C, &gilstate); py_class= RNA_struct_py_type_get(ptr->type); @@ -2996,7 +2997,7 @@ PyErr_Clear(); } - PyGILState_Release(gilstate); + bpy_context_clear(C, &gilstate); return err; } Modified: branches/blender2.5/blender/source/blender/python/intern/bpy_util.h =================================================================== --- branches/blender2.5/blender/source/blender/python/intern/bpy_util.h 2009-08-07 15:57:02 UTC (rev 22300) +++ branches/blender2.5/blender/source/blender/python/intern/bpy_util.h 2009-08-07 16:20:19 UTC (rev 22301) @@ -82,4 +82,8 @@ struct bContext *BPy_GetContext(void); void BPy_SetContext(struct bContext *C); +extern void bpy_context_set(struct bContext *C, PyGILState_STATE *gilstate); +extern void bpy_context_clear(struct bContext *C, PyGILState_STATE *gilstate); + + #endif _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org http://lists.blender.org/mailman/listinfo/bf-blender-cvs