WM: correct logic for resetting add-ons & caching meta-data

All add-ons were being scanned at startup, while this didn't cause
errors it was noticeable with extensions where any errors in the
manifest were being reported at startup, even when running with
factory-startup (including blender's own tests).

Address two issues:

- The logic to "reset" add-ons, so as to match the preferences when
  reverting or resetting preferences always ran on startup.
  This occurred because a check for Python being initialized was
  incorrectly used to detect that this wasn't the first time preferences
  were being loaded (regression in [0]).

- Resetting add-ons scanned all add-ons (including disabled add-ons) to
  ensure their module cache is up to date. Since this the cache is
  lazily initialized, it's simpler to set it as uninitialized as
  resetting the add-ons doesn't require the cached meta-data.

[0]: 497bc4d199
This commit is contained in:
Campbell Barton
2024-06-10 00:20:32 +10:00
parent b7e0d7d1c3
commit b4ea8583ed
5 changed files with 20 additions and 7 deletions

View File

@@ -536,8 +536,9 @@ def reset_all(*, reload_scripts=False):
"""
import sys
# initializes addons_fake_modules
modules_refresh()
# Ensures stale `addons_fake_modules` isn't used.
modules._is_first = True
addons_fake_modules.clear()
for path, pkg_id in _paths_with_extension_repos():
if not pkg_id:

View File

@@ -852,6 +852,8 @@ class PREFERENCES_OT_addon_expand(Operator):
addon_module_name = self.module
# Ensure `addons_fake_modules` is set.
_modules = addon_utils.modules(refresh=False)
mod = addon_utils.addons_fake_modules.get(addon_module_name)
if mod is not None:
bl_info = addon_utils.module_bl_info(mod)
@@ -876,6 +878,7 @@ class PREFERENCES_OT_addon_show(Operator):
addon_module_name = self.module
# Ensure `addons_fake_modules` is set.
_modules = addon_utils.modules(refresh=False)
mod = addon_utils.addons_fake_modules.get(addon_module_name)
if mod is not None:

View File

@@ -671,6 +671,7 @@ struct wmFileReadPost_Params {
/* Used by #wm_homefile_read_post. */
uint success : 1;
uint is_alloc : 1;
uint is_first_time : 1;
};
/**
@@ -701,11 +702,10 @@ static void wm_file_read_post(bContext *C,
#ifdef WITH_PYTHON
if (is_startup_file) {
/* On startup (by default), Python won't have been initialized.
*
* The following block handles data & preferences being reloaded
/* The following block handles data & preferences being reloaded
* which requires resetting some internal variables. */
if (CTX_py_init_get(C)) {
if (!params->is_first_time) {
BLI_assert(CTX_py_init_get(C));
bool reset_all = use_userdef;
if (use_userdef || reset_app_template) {
/* Only run when we have a template path found. */
@@ -1249,7 +1249,8 @@ void wm_homefile_read_ex(bContext *C,
if (use_userdef || reset_app_template) {
#ifdef WITH_PYTHON
/* This only runs once Blender has already started. */
if (CTX_py_init_get(C)) {
if (!params_homefile->is_first_time) {
BLI_assert(CTX_py_init_get(C));
/* This is restored by 'wm_file_read_post', disable before loading any preferences
* so an add-on can read their own preferences when un-registering,
* and use new preferences if/when re-registering, see #67577.
@@ -1502,6 +1503,8 @@ void wm_homefile_read_ex(bContext *C,
params_file_read_post.use_userdef = use_userdef;
params_file_read_post.is_startup_file = true;
params_file_read_post.is_factory_startup = is_factory_startup;
params_file_read_post.is_first_time = params_homefile->is_first_time;
params_file_read_post.reset_app_template = reset_app_template;
params_file_read_post.success = success;

View File

@@ -276,6 +276,7 @@ void WM_init(bContext *C, int argc, const char **argv)
read_homefile_params.use_empty_data = false;
read_homefile_params.filepath_startup_override = nullptr;
read_homefile_params.app_template_override = WM_init_state_app_template_get();
read_homefile_params.is_first_time = true;
wm_homefile_read_ex(C, &read_homefile_params, nullptr, &params_file_read_post);

View File

@@ -42,6 +42,11 @@ struct wmHomeFileRead_Params {
* Useful for automated content generation, so the file starts without data.
*/
unsigned int use_empty_data : 1;
/**
* When true, this is the first time the home file is read.
* In this case resetting the previous state can be skipped.
*/
unsigned int is_first_time : 1;
/**
* Optional path pointing to an alternative blend file (may be NULL).
*/