Create a Validation Plugin¶
One of the more common reasons to build a plugin is to add support for taxonomy- or jurisdiction-specific validation rules. To accelerate the process of creating new validation plugins, there’s an example template validation plugin that can serve as a starting point.
The example plugin demonstrates how to use the ValidationPlugin class, the @validation decorator, and the PluginData to write validation rules.
The @validation decorator is used to register functions as validation rules and specify which disclosure systems they should run with.
The ValidationPlugin class is responsible for collecting and running the decorated validation rules.
The PluginData data class is used for caching plugin data that’s expensive to compute. It is passed between rule functions by the ValidationPlugin class. The default implementation only contains a name field. To include your own fields, you should extend the data class and define the fields you need. Also, extend the ValidationPlugin class and override the newPluginData method to return your data class.
Note
Validation rules for the same ValidationHook are not guaranteed to run in a specific order. If you
need a rule to run before another you can either implement them with different hooks, such as Validate.XBRL.Start
and
Validate.XBRL.Finally
or implement them within the same @validation decorated function.
Steps to Create a New Validation Plugin¶
Copy the XYZ validation plugin from the examples directory into the Arelle/plugins/validate directory.
Rename the plugin module from
XYZ
to the name of the taxonomy or jurisdiction you’re implementing validation rules for.Update the
resources/config.xml
disclosure system file with details for your plugin.Update
DisclosureSystems.py
with the names of your disclosure systems.Update the
__init__.py
module:If there’s a filer manual or other documentation for the rules you’re implementing available online, update the comment at the top of the
__init__.py
module with a link.Update the
__pluginInfo__
details with the name and description of your plugin.Update the
DISCLOSURE_SYSTEM_VALIDATION_TYPE
variable to match the validation type you used in resources/config.xml.Remove any of the plugin hooks you don’t need, including the functions defined in the
ValidationPluginExtension
class.
Update the
PluginValidationDataExtension
dataclass with any fields you need. This is passed between rules and is how you should cache data. Note, you should’Implement the plugin specific validation rules in the rules directory using functions and the @validation decorator.
Open a PR to have your plugin merged into Arelle.
Example of a validation rule¶
@validation(
hook=ValidationHook.XBRL_FINALLY,
disclosureSystems=DISCLOSURE_SYSTEM_2022,
)
def rule01_01_2022(
pluginData: PluginValidationDataExtension,
val: ValidateXbrl,
*args: Any,
**kwargs: Any,
) -> Iterable[Validation]:
if "Cash" not in val.modelXbrl.factsByLocalName:
yield Validation.error(
codes="XYZ.01.01",
msg=_("Cash must be reported."),
modelObject=val.modelXbrl,
)