This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: json.dumps converts None to "null" (not null)
Type: behavior Stage: resolved
Components: Documentation Versions: Python 3.0, Python 3.1, Python 2.6
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: bob.ippolito Nosy List: bob.ippolito, eric.araujo, exarkun, kirubakaran, python-dev, srid, valhallasw
Priority: normal Keywords: patch

Created on 2009-07-24 21:07 by srid, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
6566.2.7.patch kirubakaran, 2012-03-17 07:31 Patch for 2.7
6566.3.3.patch kirubakaran, 2012-03-17 07:32 Patch for 3.3
Messages (13)
msg90896 - (view) Author: Sridhar Ratnakumar (srid) Date: 2009-07-24 21:07
In [2]: json.dumps({'a': 1, 'b': {'c': 3, None: 5}})
Out[2]: '{"a": 1, "b": {"c": 3, "null": 5}}'

In [3]: j = json.dumps({'a': 1, 'b': {'c': 3, None: 5}})

In [4]: json.loads(j)
Out[4]: {u'a': 1, u'b': {u'c': 3, u'null': 5}}

I was surprised to note that None was converted to "null" instead of 
null. This happens only in dicts and not, for example, lists:

In [5]: json.dumps([None, 1, "a"])
Out[5]: '[null, 1, "a"]'
msg90897 - (view) Author: Sridhar Ratnakumar (srid) Date: 2009-07-24 21:09
The simplest repro:

In [6]: json.dumps({None: 3})
Out[6]: '{"null": 3}'

In [7]: json.loads(json.dumps({None: 3}))
Out[7]: {u'null': 3}
msg90898 - (view) Author: Sridhar Ratnakumar (srid) Date: 2009-07-24 21:13
Also repros on 3.0/3.1
msg90899 - (view) Author: Jean-Paul Calderone (exarkun) * (Python committer) Date: 2009-07-24 21:13
Notice what it does to other dict keys:

    >>> simplejson.dumps({1: 1})
    '{"1": 1}'

In other words, I don't think this is a bug.  It's how JSON works.  JSON
dict keys are strings *only*.
msg90900 - (view) Author: Sridhar Ratnakumar (srid) Date: 2009-07-24 21:17
> JSON dict keys are strings *only*.

I might be helpful to point this out (along with other caveats) in the 
standard library documentation for JSON.

An explicit mention of ``loads(dumps(x)) != x for certain structures`` 
would be nice.

I, sir, was genuinely surprised to discover this.
msg90934 - (view) Author: Bob Ippolito (bob.ippolito) * (Python committer) Date: 2009-07-26 04:52
JP is correct, this is how JSON works. The behavior of coercing keys to 
strings is often desirable, although I agree it could be confusing if you 
aren't familiar with the JSON spec.
msg156142 - (view) Author: Kirubakaran Athmanathan (kirubakaran) Date: 2012-03-17 07:31
Here is the patch that fixes for 2.7
msg156143 - (view) Author: Kirubakaran Athmanathan (kirubakaran) Date: 2012-03-17 07:32
Here is the patch that fixes for 3.3
msg156144 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2012-03-17 07:41
New changeset 7c818b4cd98a by Senthil Kumaran in branch '2.7':
explain json.dumps for non-string keys in dicts. closes issue6566. Patch contributed Kirubakaran Athmanathan
http://hg.python.org/cpython/rev/7c818b4cd98a

New changeset 613919591a05 by Senthil Kumaran in branch '3.2':
3.2 explain json.dumps for non-string keys in dicts. closes issue6566. Patch contributed Kirubakaran Athmanathan
http://hg.python.org/cpython/rev/613919591a05

New changeset 0554183066b5 by Senthil Kumaran in branch 'default':
merge from 3.2 - issue6566
http://hg.python.org/cpython/rev/0554183066b5
msg156163 - (view) Author: Éric Araujo (eric.araujo) * (Python committer) Date: 2012-03-17 15:56
Shouldn’t the 2.7 docs talk about str and unicode, or maybe basestring, instead of just str?
msg156174 - (view) Author: Kirubakaran Athmanathan (kirubakaran) Date: 2012-03-17 16:33
The note added "Keys in key/value pairs of JSON are always of the type
str. When a dictionary is converted into JSON, all the keys of the
dictionary are coerced to strings." is true for unicode keys too.

'{"foo": "bar"}'
msg156175 - (view) Author: Kirubakaran Athmanathan (kirubakaran) Date: 2012-03-17 16:34
json.dumps({u'foo':'bar'})
'{"foo": "bar"}'
msg156176 - (view) Author: Merlijn van Deen (valhallasw) * Date: 2012-03-17 16:37
JSON does not have the distinction between bytes and unicode; py2 strings are coerced into unicode.

I think it would be better to speak about 'JSON string' or 'JSON string element' if it's JSON and about 'unicode' (2.7) or 'str' (3.x) when speaking about the data that has been decoded again.

>>> json.loads(json.dumps("boo"))
u'boo'
>>> json.loads(json.dumps({"a": "b"}))
{u'a': u'b'}

(the keys will always be unicode in 2.7)
History
Date User Action Args
2022-04-11 14:56:51adminsetgithub: 50815
2012-03-17 16:37:46valhallaswsetnosy: + valhallasw
messages: + msg156176
2012-03-17 16:34:49kirubakaransetmessages: + msg156175
2012-03-17 16:33:28kirubakaransetmessages: + msg156174
2012-03-17 15:56:22eric.araujosetnosy: + eric.araujo
messages: + msg156163
2012-03-17 07:41:26python-devsetstatus: closed

nosy: + python-dev
messages: + msg156144

resolution: fixed
stage: resolved
2012-03-17 07:32:31kirubakaransetfiles: + 6566.3.3.patch

messages: + msg156143
2012-03-17 07:31:40kirubakaransetfiles: + 6566.2.7.patch

nosy: + kirubakaran
messages: + msg156142

keywords: + patch
2009-07-26 04:52:15bob.ippolitosetnosy: bob.ippolito, exarkun, srid
messages: + msg90934
components: + Documentation, - Library (Lib)
2009-07-24 21:17:35sridsetmessages: + msg90900
2009-07-24 21:13:34exarkunsetnosy: + exarkun
messages: + msg90899
2009-07-24 21:13:14sridsetmessages: + msg90898
versions: + Python 3.0, Python 3.1
2009-07-24 21:11:48benjamin.petersonsetstatus: open -> (no value)
assignee: bob.ippolito

nosy: + bob.ippolito
2009-07-24 21:09:01sridsetmessages: + msg90897
2009-07-24 21:07:57sridcreate