Message293494
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. |
|
Date |
User |
Action |
Args |
2017-05-11 13:58:26 | Xophmeister | set | recipients:
+ Xophmeister |
2017-05-11 13:58:26 | Xophmeister | set | messageid: <1494511106.37.0.544159404801.issue30343@psf.upfronthosting.co.za> |
2017-05-11 13:58:26 | Xophmeister | link | issue30343 messages |
2017-05-11 13:58:25 | Xophmeister | create | |
|