diff options
author | Julian Berman <Julian@GrayVines.com> | 2013-10-27 20:38:49 -0400 |
---|---|---|
committer | Julian Berman <Julian@GrayVines.com> | 2013-10-27 20:38:49 -0400 |
commit | b4f098bdccb25b6d124050e4ecda48371c7ccc4a (patch) | |
tree | ceb0b10d2aa747759bd595fafe5e20b7fb3bd23a /jsonschema/exceptions.py | |
parent | 11b3220eac39292e88df04a8b8a5a142812496fe (diff) | |
download | jsonschema-b4f098bdccb25b6d124050e4ecda48371c7ccc4a.tar.gz |
Different strategy that's a lot more robust.
Diffstat (limited to 'jsonschema/exceptions.py')
-rw-r--r-- | jsonschema/exceptions.py | 40 |
1 files changed, 17 insertions, 23 deletions
diff --git a/jsonschema/exceptions.py b/jsonschema/exceptions.py index 8df987d..04a3c0b 100644 --- a/jsonschema/exceptions.py +++ b/jsonschema/exceptions.py @@ -7,6 +7,9 @@ from jsonschema import _utils from jsonschema.compat import PY3, iteritems +WEAK_MATCHES = frozenset(["anyOf", "oneOf"]) +STRONG_MATCHES = frozenset() + _unset = _utils.Unset() @@ -30,24 +33,6 @@ class _Error(Exception): return NotImplemented return self._contents() == other._contents() - def __lt__(self, other): - if not isinstance(other, self.__class__): - # On Py2 Python will "helpfully" make this succeed. So be more - # forceful, because we really don't want this to work, it probably - # means a ValidationError and a SchemaError are being compared - # accidentally. - if not PY3: - message = "unorderable types: %s() < %s()" % ( - self.__class__.__name__, other.__class__.__name__, - ) - raise TypeError(message) - return NotImplemented - - is_deeper = len(self.path) > len(other.path) - is_weak_matcher = self.validator in ("anyOf", "oneOf") - other_is_weak_matcher = other.validator in ("anyOf", "oneOf") - return is_deeper or is_weak_matcher > other_is_weak_matcher - def __ne__(self, other): return not self == other @@ -159,11 +144,20 @@ class FormatError(Exception): __str__ = __unicode__ -def best_match(errors): - first = next(iter(errors), None) - if first is None: +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 + + +def best_match(errors, key=by_relevance()): + errors = iter(errors) + best = next(errors, None) + if best is None: return - best = max(itertools.chain([first], errors)) + best = max(itertools.chain([best], errors), key=key) + while best.context: - best = min(best.context) + best = min(best.context, key=key) return best |