From d76b3bece60617b2df62ac57a47a8f92c318d7d2 2013-10-23 02:40:35
From: MinRK <benjaminrk@gmail.com>
Date: 2013-10-23 02:40:35
Subject: [PATCH] hook up output for comm messages

---

diff --git a/IPython/html/static/notebook/js/comm.js b/IPython/html/static/notebook/js/comm.js
index 6969ef8..38fafa8 100644
--- a/IPython/html/static/notebook/js/comm.js
+++ b/IPython/html/static/notebook/js/comm.js
@@ -97,35 +97,35 @@ var IPython = (function (IPython) {
     //-----------------------------------------------------------------------
     
     var Comm = function (comm_id, target) {
-        this.comm_id = comm_id;
+        this.comm_id = comm_id || new IPython.utils.uuid();
         this.target = target || 'comm';
         this._msg_callback = this._open_callback = this._close_callback = null;
     };
     
     // methods for sending messages
-    Comm.prototype.open = function (data) {
+    Comm.prototype.open = function (data, callbacks) {
         var content = {
             comm_id : this.comm_id,
             target : this.target,
             data : data || {},
         };
-        this.kernel.send_shell_message("comm_open", content);
+        return this.kernel.send_shell_message("comm_open", content, callbacks);
     };
     
-    Comm.prototype.send = function (data) {
+    Comm.prototype.send = function (data, callbacks) {
         var content = {
             comm_id : this.comm_id,
             data : data || {},
         };
-        return this.kernel.send_shell_message("comm_msg", content);
+        return this.kernel.send_shell_message("comm_msg", content, callbacks);
     };
     
-    Comm.prototype.close = function (data) {
+    Comm.prototype.close = function (data, callbacks) {
         var content = {
             comm_id : this.comm_id,
             data : data || {},
         };
-        return this.kernel.send_shell_message("comm_close", content);
+        return this.kernel.send_shell_message("comm_close", content, callbacks);
     };
     
     // methods for registering callbacks for incoming messages
@@ -144,7 +144,7 @@ var IPython = (function (IPython) {
     Comm.prototype.on_close = function (callback) {
         this._register_callback('close', callback);
     };
-
+    
     // methods for handling incoming messages
     
     Comm.prototype._maybe_callback = function (key, msg) {
@@ -166,7 +166,7 @@ var IPython = (function (IPython) {
     
     IPython.CommManager = CommManager;
     IPython.Comm = Comm;
-
+    
     return IPython;
 
 }(IPython));
diff --git a/IPython/kernel/comm/manager.py b/IPython/kernel/comm/manager.py
index 981dde6..54abae6 100644
--- a/IPython/kernel/comm/manager.py
+++ b/IPython/kernel/comm/manager.py
@@ -11,6 +11,8 @@
 # Imports
 #-----------------------------------------------------------------------------
 
+import sys
+
 from IPython.config import LoggingConfigurable
 from IPython.core.prompts import LazyEvaluate
 from IPython.core.getipython import get_ipython
@@ -33,6 +35,23 @@ def lazy_keys(dikt):
     return LazyEvaluate(lambda d: list(d.keys()))
 
 
+def with_output(method):
+    """method decorator for ensuring output is handled properly in a message handler
+    
+    - sets parent header before entering the method
+    - flushes stdout/stderr after
+    """
+    def method_with_output(self, stream, ident, msg):
+        self.shell.set_parent(msg['header'])
+        try:
+            return method(self, stream, ident, msg)
+        finally:
+            sys.stdout.flush()
+            sys.stderr.flush()
+    
+    return method_with_output
+
+
 class CommManager(LoggingConfigurable):
     """Manager for Comms in the Kernel"""
     
@@ -97,7 +116,7 @@ class CommManager(LoggingConfigurable):
         return comm
     
     # Message handlers
-    
+    @with_output
     def comm_open(self, stream, ident, msg):
         """Handler for comm_open messages"""
         content = msg['content']
@@ -117,6 +136,7 @@ class CommManager(LoggingConfigurable):
         comm.handle_open(msg)
         self.register_comm(comm)
     
+    @with_output
     def comm_msg(self, stream, ident, msg):
         """Handler for comm_msg messages"""
         content = msg['content']
@@ -127,6 +147,7 @@ class CommManager(LoggingConfigurable):
             return
         comm.handle_msg(msg)
     
+    @with_output
     def comm_close(self, stream, ident, msg):
         """Handler for comm_close messages"""
         content = msg['content']