diff options
Diffstat (limited to 'lib/spack/external/jsonschema/_validators.py')
-rw-r--r-- | lib/spack/external/jsonschema/_validators.py | 279 |
1 files changed, 147 insertions, 132 deletions
diff --git a/lib/spack/external/jsonschema/_validators.py b/lib/spack/external/jsonschema/_validators.py index c6e801ccb2..179fec09a9 100644 --- a/lib/spack/external/jsonschema/_validators.py +++ b/lib/spack/external/jsonschema/_validators.py @@ -1,13 +1,18 @@ import re -from jsonschema import _utils +from jsonschema._utils import ( + ensure_list, + equal, + extras_msg, + find_additional_properties, + types_msg, + unbool, + uniq, +) from jsonschema.exceptions import FormatError, ValidationError from jsonschema.compat import iteritems -FLOAT_TOLERANCE = 10 ** -15 - - def patternProperties(validator, patternProperties, instance, schema): if not validator.is_type(instance, "object"): return @@ -21,35 +26,60 @@ def patternProperties(validator, patternProperties, instance, schema): yield error +def propertyNames(validator, propertyNames, instance, schema): + if not validator.is_type(instance, "object"): + return + + for property in instance: + for error in validator.descend( + instance=property, + schema=propertyNames, + ): + yield error + + def additionalProperties(validator, aP, instance, schema): if not validator.is_type(instance, "object"): return - extras = set(_utils.find_additional_properties(instance, schema)) + extras = set(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)) + if "patternProperties" in schema: + patterns = sorted(schema["patternProperties"]) + if len(extras) == 1: + verb = "does" + else: + verb = "do" + error = "%s %s not match any of the regexes: %s" % ( + ", ".join(map(repr, sorted(extras))), + verb, + ", ".join(map(repr, patterns)), + ) + yield ValidationError(error) + else: + error = "Additional properties are not allowed (%s %s unexpected)" + yield ValidationError(error % 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: + if validator.is_type(items, "array"): for (index, item), subschema in zip(enumerate(instance), items): for error in validator.descend( item, subschema, path=index, schema_path=index, ): yield error + else: + for index, item in enumerate(instance): + for error in validator.descend(item, items, path=index): + yield error def additionalItems(validator, aI, instance, schema): @@ -68,41 +98,66 @@ def additionalItems(validator, aI, instance, schema): error = "Additional items are not allowed (%s %s unexpected)" yield ValidationError( error % - _utils.extras_msg(instance[len(schema.get("items", [])):]) + extras_msg(instance[len(schema.get("items", [])):]) ) -def minimum(validator, minimum, instance, schema): +def const(validator, const, instance, schema): + if not equal(instance, const): + yield ValidationError("%r was expected" % (const,)) + + +def contains(validator, contains, instance, schema): + if not validator.is_type(instance, "array"): + return + + if not any(validator.is_valid(element, contains) for element in instance): + yield ValidationError( + "None of %r are valid under the given schema" % (instance,) + ) + + +def exclusiveMinimum(validator, minimum, instance, schema): if not validator.is_type(instance, "number"): return - if schema.get("exclusiveMinimum", False): - failed = float(instance) <= minimum - cmp = "less than or equal to" - else: - failed = float(instance) < minimum - cmp = "less than" + if instance <= minimum: + yield ValidationError( + "%r is less than or equal to the minimum of %r" % ( + instance, minimum, + ), + ) - if failed: + +def exclusiveMaximum(validator, maximum, instance, schema): + if not validator.is_type(instance, "number"): + return + + if instance >= maximum: yield ValidationError( - "%r is %s the minimum of %r" % (instance, cmp, minimum) + "%r is greater than or equal to the maximum of %r" % ( + instance, maximum, + ), ) -def maximum(validator, maximum, instance, schema): +def minimum(validator, minimum, 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 instance < minimum: + yield ValidationError( + "%r is less than the minimum of %r" % (instance, minimum) + ) - if failed: + +def maximum(validator, maximum, instance, schema): + if not validator.is_type(instance, "number"): + return + + if instance > maximum: yield ValidationError( - "%r is %s the maximum of %r" % (instance, cmp, maximum) + "%r is greater than the maximum of %r" % (instance, maximum) ) @@ -111,8 +166,8 @@ def multipleOf(validator, dB, instance, schema): return if isinstance(dB, float): - mod = instance % dB - failed = (mod > FLOAT_TOLERANCE) and (dB - mod) > FLOAT_TOLERANCE + quotient = instance / dB + failed = int(quotient) != quotient else: failed = instance % dB @@ -134,9 +189,9 @@ def uniqueItems(validator, uI, instance, schema): if ( uI and validator.is_type(instance, "array") and - not _utils.uniq(instance) + not uniq(instance) ): - yield ValidationError("%r has non-unique elements" % instance) + yield ValidationError("%r has non-unique elements" % (instance,)) def pattern(validator, patrn, instance, schema): @@ -173,104 +228,52 @@ def dependencies(validator, dependencies, instance, schema): if property not in instance: continue - if validator.is_type(dependency, "object"): + if validator.is_type(dependency, "array"): + for each in dependency: + if each not in instance: + message = "%r is a dependency of %r" + yield ValidationError(message % (each, property)) + else: 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: + if instance == 0 or instance == 1: + unbooled = unbool(instance) + if all(unbooled != unbool(each) for each in enums): + yield ValidationError("%r is not one of %r" % (instance, enums)) + elif instance not in enums: yield ValidationError("%r is not one of %r" % (instance, enums)) def ref(validator, ref, instance, schema): - with validator.resolver.resolving(ref) as resolved: - for error in validator.descend(instance, resolved): - yield error - - -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 + resolve = getattr(validator.resolver, "resolve", None) + if resolve is None: + with validator.resolver.resolving(ref) as resolved: + for error in validator.descend(instance, resolved): + yield error 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 + scope, resolved = validator.resolver.resolve(ref) + validator.resolver.push_scope(scope) - for property, subschema in iteritems(properties): - if property in instance: - for error in validator.descend( - instance[property], - subschema, - path=property, - schema_path=property, - ): + try: + for error in validator.descend(instance, resolved): 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) - ) + finally: + validator.resolver.pop_scope() -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) +def type(validator, types, instance, schema): + types = ensure_list(types) if not any(validator.is_type(instance, type) for type in types): - yield ValidationError(_utils.types_msg(instance, types)) + yield ValidationError(types_msg(instance, types)) -def properties_draft4(validator, properties, instance, schema): +def properties(validator, properties, instance, schema): if not validator.is_type(instance, "object"): return @@ -285,7 +288,7 @@ def properties_draft4(validator, properties, instance, schema): yield error -def required_draft4(validator, required, instance, schema): +def required(validator, required, instance, schema): if not validator.is_type(instance, "object"): return for property in required: @@ -293,33 +296,31 @@ def required_draft4(validator, required, instance, schema): yield ValidationError("%r is a required property" % property) -def minProperties_draft4(validator, mP, instance, schema): +def minProperties(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): +def maxProperties(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): +def allOf(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) +def anyOf(validator, anyOf, instance, schema): all_errors = [] - for index, subschema in subschemas: + for index, subschema in enumerate(anyOf): errs = list(validator.descend(instance, subschema, schema_path=index)) if not errs: - first_valid = subschema break all_errors.extend(errs) else: @@ -328,20 +329,14 @@ def oneOf_draft4(validator, oneOf, instance, schema): 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): +def oneOf(validator, oneOf, instance, schema): + subschemas = enumerate(oneOf) all_errors = [] - for index, subschema in enumerate(anyOf): + 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: @@ -350,9 +345,29 @@ def anyOf_draft4(validator, anyOf, instance, schema): 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 not_draft4(validator, not_schema, instance, schema): +def not_(validator, not_schema, instance, schema): if validator.is_valid(instance, not_schema): yield ValidationError( "%r is not allowed for %r" % (not_schema, instance) ) + + +def if_(validator, if_schema, instance, schema): + if validator.is_valid(instance, if_schema): + if u"then" in schema: + then = schema[u"then"] + for error in validator.descend(instance, then, schema_path="then"): + yield error + elif u"else" in schema: + else_ = schema[u"else"] + for error in validator.descend(instance, else_, schema_path="else"): + yield error |