Merge branch 'blender-v4.3-release'

This commit is contained in:
Campbell Barton 2024-11-09 11:46:44 +11:00
commit 9ee8e00fbc
4 changed files with 57 additions and 27 deletions

View File

@ -675,7 +675,12 @@ def _preferences_ensure_disabled(
if not hasattr(repo_module, pkg_id):
print("Repo module \"{:s}.{:s}\" not a sub-module!".format(".".join(module_base_elem), pkg_id))
addon_utils.disable(addon_module_name, default_set=default_set, handle_error=error_fn)
addon_utils.disable(
addon_module_name,
default_set=default_set,
refresh_handled=True,
handle_error=error_fn,
)
modules_clear.append(pkg_id)
@ -725,7 +730,12 @@ def _preferences_ensure_enabled(*, repo_item, pkg_id_sequence, result, handle_er
if not loaded_state:
continue
addon_utils.enable(addon_module_name, default_set=loaded_default, handle_error=handle_error)
addon_utils.enable(
addon_module_name,
default_set=loaded_default,
refresh_handled=True,
handle_error=handle_error,
)
def _preferences_ensure_enabled_all(*, addon_restore, handle_error):
@ -766,7 +776,13 @@ def _preferences_install_post_enable_on_install(
continue
addon_module_name = "{:s}.{:s}.{:s}".format(_ext_base_pkg_idname, repo_item.module, pkg_id)
addon_utils.enable(addon_module_name, default_set=True, handle_error=handle_error)
addon_utils.enable(
addon_module_name,
default_set=True,
# Handled by `_extensions_repo_sync_wheels`.
refresh_handled=True,
handle_error=handle_error,
)
elif item_local.type == "theme":
if has_theme:
continue

View File

@ -31,7 +31,7 @@ def set_from_cli(addons_as_string):
for m in addon_modules:
if check(m)[1] is False:
if enable(m, persistent=True) is None:
if enable(m, persistent=True, refresh_handled=True) is None:
if check_extension(m):
addon_modules_extensions_has_failure = True

View File

@ -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

View File

@ -484,9 +484,6 @@ class PREFERENCES_OT_addon_enable(Operator):
# Ensure any wheels are setup before enabling.
module_name = self.module
is_extension = addon_utils.check_extension(module_name)
if is_extension:
addon_utils.extensions_refresh(ensure_wheels=True, addon_modules_pending=[module_name])
mod = addon_utils.enable(module_name, default_set=True, handle_error=err_cb)
@ -511,10 +508,6 @@ class PREFERENCES_OT_addon_enable(Operator):
if err_str:
self.report({'ERROR'}, err_str)
if is_extension:
# Since the add-on didn't work, remove any wheels it may have installed.
addon_utils.extensions_refresh(ensure_wheels=True)
result = {'CANCELLED'}
if cursor_set:
@ -552,8 +545,6 @@ class PREFERENCES_OT_addon_disable(Operator):
module_name = self.module
is_extension = addon_utils.check_extension(module_name)
addon_utils.disable(module_name, default_set=True, handle_error=err_cb)
if is_extension:
addon_utils.extensions_refresh(ensure_wheels=True)
if err_str:
self.report({'ERROR'}, err_str)