Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e663964

Browse files
author
bugfix-mission
committed
fix(exceptions): count duplicate-validator errors in ErrorTree
ErrorTree.total_errors used len(self.errors), but self.errors is a dict keyed by validator keyword, so multiple errors at the same path sharing a validator (e.g. several 'type' failures) were collapsed and undercounted. Track every error in an internal list and use its length for total_errors.
1 parent b747e59 commit e663964

2 files changed

Lines changed: 14 additions & 1 deletion

File tree

jsonschema/exceptions.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,13 +321,15 @@ class ErrorTree:
321321

322322
def __init__(self, errors: Iterable[ValidationError] = ()):
323323
self.errors: MutableMapping[str, ValidationError] = {}
324+
self._all_errors: list[ValidationError] = []
324325
self._contents: Mapping[str, ErrorTree] = defaultdict(self.__class__)
325326

326327
for error in errors:
327328
container = self
328329
for element in error.path:
329330
container = container[element]
330331
container.errors[error.validator] = error
332+
container._all_errors.append(error)
331333

332334
container._instance = error.instance
333335

@@ -390,7 +392,7 @@ def total_errors(self):
390392
The total number of errors in the entire tree, including children.
391393
"""
392394
child_errors = sum(len(tree) for _, tree in self._contents.items())
393-
return len(self.errors) + child_errors
395+
return len(self._all_errors) + child_errors
394396

395397

396398
def by_relevance(weak=WEAK_MATCHES, strong=STRONG_MATCHES):

jsonschema/tests/test_exceptions.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,17 @@ def test_it_knows_how_many_total_errors_it_contains(self):
394394
tree = exceptions.ErrorTree(errors)
395395
self.assertEqual(tree.total_errors, 8)
396396

397+
def test_total_errors_counts_duplicate_validators(self):
398+
# Regression test for #442: multiple errors at the same path
399+
# sharing the same validator keyword should all be counted.
400+
errors = [
401+
exceptions.ValidationError("first", validator="type"),
402+
exceptions.ValidationError("second", validator="type"),
403+
exceptions.ValidationError("third", validator="type"),
404+
]
405+
tree = exceptions.ErrorTree(errors)
406+
self.assertEqual(tree.total_errors, 3)
407+
397408
def test_it_contains_an_item_if_the_item_had_an_error(self):
398409
errors = [exceptions.ValidationError("a message", path=["bar"])]
399410
tree = exceptions.ErrorTree(errors)

0 commit comments

Comments
 (0)