def reset_all(*, reload_scripts=False): """ Sets the addon state based on the user preferences. """ import sys # initializes addons_fake_modules modules_refresh() # RELEASE SCRIPTS: official scripts distributed in Blender releases paths_list = paths() for path in paths_list: _bpy.utils._sys_path_ensure(path) for mod_name, mod_path in _bpy.path.module_names(path): is_enabled, is_loaded = check(mod_name) # first check if reload is needed before changing state. if reload_scripts: import importlib mod = sys.modules.get(mod_name) if mod: importlib.reload(mod) AddonRegisterInfo.wrap_module(mod) if is_enabled == is_loaded: pass elif is_enabled: enable(mod_name) elif is_loaded: print("\taddon_utils.reset_all unloading", mod_name) disable(mod_name)
def enable(module_name, *, default_set=False, persistent=False, handle_error=None): """ Enables an addon by name. :arg module_name: the name of the addon and module. :type module_name: string :arg default_set: Set the user-preference. :type default_set: bool :arg persistent: Ensure the addon is enabled for the entire session (after loading new files). :type persistent: bool :arg handle_error: Called in the case of an error, taking an exception argument. :type handle_error: function :return: the loaded module or None on failure. :rtype: module """ import os import sys from bpy_restrict_state import RestrictBlend if handle_error is None: def handle_error(ex): import traceback traceback.print_exc() # reload if the mtime changes mod = sys.modules.get(module_name) # chances of the file _not_ existing are low, but it could be removed if mod and os.path.exists(mod.__file__): if getattr(mod, "__addon_enabled__", False): # This is an unlikely situation, # re-register if the module is enabled. # Note: the UI doesn't allow this to happen, # in most cases the caller should 'check()' first. try: mod.unregister() except Exception as ex: print("Exception in module unregister(): %r" % getattr(mod, "__file__", module_name)) handle_error(ex) return None mod.__addon_enabled__ = False mtime_orig = getattr(mod, "__time__", 0) mtime_new = os.path.getmtime(mod.__file__) if mtime_orig != mtime_new: import importlib print("module changed on disk:", mod.__file__, "reloading...") try: importlib.reload(mod) except Exception as ex: handle_error(ex) del sys.modules[module_name] return None mod.__addon_enabled__ = False # add the addon first it may want to initialize its own preferences. # must remove on fail through. if default_set: _addon_ensure(module_name) # Split registering up into 3 steps so we can undo # if it fails par way through. # disable the context, using the context at all is # really bad while loading an addon, don't do it! with RestrictBlend(): # 1) try import try: mod = __import__(module_name) mod.__time__ = os.path.getmtime(mod.__file__) mod.__addon_enabled__ = False except Exception as ex: # if the addon doesn't exist, dont print full traceback if type(ex) is ImportError and ex.name == module_name: print("addon not found: %r" % module_name) else: handle_error(ex) if default_set: _addon_remove(module_name) return None # 2) try register collected modules # removed, addons need to handle own registration now. # 3) try run the modules register function try: AddonRegisterInfo.wrap_module(mod) mod.register() except Exception as ex: print("Exception in module register(): %r" % getattr(mod, "__file__", module_name)) handle_error(ex) del sys.modules[module_name] if default_set: _addon_remove(module_name) return None # * OK loaded successfully! * mod.__addon_enabled__ = True mod.__addon_persistent__ = persistent if _bpy.app.debug_python: print("\taddon_utils.enable", mod.__name__) return mod