Merge branch 'blender-v4.3-release'

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

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