##// END OF EJS Templates
Merge pull request #3765 from minrk/console-is-bad...
Min RK -
r11763:60cf5d83 merge
parent child Browse files
Show More
@@ -43,6 +43,7 from IPython.terminal.console.completer import ZMQCompleter
43 class ZMQTerminalInteractiveShell(TerminalInteractiveShell):
43 class ZMQTerminalInteractiveShell(TerminalInteractiveShell):
44 """A subclass of TerminalInteractiveShell that uses the 0MQ kernel"""
44 """A subclass of TerminalInteractiveShell that uses the 0MQ kernel"""
45 _executing = False
45 _executing = False
46 _execution_state = Unicode('')
46
47
47 image_handler = Enum(('PIL', 'stream', 'tempfile', 'callable'),
48 image_handler = Enum(('PIL', 'stream', 'tempfile', 'callable'),
48 config=True, help=
49 config=True, help=
@@ -151,32 +152,42 class ZMQTerminalInteractiveShell(TerminalInteractiveShell):
151 # explicitly handle 'exit' command
152 # explicitly handle 'exit' command
152 return self.ask_exit()
153 return self.ask_exit()
153
154
154 self._executing = True
155 # flush stale replies, which could have been ignored, due to missed heartbeats
155 # flush stale replies, which could have been ignored, due to missed heartbeats
156 while self.client.shell_channel.msg_ready():
156 while self.client.shell_channel.msg_ready():
157 self.client.shell_channel.get_msg()
157 self.client.shell_channel.get_msg()
158 # shell_channel.execute takes 'hidden', which is the inverse of store_hist
158 # shell_channel.execute takes 'hidden', which is the inverse of store_hist
159 msg_id = self.client.shell_channel.execute(cell, not store_history)
159 msg_id = self.client.shell_channel.execute(cell, not store_history)
160 while not self.client.shell_channel.msg_ready() and self.client.is_alive():
160
161 # first thing is wait for any side effects (output, stdin, etc.)
162 self._executing = True
163 self._execution_state = "busy"
164 while self._execution_state != 'idle' and self.client.is_alive():
161 try:
165 try:
162 self.handle_stdin_request(timeout=0.05)
166 self.handle_stdin_request(msg_id, timeout=0.05)
163 except Empty:
167 except Empty:
164 # display intermediate print statements, etc.
168 # display intermediate print statements, etc.
165 self.handle_iopub()
169 self.handle_iopub(msg_id)
170 pass
171
172 # after all of that is done, wait for the execute reply
173 while self.client.is_alive():
174 try:
175 self.handle_execute_reply(msg_id, timeout=0.05)
176 except Empty:
166 pass
177 pass
167 if self.client.shell_channel.msg_ready():
178 else:
168 self.handle_execute_reply(msg_id)
179 break
169 self._executing = False
180 self._executing = False
170
181
171 #-----------------
182 #-----------------
172 # message handlers
183 # message handlers
173 #-----------------
184 #-----------------
174
185
175 def handle_execute_reply(self, msg_id):
186 def handle_execute_reply(self, msg_id, timeout=None):
176 msg = self.client.shell_channel.get_msg()
187 msg = self.client.shell_channel.get_msg(block=False, timeout=timeout)
177 if msg["parent_header"].get("msg_id", None) == msg_id:
188 if msg["parent_header"].get("msg_id", None) == msg_id:
178
189
179 self.handle_iopub()
190 self.handle_iopub(msg_id)
180
191
181 content = msg["content"]
192 content = msg["content"]
182 status = content['status']
193 status = content['status']
@@ -198,24 +209,25 class ZMQTerminalInteractiveShell(TerminalInteractiveShell):
198 self.execution_count = int(content["execution_count"] + 1)
209 self.execution_count = int(content["execution_count"] + 1)
199
210
200
211
201 def handle_iopub(self):
212 def handle_iopub(self, msg_id):
202 """ Method to procces subscribe channel's messages
213 """ Method to process subscribe channel's messages
203
214
204 This method reads a message and processes the content in different
215 This method consumes and processes messages on the IOPub channel,
205 outputs like stdout, stderr, pyout and status
216 such as stdout, stderr, pyout and status.
206
217
207 Arguments:
218 It only displays output that is caused by the given msg_id
208 sub_msg: message receive from kernel in the sub socket channel
209 capture by kernel manager.
210 """
219 """
211 while self.client.iopub_channel.msg_ready():
220 while self.client.iopub_channel.msg_ready():
212 sub_msg = self.client.iopub_channel.get_msg()
221 sub_msg = self.client.iopub_channel.get_msg()
213 msg_type = sub_msg['header']['msg_type']
222 msg_type = sub_msg['header']['msg_type']
214 parent = sub_msg["parent_header"]
223 parent = sub_msg["parent_header"]
215 if (not parent) or self.session_id == parent['session']:
224 if (not parent) or msg_id == parent['msg_id']:
216 if msg_type == 'status' :
225 if msg_type == 'status':
217 if sub_msg["content"]["execution_state"] == "busy" :
226 state = self._execution_state = sub_msg["content"]["execution_state"]
218 pass
227 # idle messages mean an individual sequence is complete,
228 # so break out of consumption to allow other things to take over.
229 if state == 'idle':
230 break
219
231
220 elif msg_type == 'stream' :
232 elif msg_type == 'stream':
221 if sub_msg["content"]["name"] == "stdout":
233 if sub_msg["content"]["name"] == "stdout":
@@ -240,6 +252,7 class ZMQTerminalInteractiveShell(TerminalInteractiveShell):
240 elif msg_type == 'display_data':
252 elif msg_type == 'display_data':
241 self.handle_rich_data(sub_msg["content"]["data"])
253 self.handle_rich_data(sub_msg["content"]["data"])
242
254
255
243 _imagemime = {
256 _imagemime = {
244 'image/png': 'png',
257 'image/png': 'png',
245 'image/jpeg': 'jpeg',
258 'image/jpeg': 'jpeg',
@@ -292,13 +305,13 class ZMQTerminalInteractiveShell(TerminalInteractiveShell):
292 def handle_image_callable(self, data, mime):
305 def handle_image_callable(self, data, mime):
293 self.callable_image_handler(data)
306 self.callable_image_handler(data)
294
307
295 def handle_stdin_request(self, timeout=0.1):
308 def handle_stdin_request(self, msg_id, timeout=0.1):
296 """ Method to capture raw_input
309 """ Method to capture raw_input
297 """
310 """
298 msg_rep = self.client.stdin_channel.get_msg(timeout=timeout)
311 msg_rep = self.client.stdin_channel.get_msg(timeout=timeout)
299 # in case any iopub came while we were waiting:
312 # in case any iopub came while we were waiting:
300 self.handle_iopub()
313 self.handle_iopub(msg_id)
301 if self.session_id == msg_rep["parent_header"].get("session"):
314 if msg_id == msg_rep["parent_header"].get("msg_id"):
302 # wrap SIGINT handler
315 # wrap SIGINT handler
303 real_handler = signal.getsignal(signal.SIGINT)
316 real_handler = signal.getsignal(signal.SIGINT)
304 def double_int(sig,frame):
317 def double_int(sig,frame):
@@ -373,7 +386,7 class ZMQTerminalInteractiveShell(TerminalInteractiveShell):
373 # run a non-empty no-op, so that we don't get a prompt until
386 # run a non-empty no-op, so that we don't get a prompt until
374 # we know the kernel is ready. This keeps the connection
387 # we know the kernel is ready. This keeps the connection
375 # message above the first prompt.
388 # message above the first prompt.
376 if not self.wait_for_kernel(3):
389 if not self.wait_for_kernel(10):
377 error("Kernel did not respond\n")
390 error("Kernel did not respond\n")
378 return
391 return
379
392
@@ -394,7 +407,7 class ZMQTerminalInteractiveShell(TerminalInteractiveShell):
394 if ans:
407 if ans:
395 if self.manager:
408 if self.manager:
396 self.manager.restart_kernel(True)
409 self.manager.restart_kernel(True)
397 self.wait_for_kernel(3)
410 self.wait_for_kernel(10)
398 else:
411 else:
399 self.exit_now = True
412 self.exit_now = True
400 continue
413 continue
General Comments 0
You need to be logged in to leave comments. Login now