diff options
-rw-r--r-- | release/scripts/modules/bpy/utils.py | 70 | ||||
-rw-r--r-- | release/scripts/modules/bpy_types.py | 11 | ||||
-rw-r--r-- | release/scripts/op/console_python.py | 4 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_interface.c | 5 |
4 files changed, 40 insertions, 50 deletions
diff --git a/release/scripts/modules/bpy/utils.py b/release/scripts/modules/bpy/utils.py index c138d575234..3f3eab2ac2a 100644 --- a/release/scripts/modules/bpy/utils.py +++ b/release/scripts/modules/bpy/utils.py @@ -29,8 +29,6 @@ import sys as _sys from _bpy import blend_paths from _bpy import script_paths as _bpy_script_paths -from _bpy import _load_module, _unload_module - def _test_import(module_name, loaded_modules): import traceback @@ -86,8 +84,8 @@ def modules_from_path(path, loaded_modules): return modules -_loaded = [] # store loaded modules for reloading. -_bpy_types = __import__("bpy_types") # keep for comparisons, never ever reload this. +_global_loaded_modules = [] # store loaded module names for reloading. +import bpy_types as _bpy_types # keep for comparisons, never ever reload this. def load_scripts(reload_scripts=False, refresh_scripts=False): @@ -111,16 +109,31 @@ def load_scripts(reload_scripts=False, refresh_scripts=False): if refresh_scripts: original_modules = _sys.modules.values() + + if reload_scripts: + _bpy_types.TypeMap.clear() + _bpy_types.PropertiesMap.clear() - def unload_module(mod): - _unload_module(mod.__name__) + def register_module_call(mod): + _bpy_types._register_module(mod.__name__) + register = getattr(mod, "register", None) + if register: + try: + register() + except: + traceback.print_exc() + else: + print("\nWarning! '%s' has no register function, this is now a requirement for registerable scripts." % mod.__file__) + + def unregister_module_call(mod): + _bpy_types._unregister_module(mod.__name__) unregister = getattr(mod, "unregister", None) if unregister: try: unregister() except: traceback.print_exc() - + def sys_path_ensure(path): if path not in _sys.path: # reloading would add twice _sys.path.insert(0, path) @@ -147,44 +160,23 @@ def load_scripts(reload_scripts=False, refresh_scripts=False): mod = test_reload(mod) if mod: - _load_module(mod.__name__, reload_scripts) - register = getattr(mod, "register", None) - if register: - try: - register() - except: - traceback.print_exc() - else: - print("\nWarning! '%s' has no register function, this is now a requirement for registerable scripts." % mod.__file__) - _loaded.append(mod) + register_module_call(mod) + _global_loaded_modules.append(mod.__name__) if reload_scripts: - # TODO, this is broken but should work, needs looking into - ''' - # reload modules that may not be directly included - for type_class_name in dir(_bpy.types): - type_class = getattr(_bpy.types, type_class_name) - module_name = getattr(type_class, "__module__", "") - - if module_name and module_name != "bpy.types": # hard coded for C types - loaded_modules.add(module_name) - - # sorting isnt needed but rather it be pradictable - for module_name in sorted(loaded_modules): - print("Reloading:", module_name) - test_reload(_sys.modules[module_name]) - ''' + # module names -> modules + _global_loaded_modules[:] = [_sys.modules[mod_name] for mod_name in _global_loaded_modules] # loop over and unload all scripts - _loaded.reverse() - for mod in _loaded: - unload_module(mod) + _global_loaded_modules.reverse() + for mod in _global_loaded_modules: + unregister_module_call(mod) - for mod in _loaded: - reload(mod) + for mod in _global_loaded_modules: + test_reload(mod) - _loaded[:] = [] + _global_loaded_modules[:] = [] user_path = user_script_path() @@ -206,7 +198,7 @@ def load_scripts(reload_scripts=False, refresh_scripts=False): # load addons used_ext = {ext.module for ext in _bpy.context.user_preferences.addons} - paths = script_paths("addons") + paths = script_paths("addons") + script_paths("addons_contrib") for path in paths: sys_path_ensure(path) diff --git a/release/scripts/modules/bpy_types.py b/release/scripts/modules/bpy_types.py index db89983744e..c5f7ee150c9 100644 --- a/release/scripts/modules/bpy_types.py +++ b/release/scripts/modules/bpy_types.py @@ -551,13 +551,13 @@ PropertiesMap = {} # registers moduals instantly. _register_immediate = True -def _unload_module(module, free=True): +def _unregister_module(module, free=True): for t in TypeMap.get(module, ()): try: bpy_types.unregister(t) except: import traceback - print("bpy.utils._unload_module(): Module '%s' failed to unregister class '%s.%s'" % (module, t.__module__, t.__name__)) + print("bpy.utils._unregister_module(): Module '%s' failed to unregister class '%s.%s'" % (module, t.__module__, t.__name__)) traceback.print_exc() if free == True and module in TypeMap: @@ -575,17 +575,16 @@ def _unload_module(module, free=True): if free == True and module in PropertiesMap: del PropertiesMap[module] -def _load_module(module, force=False): + +def _register_module(module): for t in TypeMap.get(module, ()): try: bpy_types.register(t) except: import traceback - print("bpy.utils._load_module(): Module '%s' failed to register class '%s.%s'" % (module, t.__module__, t.__name__)) + print("bpy.utils._register_module(): Module '%s' failed to register class '%s.%s'" % (module, t.__module__, t.__name__)) traceback.print_exc() -_bpy._load_module = _load_module -_bpy._unload_module = _unload_module class RNAMeta(type): @classmethod diff --git a/release/scripts/op/console_python.py b/release/scripts/op/console_python.py index 8c7f543db36..cc0f3673e5c 100644 --- a/release/scripts/op/console_python.py +++ b/release/scripts/op/console_python.py @@ -44,17 +44,17 @@ def get_console(console_id): from code import InteractiveConsole consoles = getattr(get_console, "consoles", None) + hash_next = hash(bpy.context.manager) if consoles is None: consoles = get_console.consoles = {} - get_console.consoles_namespace_hash = hash(bpy.context.manager) + get_console.consoles_namespace_hash = hash_next else: # check if clearning the namespace is needed to avoid a memory leak. # the window manager is normally loaded with new blend files # so this is a reasonable way to deal with namespace clearing. # bpy.data hashing is reset by undo so cant be used. hash_prev = getattr(get_console, "consoles_namespace_hash", 0) - hash_next = hash(bpy.context.manager) if hash_prev != hash_next: get_console.consoles_namespace_hash = hash_next diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index 375bf20797b..5fe755747d3 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -160,11 +160,10 @@ static PyObject *CreateGlobalDictionary(bContext *C, const char *filename) PyObject *mod_main= PyModule_New("__main__"); PyDict_SetItemString(interp->modules, "__main__", mod_main); Py_DECREF(mod_main); /* sys.modules owns now */ - - 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 */ - + PyModule_AddObject(mod_main, "__builtins__", interp->builtins); + Py_INCREF(interp->builtins); /* AddObject steals a reference */ return PyModule_GetDict(mod_main); } |