views:

65

answers:

2

Dumping and loading a dict with None as key, results in a dict with "null" as the key.

Values are un-affected, but things get even worse if a string-key "null" actually exists.

What am I doing wrong here? Why cant i serialize/deserialize a dict with "None" keys?

Example

>>> json.loads(json.dumps({'123':None, None:'What happened to None?'}))
{u'123': None, u'null': u'What happened to None?'}
>>> json.loads(json.dumps({'123':None, None:'What happened to None?', 'null': 'boom'}))
{u'123': None, u'null': u'boom'}
+1  A: 

According to the specification, None is not a valid key. It would amount to a JSON object expression, which looks like

{ ..., null: ..., ... }

which is not valid (i.e., cannot be generated using the syntax diagram.)

Arguably, the JSON module should have raised an exception upon serialization instead of silently generating a string representation of the value.

EDIT Just saw, that the behaviour of the module is documented (somewhat implicitly):

If skipkeys is True (default: False), then dict keys that are not of a basic type (str, unicode, int, long, float, bool, None) will be skipped instead of raising a TypeError.

so it seems, as if this behaviour is intentional (I still find it questionable given the current JSON specification).

Dirk
skipKeys does not have an effect on the observed behavior."None" is a basic type so skipKeys=True would not cause a "skipping" just as skipKeys=False does not cause a TypeError.I would have liked a small note in the documentation, something like: "For reversible encoding, only use strings as keys."
safl
+3  A: 

JSON objects are maps of strings to values. If you try to use another type of key, they'll get converted to strings.

>>> json.loads(json.dumps({123: None}))
{'123': None}
>>> json.loads(json.dumps({None: None}))
{'null': None}
dan04