Source code for qudi.core.config.validator
# -*- coding: utf-8 -*-
"""
JSON (draft v7) validator for qudi YAML configurations that also fills in default values.
The corresponding JSON schema is defined in :file:`.__schema.py`.
.. Copyright (c) 2021, the qudi developers. See the AUTHORS.md file at the top-level directory of this
.. distribution and on <https://github.com/Ulm-IQO/qudi-core/>
..
.. This file is part of qudi.
..
.. Qudi is free software: you can redistribute it and/or modify it under the terms of
.. the GNU Lesser General Public License as published by the Free Software Foundation,
.. either version 3 of the License, or (at your option) any later version.
..
.. Qudi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
.. without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
.. See the GNU Lesser General Public License for more details.
..
.. You should have received a copy of the GNU Lesser General Public License along with qudi.
.. If not, see <https://www.gnu.org/licenses/>.
"""
__all__ = [
'ValidationError',
'validate_config',
'validate_local_module_config',
'validate_remote_module_config',
'validate_module_name',
]
import re
from typing import Mapping, Any
from jsonschema import ValidationError
from jsonschema import validators as __validators
from jsonschema import Draft7Validator as __BaseValidator
from .schema import (
config_schema,
remote_module_config_schema,
local_module_config_schema,
)
def __set_defaults(validator, properties, instance, schema):
# Only insert default values of current schema into instance if validation passses
try:
__BaseValidator(schema).validate(instance)
except ValidationError:
pass
else:
for property, subschema in properties.items():
if 'default' in subschema:
try:
instance.setdefault(property, subschema['default'])
except AttributeError:
pass
for error in __BaseValidator.VALIDATORS['properties'](
validator, properties, instance, schema
):
yield error
def __is_iterable(checker, instance):
return __BaseValidator.TYPE_CHECKER.is_type(instance, 'array') or isinstance(
instance, (set, frozenset, tuple)
)
# Add custom JSON schema (draft v7) validator that accepts all Python builtin sequences as "array"
# type
DefaultInsertionValidator = __validators.extend(
validator=__BaseValidator,
validators={'properties': __set_defaults},
type_checker=__BaseValidator.TYPE_CHECKER.redefine('array', __is_iterable),
)
[docs]
def validate_config(config: Mapping[str, Any]) -> None:
"""JSON schema (draft v7) validator for qudi configuration.
Raises jsonschema.ValidationError if invalid.
"""
DefaultInsertionValidator(config_schema()).validate(config)
[docs]
def validate_local_module_config(config: Mapping[str, Any]) -> None:
"""JSON schema (draft v7) validator for single qudi local module configuration.
Raises jsonschema.ValidationError if invalid.
"""
DefaultInsertionValidator(local_module_config_schema()).validate(config)
[docs]
def validate_remote_module_config(config: Mapping[str, Any]) -> None:
"""JSON schema (draft v7) validator for single qudi remote module configuration.
Raises jsonschema.ValidationError if invalid.
"""
DefaultInsertionValidator(remote_module_config_schema()).validate(config)
[docs]
def validate_module_name(name: str) -> None:
"""Regular expression validator for qudi module names.
Raises jsonschema.ValidationError if invalid.
WARNING: The jsonschema.ValidationError raised does not contain any JSON schema information.
"""
if re.match(r'^[a-zA-Z_]+[a-zA-Z0-9_]*$', name) is None:
raise ValidationError(
'Module names must only contain word characters [a-zA-Z0-9_] and not start on a number.'
)