mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-05 23:41:44 +00:00
Bonsai: fail with an actionable error instead of a bare KeyError when addon preferences can't be found
get_addon_preferences() looked up bpy.context.preferences.addons using a package name Bonsai cached for itself once, at register() time. If that cached name stops matching a currently enabled Blender addon (#7288: the extension was moved to a different repository, e.g. bl_ext.user_default vs bl_ext.blender_org, without restarting Blender, leaving the install in an inconsistent state), the raw dict-style lookup raised an unhandled KeyError with an internal, non-actionable message. That propagated out of create_spatial_elements() during project load and aborted the entire load, so any IFC file failed the same way, well before any geometry was even read. Chose to fail loudly but clearly rather than silently guess a replacement addon entry: the maintainer's own diagnosis for #7288 was that this represents a genuinely broken/inconsistent install, and auto-resolving a different addon entry risks masking that instead of telling the user their install needs attention. get_addon_preferences() now raises a RuntimeError naming the exact mismatch and pointing at the fix (restart Blender, or reinstall from Preferences > Get Extensions), rather than a bare KeyError whose message is a raw bpy_prop_collection repr. Verified live in headless Blender against the actually-deployed Bonsai extension on this machine: reproduced the exact bare KeyError by staging a stale cached package name, confirmed the fix turns it into the new RuntimeError, and confirmed the healthy/correctly-registered case still returns a normal preferences object unchanged. No caller of get_addon_preferences() catches KeyError specifically, so widening the exception type is not a behavioural break for any of them. Fixes #7288 Generated with the assistance of an AI coding tool.
This commit is contained in:
@@ -1915,7 +1915,17 @@ class Blender(bonsai.core.tool.Blender):
|
||||
@classmethod
|
||||
def get_addon_preferences(cls) -> bonsai.bim.ui.BIM_ADDON_preferences:
|
||||
blender_package_name = cls.get_blender_addon_package_name()
|
||||
return bpy.context.preferences.addons[blender_package_name].preferences
|
||||
addon = bpy.context.preferences.addons.get(blender_package_name)
|
||||
if addon is None:
|
||||
raise RuntimeError(
|
||||
f"Bonsai's addon preferences could not be found: Bonsai registered itself as "
|
||||
f"'{blender_package_name}', but that is not a currently enabled Blender addon. "
|
||||
"This usually means the Bonsai install is broken or in an inconsistent state, for "
|
||||
"example if it was moved to a different extension repository without restarting "
|
||||
"Blender. Please restart Blender, or reinstall the Bonsai extension from "
|
||||
"Preferences > Get Extensions."
|
||||
)
|
||||
return addon.preferences
|
||||
|
||||
@classmethod
|
||||
def get_addon(cls, name: str) -> Union[types.ModuleType, None]:
|
||||
|
||||
@@ -237,3 +237,20 @@ class TestGetObjectFromGuidMissing(NewFile):
|
||||
bpy.ops.bim.create_project()
|
||||
assert tool.Ifc.get() is not None
|
||||
assert subject.get_object_from_guid("3iyt7r$Hf4_hQYNhBIDJI4") is None
|
||||
|
||||
|
||||
class TestGetAddonPreferences(NewFile):
|
||||
"""``get_addon_preferences`` looks up Bonsai's own cached registration name in
|
||||
``bpy.context.preferences.addons``. If Bonsai's install ends up in an
|
||||
inconsistent state (e.g. moved to a different extension repository without
|
||||
restarting Blender), that cached name stops matching any enabled addon. This
|
||||
must fail with an actionable ``RuntimeError``, not the bare ``KeyError`` a raw
|
||||
dict-style lookup would raise."""
|
||||
|
||||
def test_returns_preferences_for_the_currently_registered_addon(self):
|
||||
assert subject.get_addon_preferences() is not None
|
||||
|
||||
def test_raises_actionable_error_when_registered_name_is_stale(self, monkeypatch):
|
||||
monkeypatch.setattr(bonsai, "REGISTERED_BBIM_PACKAGE", "bl_ext.some_other_repo.bonsai")
|
||||
with pytest.raises(RuntimeError, match="bl_ext.some_other_repo.bonsai"):
|
||||
subject.get_addon_preferences()
|
||||
|
||||
Reference in New Issue
Block a user