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 @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 PluginValidationData 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.
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.Finally or implement them within the same @validation decorated function.
Steps to Create a New Validation Plugin#
Rename the plugin module from
XYZto the name of the taxonomy or jurisdiction you’re implementing validation rules for.
resources/config.xmldisclosure system file with details for your plugin.
DisclosureSystems.pywith the names of your disclosure systems.
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__.pymodule with a link.
__pluginInfo__details with the name and description of your plugin.
DISCLOSURE_SYSTEM_VALIDATION_TYPEvariable 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
PluginValidationDataExtensiondataclass 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] | None: if "Cash" not in val.modelXbrl.factsByLocalName: yield Validation.error( codes="XYZ.01.01", msg=_("Cash must be reported."), modelObject=val.modelXbrl, )