Running JSON through Python's eval()?

json, python

Solution

If you're comfortable with your script working fine for a while, and then randomly failing on some obscure edge case, I would go with eval.

If it's important that your code be robust, I would take the time to add simplejson. You don't need the C portion for speedups, so it really shouldn't be hard to dump a few .py files into a directory somewhere.

As an example of something that might bite you, JSON uses Unicode and simplejson returns Unicode, whereas eval returns str:

>>> simplejson.loads('{"a":1, "b":2}')
{u'a': 1, u'b': 2}
>>> eval('{"a":1, "b":2}')
{'a': 1, 'b': 2}

Edit: a better example of where eval() behaves differently:

>>> simplejson.loads('{"X": "\uabcd"}')
{u'X': u'\uabcd'}
>>> eval('{"X": "\uabcd"}')
{'X': '\\uabcd'}
>>> simplejson.loads('{"X": "\uabcd"}') == eval('{"X": "\uabcd"}')
False

Edit 2: saw yet another problem today pointed out by SilentGhost: eval doesn't handle true -> True, false -> False, null -> None correctly.

>>> simplejson.loads('[false, true, null]')
[False, True, None]
>>> eval('[false, true, null]')
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
  File "<string>", line 1, in <module>
NameError: name 'false' is not defined
>>> 

Problem

DO NOT DO THIS. This question is still getting upvotes, so I wanted to add a warning to it. If you're using Python 3, just use the included `json` package. If you're using Python 2, do everything you can to move to Python 3. If you're prevented from using Python 3 (my condolences), use the simplejson package suggested by James Thompson. Original question follows. Best practices aside, is there a compelling reason not to do this? I'm writing a post-commit hook for use with a Google Code project, which provides commit data via a JSON object. GC provides an HMAC authentication token along with the request (outside the JSON data), so by validating that token I gain high confidence that the JSON data is both benign (as there's little point in distrusting Google) and valid. My own (brief) investigations suggest that JSON happens to be completely valid Python, with the exception of the `"\/"` escape sequence — which GC doesn't appear to generate. So, as I'm working with Python 2.4 (i.e. no `json` module), `eval()` is looking really tempting. Edit: For the record, I am very much not asking if this is a good idea. I'm quite aware that it isn't, and I very much doubt I'll ever use this technique for any future projects even if I end up using it for this one. I just wanted to make sure that I know what kind of trouble I'll run into if I do. :-)

Original source