##// END OF EJS Templates
First working draft of new payload system.
Brian Granger -
Show More
@@ -1901,6 +1901,9 b' class InteractiveShell(Configurable, Magic):'
1901 1901 - 1: an error occurred.
1902 1902 """
1903 1903
1904 # Clear the payload before executing new code.
1905 self.payload_manager.clear_payload()
1906
1904 1907 # Set our own excepthook in case the user code tries to call it
1905 1908 # directly, so that the IPython crash handler doesn't get triggered
1906 1909 old_excepthook,sys.excepthook = sys.excepthook, self.excepthook
@@ -32,10 +32,10 b' class PayloadManager(Configurable):'
32 32 def write_payload(self, data):
33 33 if not isinstance(data, dict):
34 34 raise TypeError('Each payload write must be a dict, got: %r' % data)
35 self.payload.append(data)
36
37 def reset_payload(self):
38 self.payload = []
35 self._payload.append(data)
39 36
40 37 def read_payload(self):
41 38 return self._payload
39
40 def clear_payload(self):
41 self._payload = []
@@ -60,20 +60,28 b' class RichIPythonWidget(IPythonWidget):'
60 60 """ Reimplemented to handle matplotlib plot payloads.
61 61 """
62 62 payload = msg['content']['payload']
63 plot_payload = payload.get('plot', None)
64 if plot_payload and plot_payload['format'] == 'svg':
65 svg = plot_payload['data']
66 try:
67 image = svg_to_image(svg)
68 except ValueError:
69 self._append_plain_text('Received invalid plot data.')
70 else:
71 format = self._add_image(image)
72 format.setProperty(self._svg_text_format_property, svg)
73 cursor = self._get_end_cursor()
74 cursor.insertBlock()
75 cursor.insertImage(format)
76 cursor.insertBlock()
63 if payload:
64 for item in payload:
65 if item['type'] == 'plot':
66 if item['format'] == 'svg':
67 svg = item['data']
68 try:
69 image = svg_to_image(svg)
70 except ValueError:
71 self._append_plain_text('Received invalid plot data.')
72 else:
73 format = self._add_image(image)
74 format.setProperty(self._svg_text_format_property, svg)
75 cursor = self._get_end_cursor()
76 cursor.insertBlock()
77 cursor.insertImage(format)
78 cursor.insertBlock()
79 else:
80 # Add other plot formats here!
81 pass
82 else:
83 # Add other payload types here!
84 pass
77 85 else:
78 86 super(RichIPythonWidget, self)._process_execute_ok(msg)
79 87
@@ -49,9 +49,6 b' class Kernel(Configurable):'
49 49 pub_socket = Instance('zmq.Socket')
50 50 req_socket = Instance('zmq.Socket')
51 51
52 # The global kernel instance.
53 _kernel = None
54
55 52 # Maps user-friendly backend names to matplotlib backend identifiers.
56 53 _pylab_map = { 'tk': 'TkAgg',
57 54 'gtk': 'GTKAgg',
@@ -69,9 +66,6 b' class Kernel(Configurable):'
69 66 self.shell.displayhook.session = self.session
70 67 self.shell.displayhook.pub_socket = self.pub_socket
71 68
72 # Protected variables.
73 self._exec_payload = {}
74
75 69 # Build dict of handlers for message types
76 70 msg_types = [ 'execute_request', 'complete_request',
77 71 'object_info_request', 'prompt_request',
@@ -80,11 +74,6 b' class Kernel(Configurable):'
80 74 for msg_type in msg_types:
81 75 self.handlers[msg_type] = getattr(self, msg_type)
82 76
83 def add_exec_payload(self, key, value):
84 """ Adds a key/value pair to the execute payload.
85 """
86 self._exec_payload[key] = value
87
88 77 def activate_pylab(self, backend=None, import_all=True):
89 78 """ Activates pylab in this kernel's namespace.
90 79
@@ -126,21 +115,9 b' class Kernel(Configurable):'
126 115
127 116 matplotlib.interactive(True)
128 117
129 @classmethod
130 def get_kernel(cls):
131 """ Return the global kernel instance or raise a RuntimeError if it does
132 not exist.
133 """
134 if cls._kernel is None:
135 raise RuntimeError("Kernel not started!")
136 else:
137 return cls._kernel
138
139 118 def start(self):
140 119 """ Start the kernel main loop.
141 120 """
142 # Set the global kernel instance.
143 self.__class__._kernel = self
144 121
145 122 while True:
146 123 ident = self.reply_socket.recv()
@@ -169,9 +146,6 b' class Kernel(Configurable):'
169 146 pyin_msg = self.session.msg(u'pyin',{u'code':code}, parent=parent)
170 147 self.pub_socket.send_json(pyin_msg)
171 148
172 # Clear the execute payload from the last request.
173 self._exec_payload = {}
174
175 149 try:
176 150 # Replace raw_input. Note that is not sufficient to replace
177 151 # raw_input in the user namespace.
@@ -182,7 +156,6 b' class Kernel(Configurable):'
182 156 self.shell.displayhook.set_parent(parent)
183 157
184 158 self.shell.runlines(code)
185 # exec comp_code in self.user_ns, self.user_ns
186 159 except:
187 160 etype, evalue, tb = sys.exc_info()
188 161 tb = traceback.format_exception(etype, evalue, tb)
@@ -196,7 +169,11 b' class Kernel(Configurable):'
196 169 self.pub_socket.send_json(exc_msg)
197 170 reply_content = exc_content
198 171 else:
199 reply_content = { 'status' : 'ok', 'payload' : self._exec_payload }
172 payload = self.shell.payload_manager.read_payload()
173 # Be agressive about clearing the payload because we don't want
174 # it to sit in memory until the next execute_request comes in.
175 self.shell.payload_manager.clear_payload()
176 reply_content = { 'status' : 'ok', 'payload' : payload }
200 177
201 178 # Compute the prompt information
202 179 prompt_number = self.shell.displayhook.prompt_count
@@ -2,7 +2,7 b''
2 2 """
3 3
4 4 # Local imports.
5 from IPython.zmq.ipkernel import Kernel
5 from IPython.core.interactiveshell import InteractiveShell
6 6
7 7
8 8 def add_plot_payload(format, data, metadata={}):
@@ -19,5 +19,5 b' def add_plot_payload(format, data, metadata={}):'
19 19 metadata : dict, optional [default empty]
20 20 Allows for specification of additional information about the plot data.
21 21 """
22 payload = dict(format=format, data=data, metadata=metadata)
23 Kernel.get_kernel().add_exec_payload('plot', payload)
22 payload = dict(type='plot', format=format, data=data, metadata=metadata)
23 InteractiveShell.instance().payload_manager.write_payload(payload)
General Comments 0
You need to be logged in to leave comments. Login now