Source code for swh.model.fields.compound

# Copyright (C) 2015  The Software Heritage developers
# See the AUTHORS file at the top-level directory of this distribution
# License: GNU General Public License version 3, or any later version
# See top-level LICENSE file for more information

from collections import defaultdict
import itertools

from ..exceptions import NON_FIELD_ERRORS, ValidationError


[docs] def validate_against_schema(model, schema, value): """Validate a value for the given model against the given schema. Args: model: the name of the model schema: the schema to validate against value: the value to validate Returns: True if the value is correct against the schema Raises: ValidationError if the value does not validate against the schema """ if not isinstance(value, dict): raise ValidationError( "Unexpected type %(type)s for %(model)s, expected dict", params={ "model": model, "type": value.__class__.__name__, }, code="model-unexpected-type", ) errors = defaultdict(list) for key, (mandatory, validators) in itertools.chain( ((k, v) for k, v in schema.items() if k != NON_FIELD_ERRORS), [(NON_FIELD_ERRORS, (False, schema.get(NON_FIELD_ERRORS, [])))], ): if not validators: continue if not isinstance(validators, list): validators = [validators] validated_value = value if key != NON_FIELD_ERRORS: try: validated_value = value[key] except KeyError: if mandatory: errors[key].append( ValidationError( "Field %(field)s is mandatory", params={"field": key}, code="model-field-mandatory", ) ) continue else: if errors: # Don't validate the whole object if some fields are broken continue for validator in validators: try: valid = validator(validated_value) except ValidationError as e: errors[key].append(e) else: if not valid: errdata = { "validator": validator.__name__, } if key == NON_FIELD_ERRORS: errmsg = ( "Validation of model %(model)s failed in " "%(validator)s" ) errdata["model"] = model errcode = "model-validation-failed" else: errmsg = ( "Validation of field %(field)s failed in " "%(validator)s" ) errdata["field"] = key errcode = "field-validation-failed" errors[key].append( ValidationError(errmsg, params=errdata, code=errcode) ) if errors: raise ValidationError(dict(errors)) return True
[docs] def validate_all_keys(value, keys): """Validate that all the given keys are present in value""" missing_keys = set(keys) - set(value) if missing_keys: missing_fields = ", ".join(sorted(missing_keys)) raise ValidationError( "Missing mandatory fields %(missing_fields)s", params={"missing_fields": missing_fields}, code="missing-mandatory-field", ) return True
[docs] def validate_any_key(value, keys): """Validate that any of the given keys is present in value""" present_keys = set(keys) & set(value) if not present_keys: missing_fields = ", ".join(sorted(keys)) raise ValidationError( "Must contain one of the alternative fields %(missing_fields)s", params={"missing_fields": missing_fields}, code="missing-alternative-field", ) return True