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

  1. Copy the XYZ validation plugin from the examples directory into the Arelle/plugins/validate directory.

  2. Rename the plugin module from XYZ to the name of the taxonomy or jurisdiction you’re implementing validation rules for.

  3. Update the resources/config.xml disclosure system file with details for your plugin.

  4. Update DisclosureSystems.py with the names of your disclosure systems.

  5. Update the __init__.py module:

    1. 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.

    2. Update the __pluginInfo__ details with the name and description of your plugin.

    3. Update the DISCLOSURE_SYSTEM_VALIDATION_TYPE variable to match the validation type you used in resources/config.xml.

    4. Remove any of the plugin hooks you don’t need, including the functions defined in the ValidationPluginExtension class.

  6. Update the PluginValidationDataExtension dataclass with any fields you need. This is passed between rules and is how you should cache data. Note, you should’

  7. Implement the plugin specific validation rules in the rules directory using functions and the @validation decorator.

  8. 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,
        )