garak/configurable.py defines the Configurable base class, which all garak plugins (generators, probes, detectors, buffs, harnesses) inherit from to receive config loading, dependency management, and API key validation.[1]
Configurable._load_config() is idempotent: it sets _instance_configured = True on first run and returns immediately on subsequent calls, preventing re-application of config for subclasses.[1] Configurable._load_config() also supports a dot-namespaced key format (namespace.ClassName) in the plugins config dict, maintained for backward compatibility with CLI-style config keys.[1] Configurable._apply_config() will NOT override an attribute that was already set to a non-default value by the caller — constructor arguments take precedence over config file values.[1] For dict-valued config entries, Configurable._apply_config() merges the existing instance dict with the incoming config using the | operator (existing | incoming) rather than replacing it outright.[1] Configurable._apply_missing_instance_defaults() applies values from the class-level DEFAULT_PARAMS dict to the instance only for attributes not already set; for dict-valued defaults it merges as DEFAULT_PARAMS[k] | instance_value, giving default values lower precedence.[1]
Configurable._load_deps() imports modules listed in extra_dependency_names at runtime, converting . and - to _ for the attribute name, and raises ModuleNotFoundError (via _import_failed) if any are unavailable.[1]
Configurable.__getstate__() sets all _unsafe_attributes and dynamically loaded extra-dependency attributes to None before pickling, preventing serialization of unpicklable objects.[1] Configurable.__setstate__() calls _load_deps() and, if present, _load_unsafe() after unpickling, restoring runtime dependencies and unsafe attributes.[1] _unsafe_attributes is a class-level list on Configurable subclasses where plugin authors declare attribute names holding objects incapable of serialization, such as open file handles or live network connections.
Sources