Sort extra keys when formatting ForbiddenExtraKeysError - #776
Merged
Tinche merged 1 commit intoSep 7, 2026
Merged
Conversation
`ForbiddenExtraKeysError.extra_fields` is a `set`, and `format_exception` in src/cattrs/v.py joined it directly, so `transform_error` put the extra keys in whatever order that set happened to iterate in. String hashing is randomized per process, so the message text changed from run to run once more than one extra key was present, which breaks anything that compares or snapshots the output of `transform_error`. `ForbiddenExtraKeysError.__str__` in src/cattrs/errors.py already sorts the same set, so the two renderings of one error disagreed as well. Sort the keys in `format_exception` too, and add a regression test with five extra keys, since the existing test only used one and could not observe the ordering.
Member
|
LGTM, thanks! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
transform_errorreports the extra keys of aForbiddenExtraKeysErrorin a different order on every run.ForbiddenExtraKeysError.extra_fieldsis aset, andformat_exceptioninsrc/cattrs/v.pyline 44 joins it as it comes:res = f"extra fields found ({', '.join(exc.extra_fields)})". String hashing is randomized per process, so the message text changes between runs as soon as there is more than one extra key, and anything that compares or snapshots the output oftransform_errorfails intermittently.ForbiddenExtraKeysError.__str__insrc/cattrs/errors.pyline 141 already sorts the same set, so the two renderings of a single error disagree with each other too.Three runs of that, on
main:The fix is to sort in
format_exceptionas well. The regression test uses five extra keys, because the existingtest_class_errorsonly ever produces one and so cannot see an ordering at all.Verification, all on the branch unless stated otherwise:
uv run --all-extras --group test --group lint pytest tests/test_v.py::test_extra_keys_are_sorted -qunderPYTHONHASHSEED1 through 8 with the test applied to unmodifiedmain: 8 failures out of 8, for exampleAt index 0 diff: 'extra fields found (c, d, b, e) @ $' != 'extra fields found (b, c, d, e) @ $'. The same command ontests/test_v.pywith the fix underPYTHONHASHSEED1 through 12: 12 passes out of 12.uv run --all-extras --group test --group lint pytest -n 2 tests -qon 3.11: 941 passed, 15 xfailed.uv run -p <version> ... pytest tests/test_v.py -qon 3.10, 3.11, 3.14 and pypy3.10: 10 passed each. I ran pypy without--all-extrasbecauseujsonhas no pypy wheel on macOS, which is unrelated to this change.uv run -p python3.14 --group lint ruff check src/ tests bench: All checks passed.uv run -p python3.14 --group lint ruff format --check src tests docs/conf.py: 115 files already formatted.