Fall back from invalid settings stores (#1416)
This commit is contained in:
@@ -184,8 +184,10 @@ def load_settings() -> dict:
|
|||||||
try:
|
try:
|
||||||
with open(SETTINGS_FILE, "r", encoding="utf-8") as f:
|
with open(SETTINGS_FILE, "r", encoding="utf-8") as f:
|
||||||
saved = json.load(f)
|
saved = json.load(f)
|
||||||
|
if not isinstance(saved, dict):
|
||||||
|
raise ValueError("settings must be an object")
|
||||||
merged = {**DEFAULT_SETTINGS, **saved}
|
merged = {**DEFAULT_SETTINGS, **saved}
|
||||||
except (FileNotFoundError, json.JSONDecodeError):
|
except (FileNotFoundError, json.JSONDecodeError, ValueError):
|
||||||
merged = dict(DEFAULT_SETTINGS)
|
merged = dict(DEFAULT_SETTINGS)
|
||||||
_settings_cache = (now, merged)
|
_settings_cache = (now, merged)
|
||||||
return merged
|
return merged
|
||||||
@@ -213,7 +215,8 @@ def is_setting_overridden(key: str) -> bool:
|
|||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
with open(SETTINGS_FILE, "r", encoding="utf-8") as f:
|
with open(SETTINGS_FILE, "r", encoding="utf-8") as f:
|
||||||
return key in json.load(f)
|
saved = json.load(f)
|
||||||
|
return isinstance(saved, dict) and key in saved
|
||||||
except (FileNotFoundError, json.JSONDecodeError):
|
except (FileNotFoundError, json.JSONDecodeError):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@@ -264,8 +267,10 @@ def load_features() -> dict:
|
|||||||
try:
|
try:
|
||||||
with open(FEATURES_FILE, "r", encoding="utf-8") as f:
|
with open(FEATURES_FILE, "r", encoding="utf-8") as f:
|
||||||
saved = json.load(f)
|
saved = json.load(f)
|
||||||
|
if not isinstance(saved, dict):
|
||||||
|
raise ValueError("features must be an object")
|
||||||
merged = {**DEFAULT_FEATURES, **saved}
|
merged = {**DEFAULT_FEATURES, **saved}
|
||||||
except (FileNotFoundError, json.JSONDecodeError):
|
except (FileNotFoundError, json.JSONDecodeError, ValueError):
|
||||||
merged = dict(DEFAULT_FEATURES)
|
merged = dict(DEFAULT_FEATURES)
|
||||||
_features_cache = (now, merged)
|
_features_cache = (now, merged)
|
||||||
return merged
|
return merged
|
||||||
|
|||||||
20
tests/test_settings_store_shape.py
Normal file
20
tests/test_settings_store_shape.py
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
from src import settings
|
||||||
|
|
||||||
|
|
||||||
|
def test_load_settings_falls_back_for_non_object_json(tmp_path, monkeypatch):
|
||||||
|
settings_file = tmp_path / "settings.json"
|
||||||
|
settings_file.write_text("[]", encoding="utf-8")
|
||||||
|
monkeypatch.setattr(settings, "SETTINGS_FILE", str(settings_file))
|
||||||
|
settings._invalidate_caches()
|
||||||
|
|
||||||
|
assert settings.load_settings() == settings.DEFAULT_SETTINGS
|
||||||
|
assert settings.is_setting_overridden("default_model") is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_load_features_falls_back_for_non_object_json(tmp_path, monkeypatch):
|
||||||
|
features_file = tmp_path / "features.json"
|
||||||
|
features_file.write_text("[]", encoding="utf-8")
|
||||||
|
monkeypatch.setattr(settings, "FEATURES_FILE", str(features_file))
|
||||||
|
settings._invalidate_caches()
|
||||||
|
|
||||||
|
assert settings.load_features() == settings.DEFAULT_FEATURES
|
||||||
Reference in New Issue
Block a user