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:
-rw-r--r--source/blender/python/api2_2x/bpy_internal_import.c62
-rw-r--r--source/blender/python/api2_2x/bpy_internal_import.h1
-rw-r--r--source/gameengine/Ketsji/KX_PythonInit.cpp9
3 files changed, 71 insertions, 1 deletions
diff --git a/source/blender/python/api2_2x/bpy_internal_import.c b/source/blender/python/api2_2x/bpy_internal_import.c
index d944c24d928..a62ae689f59 100644
--- a/source/blender/python/api2_2x/bpy_internal_import.c
+++ b/source/blender/python/api2_2x/bpy_internal_import.c
@@ -265,3 +265,65 @@ static PyObject *blender_reload( PyObject * self, PyObject * args )
PyMethodDef bpy_import[] = { {"bpy_import", blender_import, METH_KEYWORDS, "blenders import"} };
PyMethodDef bpy_reload[] = { {"bpy_reload", blender_reload, METH_VARARGS, "blenders reload"} };
+
+/* Clear user modules.
+ * This is to clear any modules that could be defined from running scripts in blender.
+ *
+ * Its also needed for the BGE Python api so imported scripts are not used between levels
+ *
+ * This clears every modules that has a __file__ attribute (is not a builtin)
+ * and is a filename only (no path). since pythons bultins include a full path even for win32.
+ * even if we remove a python module a reimport will bring it back again.
+ */
+
+
+#if defined(WIN32) || defined(WIN64)
+#define SEPSTR "\\"
+#else
+#define SEPSTR "/"
+#endif
+
+
+void importClearUserModules(void)
+{
+ PyObject *modules= PySys_GetObject("modules");
+
+ char *fname;
+ char *file_extension;
+
+ /* looping over the dict */
+ PyObject *key, *value;
+ Py_ssize_t pos = 0;
+
+ /* new list */
+ PyObject *list= PyList_New(0);
+
+ /* go over sys.modules and remove anything with a
+ * sys.modukes[x].__file__ thats ends with a .py and has no path
+ */
+ while (PyDict_Next(modules, &pos, &key, &value)) {
+ fname= PyModule_GetFilename(value);
+ if(fname) {
+ if ((strstr(fname, SEPSTR))==0) { /* no path ? */
+ file_extension = strstr(fname, ".py");
+ if(file_extension && *(file_extension + 3) == '\0') { /* .py extension ? */
+ /* now we can be fairly sure its a python import from the blendfile */
+ PyList_Append(list, key); /* free'd with the list */
+ }
+ }
+ }
+ else {
+ PyErr_Clear();
+ }
+ }
+
+ /* remove all our modules */
+ for(pos=0; pos < PyList_Size(list); pos++) {
+ /* PyObject_Print(key, stderr, 0); */
+ key= PyList_GET_ITEM(list, pos);
+ PyDict_DelItem(modules, key);
+ }
+
+ Py_DECREF(list); /* removes all references from append */
+}
+
diff --git a/source/blender/python/api2_2x/bpy_internal_import.h b/source/blender/python/api2_2x/bpy_internal_import.h
index 7fe412019ab..9d440406636 100644
--- a/source/blender/python/api2_2x/bpy_internal_import.h
+++ b/source/blender/python/api2_2x/bpy_internal_import.h
@@ -37,6 +37,7 @@
PyObject *importText( char *name, int *found );
PyObject *reimportText( PyObject *module, int *found );
+void importClearUserModules( void ); /* Clear user modules */
extern PyMethodDef bpy_import[];
extern PyMethodDef bpy_reload[];
diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp
index 924c5451608..eafb7fc0cb8 100644
--- a/source/gameengine/Ketsji/KX_PythonInit.cpp
+++ b/source/gameengine/Ketsji/KX_PythonInit.cpp
@@ -102,7 +102,7 @@ extern "C" {
#include "GPU_material.h"
static void setSandbox(TPythonSecurityLevel level);
-
+static void clearGameModules();
// 'local' copy of canvas ptr, for window height/width python scripts
static RAS_ICanvas* gp_Canvas = NULL;
@@ -1402,6 +1402,10 @@ PyObject* initGamePythonScripting(const STR_String& progname, TPythonSecurityLev
initPyTypes();
bpy_import_main_set(maggie);
+
+ /* run this to clear game modules and user modules which
+ * may contain references to in game data */
+ clearGameModules();
PyObject* moduleobj = PyImport_AddModule("__main__");
return PyModule_GetDict(moduleobj);
@@ -1434,6 +1438,9 @@ static void clearGameModules()
clearModule(modules, "Mathutils");
clearModule(modules, "BGL");
PyErr_Clear(); // incase some of these were alredy removed.
+
+ /* clear user defined modules */
+ importClearUserModules();
}
void exitGamePythonScripting()