import re from jsonschema import _utils from jsonschema.exceptions import FormatError, ValidationError from jsonschema.compat import iteritems def patternProperties(validator, patternProperties, instance, schema): if not validator.is_type(instance, "object"): return for pattern, subschema in iteritems(patternProperties): for k, v in iteritems(instance): if re.search(pattern, k): for error in validator.descend( v, subschema, path=k, schema_path=pattern, ): yield error def additionalProperties(validator, aP, instance, schema): if not validator.is_type(instance, "object"): return extras = set(_utils.find_additional_properties(instance, schema)) if validator.is_type(aP, "object"): for extra in extras: for error in validator.descend(instance[extra], aP, path=extra): yield error elif not aP and extras: error = "Additional properties are not allowed (%s %s unexpected)" yield ValidationError(error % _utils.extras_msg(extras)) def items(validator, items, instance, schema): if not validator.is_type(instance, "array"): return if validator.is_type(items, "object"): for index, item in enumerate(instance): for error in validator.descend(item, items, path=index): yield error else: for (index, item), subschema in zip(enumerate(instance), items): for error in validator.descend( item, subschema, path=index, schema_path=index, ): yield error def additionalItems(validator, aI, instance, schema): if ( not validator.is_type(instance, "array") or validator.is_type(schema.get("items", {}), "object") ): return len_items = len(schema.get("items", [])) if validator.is_type(aI, "object"): for index, item in enumerate(instance[len_items:], start=len_items): for error in validator.descend(item, aI, path=index): yield error elif not aI and len(instance) > len(schema.get("items", [])): error = "Additional items are not allowed (%s %s unexpected)" yield ValidationError( error % _utils.extras_msg(instance[len(schema.get("items", [])):]) ) def minimum(validator, minimum, instance, schema): if not validator.is_type(instance, "number"): return if schema.get("exclusiveMinimum", False): failed = instance <= minimum cmp = "less than or equal to" else: failed = instance < minimum cmp = "less than" if failed: yield ValidationError( "%r is %s the minimum of %r" % (instance, cmp, minimum) ) def maximum(validator, maximum, instance, schema): if not validator.is_type(instance, "number"): return if schema.get("exclusiveMaximum", False): failed = instance >= maximum cmp = "greater than or equal to" else: failed = instance > maximum cmp = "greater than" if failed: yield ValidationError( "%r is %s the maximum of %r" % (instance, cmp, maximum) ) def multipleOf(validator, dB, instance, schema): if not validator.is_type(instance, "number"): return if isinstance(dB, float): quotient = instance / dB failed = int(quotient) != quotient else: failed = instance % dB if failed: yield ValidationError("%r is not a multiple of %r" % (instance, dB)) def minItems(validator, mI, instance, schema): if validator.is_type(instance, "array") and len(instance) < mI: yield ValidationError("%r is too short" % (instance,)) def maxItems(validator, mI, instance, schema): if validator.is_type(instance, "array") and len(instance) > mI: yield ValidationError("%r is too long" % (instance,)) def uniqueItems(validator, uI, instance, schema): if ( uI and validator.is_type(instance, "array") and not _utils.uniq(instance) ): yield ValidationError("%r has non-unique elements" % instance) def pattern(validator, patrn, instance, schema): if ( validator.is_type(instance, "string") and not re.search(patrn, instance) ): yield ValidationError("%r does not match %r" % (instance, patrn)) def format(validator, format, instance, schema): if validator.format_checker is not None: try: validator.format_checker.check(instance, format) except FormatError as error: yield ValidationError(error.message, cause=error.cause) def minLength(validator, mL, instance, schema): if validator.is_type(instance, "string") and len(instance) < mL: yield ValidationError("%r is too short" % (instance,)) def maxLength(validator, mL, instance, schema): if validator.is_type(instance, "string") and len(instance) > mL: yield ValidationError("%r is too long" % (instance,)) def dependencies(validator, dependencies, instance, schema): if not validator.is_type(instance, "object"): return for property, dependency in iteritems(dependencies): if property not in instance: continue if validator.is_type(dependency, "object"): for error in validator.descend( instance, dependency, schema_path=property, ): yield error else: dependencies = _utils.ensure_list(dependency) for dependency in dependencies: if dependency not in instance: yield ValidationError( "%r is a dependency of %r" % (dependency, property) ) def enum(validator, enums, instance, schema): if instance not in enums: yield ValidationError("%r is not one of %r" % (instance, enums)) def ref(validator, ref, instance, schema): scope, resolved = validator.resolver.resolve(ref) validator.resolver.push_scope(scope) try: for error in validator.descend(instance, resolved): yield error finally: validator.resolver.pop_scope() def type_draft3(validator, types, instance, schema): types = _utils.ensure_list(types) all_errors = [] for index, type in enumerate(types): if type == "any": return if validator.is_type(type, "object"): errors = list(validator.descend(instance, type, schema_path=index)) if not errors: return all_errors.extend(errors) else: if validator.is_type(instance, type): return else: yield ValidationError( _utils.types_msg(instance, types), context=all_errors, ) def properties_draft3(validator, properties, instance, schema): if not validator.is_type(instance, "object"): return for property, subschema in iteritems(properties): if property in instance: for error in validator.descend( instance[property], subschema, path=property, schema_path=property, ): yield error elif subschema.get("required", False): error = ValidationError("%r is a required property" % property) error._set( validator="required", validator_value=subschema["required"], instance=instance, schema=schema, ) error.path.appendleft(property) error.schema_path.extend([property, "required"]) yield error def disallow_draft3(validator, disallow, instance, schema): for disallowed in _utils.ensure_list(disallow): if validator.is_valid(instance, {"type" : [disallowed]}): yield ValidationError( "%r is disallowed for %r" % (disallowed, instance) ) def extends_draft3(validator, extends, instance, schema): if validator.is_type(extends, "object"): for error in validator.descend(instance, extends): yield error return for index, subschema in enumerate(extends): for error in validator.descend(instance, subschema, schema_path=index): yield error def type_draft4(validator, types, instance, schema): types = _utils.ensure_list(types) if not any(validator.is_type(instance, type) for type in types): yield ValidationError(_utils.types_msg(instance, types)) def properties_draft4(validator, properties, instance, schema): if not validator.is_type(instance, "object"): return for property, subschema in iteritems(properties): if property in instance: for error in validator.descend( instance[property], subschema, path=property, schema_path=property, ): yield error def required_draft4(validator, required, instance, schema): if not validator.is_type(instance, "object"): return for property in required: if property not in instance: yield ValidationError("%r is a required property" % property) def minProperties_draft4(validator, mP, instance, schema): if validator.is_type(instance, "object") and len(instance) < mP: yield ValidationError( "%r does not have enough properties" % (instance,) ) def maxProperties_draft4(validator, mP, instance, schema): if not validator.is_type(instance, "object"): return if validator.is_type(instance, "object") and len(instance) > mP: yield ValidationError("%r has too many properties" % (instance,)) def allOf_draft4(validator, allOf, instance, schema): for index, subschema in enumerate(allOf): for error in validator.descend(instance, subschema, schema_path=index): yield error def oneOf_draft4(validator, oneOf, instance, schema): subschemas = enumerate(oneOf) all_errors = [] for index, subschema in subschemas: errs = list(validator.descend(instance, subschema, schema_path=index)) if not errs: first_valid = subschema break all_errors.extend(errs) else: yield ValidationError( "%r is not valid under any of the given schemas" % (instance,), context=all_errors, ) more_valid = [s for i, s in subschemas if validator.is_valid(instance, s)] if more_valid: more_valid.append(first_valid) reprs = ", ".join(repr(schema) for schema in more_valid) yield ValidationError( "%r is valid under each of %s" % (instance, reprs) ) def anyOf_draft4(validator, anyOf, instance, schema): all_errors = [] for index, subschema in enumerate(anyOf): errs = list(validator.descend(instance, subschema, schema_path=index)) if not errs: break all_errors.extend(errs) else: yield ValidationError( "%r is not valid under any of the given schemas" % (instance,), context=all_errors, ) def not_draft4(validator, not_schema, instance, schema): if validator.is_valid(instance, not_schema): yield ValidationError( "%r is not allowed for %r" % (not_schema, instance) )