Fix reloading preferences ignoring 'script_directory'

Reloading preferences didn't update Python's `sys.path` to account
for the modified `script_directory`.

This meant the operator to load settings from a previous version
required a restart to initialize Python when this directory was set.
This commit is contained in:
Campbell Barton 2021-02-16 15:51:04 +11:00
parent f34d5d99dc
commit 7bb5e4a3c1
Notes: blender-bot 2023-02-13 19:36:30 +01:00
Referenced by issue #85589, No RMB selection from latest builds from master
2 changed files with 32 additions and 4 deletions

View File

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

View File

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