diff options
author | Julian Berman <Julian@GrayVines.com> | 2013-05-20 12:21:07 -0400 |
---|---|---|
committer | Julian Berman <Julian@GrayVines.com> | 2013-05-20 12:24:30 -0400 |
commit | 0fe509c9c0ce61331c7c438bae983635cdf86076 (patch) | |
tree | 10d2dc912b23e33115ff4e9849128659adedbf46 | |
parent | 04ca6d5c3114f2e681777f5a138f0b3357f5666e (diff) | |
download | jsonschema-0fe509c9c0ce61331c7c438bae983635cdf86076.tar.gz |
Magic
Reimplement validators with jsonschema.validators.create
-rw-r--r-- | jsonschema/__init__.py | 5 | ||||
-rw-r--r-- | jsonschema/_utils.py | 10 | ||||
-rw-r--r-- | jsonschema/_validators.py | 438 | ||||
-rw-r--r-- | jsonschema/tests/test_validators.py | 11 | ||||
-rw-r--r-- | jsonschema/validators.py | 510 |
5 files changed, 522 insertions, 452 deletions
diff --git a/jsonschema/__init__.py b/jsonschema/__init__.py index adf9e2d..d2e1b6f 100644 --- a/jsonschema/__init__.py +++ b/jsonschema/__init__.py @@ -12,9 +12,10 @@ instance under a schema, and will create a validator for you. from jsonschema._format import ( FormatChecker, FormatError, draft3_format_checker, draft4_format_checker, ) +from jsonschema._validators import ValidationError from jsonschema.validators import ( - RefResolutionError, SchemaError, ValidationError, UnknownType, - ErrorTree, Draft3Validator, Draft4Validator, RefResolver, ValidatorMixin, + RefResolutionError, SchemaError, UnknownType, ErrorTree, + Draft3Validator, Draft4Validator, RefResolver, ValidatorMixin, validate, validates, ) diff --git a/jsonschema/_utils.py b/jsonschema/_utils.py index 044475c..44a577a 100644 --- a/jsonschema/_utils.py +++ b/jsonschema/_utils.py @@ -38,6 +38,16 @@ class URIDict(MutableMapping): return repr(self.store) +class Unset(object): + """ + An as-of-yet unset attribute or unprovided default parameter. + + """ + + def __repr__(self): + return "<unset>" + + def load_schema(name): """ Load a schema from ./schemas/``name``.json and return it. diff --git a/jsonschema/_validators.py b/jsonschema/_validators.py new file mode 100644 index 0000000..89d0086 --- /dev/null +++ b/jsonschema/_validators.py @@ -0,0 +1,438 @@ +import collections +import pprint +import re +import textwrap + +from jsonschema import _utils +from jsonschema._format import FormatError +from jsonschema.compat import PY3, iteritems + + +FLOAT_TOLERANCE = 10 ** -15 +unset = _utils.Unset() + + +class _Error(Exception): + def __init__( + self, message, validator=unset, path=(), cause=None, context=(), + validator_value=unset, instance=unset, schema=unset, schema_path=(), + ): + self.message = message + self.path = collections.deque(path) + self.schema_path = collections.deque(schema_path) + self.context = list(context) + self.cause = self.__cause__ = cause + self.validator = validator + self.validator_value = validator_value + self.instance = instance + self.schema = schema + + @classmethod + def create_from(cls, other): + return cls( + message=other.message, + cause=other.cause, + context=other.context, + path=other.path, + schema_path=other.schema_path, + validator=other.validator, + validator_value=other.validator_value, + instance=other.instance, + schema=other.schema, + ) + + def _set(self, **kwargs): + for k, v in iteritems(kwargs): + if getattr(self, k) is unset: + setattr(self, k, v) + + def __repr__(self): + return "<%s: %r>" % (self.__class__.__name__, self.message) + + def __str__(self): + return unicode(self).encode("utf-8") + + def __unicode__(self): + if unset in ( + self.validator, self.validator_value, self.instance, self.schema, + ): + return self.message + + path = _utils.format_as_index(self.path) + schema_path = _utils.format_as_index(list(self.schema_path)[:-1]) + + pschema = pprint.pformat(self.schema, width=72) + pinstance = pprint.pformat(self.instance, width=72) + return self.message + textwrap.dedent(""" + + Failed validating %r in schema%s: + %s + + On instance%s: + %s + """.rstrip() + ) % ( + self.validator, + schema_path, + _utils.indent(pschema), + path, + _utils.indent(pinstance), + ) + + if PY3: + __str__ = __unicode__ + + +class ValidationError(_Error): pass + + +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 + + if validator.is_type(aI, "object"): + for index, item in enumerate(instance[len(schema.get("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 + + instance = float(instance) + 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 + + instance = float(instance) + 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): + mod = instance % dB + failed = (mod > FLOAT_TOLERANCE) and (dB - mod) > FLOAT_TOLERANCE + 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 and + validator.is_type(instance, "string") + ): + 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): + 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) + elif validator.is_type(type, "string"): + 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 is too short" % (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 is too short" % (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) + ) diff --git a/jsonschema/tests/test_validators.py b/jsonschema/tests/test_validators.py index 1db6c64..1457be5 100644 --- a/jsonschema/tests/test_validators.py +++ b/jsonschema/tests/test_validators.py @@ -4,13 +4,12 @@ import json import pprint import textwrap -from jsonschema import FormatChecker +from jsonschema import FormatChecker, ValidationError from jsonschema.compat import PY3 from jsonschema.tests.compat import mock, unittest from jsonschema.validators import ( - RefResolutionError, UnknownType, ValidationError, ErrorTree, - Draft3Validator, Draft4Validator, RefResolver, ValidatorMixin, - meta_schemas, create, validate, + RefResolutionError, UnknownType, ErrorTree, Draft3Validator, + Draft4Validator, RefResolver, ValidatorMixin, create, validate, ) @@ -49,7 +48,7 @@ class TestCreate(unittest.TestCase): self.assertEqual(list(self.validator.iter_errors(instance)), [error]) self.smelly.assert_called_with( - self.validator_value, instance, self.schema, + self.validator, self.validator_value, instance, self.schema, ) def test_if_a_version_is_provided_it_is_registered(self): @@ -61,7 +60,7 @@ class TestCreate(unittest.TestCase): def test_if_a_version_is_not_provided_it_is_not_registered(self): with mock.patch("jsonschema.validators.validates") as validates: - Validator = create(meta_schema={"id" : "id"}) + create(meta_schema={"id" : "id"}) self.assertFalse(validates.called) diff --git a/jsonschema/validators.py b/jsonschema/validators.py index 582f53b..43ed517 100644 --- a/jsonschema/validators.py +++ b/jsonschema/validators.py @@ -4,115 +4,27 @@ import collections import contextlib import json import numbers -import pprint -import re -import textwrap try: import requests except ImportError: requests = None -from jsonschema import _utils +from jsonschema import _utils, _validators from jsonschema.compat import ( PY3, Sequence, urljoin, urlsplit, urldefrag, unquote, urlopen, str_types, int_types, iteritems, ) -from jsonschema._format import FormatError -FLOAT_TOLERANCE = 10 ** -15 -validators = {} - - -class _Unset(object): - """ - An as-of-yet unset attribute. - - """ - - def __repr__(self): - return "<unset>" -_unset = _Unset() - - -class _Error(Exception): - def __init__( - self, message, validator=_unset, path=(), cause=None, context=(), - validator_value=_unset, instance=_unset, schema=_unset, schema_path=(), - ): - self.message = message - self.path = collections.deque(path) - self.schema_path = collections.deque(schema_path) - self.context = list(context) - self.cause = self.__cause__ = cause - self.validator = validator - self.validator_value = validator_value - self.instance = instance - self.schema = schema - - @classmethod - def create_from(cls, other): - return cls( - message=other.message, - cause=other.cause, - context=other.context, - path=other.path, - schema_path=other.schema_path, - validator=other.validator, - validator_value=other.validator_value, - instance=other.instance, - schema=other.schema, - ) - - def _set(self, **kwargs): - for k, v in iteritems(kwargs): - if getattr(self, k) is _unset: - setattr(self, k, v) - - def __repr__(self): - return "<%s: %r>" % (self.__class__.__name__, self.message) - - def __str__(self): - return unicode(self).encode("utf-8") - - def __unicode__(self): - if _unset in ( - self.validator, self.validator_value, self.instance, self.schema, - ): - return self.message - - path = _utils.format_as_index(self.path) - schema_path = _utils.format_as_index(list(self.schema_path)[:-1]) - - pschema = pprint.pformat(self.schema, width=72) - pinstance = pprint.pformat(self.instance, width=72) - return self.message + textwrap.dedent(""" - - Failed validating %r in schema%s: - %s - - On instance%s: - %s - """.rstrip() - ) % ( - self.validator, - schema_path, - _utils.indent(pschema), - path, - _utils.indent(pinstance), - ) - - if PY3: - __str__ = __unicode__ - - -class SchemaError(_Error): pass -class ValidationError(_Error): pass class RefResolutionError(Exception): pass +class SchemaError(_validators._Error): pass class UnknownType(Exception): pass +_unset = _utils.Unset() + +validators = {} meta_schemas = _utils.URIDict() @@ -183,7 +95,7 @@ def create(meta_schema, validators=(), version=None, default_types=None): # noq if validator is None: continue - errors = validator(v, instance, _schema) or () + errors = validator(self, v, instance, _schema) or () for error in errors: # set details if not already set by the called fn error._set( @@ -250,357 +162,67 @@ class ValidatorMixin(create(meta_schema={})): self.VALIDATORS = _VALIDATORS() -class _Draft34CommonMixin(object): - """ - Contains the validator methods common to both JSON schema drafts. - - """ - - def validate_patternProperties(self, patternProperties, instance, schema): - if not self.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 self.descend( - v, subschema, path=k, schema_path=pattern - ): - yield error - - def validate_additionalProperties(self, aP, instance, schema): - if not self.is_type(instance, "object"): - return - - extras = set(_utils.find_additional_properties(instance, schema)) - - if self.is_type(aP, "object"): - for extra in extras: - for error in self.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 validate_items(self, items, instance, schema): - if not self.is_type(instance, "array"): - return - - if self.is_type(items, "object"): - for index, item in enumerate(instance): - for error in self.descend(item, items, path=index): - yield error - else: - for (index, item), subschema in zip(enumerate(instance), items): - for error in self.descend( - item, subschema, path=index, schema_path=index - ): - yield error - - def validate_additionalItems(self, aI, instance, schema): - if ( - not self.is_type(instance, "array") or - self.is_type(schema.get("items", {}), "object") - ): - return - - if self.is_type(aI, "object"): - for index, item in enumerate( - instance[len(schema.get("items", [])):]): - for error in self.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 validate_minimum(self, minimum, instance, schema): - if not self.is_type(instance, "number"): - return - - instance = float(instance) - 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 validate_maximum(self, maximum, instance, schema): - if not self.is_type(instance, "number"): - return - - instance = float(instance) - 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 _validate_multipleOf(self, dB, instance, schema): - if not self.is_type(instance, "number"): - return - - if isinstance(dB, float): - mod = instance % dB - failed = (mod > FLOAT_TOLERANCE) and (dB - mod) > FLOAT_TOLERANCE - else: - failed = instance % dB - - if failed: - yield ValidationError( - "%r is not a multiple of %r" % (instance, dB) - ) - - def validate_minItems(self, mI, instance, schema): - if self.is_type(instance, "array") and len(instance) < mI: - yield ValidationError("%r is too short" % (instance,)) - - def validate_maxItems(self, mI, instance, schema): - if self.is_type(instance, "array") and len(instance) > mI: - yield ValidationError("%r is too long" % (instance,)) - - def validate_uniqueItems(self, uI, instance, schema): - if ( - uI and - self.is_type(instance, "array") and - not _utils.uniq(instance) - ): - yield ValidationError("%r has non-unique elements" % instance) - - def validate_pattern(self, patrn, instance, schema): - if self.is_type(instance, "string") and not re.search(patrn, instance): - yield ValidationError("%r does not match %r" % (instance, patrn)) - - def validate_format(self, format, instance, schema): - if ( - self.format_checker is not None and - self.is_type(instance, "string") - ): - try: - self.format_checker.check(instance, format) - except FormatError as error: - yield ValidationError(error.message, cause=error.cause) - - def validate_minLength(self, mL, instance, schema): - if self.is_type(instance, "string") and len(instance) < mL: - yield ValidationError("%r is too short" % (instance,)) - - def validate_maxLength(self, mL, instance, schema): - if self.is_type(instance, "string") and len(instance) > mL: - yield ValidationError("%r is too long" % (instance,)) - - def validate_dependencies(self, dependencies, instance, schema): - if not self.is_type(instance, "object"): - return - - for property, dependency in iteritems(dependencies): - if property not in instance: - continue - - if self.is_type(dependency, "object"): - for error in self.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 validate_enum(self, enums, instance, schema): - if instance not in enums: - yield ValidationError("%r is not one of %r" % (instance, enums)) - - def validate_ref(self, ref, instance, schema): - with self.resolver.resolving(ref) as resolved: - for error in self.descend(instance, resolved): - yield error - - -@validates("draft3") -class Draft3Validator(ValidatorMixin, _Draft34CommonMixin, object): - """ - A validator for JSON Schema draft 3. - - """ - - def validate_type(self, types, instance, schema): - types = _utils.ensure_list(types) - - all_errors = [] - for index, type in enumerate(types): - if type == "any": - return - if self.is_type(type, "object"): - errors = list(self.descend(instance, type, schema_path=index)) - if not errors: - return - all_errors.extend(errors) - elif self.is_type(type, "string"): - if self.is_type(instance, type): - return - else: - yield ValidationError( - _utils.types_msg(instance, types), context=all_errors, - ) - - def validate_properties(self, properties, instance, schema): - if not self.is_type(instance, "object"): - return - - for property, subschema in iteritems(properties): - if property in instance: - for error in self.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 validate_disallow(self, disallow, instance, schema): - for disallowed in _utils.ensure_list(disallow): - if self.is_valid(instance, {"type" : [disallowed]}): - yield ValidationError( - "%r is disallowed for %r" % (disallowed, instance) - ) - - def validate_extends(self, extends, instance, schema): - if self.is_type(extends, "object"): - for error in self.descend(instance, extends): - yield error - return - for index, subschema in enumerate(extends): - for error in self.descend(instance, subschema, schema_path=index): - yield error - - validate_divisibleBy = _Draft34CommonMixin._validate_multipleOf - - META_SCHEMA = _utils.load_schema('draft3') - - -@validates("draft4") -class Draft4Validator(ValidatorMixin, _Draft34CommonMixin, object): - """ - A validator for JSON Schema draft 4. - - """ - - def validate_type(self, types, instance, schema): - types = _utils.ensure_list(types) - - if not any(self.is_type(instance, type) for type in types): - yield ValidationError(_utils.types_msg(instance, types)) - - def validate_properties(self, properties, instance, schema): - if not self.is_type(instance, "object"): - return - - for property, subschema in iteritems(properties): - if property in instance: - for error in self.descend( - instance[property], - subschema, - path=property, - schema_path=property, - ): - yield error - - def validate_required(self, required, instance, schema): - if not self.is_type(instance, "object"): - return - for property in required: - if property not in instance: - yield ValidationError("%r is a required property" % property) - - def validate_minProperties(self, mP, instance, schema): - if self.is_type(instance, "object") and len(instance) < mP: - yield ValidationError("%r is too short" % (instance,)) - - def validate_maxProperties(self, mP, instance, schema): - if not self.is_type(instance, "object"): - return - if self.is_type(instance, "object") and len(instance) > mP: - yield ValidationError("%r is too short" % (instance,)) - - def validate_allOf(self, allOf, instance, schema): - for index, subschema in enumerate(allOf): - for error in self.descend(instance, subschema, schema_path=index): - yield error - - def validate_oneOf(self, oneOf, instance, schema): - subschemas = enumerate(oneOf) - all_errors = [] - for index, subschema in subschemas: - errors = list(self.descend(instance, subschema, schema_path=index)) - if not errors: - first_valid = subschema - break - all_errors.extend(errors) - 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 self.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 validate_anyOf(self, anyOf, instance, schema): - all_errors = [] - for index, subschema in enumerate(anyOf): - errors = list(self.descend(instance, subschema, schema_path=index)) - if not errors: - break - all_errors.extend(errors) - else: - yield ValidationError( - "%r is not valid under any of the given schemas" % (instance,), - context=all_errors, - ) - - def validate_not(self, not_schema, instance, schema): - if self.is_valid(instance, not_schema): - yield ValidationError( - "%r is not allowed for %r" % (not_schema, instance) - ) - - validate_multipleOf = _Draft34CommonMixin._validate_multipleOf +Draft3Validator = create( + meta_schema=_utils.load_schema("draft3"), + validators={ + "$ref" : _validators.ref, + "additionalItems" : _validators.additionalItems, + "additionalProperties" : _validators.additionalProperties, + "dependencies" : _validators.dependencies, + "disallow" : _validators.disallow_draft3, + "divisibleBy" : _validators.multipleOf, + "enum" : _validators.enum, + "extends" : _validators.extends_draft3, + "format" : _validators.format, + "items" : _validators.items, + "maxItems" : _validators.maxItems, + "maxLength" : _validators.maxLength, + "maximum" : _validators.maximum, + "minItems" : _validators.minItems, + "minLength" : _validators.minLength, + "minimum" : _validators.minimum, + "multipleOf" : _validators.multipleOf, + "pattern" : _validators.pattern, + "patternProperties" : _validators.patternProperties, + "properties" : _validators.properties_draft3, + "type" : _validators.type_draft3, + "uniqueItems" : _validators.uniqueItems, + }, + version="draft3", +) - META_SCHEMA = _utils.load_schema('draft4') +Draft4Validator = create( + meta_schema=_utils.load_schema("draft4"), + validators={ + "$ref" : _validators.ref, + "additionalItems" : _validators.additionalItems, + "additionalProperties" : _validators.additionalProperties, + "allOf" : _validators.allOf_draft4, + "anyOf" : _validators.anyOf_draft4, + "dependencies" : _validators.dependencies, + "enum" : _validators.enum, + "format" : _validators.format, + "items" : _validators.items, + "maxItems" : _validators.maxItems, + "maxLength" : _validators.maxLength, + "maxProperties" : _validators.maxProperties_draft4, + "maximum" : _validators.maximum, + "minItems" : _validators.minItems, + "minLength" : _validators.minLength, + "minProperties" : _validators.minProperties_draft4, + "minimum" : _validators.minimum, + "multipleOf" : _validators.multipleOf, + "not" : _validators.not_draft4, + "oneOf" : _validators.oneOf_draft4, + "pattern" : _validators.pattern, + "patternProperties" : _validators.patternProperties, + "properties" : _validators.properties_draft4, + "required" : _validators.required_draft4, + "type" : _validators.type_draft4, + "uniqueItems" : _validators.uniqueItems, + }, + version="draft4", +) class RefResolver(object): |