From 6d156a1bab818a8b41dbabca9fb539bde97ad810 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 25 May 2009 13:48:44 +0000 Subject: [PATCH] Store the context for python in a static variable with assessor functions - BPy_GetContext/BPy_SetContext, Still not happy with this in the long term but its less problematic then storing the context in pythons namespace which couldn't be set before importing modules. This might fix a crash quite a few people have reported (but I cant reproduce). --- source/blender/python/intern/bpy_interface.c | 6 +++--- source/blender/python/intern/bpy_operator.c | 2 +- source/blender/python/intern/bpy_rna.c | 11 +++-------- source/blender/python/intern/bpy_ui.c | 18 +++++------------- source/blender/python/intern/bpy_util.c | 7 +++++++ source/blender/python/intern/bpy_util.h | 4 ++++ 6 files changed, 23 insertions(+), 25 deletions(-) diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index 140c7ef947d..999f6d8e9cb 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -90,9 +90,7 @@ static PyObject *CreateGlobalDictionary( bContext *C ) Py_DECREF(item); // XXX - evil, need to access context - item = PyCObject_FromVoidPtr( C, NULL ); - PyDict_SetItemString( dict, "__bpy_context__", item ); - Py_DECREF(item); + BPy_SetContext(C); // XXX - put somewhere more logical { @@ -386,6 +384,8 @@ void BPY_run_ui_scripts(bContext *C, int reload) PySys_SetObject("path", sys_path_new); Py_DECREF(sys_path_new); + // XXX - evil, need to access context + BPy_SetContext(C); while((de = readdir(dir)) != NULL) { /* We could stat the file but easier just to let python diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c index f8dcb1f43a1..b03540fb765 100644 --- a/source/blender/python/intern/bpy_operator.c +++ b/source/blender/python/intern/bpy_operator.c @@ -126,7 +126,7 @@ static PyObject *pyop_base_call( PyObject * self, PyObject * args, PyObject * k PointerRNA ptr; // XXX Todo, work out a better solution for passing on context, could make a tuple from self and pack the name and Context into it... - bContext *C = (bContext *)PyCObject_AsVoidPtr(PyDict_GetItemString(PyEval_GetGlobals(), "__bpy_context__")); + bContext *C = BPy_GetContext(); char *opname = _PyUnicode_AsString(self); diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index f1aa5e8fdfe..7b4d5a2d8ef 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -1968,10 +1968,7 @@ PyObject *pyrna_basetype_register(PyObject *self, PyObject *args) } /* get the context, so register callback can do necessary refreshes */ - item= PyDict_GetItemString(PyEval_GetGlobals(), "__bpy_context__"); /* borrow ref */ - - if(item) - C= (bContext*)PyCObject_AsVoidPtr(item); + C= BPy_GetContext(); /* call the register callback */ BKE_reports_init(&reports, RPT_PRINT); @@ -2031,10 +2028,8 @@ PyObject *pyrna_basetype_unregister(PyObject *self, PyObject *args) } /* get the context, so register callback can do necessary refreshes */ - item= PyDict_GetItemString(PyEval_GetGlobals(), "__bpy_context__"); /* borrow ref */ - - if(item) - C= (bContext*)PyCObject_AsVoidPtr(item); + C= BPy_GetContext(); + /* call unregister */ unreg(C, py_srna->ptr.data); diff --git a/source/blender/python/intern/bpy_ui.c b/source/blender/python/intern/bpy_ui.c index bdf656e5e57..1c15fc34547 100644 --- a/source/blender/python/intern/bpy_ui.c +++ b/source/blender/python/intern/bpy_ui.c @@ -303,17 +303,9 @@ static PyObject *Method_registerKey( PyObject * self, PyObject * args ) Py_RETURN_NONE; } -/* internal use only */ -static bContext *get_py_context__internal(void) -{ - PyObject *globals = PyEval_GetGlobals(); - PyObject *val= PyDict_GetItemString(globals, "__bpy_context__"); /* borrow ref */ - return PyCObject_AsVoidPtr(val); -} - static PyObject *Method_getRegonPtr( PyObject * self ) { - bContext *C= get_py_context__internal(); + bContext *C= BPy_GetContext(); ARegion *ar = CTX_wm_region(C); return PyCObject_FromVoidPtr(ar, NULL); @@ -321,7 +313,7 @@ static PyObject *Method_getRegonPtr( PyObject * self ) static PyObject *Method_getAreaPtr( PyObject * self ) { - bContext *C= get_py_context__internal(); + bContext *C= BPy_GetContext(); ScrArea *area = CTX_wm_area(C); return PyCObject_FromVoidPtr(area, NULL); @@ -329,7 +321,7 @@ static PyObject *Method_getAreaPtr( PyObject * self ) static PyObject *Method_getScreenPtr( PyObject * self ) { - bContext *C= get_py_context__internal(); + bContext *C= BPy_GetContext(); bScreen *screen= CTX_wm_screen(C); return PyCObject_FromVoidPtr(screen, NULL); @@ -337,7 +329,7 @@ static PyObject *Method_getScreenPtr( PyObject * self ) static PyObject *Method_getSpacePtr( PyObject * self ) { - bContext *C= get_py_context__internal(); + bContext *C= BPy_GetContext(); SpaceLink *sl= CTX_wm_space_data(C); return PyCObject_FromVoidPtr(sl, NULL); @@ -345,7 +337,7 @@ static PyObject *Method_getSpacePtr( PyObject * self ) static PyObject *Method_getWindowPtr( PyObject * self ) { - bContext *C= get_py_context__internal(); + bContext *C= BPy_GetContext(); wmWindow *window= CTX_wm_window(C); return PyCObject_FromVoidPtr(window, NULL); diff --git a/source/blender/python/intern/bpy_util.c b/source/blender/python/intern/bpy_util.c index 66cf244e3bd..8fcade0911d 100644 --- a/source/blender/python/intern/bpy_util.c +++ b/source/blender/python/intern/bpy_util.c @@ -29,6 +29,13 @@ #include "MEM_guardedalloc.h" #include "BKE_report.h" + +#include "BKE_context.h" +bContext* __py_context = NULL; +bContext* BPy_GetContext(void) { return __py_context; }; +void BPy_SetContext(bContext *C) { __py_context= C; }; + + PyObject *BPY_flag_to_list(struct BPY_flag_def *flagdef, int flag) { PyObject *list = PyList_New(0); diff --git a/source/blender/python/intern/bpy_util.h b/source/blender/python/intern/bpy_util.h index db31f403714..49f48802249 100644 --- a/source/blender/python/intern/bpy_util.h +++ b/source/blender/python/intern/bpy_util.h @@ -74,4 +74,8 @@ char *BPy_enum_as_string(struct EnumPropertyItem *item); /* error reporting */ int BPy_reports_to_error(struct ReportList *reports); +/* TODO - find a better solution! */ +struct bContext *BPy_GetContext(void); +void BPy_SetContext(struct bContext *C); + #endif