FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Add "array_hook" parameter to JSON decoder · Issue #146440 · python/cpython · GitHub

Repository navigation

Add "array_hook" parameter to JSON decoder #146440

Closed

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

Linked PRs

Activity

  1. serhiy-storchaka commented on Mar 26, 2026

    Member
  2. added
    stdlibStandard Library Python modules in the Lib/ directory
    on Mar 26, 2026
  3. mpkocher commented on Mar 26, 2026

    Contributor

    This seems like a hyper specific use case.

    When would a user use anything other than tuple for array_hook=?

  4. etrepum commented on Mar 26, 2026

    Contributor

    I'm sure there are other hyper specific use cases when the schema of the JSON is well known, such as an array from the array module or numpy

  5. mpkocher commented on Mar 26, 2026

    Contributor

    I'm sure there are other hyper specific use cases when the schema of the JSON is well known, such as an array from the array module or numpy

    Python typically aims for more for the 80/20 or 90/10 sort of model in the std lib, it doesn't really aim to solve hyper specific use cases.

  6. etrepum commented on Mar 26, 2026

    Contributor

    I'm well aware, a frozen=True option might make more sense for most people, but also makes things complicated because it would essentially conflict with object_hook.

    Perhaps an even better solution would be to have a function specifically for decoding to a specific frozendict/tuple representation without the options so the complexity could be handled internally with a private API.

  7. added a commit that references this issue on Mar 27, 2026
  8. vstinner commented on Mar 27, 2026

    Member

    Feature implemented by change d0061d5.

    Example from the added tests:

    $ ./python
    >>> import json
    >>> s = '{"xkd": [[1], [2], [3]]}'
    >>> data = json.loads(s, object_hook=frozendict, array_hook=tuple)
    >>> data
    frozendict({'xkd': ((1,), (2,), (3,))})
    
  9. added a commit that references this issue on Apr 16, 2026
  10. added a commit that references this issue on Apr 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    stdlibStandard Library Python modules in the Lib/ directorytype-featureA feature request or enhancement

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions


      Back | FazBrowse Home | New Git URL