[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [22301] branches/blender2.5/blender/source /blender/python/intern: bpy_context_set and bpy_context_clear to replace a number of functions ( some were not always called causing bugs).

Campbell Barton ideasman42 at gmail.com
Fri Aug 7 18:20:19 CEST 2009


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





More information about the Bf-blender-cvs mailing list