PNG  IHDR* pHYs+ IDATx]n#; cdLb Ǚ[at¤_:uP}>!Usă cag޿ ֵNu`ݼTâabO7uL&y^wFٝA"l[|ŲHLN밪4*sG3|Dv}?+y߉{OuOAt4Jj.u]Gz*҉sP'VQKbA1u\`& Af;HWj hsO;ogTu uj7S3/QzUr&wS`M$X_L7r2;aE+ώ%vikDA:dR+%KzƉo>eOth$z%: :{WwaQ:wz%4foɹE[9<]#ERINƻv溂E%P1i01 |Jvҗ&{b?9g=^wζXn/lK::90KwrюO\!ջ3uzuGv^;騢wq<Iatv09:tt~hEG`v;3@MNZD.1]L:{ծI3`L(÷ba")Y.iljCɄae#I"1 `3*Bdz>j<fU40⨬%O$3cGt]j%Fߠ_twJ;ABU8vP3uEԑwQ V:h%))LfraqX-ۿX]v-\9I gl8tzX ]ecm)-cgʒ#Uw=Wlێn(0hPP/ӨtQ“&J35 $=]r1{tLuǮ*i0_;NƝ8;-vݏr8+U-kruȕYr0RnC]*ެ(M:]gE;{]tg(#ZJ9y>utRDRMdr9㪩̞zֹb<ģ&wzJM"iI( .ꮅX)Qw:9,i좜\Ԛi7&N0:asϓc];=ΗOӣ APqz93 y $)A*kVHZwBƺnWNaby>XMN*45~ղM6Nvm;A=jֲ.~1}(9`KJ/V F9[=`~[;sRuk]rєT!)iQO)Y$V ی ۤmzWz5IM Zb )ˆC`6 rRa}qNmUfDsWuˤV{ Pݝ'=Kֳbg,UҘVz2ﴻnjNgBb{? ߮tcsͻQuxVCIY۠:(V뺕 ٥2;t`@Fo{Z9`;]wMzU~%UA蛚dI vGq\r82iu +St`cR.6U/M9IENDB`from collections import defaultdict, deque import itertools import pprint import textwrap from jsonschema import _utils from jsonschema.compat import PY3, iteritems WEAK_MATCHES = frozenset(["anyOf", "oneOf"]) STRONG_MATCHES = frozenset() _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=(), parent=None, ): super(_Error, self).__init__( message, validator, path, cause, context, validator_value, instance, schema, schema_path, parent, ) self.message = message self.path = self.relative_path = deque(path) self.schema_path = self.relative_schema_path = 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 self.parent = parent for error in context: error.parent = self def __repr__(self): return "<%s: %r>" % (self.__class__.__name__, self.message) def __unicode__(self): essential_for_verbose = ( self.validator, self.validator_value, self.instance, self.schema, ) if any(m is _unset for m in essential_for_verbose): return self.message 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, _utils.format_as_index(list(self.relative_schema_path)[:-1]), _utils.indent(pschema), _utils.format_as_index(self.relative_path), _utils.indent(pinstance), ) if PY3: __str__ = __unicode__ else: def __str__(self): return unicode(self).encode("utf-8") @classmethod def create_from(cls, other): return cls(**other._contents()) @property def absolute_path(self): parent = self.parent if parent is None: return self.relative_path path = deque(self.relative_path) path.extendleft(reversed(parent.absolute_path)) return path @property def absolute_schema_path(self): parent = self.parent if parent is None: return self.relative_schema_path path = deque(self.relative_schema_path) path.extendleft(reversed(parent.absolute_schema_path)) return path def _set(self, **kwargs): for k, v in iteritems(kwargs): if getattr(self, k) is _unset: setattr(self, k, v) def _contents(self): attrs = ( "message", "cause", "context", "validator", "validator_value", "path", "schema_path", "instance", "schema", "parent", ) return dict((attr, getattr(self, attr)) for attr in attrs) class ValidationError(_Error): pass class SchemaError(_Error): pass class RefResolutionError(Exception): pass class UnknownType(Exception): def __init__(self, type, instance, schema): self.type = type self.instance = instance self.schema = schema def __unicode__(self): pschema = pprint.pformat(self.schema, width=72) pinstance = pprint.pformat(self.instance, width=72) return textwrap.dedent(""" Unknown type %r for validator with schema: %s While checking instance: %s """.rstrip() ) % (self.type, _utils.indent(pschema), _utils.indent(pinstance)) if PY3: __str__ = __unicode__ else: def __str__(self): return unicode(self).encode("utf-8") class FormatError(Exception): def __init__(self, message, cause=None): super(FormatError, self).__init__(message, cause) self.message = message self.cause = self.__cause__ = cause def __unicode__(self): return self.message if PY3: __str__ = __unicode__ else: def __str__(self): return self.message.encode("utf-8") class ErrorTree(object): """ ErrorTrees make it easier to check which validations failed. """ _instance = _unset def __init__(self, errors=()): self.errors = {} self._contents = defaultdict(self.__class__) for error in errors: container = self for element in error.path: container = container[element] container.errors[error.validator] = error container._instance = error.instance def __contains__(self, index): """ Check whether ``instance[index]`` has any errors. """ return index in self._contents def __getitem__(self, index): """ Retrieve the child tree one level down at the given ``index``. If the index is not in the instance that this tree corresponds to and is not known by this tree, whatever error would be raised by ``instance.__getitem__`` will be propagated (usually this is some subclass of :class:`LookupError`. """ if self._instance is not _unset and index not in self: self._instance[index] return self._contents[index] def __setitem__(self, index, value): self._contents[index] = value def __iter__(self): """ Iterate (non-recursively) over the indices in the instance with errors. """ return iter(self._contents) def __len__(self): """ Same as :attr:`total_errors`. """ return self.total_errors def __repr__(self): return "<%s (%s total errors)>" % (self.__class__.__name__, len(self)) @property def total_errors(self): """ The total number of errors in the entire tree, including children. """ child_errors = sum(len(tree) for _, tree in iteritems(self._contents)) return len(self.errors) + child_errors def by_relevance(weak=WEAK_MATCHES, strong=STRONG_MATCHES): def relevance(error): validator = error.validator return -len(error.path), validator not in weak, validator in strong return relevance relevance = by_relevance() def best_match(errors, key=relevance): errors = iter(errors) best = next(errors, None) if best is None: return best = max(itertools.chain([best], errors), key=key) while best.context: best = min(best.context, key=key) return best