-
-
Notifications
You must be signed in to change notification settings - Fork 34.3k
Description
Feature or enhancement
Proposal:
The json.load and .loads in Python are customizable, allowing callbacks to be passed for transforming decoded JSON objects, key/value pairs, integers, floats, json constants - and notably absent is a callback to transform JSON arrays before the final Python object is returned.
With the introduction of frozendict, a combination of passing frozendict to either object_hook or object_pairs_hook, combined with passing tuple as an array_hook callback, is a straightforward way to get an arbitrarily nested imutable data structure.
The advantages of having a structure composed of mappings and sequences, but immutable will be the same that we get for having frozendicts in the first place. In particular, they provide data-structures which can make certain concurrent scenarios in free threading, or when sharing data across sub-interpreters easier to handle.
And, usefulness apart, this certainly addresses an asymmetry in the API, fixing the fact that from all possible JSON literals, just arrays are not directly customizable when decoding.
For sake of completeness, it is possible to replace the resulting lists from decoded JSON arrays in both object_hook and object_pairs_hook callbacks, but (1) that requires writing a full function with a for-loop looking for any lists, instead of, say, just passing a compatible Sequence class, and (2) if the JSON array happens to be the outermost container in the JSON string, this approach won't convert it, requiring some extra-checking in the caller code, after calling json.load.
Current approach:
frozen = json.loads(
json_str, object_hook=lambda dct: frozendict({k: (tuple(v) if isinstance(v, list) else v) for k, v in dct.items()}))
if isinstance(frozen, list):
frozen = tuple(frozen)
With the proposed array_hook parameter:
frozen = json.loads(json_str, object_hook=frozendict, array_hook=tuple)
Has this already been discussed elsewhere?
This is a minor feature, which does not need previous discussion elsewhere
Links to previous discussion of this feature:
Although it is a a minor feature, I've created the Discourse thread for it, where it raised no eyebrows - seemingly, there are no downsides:
https://discuss.python.org/t/add-array-hook-to-json-decoder-options/106304