Source code for pyhf.schema.validator

import numbers
from typing import Mapping, Union

import jsonschema

import pyhf.exceptions
from pyhf import tensor
from pyhf.schema import variables
from pyhf.schema.loader import load_schema


def _is_array_or_tensor(checker, instance):
    """
    A helper function for allowing the validation of tensors as list types in schema validation.

    .. warning:

        This will check for valid array types using any backends that have been loaded so far.
    """
    return isinstance(instance, (list, *tensor.array_types))


def _is_number_or_tensor_subtype(checker, instance):
    """
    A helper function for allowing the validation of tensor contents as number types in schema validation.

    .. warning:
        This will check for valid array subtypes using any backends that have been loaded so far.
    """
    is_number = jsonschema._types.is_number(checker, instance)
    if is_number:
        return True
    return isinstance(instance, (numbers.Number, *tensor.array_subtypes))


[docs]def validate( spec: Mapping, schema_name: str, *, version: Union[str, None] = None, allow_tensors: bool = True, ): """ Validate the provided instance, ``spec``, against the schema associated with ``schema_name``. Args: spec (:obj:`object`): An object instance to validate against a schema. schema_name (:obj:`string`): The name of a schema to validate against. See :func:`pyhf.schema.load_schema` for more details. version (:obj:`string`): The version of the schema to use. See :func:`pyhf.schema.load_schema` for more details. allow_tensors (:obj:`bool`): A flag to enable or disable tensors as part of schema validation. If enabled, tensors in the ``spec`` will be treated like python :obj:`list`. Default: ``True``. Raises: ~pyhf.exceptions.InvalidSpecification: if the provided instance does not validate against the schema. Returns: None: if there are no errors with the provided instance. Example: >>> import pyhf >>> model = pyhf.simplemodels.uncorrelated_background( ... signal=[12.0, 11.0], bkg=[50.0, 52.0], bkg_uncertainty=[3.0, 7.0] ... ) >>> pyhf.schema.validate(model.spec, "model.json") >>> """ version = version or variables.SCHEMA_VERSION schema = load_schema(f'{version}/{schema_name}') # note: trailing slash needed for RefResolver to resolve correctly resolver = jsonschema.RefResolver( base_uri=f"file://{variables.schemas}/{version}/", referrer=f"{schema_name}", store=variables.SCHEMA_CACHE, ) Validator = jsonschema.Draft6Validator if allow_tensors: type_checker = Validator.TYPE_CHECKER.redefine( "array", _is_array_or_tensor ).redefine("number", _is_number_or_tensor_subtype) Validator = jsonschema.validators.extend(Validator, type_checker=type_checker) validator = Validator(schema, resolver=resolver, format_checker=None) try: return validator.validate(spec) except jsonschema.ValidationError as err: raise pyhf.exceptions.InvalidSpecification(err, schema_name)