From 11fe932a37bffea6ad353ec26776620bc8c3cd35 Mon Sep 17 00:00:00 2001 From: manunicholasjacob Date: Fri, 31 Jul 2026 21:29:12 -0500 Subject: [PATCH] fix: restore unreachable no-default-class error in load_plugin load_plugin read generator_mod.DEFAULT_CLASS directly, so a module without that attribute raised AttributeError before the else branch could run. That made the 'no default class; pass module.ClassName to target_type' ValueError unreachable, and callers passing break_on_fail=False got an exception instead of False. Use a defaulted lookup so the intended error path is reachable. Signed-off-by: manunicholasjacob --- garak/_plugins.py | 5 +++-- tests/plugins/test_plugin_load.py | 9 +++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/garak/_plugins.py b/garak/_plugins.py index f2400ba1d..3e9cfd705 100644 --- a/garak/_plugins.py +++ b/garak/_plugins.py @@ -416,8 +416,9 @@ def load_plugin(path, break_on_fail=True, config_root=_config) -> object: raise ValueError( f"Unknown plugin module specification: {category}.{module_name}" ) from e - if generator_mod.DEFAULT_CLASS: - plugin_class_name = generator_mod.DEFAULT_CLASS + default_class = getattr(generator_mod, "DEFAULT_CLASS", None) + if default_class: + plugin_class_name = default_class else: raise ValueError( f"module {module_name} has no default class; pass module.ClassName to target_type" diff --git a/tests/plugins/test_plugin_load.py b/tests/plugins/test_plugin_load.py index b8b5529c4..5dce2e708 100644 --- a/tests/plugins/test_plugin_load.py +++ b/tests/plugins/test_plugin_load.py @@ -146,3 +146,12 @@ def test_instantiate_generators(plugin_configuration): pytest.skip("required deps not present") assert isinstance(g, garak.generators.base.Generator) ensure_pickle_support(g) + + +def test_load_plugin_module_without_default_class(): + assert _plugins.load_plugin("detectors.always", break_on_fail=False) is False + + with pytest.raises(ValueError) as exc_info: + _plugins.load_plugin("detectors.always") + + assert "no default class" in str(exc_info.value.__cause__)