diff options
author | Campbell Barton <ideasman42@gmail.com> | 2010-02-15 13:54:51 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2010-02-15 13:54:51 +0300 |
commit | 536e448e7a02053108556d7f529eca181246a82b (patch) | |
tree | cc5cdf887c3a883c47b854c5eb27acac309dbda0 /release | |
parent | 1d5fe11a62890ef7760c8d3db663bcde58be20bb (diff) |
[#21141] boring segfault on F8/"reload scripts", 26878, backtrace
reloading bpy_types was causing reload to fail. also unregister all modules in the reverse order that they were loaded, so when reloading removed files done hang around.
Diffstat (limited to 'release')
-rw-r--r-- | release/scripts/modules/bpy/utils.py | 40 | ||||
-rw-r--r-- | release/scripts/modules/bpy_types.py | 5 |
2 files changed, 34 insertions, 11 deletions
diff --git a/release/scripts/modules/bpy/utils.py b/release/scripts/modules/bpy/utils.py index cfe0207c7ca..c8288df2e5d 100644 --- a/release/scripts/modules/bpy/utils.py +++ b/release/scripts/modules/bpy/utils.py @@ -74,6 +74,9 @@ 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. + def load_scripts(reload_scripts=False, refresh_scripts=False): import traceback @@ -82,18 +85,31 @@ def load_scripts(reload_scripts=False, refresh_scripts=False): t_main = time.time() loaded_modules = set() + + if refresh_scripts: + original_modules = _sys.modules.values() def sys_path_ensure(path): if path not in _sys.path: # reloading would add twice _sys.path.insert(0, path) - def test_reload(module): + def test_reload(mod): + # reloading this causes internal errors + # because the classes from this module are stored internally + # possibly to refresh internal references too but for now, best not to. + if mod == _bpy_types: + return mod + try: - return reload(module) + return reload(mod) except: traceback.print_exc() def test_register(mod): + + if refresh_scripts and mod in original_modules: + return + if reload_scripts and mod: print("Reloading:", mod) mod = test_reload(mod) @@ -104,6 +120,7 @@ def load_scripts(reload_scripts=False, refresh_scripts=False): register() else: print("\nWarning! '%s' has no register function, this is now a requirement for registerable scripts." % mod.__file__) + _loaded.append(mod) if reload_scripts: # reload modules that may not be directly included @@ -117,23 +134,26 @@ def load_scripts(reload_scripts=False, refresh_scripts=False): for module_name in loaded_modules: print("Reloading:", module_name) test_reload(_sys.modules[module_name]) + + # loop over and unload all scripts + _loaded.reverse() + for mod in _loaded: + func = getattr(mod, "unregister", None) + if func: + func() + _loaded[:] = [] + for base_path in script_paths(): for path_subdir in ("", "ui", "op", "io", "cfg"): path = _os.path.join(base_path, path_subdir) if _os.path.isdir(path): - - # needed to load scripts after the users script path changes - # we should also support a full reload but since this is now unstable it can be postponed. - if refresh_scripts and path in _sys.path: - continue - sys_path_ensure(path) - + for mod in modules_from_path(path, loaded_modules): test_register(mod) - + # load extensions used_ext = {ext.module for ext in _bpy.context.user_preferences.extensions} paths = script_paths("extensions") diff --git a/release/scripts/modules/bpy_types.py b/release/scripts/modules/bpy_types.py index 9d2e157f843..060de711637 100644 --- a/release/scripts/modules/bpy_types.py +++ b/release/scripts/modules/bpy_types.py @@ -473,7 +473,10 @@ class _GenericUI: def remove(cls, draw_func): """Remove a draw function that has been added to this menu""" draw_funcs = cls._dyn_ui_initialize() - draw_funcs.remove(draw_func) + try: + draw_funcs.remove(draw_func) + except: + pass class Panel(StructRNA, _GenericUI): |