[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [30938] trunk/blender/source/blender/ python/intern/bpy_interface.c: bugfix [#23129] alt-p in the texteditor doesn't work anymore

Campbell Barton ideasman42 at gmail.com
Sun Aug 1 15:57:04 CEST 2010


Revision: 30938
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=30938
Author:   campbellbarton
Date:     2010-08-01 15:57:04 +0200 (Sun, 01 Aug 2010)

Log Message:
-----------
bugfix [#23129] alt-p in the texteditor doesn't work anymore
recent commit cleared the __main__ namespace once a script finished which meant classes defined there would loose their namespace.
now inset a new __main__ module into sys.modules for every script that runs, any classes that are registered will hold a reference to that modules namespace.

Modified Paths:
--------------
    trunk/blender/source/blender/python/intern/bpy_interface.c

Modified: trunk/blender/source/blender/python/intern/bpy_interface.c
===================================================================
--- trunk/blender/source/blender/python/intern/bpy_interface.c	2010-08-01 12:57:01 UTC (rev 30937)
+++ trunk/blender/source/blender/python/intern/bpy_interface.c	2010-08-01 13:57:04 UTC (rev 30938)
@@ -148,51 +148,25 @@
 
 /*****************************************************************************
 * Description: This function creates a new Python dictionary object.
+* note: dict is owned by sys.modules["__main__"] module, reference is borrowed
+* note: important we use the dict from __main__, this is what python expects
+  for 'pickle' to work as well as strings like this...
+ >> foo = 10
+ >> print(__import__("__main__").foo)
 *****************************************************************************/
-static PyObject *CreateGlobalDictionary(bContext *C, const char *filename, PyObject *main_ns_orig)
+static PyObject *CreateGlobalDictionary(bContext *C, const char *filename)
 {
-	PyObject *item;
-	PyObject *dict;
+	PyInterpreterState *interp= PyThreadState_GET()->interp;
+	PyObject *mod_main= PyModule_New("__main__");	
+	PyDict_SetItemString(interp->modules, "__main__", mod_main);
 
+	PyModule_AddObject(mod_main, "__builtins__", interp->builtins);
+	PyModule_AddStringConstant(mod_main, "__name__", "__main__");
+	PyModule_AddStringConstant(mod_main, "__file__", filename); /* __file__ only for nice UI'ness */
 
-	/* important we use the dict from __main__, this is what python expects
-	 * for 'pickle' to work as well as strings like this... 
-
-	>> foo = 10
-	>> print(__import__("__main__").foo)
-	 */
-	dict= PyModule_GetDict(PyImport_AddModule("__main__"));
-	PyDict_Merge(main_ns_orig, dict, 1);
-	PyDict_Clear(dict);
-	Py_INCREF(dict);
-
-	/* using builtins rather then PyEval_GetBuiltins()
-	 * print's many less items when printing, the modules __dict__
-	 *  this is how python works so better follow. */
-	PyDict_SetItemString(dict, "__builtins__", PyImport_AddModule("builtins"));
-
-
-	item = PyUnicode_FromString( "__main__" );
-	PyDict_SetItemString( dict, "__name__", item );
-	Py_DECREF(item);
-	
-	/* __file__ only for nice UI'ness */
-	if(filename) {
-		PyObject *item = PyUnicode_FromString( filename );
-		PyDict_SetItemString( dict, "__file__", item );
-		Py_DECREF(item);
-	}
-
-	return dict;
+	return PyModule_GetDict(mod_main);
 }
 
-static void CreateGlobalDictionary_Restore(PyObject *main_ns_orig)
-{
-	PyObject *main_ns= PyModule_GetDict(PyImport_AddModule("__main__"));
-	PyDict_Clear(main_ns);
-	PyDict_Merge(main_ns, main_ns_orig, 1);
-}
-
 /* must be called before Py_Initialize */
 void BPY_start_python_path(void)
 {
@@ -346,7 +320,6 @@
 int BPY_run_python_script( bContext *C, const char *fn, struct Text *text, struct ReportList *reports)
 {
 	PyObject *py_dict, *py_result= NULL;
-	PyObject *main_ns_orig= PyDict_New();
 	PyGILState_STATE gilstate;
 	
 	if (fn==NULL && text==NULL) {
@@ -358,7 +331,7 @@
 	if (text) {
 		char fn_dummy[FILE_MAXDIR];
 		bpy_text_filename_get(fn_dummy, text);
-		py_dict = CreateGlobalDictionary(C, fn_dummy, main_ns_orig);
+		py_dict = CreateGlobalDictionary(C, fn_dummy);
 		
 		if( !text->compiled ) {	/* if it wasn't already compiled, do it now */
 			char *buf = txt_to_buf( text );
@@ -379,7 +352,7 @@
 	else {
 		FILE *fp= fopen(fn, "r");
 
-		py_dict = CreateGlobalDictionary(C, fn, main_ns_orig);
+		py_dict = CreateGlobalDictionary(C, fn);
 
 		if(fp) {
 #ifdef _WIN32
@@ -413,12 +386,9 @@
 	} else {
 		Py_DECREF( py_result );
 	}
-
-	CreateGlobalDictionary_Restore(main_ns_orig);
-	Py_DECREF(main_ns_orig);
-
-	Py_DECREF(py_dict);
 	
+	PyDict_SetItemString(PyThreadState_GET()->interp->modules, "__main__", Py_None);
+	
 	bpy_context_clear(C, &gilstate);
 
 	return py_result ? 1:0;
@@ -555,7 +525,7 @@
 	
 	Py_XDECREF(module);
 	
-	Py_DECREF(py_dict);
+	PyDict_SetItemString(PyThreadState_GET()->interp->modules, "__main__", Py_None);
 	
 	PyGILState_Release(gilstate);
 	return 1;
@@ -566,8 +536,7 @@
 int BPY_eval_button(bContext *C, const char *expr, double *value)
 {
 	PyGILState_STATE gilstate;
-	PyObject *dict, *mod, *retval;
-	PyObject *main_ns_orig= PyDict_New();
+	PyObject *py_dict, *mod, *retval;
 	int error_ret = 0;
 	
 	if (!value || !expr) return -1;
@@ -579,11 +548,11 @@
 
 	bpy_context_set(C, &gilstate);
 	
-	dict= CreateGlobalDictionary(C, NULL, main_ns_orig);
+	py_dict= CreateGlobalDictionary(C, "<blender button>");
 
 	mod = PyImport_ImportModule("math");
 	if (mod) {
-		PyDict_Merge(dict, PyModule_GetDict(mod), 0); /* 0 - dont overwrite existing values */
+		PyDict_Merge(py_dict, PyModule_GetDict(mod), 0); /* 0 - dont overwrite existing values */
 		Py_DECREF(mod);
 	}
 	else { /* highly unlikely but possibly */
@@ -591,7 +560,7 @@
 		PyErr_Clear();
 	}
 	
-	retval = PyRun_String(expr, Py_eval_input, dict, dict);
+	retval = PyRun_String(expr, Py_eval_input, py_dict, py_dict);
 	
 	if (retval == NULL) {
 		error_ret= -1;
@@ -628,11 +597,9 @@
 	if(error_ret) {
 		BPy_errors_to_report(CTX_wm_reports(C));
 	}
-	
-	CreateGlobalDictionary_Restore(main_ns_orig);
-	Py_DECREF(main_ns_orig);
 
-	Py_DECREF(dict);
+	PyDict_SetItemString(PyThreadState_GET()->interp->modules, "__main__", Py_None);
+	
 	bpy_context_clear(C, &gilstate);
 	
 	return error_ret;
@@ -641,8 +608,7 @@
 int BPY_eval_string(bContext *C, const char *expr)
 {
 	PyGILState_STATE gilstate;
-	PyObject *dict, *retval;
-	PyObject *main_ns_orig= PyDict_New();
+	PyObject *py_dict, *retval;
 	int error_ret = 0;
 
 	if (!expr) return -1;
@@ -653,9 +619,9 @@
 
 	bpy_context_set(C, &gilstate);
 
-	dict= CreateGlobalDictionary(C, NULL, main_ns_orig);
+	py_dict= CreateGlobalDictionary(C, "<blender string>");
 
-	retval = PyRun_String(expr, Py_eval_input, dict, dict);
+	retval = PyRun_String(expr, Py_eval_input, py_dict, py_dict);
 
 	if (retval == NULL) {
 		error_ret= -1;
@@ -666,12 +632,10 @@
 		Py_DECREF(retval);
 	}
 
-	CreateGlobalDictionary_Restore(main_ns_orig);
-	Py_DECREF(main_ns_orig);
+	PyDict_SetItemString(PyThreadState_GET()->interp->modules, "__main__", Py_None);
 	
-	Py_DECREF(dict);
 	bpy_context_clear(C, &gilstate);
-
+	
 	return error_ret;
 }
 





More information about the Bf-blender-cvs mailing list