X Tutup
The Wayback Machine - https://web.archive.org/web/20240111192404/https://github.com/python/cpython/issues/74528
Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Subclassed json.JSONEncoder does not respect default method for supported types #74528

Open
Xophmeister mannequin opened this issue May 11, 2017 · 3 comments
Open

Subclassed json.JSONEncoder does not respect default method for supported types #74528

Xophmeister mannequin opened this issue May 11, 2017 · 3 comments
Labels
stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error

Comments

@Xophmeister
Copy link
Mannequin

Xophmeister mannequin commented May 11, 2017

BPO 30343
Nosy @merwok, @Xophmeister
PRs
  • bpo-30343: New API for JSON encoder to override supported types #1558
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = None
    closed_at = None
    created_at = <Date 2017-05-11.13:58:26.296>
    labels = ['type-bug', 'library']
    title = 'Subclassed json.JSONEncoder does not respect default method for supported types'
    updated_at = <Date 2020-10-19.22:32:36.651>
    user = 'https://github.com/Xophmeister'

    bugs.python.org fields:

    activity = <Date 2020-10-19.22:32:36.651>
    actor = 'eric.araujo'
    assignee = 'none'
    closed = False
    closed_date = None
    closer = None
    components = ['Library (Lib)']
    creation = <Date 2017-05-11.13:58:26.296>
    creator = 'Xophmeister'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 30343
    keywords = []
    message_count = 3.0
    messages = ['293494', '293554', '379046']
    nosy_count = 2.0
    nosy_names = ['eric.araujo', 'Xophmeister']
    pr_nums = ['1558']
    priority = 'normal'
    resolution = None
    stage = None
    status = 'open'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue30343'
    versions = ['Python 3.6']

    @Xophmeister
    Copy link
    Mannequin Author

    Xophmeister mannequin commented May 11, 2017

    If you subclass json.JSONEncoder to enable serialisation of custom types beyond those supported, you are meant to transform values of said type into a serialisable version within an overridden default method. For example:

        class MyJSONEncoder(json.JSONEncoder):
            def default(self, o):
                if isinstance(o, MyType):
                    return str(o)
            # Raise TypeError when we have a type we can't serialise
            super().default(o)
    

    This, however, won't work if your custom type is an instance of one of the supported types. This is because, in Lib/json/encoder.py, the _iterencode function (defined in _make_iterencode) type checks against supported types before it delegates to the default method.

    The reason this came up is because I wanted to serialise a named tuple into a JSON object, with keys corresponding to the named tuple's field names. Ignoring the merits (or otherwise) of this desired outcome, this can't work because a named tuple is still a tuple and thus the default method is never called.

    In Python 2.7, the _iterencode method was part of the JSONEncoder class, so you could override it in a subclass; even if doing so is somewhat brittle. In Python 3, this method has been moved out into the module namespace (tested in 3.6; looking through the repo, it looks like this change was made in Python 3.1), so it can't easily be monkey-patched without it affecting other things.

    I believe this to be a bug. It seems reasonable to subclass at least named tuples, dictionaries and lists in such a way that you'd want a different JSON serialisation to their defaults.

    @Xophmeister Xophmeister mannequin added stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error labels May 11, 2017
    @Xophmeister
    Copy link
    Mannequin Author

    Xophmeister mannequin commented May 12, 2017

    I have written a proof-of-concept implementation and submitted a pull request. See the PR for details: #1558

    (My CLA is pending; submitted around 2017-05-12T10:30:00Z+0100)

    @merwok
    Copy link
    Member

    merwok commented Oct 19, 2020

    See also https://bugs.python.org/issue34858

    This needs a discussion on python-ideas or -dev.

    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error
    Projects
    Status: No status
    Development

    No branches or pull requests

    1 participant
    X Tutup