Skip to content

Commit 8049538

Browse files
committed
Add relevance, hopefully less confusing to directly use than by_relevance().
1 parent 93465e5 commit 8049538

File tree

3 files changed

+41
-21
lines changed

3 files changed

+41
-21
lines changed

docs/errors.rst

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -303,8 +303,8 @@ instance. Each tree and child has a :attr:`~ErrorTree.errors` attribute, a
303303
dict, that maps the failed validator to the corresponding validation error.
304304

305305

306-
best_match and by_relevance
307-
---------------------------
306+
best_match and relevance
307+
------------------------
308308

309309
The :func:`best_match` function is a simple but useful function for attempting
310310
to guess the most relevant error in a given bunch.
@@ -340,8 +340,11 @@ to guess the most relevant error in a given bunch.
340340
different instances or schemas), since it won't produce sensical
341341
output.
342342
:argument callable key: the key to use when sorting errors. See
343-
:func:`by_relevance` for more details (the default is to sort with the
344-
defaults of that function).
343+
:attr:`relevance` and transitively :func:`by_relevance` for more
344+
details (the default is to sort with the defaults of that function).
345+
Changing the default is only useful if you want to change the function
346+
that rates errors but still want the error context decension done by
347+
this function.
345348
:returns: the best matching error, or ``None`` if the iterable was empty
346349

347350
.. note::
@@ -350,22 +353,23 @@ to guess the most relevant error in a given bunch.
350353
set of inputs from version to version if better heuristics are added.
351354

352355

353-
.. autofunction:: by_relevance
356+
.. function:: relevance(validation_error)
354357

355-
Create a key function that can be used to sort errors by relevance.
358+
A key function that sorts errors based on heuristic relevance.
356359

357-
If you want to sort a bunch of errors entirely, you can use this function
358-
to do so. Using the return value of this function as a key to e.g.
360+
If you want to sort a bunch of errors entirely, you can use
361+
this function to do so. Using this function as a key to e.g.
359362
:func:`sorted` or :func:`max` will cause more relevant errors to be
360363
considered greater than less relevant ones.
361364

362-
:argument set weak: a collection of validators to consider to be "weak". If
363-
there are two errors at the same level of the instance and one is in
364-
the set of weak validators, the other error will take priority. By
365-
default, :validator:`anyOf` and :validator:`oneOf` are considered weak
366-
validators and will be superceded by other same-level validation
367-
errors.
368-
:argument set strong: a collection of validators to consider to be "strong"
365+
Within the different validators that can fail, this function
366+
considers :validator:`anyOf` and :validator:`oneOf` to be *weak*
367+
validation errors, and will sort them lower than other validators at
368+
the same level in the instance.
369+
370+
If you want to change the set of weak [or strong] validators you can create
371+
a custom version of this function with :func:`by_relevance` and provide a
372+
different set of each.
369373

370374
.. doctest::
371375

@@ -383,6 +387,19 @@ to guess the most relevant error in a given bunch.
383387
>>> errors = Draft4Validator(schema).iter_errors(instance)
384388
>>> [
385389
... e.path[-1]
386-
... for e in sorted(errors, key=exceptions.by_relevance())
390+
... for e in sorted(errors, key=exceptions.relevance)
387391
... ]
388392
['home', 'name']
393+
394+
395+
.. autofunction:: by_relevance
396+
397+
Create a key function that can be used to sort errors by relevance.
398+
399+
:argument set weak: a collection of validators to consider to be "weak". If
400+
there are two errors at the same level of the instance and one is in
401+
the set of weak validators, the other error will take priority. By
402+
default, :validator:`anyOf` and :validator:`oneOf` are considered weak
403+
validators and will be superceded by other same-level validation
404+
errors.
405+
:argument set strong: a collection of validators to consider to be "strong"

jsonschema/exceptions.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,10 @@ def relevance(error):
219219
return relevance
220220

221221

222-
def best_match(errors, key=by_relevance()):
222+
relevance = by_relevance()
223+
224+
225+
def best_match(errors, key=relevance):
223226
errors = iter(errors)
224227
best = next(errors, None)
225228
if best is None:

jsonschema/tests/test_exceptions.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -162,23 +162,23 @@ class TestByRelevance(unittest.TestCase):
162162
def test_short_paths_are_better_matches(self):
163163
shallow = exceptions.ValidationError("Oh no!", path=["baz"])
164164
deep = exceptions.ValidationError("Oh yes!", path=["foo", "bar"])
165-
match = max([shallow, deep], key=exceptions.by_relevance())
165+
match = max([shallow, deep], key=exceptions.relevance)
166166
self.assertIs(match, shallow)
167167

168-
match = max([deep, shallow], key=exceptions.by_relevance())
168+
match = max([deep, shallow], key=exceptions.relevance)
169169
self.assertIs(match, shallow)
170170

171171
def test_global_errors_are_even_better_matches(self):
172172
shallow = exceptions.ValidationError("Oh no!", path=[])
173173
deep = exceptions.ValidationError("Oh yes!", path=["foo"])
174174

175-
errors = sorted([shallow, deep], key=exceptions.by_relevance())
175+
errors = sorted([shallow, deep], key=exceptions.relevance)
176176
self.assertEqual(
177177
[list(error.path) for error in errors],
178178
[["foo"], []],
179179
)
180180

181-
errors = sorted([deep, shallow], key=exceptions.by_relevance())
181+
errors = sorted([deep, shallow], key=exceptions.relevance)
182182
self.assertEqual(
183183
[list(error.path) for error in errors],
184184
[["foo"], []],

0 commit comments

Comments
 (0)