You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
C version of json.dumps accesses dict internals even for dict subclasses #110941
The optimised JSON encoder disagrees with the normal JSON encoder when encoding the following dict. The example here is as minimalistic as possible but in reality you could imagine the dict being, for example, a copy on write proxy of another dict or something similarly useful.
importjsonclassStaticDict(dict):
'Most minimal dict subclass that still fails'defkeys(self):
return ["a", "b"]
defvalues(self):
return [1, 2]
defitems(self):
returnzip(self.keys(), self.values())
def__len__(self):
return2sd=StaticDict()
c_encoder_version=json.dumps(sd) # {}json.encoder.c_make_encoder=Nonevanilla_version=json.dumps(sd) # {"a": 1, "b": 2}ifc_encoder_version!=vanilla_version:
raiseException(f"JSON C encoder disagrees with regular encoder: {c_encoder_version} != {vanilla_version}")
The culprit looks like this code which blindly assumes that every dict is a regular cpython dict. A related kind of bug affected OrderedDict and was fixed by switching to PyDict_CheckExact in one place. While that was enough to fix OrderedDict, the bug under discussion remains.
Discussion
It has been argued before that json.dump should only handle a very limited set of classes, so for example UserDict might be out of scope. Without taking a stance on which types the module should handle in general, dict certainly is one type json should handle. Since a subclass of a dict is still a dict -- not only does it quack like a duck but it literally is a kind of duck -- it seems reasonable to expect it to function in any context a regular dict does, including for this module. As long as it works like a dict, it should... work like a dict.
Failing that, throwing an exception for dict subclasses would seem the least worst alternative. This would break OrderedDict support but if one takes the json only works with native dicts stance, it should.
Activity
pythongh-110941: Fix `json.dump` encoding dict subclasses as empty.
pythongh-110941: Add NEWS blurb.