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