Skip to content

fix: prevent ErrorTree index access from mutating iteration#1469

Closed
BlocksecPHD wants to merge 3 commits intopython-jsonschema:mainfrom
BlocksecPHD:fix/errortree-index-mutation-1328
Closed

fix: prevent ErrorTree index access from mutating iteration#1469
BlocksecPHD wants to merge 3 commits intopython-jsonschema:mainfrom
BlocksecPHD:fix/errortree-index-mutation-1328

Conversation

@BlocksecPHD
Copy link
Copy Markdown

Summary

Fixes #1328

The Bug: Accessing an index in that has no error incorrectly adds that index to the tree's iteration. This violates the documented behavior that should iterate over "indices in the instance with errors".

Root Cause: is a , and used which auto-creates entries for missing keys.

Fix:

  1. In , explicitly create child trees and add to instead of relying on mutation
  2. In , check if index exists in first, and return an empty without mutation if not

Before the fix:

tree = ErrorTree([ValidationError(path=['foo'], instance={'foo': 'bar', 'baz': 'qux'})])
print(list(tree))  # ['foo']
child = tree['baz']  # Access valid but error-free index
print(list(tree))  # BUG: ['foo', 'baz'] - mutation happened!

After the fix:

tree = ErrorTree([ValidationError(path=['foo'], instance={'foo': 'bar', 'baz': 'qux'})])
print(list(tree))  # ['foo']
child = tree['baz']  # Access valid but error-free index
print(list(tree))  # ['foo'] - no mutation!

Tests

Added 3 new tests to verify the fix:

  • test_index_access_does_not_mutate_tree - basic mutation fix test
  • test_nested_index_access_does_not_mutate_tree - nested path mutation test
  • test_index_access_on_empty_tree_returns_empty_tree - empty tree edge case

All 7291 existing tests continue to pass.

Funan Zhou and others added 2 commits March 29, 2026 05:10
Issue python-jsonschema#1328: Accessing an index in ErrorTree that has no error
incorrectly adds that index to the tree's iteration. This violates
the documented behavior that __iter__ iterates over 'indices in
the instance with errors'.

The root cause was that _contents is a defaultdict, and __getitem__
used defaultdict.__getitem__ which auto-creates entries for missing
keys.

Fix by:
1. In __init__, explicitly create child trees and add to _contents
   instead of relying on __getitem__ mutation
2. In __getitem__, check if index exists in _contents first, and
   return an empty ErrorTree without mutation if not

Added tests to verify the fix.
@read-the-docs-community
Copy link
Copy Markdown

read-the-docs-community bot commented Mar 28, 2026

Documentation build overview

📚 python-jsonschema | 🛠️ Build #32020459 | 📁 Comparing 2be21cc against latest (ad0a1b3)


🔍 Preview build

Show files changed (1 files in total): 📝 1 modified | ➕ 0 added | ➖ 0 deleted
File Status
_modules/jsonschema/exceptions/index.html 📝 modified

@Julian Julian closed this Mar 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The return of __iter__() and __contains__() change after accessing of an index with no error

2 participants