Skip to content

Commit 5478cd3

Browse files
committed
docs: document why json_dumps requires sorted keys for cache hashing
Add comprehensive docstring to json_dumps() explaining that key sorting is critical for deterministic JSON output, which is used to compute cache hashes in incremental type checking. Without sorted keys, dictionaries with the same content but different key insertion order would produce different hashes, causing incorrect cache invalidation. This addresses the TODO comment and clarifies the relationship between JSON serialization and the caching system.
1 parent eabda0e commit 5478cd3

1 file changed

Lines changed: 13 additions & 3 deletions

File tree

mypy/util.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -925,12 +925,23 @@ def quote_docstring(docstr: str) -> str:
925925

926926

927927
def json_dumps(obj: object, debug: bool = False) -> bytes:
928+
"""Serialize an object to JSON bytes.
929+
930+
Keys are always sorted to ensure deterministic output. This is critical for
931+
incremental type checking: the JSON output is used to compute cache hashes
932+
(via hash_digest/hash_digest_bytes in build.py). Without key sorting, dictionaries
933+
with the same content but different key insertion order would produce different
934+
JSON strings, leading to different hashes and incorrect cache invalidation.
935+
936+
For example, in testIncrementalInternalScramble, the test verifies that mypy
937+
correctly handles incremental updates. If keys weren't sorted, the cache hash
938+
would change even when the actual content is the same, causing unnecessary
939+
re-checking and test failures.
940+
"""
928941
if orjson is not None:
929942
if debug:
930943
dumps_option = orjson.OPT_INDENT_2 | orjson.OPT_SORT_KEYS
931944
else:
932-
# TODO: If we don't sort keys here, testIncrementalInternalScramble fails
933-
# We should document exactly what is going on there
934945
dumps_option = orjson.OPT_SORT_KEYS
935946

936947
try:
@@ -942,7 +953,6 @@ def json_dumps(obj: object, debug: bool = False) -> bytes:
942953
if debug:
943954
return json.dumps(obj, indent=2, sort_keys=True).encode("utf-8")
944955
else:
945-
# See above for sort_keys comment
946956
return json.dumps(obj, sort_keys=True, separators=(",", ":")).encode("utf-8")
947957

948958

0 commit comments

Comments
 (0)