{"id":266,"date":"2013-08-01T17:23:29","date_gmt":"2013-08-01T16:23:29","guid":{"rendered":"http:\/\/mod16.org\/hurfdurf\/?p=266"},"modified":"2013-08-01T17:28:15","modified_gmt":"2013-08-01T16:28:15","slug":"use-of-ultrajson-considered-harmful","status":"publish","type":"post","link":"https:\/\/mod16.org\/hurfdurf\/?p=266","title":{"rendered":"Use of ultrajson considered harmful"},"content":{"rendered":"<p>Someone at work got the idea that we should use <a href=\"https:\/\/github.com\/esnme\/ultrajson\">this Python JSON library called ultrajson<\/a> because apparently the standard Python json library was slow, or something. Well, we did end up using it, and it turned out to be a Bad Idea.<\/p>\n<p>The standard JSON library in Python, which ujson is intended to be a drop-in replacement for, handles errors in a sane and Pythonic way. For example, if you attempt to serialize something that obviously doesn&#8217;t have a reasonable JSON representation, such as a Python function:<\/p>\n<pre>\r\n>>> def b():\r\n...  pass\r\n... \r\n>>> json.dumps({'test': b})\r\nTraceback (most recent call last):\r\n  File \"&lt;stdin&gt;\", line 1, in <module>\r\n  File \"\/System\/Library\/Frameworks\/Python.framework\/Versions\/2.7\/lib\/python2.7\/json\/__init__.py\", line 231, in dumps\r\n    return _default_encoder.encode(obj)\r\n  File \"\/System\/Library\/Frameworks\/Python.framework\/Versions\/2.7\/lib\/python2.7\/json\/encoder.py\", line 201, in encode\r\n    chunks = self.iterencode(o, _one_shot=True)\r\n  File \"\/System\/Library\/Frameworks\/Python.framework\/Versions\/2.7\/lib\/python2.7\/json\/encoder.py\", line 264, in iterencode\r\n    return _iterencode(o, 0)\r\n  File \"\/System\/Library\/Frameworks\/Python.framework\/Versions\/2.7\/lib\/python2.7\/json\/encoder.py\", line 178, in default\r\n    raise TypeError(repr(o) + \" is not JSON serializable\")\r\nTypeError: &lt;function b at 0x1056b3398&gt; is not JSON serializable\r\n<\/pre>\n<p>TypeError, of course. The programmer immediately realizes what the problem is and how to fix it.<\/p>\n<p>Let&#8217;s see what ultrajson does with, say, a Python object.<\/p>\n<pre>\r\n>>> class Test(object):\r\n...  def t(self):\r\n...   print \"hello\"\r\n... \r\n>>> t = Test()\r\n>>> ujson.dumps({'a': t})\r\n'{\"a\":{}}'\r\n<\/pre>\n<p>Yep, it apparently serializes a lot of things it doesn&#8217;t want to deal with as empty JSON objects. Silent failure, the king of error handling. We had a funny bug caused by this; thankfully it never made it to production.<\/p>\n<p>What if I try to serialize something else? Like, say, a function?<\/p>\n<pre>\r\n>>> def b():\r\n...  pass\r\n... \r\n>>> ujson.dumps({'a': b})\r\nTraceback (most recent call last):\r\n  File \"&lt;stdin&gt;\", line 1, in <module>\r\nOverflowError: Maximum recursion level reached\r\n<\/pre>\n<p>Wonderful. I hope I don&#8217;t have to explain why this stinks and how much. Please spread the word and save the world from the potential bugs caused by this terrible library.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Someone at work got the idea that we should use this Python JSON library called ultrajson because apparently the standard Python json library was slow, or something. Well, we did end up using it, and it turned out to be a Bad Idea. The standard JSON library in Python, which ujson is intended to be [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11,8],"tags":[],"class_list":["post-266","post","type-post","status-publish","format-standard","hentry","category-coding","category-morons"],"_links":{"self":[{"href":"https:\/\/mod16.org\/hurfdurf\/index.php?rest_route=\/wp\/v2\/posts\/266","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mod16.org\/hurfdurf\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mod16.org\/hurfdurf\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mod16.org\/hurfdurf\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mod16.org\/hurfdurf\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=266"}],"version-history":[{"count":6,"href":"https:\/\/mod16.org\/hurfdurf\/index.php?rest_route=\/wp\/v2\/posts\/266\/revisions"}],"predecessor-version":[{"id":273,"href":"https:\/\/mod16.org\/hurfdurf\/index.php?rest_route=\/wp\/v2\/posts\/266\/revisions\/273"}],"wp:attachment":[{"href":"https:\/\/mod16.org\/hurfdurf\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=266"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mod16.org\/hurfdurf\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=266"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mod16.org\/hurfdurf\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=266"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}