From 450d0a586c5e14955a49f8b35695347449644056 2012-07-21 03:16:08 From: Jason Grout Date: 2012-07-21 03:16:08 Subject: [PATCH] Make top-level metadata dictionary not optional. --- diff --git a/IPython/frontend/html/notebook/static/js/kernel.js b/IPython/frontend/html/notebook/static/js/kernel.js index ea80e9e..e446d5c 100644 --- a/IPython/frontend/html/notebook/static/js/kernel.js +++ b/IPython/frontend/html/notebook/static/js/kernel.js @@ -351,7 +351,7 @@ var IPython = (function (IPython) { var reply = $.parseJSON(e.data); var content = reply.content; var msg_type = reply.header.msg_type; - var metadata = reply.metadata || {}; + var metadata = reply.metadata; var callbacks = this.get_callbacks_for_msg(reply.parent_header.msg_id); if (msg_type !== 'status' && callbacks === undefined) { // Message not from one of this notebook's cells and there are no diff --git a/IPython/zmq/session.py b/IPython/zmq/session.py index 6c16c63..b5a7ee6 100644 --- a/IPython/zmq/session.py +++ b/IPython/zmq/session.py @@ -421,11 +421,9 @@ class Session(Configurable): msg['msg_type'] = header['msg_type'] msg['parent_header'] = {} if parent is None else extract_header(parent) msg['content'] = {} if content is None else content - metadata_dict = self.metadata.copy() + msg['metadata'] = self.metadata.copy() if metadata is not None: - metadata_dict.update(metadata) - if metadata_dict: - msg['metadata'] = metadata_dict + msg['metadata'].update(metadata) return msg def sign(self, msg_list): @@ -459,7 +457,7 @@ class Session(Configurable): ------- msg_list : list The list of bytes objects to be sent with the format: - [ident1,ident2,...,DELIM,HMAC,p_header,p_parent,p_content, + [ident1,ident2,...,DELIM,HMAC,p_header,p_parent,p_metadata,p_content, buffer1,buffer2,...]. In this list, the p_* entities are the packed or serialized versions, so if JSON is used, these are utf8 encoded JSON strings. @@ -480,7 +478,8 @@ class Session(Configurable): real_message = [self.pack(msg['header']), self.pack(msg['parent_header']), - content + self.pack(msg['metadata']), + content, ] to_send = [] @@ -607,7 +606,7 @@ class Session(Configurable): The ZMQ stream or socket to use for sending the message. msg_list : list The serialized list of messages to send. This only includes the - [p_header,p_parent,p_content,buffer1,buffer2,...] portion of + [p_header,p_parent,p_metadata,p_content,buffer1,buffer2,...] portion of the message. ident : ident or list A single ident or a list of idents to use in sending. @@ -705,7 +704,7 @@ class Session(Configurable): ----------- msg_list : list of bytes or Message objects The list of message parts of the form [HMAC,p_header,p_parent, - p_content,buffer1,buffer2,...]. + p_metadata,p_content,buffer1,buffer2,...]. content : bool (True) Whether to unpack the content dict (True), or leave it packed (False). @@ -719,7 +718,7 @@ class Session(Configurable): The nested message dict with top-level keys [header, parent_header, content, buffers]. """ - minlen = 4 + minlen = 5 message = {} if not copy: for i in range(minlen): @@ -741,12 +740,13 @@ class Session(Configurable): message['msg_id'] = header['msg_id'] message['msg_type'] = header['msg_type'] message['parent_header'] = self.unpack(msg_list[2]) + message['metadata'] = self.unpack(msg_list[3]) if content: - message['content'] = self.unpack(msg_list[3]) + message['content'] = self.unpack(msg_list[4]) else: - message['content'] = msg_list[3] + message['content'] = msg_list[4] - message['buffers'] = msg_list[4:] + message['buffers'] = msg_list[5:] return message def test_msg2obj(): diff --git a/IPython/zmq/tests/test_session.py b/IPython/zmq/tests/test_session.py index 5a440e6..accc179 100644 --- a/IPython/zmq/tests/test_session.py +++ b/IPython/zmq/tests/test_session.py @@ -47,10 +47,11 @@ class TestSession(SessionTestCase): def test_msg(self): """message format""" msg = self.session.msg('execute') - thekeys = set('header parent_header content msg_type msg_id'.split()) + thekeys = set('header parent_header metadata content msg_type msg_id'.split()) s = set(msg.keys()) self.assertEqual(s, thekeys) self.assertTrue(isinstance(msg['content'],dict)) + self.assertTrue(isinstance(msg['metadata'],dict)) self.assertTrue(isinstance(msg['header'],dict)) self.assertTrue(isinstance(msg['parent_header'],dict)) self.assertTrue(isinstance(msg['msg_id'],str)) @@ -69,6 +70,7 @@ class TestSession(SessionTestCase): self.assertEqual(new_msg['header'],msg['header']) self.assertEqual(new_msg['content'],msg['content']) self.assertEqual(new_msg['parent_header'],msg['parent_header']) + self.assertEqual(new_msg['metadata'],msg['metadata']) # ensure floats don't come out as Decimal: self.assertEqual(type(new_msg['content']['b']),type(new_msg['content']['b'])) @@ -85,6 +87,7 @@ class TestSession(SessionTestCase): self.assertEqual(new_msg['header'],msg['header']) self.assertEqual(new_msg['content'],msg['content']) self.assertEqual(new_msg['parent_header'],msg['parent_header']) + self.assertEqual(new_msg['metadata'],msg['metadata']) self.assertEqual(new_msg['buffers'],[b'bar']) socket.data = [] @@ -92,9 +95,10 @@ class TestSession(SessionTestCase): content = msg['content'] header = msg['header'] parent = msg['parent_header'] + metadata = msg['metadata'] msg_type = header['msg_type'] self.session.send(socket, None, content=content, parent=parent, - header=header, ident=b'foo', buffers=[b'bar']) + header=header, metadata=metadata, ident=b'foo', buffers=[b'bar']) ident, msg_list = self.session.feed_identities(socket.data) new_msg = self.session.unserialize(msg_list) self.assertEqual(ident[0], b'foo') @@ -102,6 +106,7 @@ class TestSession(SessionTestCase): self.assertEqual(new_msg['msg_type'],msg['msg_type']) self.assertEqual(new_msg['header'],msg['header']) self.assertEqual(new_msg['content'],msg['content']) + self.assertEqual(new_msg['metadata'],msg['metadata']) self.assertEqual(new_msg['parent_header'],msg['parent_header']) self.assertEqual(new_msg['buffers'],[b'bar']) @@ -114,6 +119,7 @@ class TestSession(SessionTestCase): self.assertEqual(new_msg['msg_type'],msg['msg_type']) self.assertEqual(new_msg['header'],msg['header']) self.assertEqual(new_msg['content'],msg['content']) + self.assertEqual(new_msg['metadata'],msg['metadata']) self.assertEqual(new_msg['parent_header'],msg['parent_header']) self.assertEqual(new_msg['buffers'],[b'bar']) diff --git a/docs/source/development/messaging.txt b/docs/source/development/messaging.txt index 822ad66..d723b89 100644 --- a/docs/source/development/messaging.txt +++ b/docs/source/development/messaging.txt @@ -106,7 +106,7 @@ A message is defined by the following four-dictionary structure:: # depends on the message type. 'content' : dict, - # Any metadata associated with the message; this dictionary is optional. + # Any metadata associated with the message. 'metadata' : dict, } @@ -130,7 +130,7 @@ messages upon deserialization to the following form for convenience:: 'msg_type' : str, 'parent_header' : dict, 'content' : dict, - 'metadata' : dict, # optional + 'metadata' : dict, } All messages sent to or received by any IPython process should have this