Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2009-08-07 20:20:19 +0400
committerCampbell Barton <ideasman42@gmail.com>2009-08-07 20:20:19 +0400
commit70f011bbcea9aee222e43895fea503b26d3d566a (patch)
tree829ba8d75f662c5a49369e05aa0876adec3a9e9e
parentce273aee084fd367245d20a15b307d4ad99584d8 (diff)
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.
-rw-r--r--source/blender/python/intern/bpy_interface.c77
-rw-r--r--source/blender/python/intern/bpy_operator_wrap.c9
-rw-r--r--source/blender/python/intern/bpy_rna.c7
-rw-r--r--source/blender/python/intern/bpy_util.h4
4 files changed, 63 insertions, 34 deletions
diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c
index 707c5769357..ed9dbdf2868 100644
--- a/source/blender/python/intern/bpy_interface.c
+++ b/source/blender/python/intern/bpy_interface.c
@@ -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 @@ static PyObject *CreateGlobalDictionary( bContext *C )
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,19 +265,14 @@ void BPY_end_python( void )
/* 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();
-
- gilstate = PyGILState_Ensure();
-
- BPY_update_modules(); /* can give really bad results if this isnt here */
- bpy_import_main_set(CTX_data_main(C));
+ bpy_context_set(C, &gilstate);
py_dict = CreateGlobalDictionary(C);
@@ -251,13 +287,11 @@ int BPY_run_python_script( bContext *C, const char *fn, struct Text *text, struc
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 @@ int BPY_run_python_script( bContext *C, const char *fn, struct Text *text, struc
}
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,12 +506,7 @@ void BPY_run_ui_scripts(bContext *C, int reload)
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 @@ void BPY_run_ui_scripts(bContext *C, int reload)
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
diff --git a/source/blender/python/intern/bpy_operator_wrap.c b/source/blender/python/intern/bpy_operator_wrap.c
index 080d2e8ce6a..7a92c747bd3 100644
--- a/source/blender/python/intern/bpy_operator_wrap.c
+++ b/source/blender/python/intern/bpy_operator_wrap.c
@@ -93,11 +93,9 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve
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 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve
}
#endif
- PyGILState_Release(gilstate);
- bpy_import_main_set(NULL);
+ bpy_context_clear(C, &gilstate);
return ret_flag;
}
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index 27bfb89b963..20164edc95a 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -2918,9 +2918,10 @@ static int bpy_class_call(PointerRNA *ptr, FunctionRNA *func, ParameterList *par
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 @@ static int bpy_class_call(PointerRNA *ptr, FunctionRNA *func, ParameterList *par
PyErr_Clear();
}
- PyGILState_Release(gilstate);
+ bpy_context_clear(C, &gilstate);
return err;
}
diff --git a/source/blender/python/intern/bpy_util.h b/source/blender/python/intern/bpy_util.h
index 470dd4c2a45..df204b7b90d 100644
--- a/source/blender/python/intern/bpy_util.h
+++ b/source/blender/python/intern/bpy_util.h
@@ -82,4 +82,8 @@ int BPy_errors_to_report(struct ReportList *reports);
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