Undocumented interaction between kwargs default= and cls= for json.dump() function

Open
#101,332 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
38/100
Issue type
Documentation
Clarity
Mostly clear
Activity status
Stale
Tech stack
python
Domain
documentation

Research direction

Start with the linked json.dump documentation and the supplied reproduction, then verify how default and cls interact. Done means the docs explicitly and accurately state which behavior applies when both kwargs are supplied, with wording consistent with JSONEncoder.default().

Written by the indexing model from the issue text.

Description

docs

Documentation

The current documentation states that "If specified, default should be a function that gets called for objects that can’t otherwise be serialized", and "To use a custom JSONEncoder subclass (e.g. one that overrides the default() method to serialize additional types), specify it with the cls kwarg" (emphasis mine).

This seems to imply that if both default and cls kwargs are provided, the custom JSONEncoder specified for cls will override the function specified for default. (Although honestly it is unclear from the wording what the exact behavior would be if both are specified, since "the default() method" could be referring to the one in the kwarg for dump() or the subclass override in the custom encoder class).

The observed behavior is that the opposite happens: the function specified in the default kwarg will actually override the default() function from the custom JSONEncoder.

Repro steps:

import json
from json import JSONEncoder
from datetime import datetime

class CustomEncoder(JSONEncoder):
    def default(self, o):
        return "foo"

print(json.dumps(datetime.fromisoformat("2023-01-24T12:35:14"), default=lambda x: "bar"))  # prints "bar", as expected
print(json.dumps(datetime.fromisoformat("2023-01-24T12:35:14"), cls=CustomEncoder))  # prints "foo", as expected
print(json.dumps(datetime.fromisoformat("2023-01-24T12:35:14"), cls=CustomEncoder, default=lambda x: "bar"))  # prints "bar" (but documentation seems to imply the _cls_ encoder would override the _default_ function and thus print "foo")
Dominant language
Python
Stars
77.2k
Forks
36k
Avg merge
1d 9h
Merged PRs (30d)
558

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from python/cpython

All issues in python/cpython

Similar issues

More Python issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.