diff --git a/release/scripts/modules/bpy/utils/__init__.py b/release/scripts/modules/bpy/utils/__init__.py index 7f39cc5d422..d984a6f54a4 100644 --- a/release/scripts/modules/bpy/utils/__init__.py +++ b/release/scripts/modules/bpy/utils/__init__.py @@ -121,15 +121,25 @@ def _test_import(module_name, loaded_modules): return mod -# Reloading would add twice. +# Check before adding paths as reloading would add twice. + +# Storing and restoring the full `sys.path` is risky as this may be intentionally modified +# by technical users/developers. +# +# Instead, track which paths have been added, clearing them before refreshing. +# This supports the case of loading a new preferences file which may reset scripts path. +_sys_path_ensure_paths = set() + def _sys_path_ensure_prepend(path): if path not in _sys.path: _sys.path.insert(0, path) + _sys_path_ensure_paths.add(path) def _sys_path_ensure_append(path): if path not in _sys.path: _sys.path.append(path) + _sys_path_ensure_paths.add(path) def modules_from_path(path, loaded_modules): @@ -391,6 +401,13 @@ def refresh_script_paths(): Run this after creating new script paths to update sys.path """ + for path in _sys_path_ensure_paths: + try: + _sys.path.remove(path) + except ValueError: + pass + _sys_path_ensure_paths.clear() + for base_path in script_paths(): for path_subdir in _script_module_dirs: path = _os.path.join(base_path, path_subdir) diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 42d17387d77..090c28a81a6 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -580,7 +580,10 @@ static void wm_file_read_post(bContext *C, #ifdef WITH_PYTHON if (is_startup_file) { - /* possible python hasn't been initialized */ + /* On startup (by default), Python won't have been initialized. + * + * The following block handles data & preferences being reloaded + * which requires resetting some internal variables. */ if (CTX_py_init_get(C)) { bool reset_all = use_userdef; if (use_userdef || reset_app_template) { @@ -592,8 +595,16 @@ static void wm_file_read_post(bContext *C, } } if (reset_all) { - /* sync addons, these may have changed from the defaults */ - BPY_run_string_eval(C, (const char *[]){"addon_utils", NULL}, "addon_utils.reset_all()"); + BPY_run_string_exec( + C, + (const char *[]){"bpy", "addon_utils", NULL}, + /* Refresh scripts as the preferences may have changed the user-scripts path. + * + * This is needed when loading settings from the previous version, + * otherwise the script path stored in the preferences would be ignored. */ + "bpy.utils.refresh_script_paths()\n" + /* Sync add-ons, these may have changed from the defaults. */ + "addon_utils.reset_all()"); } if (use_data) { BPY_python_reset(C);