From 6d242010451c9dc8d16c7a3e05e7dd6431f784d1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 17 Oct 2024 12:44:38 +1100 Subject: [PATCH] Fix error on script reload if the modules aren't found in sys.modules While unlikely, account for modules loaded on startup not being in `sys.modules` when reloading scripts. --- scripts/modules/bpy/utils/__init__.py | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/scripts/modules/bpy/utils/__init__.py b/scripts/modules/bpy/utils/__init__.py index 323987e1700..2cd8b5ba815 100644 --- a/scripts/modules/bpy/utils/__init__.py +++ b/scripts/modules/bpy/utils/__init__.py @@ -282,20 +282,27 @@ def load_scripts(*, reload_scripts=False, refresh_scripts=False, extensions=True _global_loaded_modules.append(mod.__name__) if reload_scripts: + # Module names -> modules. + # + # Reverse the modules so they are unregistered in the reverse order they're registered. + # While this isn't essential for the most part, it ensures any inter-dependencies can be handled properly. + global_modules = [mod for mod in map(_sys.modules.get, reversed(_global_loaded_modules)) if mod is not None] - # module names -> modules - _global_loaded_modules[:] = [_sys.modules[mod_name] - for mod_name in _global_loaded_modules] + # This should never happen, only report this to notify developers that something unexpected happened. + if len(global_modules) != len(_global_loaded_modules): + print( + "Warning: globally loaded modules not found in sys.modules:", + [mod_name for mod_name in _global_loaded_modules if mod_name not in _sys.modules] + ) + _global_loaded_modules.clear() - # loop over and unload all scripts - _global_loaded_modules.reverse() - for mod in _global_loaded_modules: + # Loop over and unload all scripts. + for mod in global_modules: unregister_module_call(mod) - for mod in _global_loaded_modules: + for mod in global_modules: test_reload(mod) - - del _global_loaded_modules[:] + del global_modules # Update key-maps to account for operators no longer existing. # Typically unloading operators would refresh the event system (such as disabling an add-on)