Merge branch 'blender-v4.3-release'
This commit is contained in:
@@ -45,7 +45,11 @@ def _initialize_once():
|
||||
_initialize_extensions_repos_once()
|
||||
|
||||
for addon in _preferences.addons:
|
||||
enable(addon.module)
|
||||
enable(
|
||||
addon.module,
|
||||
# Ensured by `_initialize_extensions_repos_once`.
|
||||
refresh_handled=True,
|
||||
)
|
||||
|
||||
_initialize_ensure_extensions_addon()
|
||||
|
||||
@@ -304,7 +308,7 @@ def _addon_remove(module_name):
|
||||
addons.remove(addon)
|
||||
|
||||
|
||||
def enable(module_name, *, default_set=False, persistent=False, handle_error=None):
|
||||
def enable(module_name, *, default_set=False, persistent=False, refresh_handled=False, handle_error=None):
|
||||
"""
|
||||
Enables an addon by name.
|
||||
|
||||
@@ -314,6 +318,10 @@ def enable(module_name, *, default_set=False, persistent=False, handle_error=Non
|
||||
:type default_set: bool
|
||||
:arg persistent: Ensure the addon is enabled for the entire session (after loading new files).
|
||||
:type persistent: bool
|
||||
:arg refresh_handled: When true, :func:`extensions_refresh` must have been called with ``module_name``
|
||||
included in ``addon_modules_pending``.
|
||||
This should be used to avoid many calls to refresh extensions when enabling multiple add-ons at once.
|
||||
:type refresh_handled: bool
|
||||
:arg handle_error: Called in the case of an error, taking an exception argument.
|
||||
:type handle_error: Callable[[Exception], None] | None
|
||||
:return: the loaded module or None on failure.
|
||||
@@ -338,6 +346,9 @@ def enable(module_name, *, default_set=False, persistent=False, handle_error=Non
|
||||
traceback.print_exc()
|
||||
|
||||
if (is_extension := module_name.startswith(_ext_base_pkg_idname_with_dot)):
|
||||
if not refresh_handled:
|
||||
extensions_refresh(addon_modules_pending=[module_name])
|
||||
|
||||
# Ensure the extensions are compatible.
|
||||
if _extensions_incompatible:
|
||||
if (error := _extensions_incompatible.get(
|
||||
@@ -347,8 +358,13 @@ def enable(module_name, *, default_set=False, persistent=False, handle_error=Non
|
||||
raise RuntimeError("Extension {:s} is incompatible ({:s})".format(module_name, error))
|
||||
except RuntimeError as ex:
|
||||
handle_error(ex)
|
||||
# No need to call `extensions_refresh` because incompatible extensions
|
||||
# will not have their wheels installed.
|
||||
return None
|
||||
|
||||
# NOTE: from now on, before returning None, `extensions_refresh()` must be called
|
||||
# to ensure wheels setup in anticipation for this extension being used are removed upon failure.
|
||||
|
||||
# reload if the mtime changes
|
||||
mod = sys.modules.get(module_name)
|
||||
# chances of the file _not_ existing are low, but it could be removed
|
||||
@@ -372,6 +388,8 @@ def enable(module_name, *, default_set=False, persistent=False, handle_error=Non
|
||||
except Exception as ex:
|
||||
print("Exception in module unregister():", (mod_file or module_name))
|
||||
handle_error(ex)
|
||||
if is_extension and not refresh_handled:
|
||||
extensions_refresh()
|
||||
return None
|
||||
|
||||
mod.__addon_enabled__ = False
|
||||
@@ -385,6 +403,9 @@ def enable(module_name, *, default_set=False, persistent=False, handle_error=Non
|
||||
except Exception as ex:
|
||||
handle_error(ex)
|
||||
del sys.modules[module_name]
|
||||
|
||||
if is_extension and not refresh_handled:
|
||||
extensions_refresh()
|
||||
return None
|
||||
mod.__addon_enabled__ = False
|
||||
|
||||
@@ -455,6 +476,8 @@ def enable(module_name, *, default_set=False, persistent=False, handle_error=Non
|
||||
|
||||
if default_set:
|
||||
_addon_remove(module_name)
|
||||
if is_extension and not refresh_handled:
|
||||
extensions_refresh()
|
||||
return None
|
||||
|
||||
if is_extension:
|
||||
@@ -492,6 +515,8 @@ def enable(module_name, *, default_set=False, persistent=False, handle_error=Non
|
||||
del sys.modules[module_name]
|
||||
if default_set:
|
||||
_addon_remove(module_name)
|
||||
if is_extension and not refresh_handled:
|
||||
extensions_refresh()
|
||||
return None
|
||||
finally:
|
||||
_bl_owner_id_set(owner_id_prev)
|
||||
@@ -506,7 +531,7 @@ def enable(module_name, *, default_set=False, persistent=False, handle_error=Non
|
||||
return mod
|
||||
|
||||
|
||||
def disable(module_name, *, default_set=False, handle_error=None):
|
||||
def disable(module_name, *, default_set=False, refresh_handled=False, handle_error=None):
|
||||
"""
|
||||
Disables an addon by name.
|
||||
|
||||
@@ -552,6 +577,9 @@ def disable(module_name, *, default_set=False, handle_error=None):
|
||||
if default_set:
|
||||
_addon_remove(module_name)
|
||||
|
||||
if not refresh_handled:
|
||||
extensions_refresh()
|
||||
|
||||
if _bpy.app.debug_python:
|
||||
print("\taddon_utils.disable", module_name)
|
||||
|
||||
@@ -568,12 +596,7 @@ def reset_all(*, reload_scripts=False):
|
||||
|
||||
# Update extensions compatibility (after reloading preferences).
|
||||
# Potentially refreshing wheels too.
|
||||
_initialize_extensions_compat_data(
|
||||
_bpy.utils.user_resource('EXTENSIONS'),
|
||||
ensure_wheels=True,
|
||||
addon_modules_pending=None,
|
||||
use_startup_fastpath=False,
|
||||
)
|
||||
extensions_refresh()
|
||||
|
||||
for path, pkg_id in _paths_with_extension_repos():
|
||||
if not pkg_id:
|
||||
@@ -592,7 +615,7 @@ def reset_all(*, reload_scripts=False):
|
||||
if is_enabled == is_loaded:
|
||||
pass
|
||||
elif is_enabled:
|
||||
enable(mod_name)
|
||||
enable(mod_name, refresh_handled=True)
|
||||
elif is_loaded:
|
||||
print("\taddon_utils.reset_all unloading", mod_name)
|
||||
disable(mod_name)
|
||||
@@ -623,7 +646,7 @@ def disable_all():
|
||||
# of one add-on disables others.
|
||||
for mod_name, mod in addon_modules:
|
||||
if getattr(mod, "__addon_enabled__", False):
|
||||
disable(mod_name)
|
||||
disable(mod_name, refresh_handled=True)
|
||||
|
||||
|
||||
def _blender_manual_url_prefix():
|
||||
@@ -1508,7 +1531,7 @@ def _initialize_extension_repos_post_addons_prepare(
|
||||
continue
|
||||
module_name_prev = "{:s}.{:s}.{:s}".format(_ext_base_pkg_idname, module_id_prev, submodule_id)
|
||||
module_name_next = "{:s}.{:s}.{:s}".format(_ext_base_pkg_idname, module_id_next, submodule_id)
|
||||
disable(module_name_prev, default_set=False)
|
||||
disable(module_name_prev, default_set=False, refresh_handled=True)
|
||||
addon = repo_userdef.get(submodule_id)
|
||||
default_set = addon is not None
|
||||
persistent = getattr(mod, "__addon_persistent__", False)
|
||||
@@ -1541,7 +1564,7 @@ def _initialize_extension_repos_post_addons_prepare(
|
||||
|
||||
for submodule_id, mod in repo_runtime.items():
|
||||
module_name_prev = "{:s}.{:s}.{:s}".format(_ext_base_pkg_idname, module_id, submodule_id)
|
||||
disable(module_name_prev, default_set=default_set)
|
||||
disable(module_name_prev, default_set=default_set, refresh_handled=True)
|
||||
del repo
|
||||
del repo_module_map
|
||||
|
||||
@@ -1550,7 +1573,7 @@ def _initialize_extension_repos_post_addons_prepare(
|
||||
repo_userdef = addon_userdef_info.get(module_id_prev, {})
|
||||
for submodule_id in repo_userdef.keys():
|
||||
module_name_prev = "{:s}.{:s}.{:s}".format(_ext_base_pkg_idname, module_id_prev, submodule_id)
|
||||
disable(module_name_prev, default_set=True)
|
||||
disable(module_name_prev, default_set=True, refresh_handled=True)
|
||||
|
||||
return addons_to_enable
|
||||
|
||||
|
||||
Reference in New Issue
Block a user