Skip to content

Commit 9f7cae7

Browse files
committed
Don't reorder dicts (particularly schemas) when rendering errors.
Schemas, particularly longer ones, are often written intentionally with their keywords in some specific human-understandable order. pprint, which we currently use (for better or worse) for rendering schemas and instances, supports *not* sorting dicts now that they maintain their insertion order. So we now pass that argument, and thereby preserve the order the schema was written in. Refs: #243
1 parent 0024b58 commit 9f7cae7

File tree

3 files changed

+36
-6
lines changed

3 files changed

+36
-6
lines changed

docs/errors.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -216,8 +216,8 @@ easier debugging.
216216
3 is not valid under any of the given schemas
217217

218218
Failed validating 'anyOf' in schema['items']:
219-
{'anyOf': [{'maxLength': 2, 'type': 'string'},
220-
{'minimum': 5, 'type': 'integer'}]}
219+
{'anyOf': [{'type': 'string', 'maxLength': 2},
220+
{'type': 'integer', 'minimum': 5}]}
221221

222222
On instance[1]:
223223
3

jsonschema/exceptions.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@
2727
_unset = _utils.Unset()
2828

2929

30+
def _pretty(thing: Any, prefix: str):
31+
"""
32+
Format something for an error message as prettily as we currently can.
33+
"""
34+
return indent(pformat(thing, width=72, sort_dicts=False), prefix).lstrip()
35+
36+
3037
def __getattr__(name):
3138
if name == "RefResolutionError":
3239
warnings.warn(
@@ -109,10 +116,10 @@ def __str__(self) -> str:
109116
{self.message}
110117
111118
Failed validating {self.validator!r} in {schema_path}:
112-
{indent(pformat(self.schema, width=72), prefix).lstrip()}
119+
{_pretty(self.schema, prefix=prefix)}
113120
114121
On {instance_path}:
115-
{indent(pformat(self.instance, width=72), prefix).lstrip()}
122+
{_pretty(self.instance, prefix=prefix)}
116123
""".rstrip(),
117124
)
118125

@@ -278,10 +285,10 @@ def __str__(self):
278285
return dedent(
279286
f"""\
280287
Unknown type {self.type!r} for validator with schema:
281-
{indent(pformat(self.schema, width=72), prefix).lstrip()}
288+
{_pretty(self.schema, prefix=prefix)}
282289
283290
While checking instance:
284-
{indent(pformat(self.instance, width=72), prefix).lstrip()}
291+
{_pretty(self.instance, prefix=prefix)}
285292
""".rstrip(),
286293
)
287294

jsonschema/tests/test_exceptions.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,29 @@ def test_uses_pprint(self):
648648
validator="maxLength",
649649
)
650650

651+
def test_does_not_reorder_dicts(self):
652+
self.assertShows(
653+
"""
654+
Failed validating 'type' in schema:
655+
{'do': 3, 'not': 7, 'sort': 37, 'me': 73}
656+
657+
On instance:
658+
{'here': 73, 'too': 37, 'no': 7, 'sorting': 3}
659+
""",
660+
schema={
661+
"do": 3,
662+
"not": 7,
663+
"sort": 37,
664+
"me": 73,
665+
},
666+
instance={
667+
"here": 73,
668+
"too": 37,
669+
"no": 7,
670+
"sorting": 3,
671+
},
672+
)
673+
651674
def test_str_works_with_instances_having_overriden_eq_operator(self):
652675
"""
653676
Check for #164 which rendered exceptions unusable when a

0 commit comments

Comments
 (0)