forked from bartvdbraak/blender
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.
This commit is contained in:
parent
ce273aee08
commit
70f011bbce
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user