From cf6b42724940f6724f9dac99fb8ba99a9dd6c555 2012-02-02 01:03:27
From: Min RK <benjaminrk@gmail.com>
Date: 2012-02-02 01:03:27
Subject: [PATCH] Merge pull request #1364 from minrk/jsonlib

avoid jsonlib returning Decimal

Cleanup jsonlib checking code in IPython.zmq.session for readability, and ensure that floating-point numbers come out of messages as floats instead of Decimal when using jsonlib.
---

diff --git a/IPython/zmq/session.py b/IPython/zmq/session.py
index 06c6e88..e92254d 100644
--- a/IPython/zmq/session.py
+++ b/IPython/zmq/session.py
@@ -73,9 +73,22 @@ def squash_unicode(obj):
 # globals and defaults
 #-----------------------------------------------------------------------------
 
-key = 'on_unknown' if jsonapi.jsonmod.__name__ == 'jsonlib' else 'default'
-json_packer = lambda obj: jsonapi.dumps(obj, **{key:date_default})
-json_unpacker = lambda s: extract_dates(jsonapi.loads(s))
+
+# jsonlib behaves a bit differently, so handle that where it affects us
+if jsonapi.jsonmod.__name__ == 'jsonlib':
+    # kwarg for serializing unknown types (datetime) is different
+    dumps_kwargs = dict(on_unknown=date_default)
+    # By default, jsonlib unpacks floats as Decimal instead of float,
+    # which can foul things up
+    loads_kwargs = dict(use_float=True)
+else:
+    # ISO8601-ify datetime objects
+    dumps_kwargs = dict(default=date_default)
+    # nothing to specify for loads
+    loads_kwargs = dict()
+
+json_packer = lambda obj: jsonapi.dumps(obj, **dumps_kwargs)
+json_unpacker = lambda s: extract_dates(jsonapi.loads(s, **loads_kwargs))
 
 pickle_packer = lambda o: pickle.dumps(o,-1)
 pickle_unpacker = pickle.loads
diff --git a/IPython/zmq/tests/test_session.py b/IPython/zmq/tests/test_session.py
index 5b010ae..33c6bf5 100644
--- a/IPython/zmq/tests/test_session.py
+++ b/IPython/zmq/tests/test_session.py
@@ -59,7 +59,7 @@ class TestSession(SessionTestCase):
         self.assertEquals(msg['msg_type'], 'execute')
 
     def test_serialize(self):
-        msg = self.session.msg('execute',content=dict(a=10))
+        msg = self.session.msg('execute', content=dict(a=10, b=1.1))
         msg_list = self.session.serialize(msg, ident=b'foo')
         ident, msg_list = self.session.feed_identities(msg_list)
         new_msg = self.session.unserialize(msg_list)
@@ -69,6 +69,8 @@ class TestSession(SessionTestCase):
         self.assertEquals(new_msg['header'],msg['header'])
         self.assertEquals(new_msg['content'],msg['content'])
         self.assertEquals(new_msg['parent_header'],msg['parent_header'])
+        # ensure floats don't come out as Decimal:
+        self.assertEquals(type(new_msg['content']['b']),type(new_msg['content']['b']))
 
     def test_send(self):
         socket = MockSocket(zmq.Context.instance(),zmq.PAIR)