##// 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 b' from IPython.terminal.console.completer import ZMQCompleter'
43 43 class ZMQTerminalInteractiveShell(TerminalInteractiveShell):
44 44 """A subclass of TerminalInteractiveShell that uses the 0MQ kernel"""
45 45 _executing = False
46 _execution_state = Unicode('')
46 47
47 48 image_handler = Enum(('PIL', 'stream', 'tempfile', 'callable'),
48 49 config=True, help=
@@ -151,32 +152,42 b' class ZMQTerminalInteractiveShell(TerminalInteractiveShell):'
151 152 # explicitly handle 'exit' command
152 153 return self.ask_exit()
153 154
154 self._executing = True
155 155 # flush stale replies, which could have been ignored, due to missed heartbeats
156 156 while self.client.shell_channel.msg_ready():
157 157 self.client.shell_channel.get_msg()
158 158 # shell_channel.execute takes 'hidden', which is the inverse of store_hist
159 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 165 try:
162 self.handle_stdin_request(timeout=0.05)
166 self.handle_stdin_request(msg_id, timeout=0.05)
163 167 except Empty:
164 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 177 pass
167 if self.client.shell_channel.msg_ready():
168 self.handle_execute_reply(msg_id)
178 else:
179 break
169 180 self._executing = False
170 181
171 182 #-----------------
172 183 # message handlers
173 184 #-----------------
174 185
175 def handle_execute_reply(self, msg_id):
176 msg = self.client.shell_channel.get_msg()
186 def handle_execute_reply(self, msg_id, timeout=None):
187 msg = self.client.shell_channel.get_msg(block=False, timeout=timeout)
177 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 192 content = msg["content"]
182 193 status = content['status']
@@ -198,26 +209,27 b' class ZMQTerminalInteractiveShell(TerminalInteractiveShell):'
198 209 self.execution_count = int(content["execution_count"] + 1)
199 210
200 211
201 def handle_iopub(self):
202 """ Method to procces subscribe channel's messages
212 def handle_iopub(self, msg_id):
213 """ Method to process subscribe channel's messages
203 214
204 This method reads a message and processes the content in different
205 outputs like stdout, stderr, pyout and status
206
207 Arguments:
208 sub_msg: message receive from kernel in the sub socket channel
209 capture by kernel manager.
215 This method consumes and processes messages on the IOPub channel,
216 such as stdout, stderr, pyout and status.
217
218 It only displays output that is caused by the given msg_id
210 219 """
211 220 while self.client.iopub_channel.msg_ready():
212 221 sub_msg = self.client.iopub_channel.get_msg()
213 222 msg_type = sub_msg['header']['msg_type']
214 223 parent = sub_msg["parent_header"]
215 if (not parent) or self.session_id == parent['session']:
216 if msg_type == 'status' :
217 if sub_msg["content"]["execution_state"] == "busy" :
218 pass
219
220 elif msg_type == 'stream' :
224 if (not parent) or msg_id == parent['msg_id']:
225 if msg_type == 'status':
226 state = self._execution_state = sub_msg["content"]["execution_state"]
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
231
232 elif msg_type == 'stream':
221 233 if sub_msg["content"]["name"] == "stdout":
222 234 print(sub_msg["content"]["data"], file=io.stdout, end="")
223 235 io.stdout.flush()
@@ -239,6 +251,7 b' class ZMQTerminalInteractiveShell(TerminalInteractiveShell):'
239 251
240 252 elif msg_type == 'display_data':
241 253 self.handle_rich_data(sub_msg["content"]["data"])
254
242 255
243 256 _imagemime = {
244 257 'image/png': 'png',
@@ -292,13 +305,13 b' class ZMQTerminalInteractiveShell(TerminalInteractiveShell):'
292 305 def handle_image_callable(self, data, mime):
293 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 309 """ Method to capture raw_input
297 310 """
298 311 msg_rep = self.client.stdin_channel.get_msg(timeout=timeout)
299 312 # in case any iopub came while we were waiting:
300 self.handle_iopub()
301 if self.session_id == msg_rep["parent_header"].get("session"):
313 self.handle_iopub(msg_id)
314 if msg_id == msg_rep["parent_header"].get("msg_id"):
302 315 # wrap SIGINT handler
303 316 real_handler = signal.getsignal(signal.SIGINT)
304 317 def double_int(sig,frame):
@@ -373,7 +386,7 b' class ZMQTerminalInteractiveShell(TerminalInteractiveShell):'
373 386 # run a non-empty no-op, so that we don't get a prompt until
374 387 # we know the kernel is ready. This keeps the connection
375 388 # message above the first prompt.
376 if not self.wait_for_kernel(3):
389 if not self.wait_for_kernel(10):
377 390 error("Kernel did not respond\n")
378 391 return
379 392
@@ -394,7 +407,7 b' class ZMQTerminalInteractiveShell(TerminalInteractiveShell):'
394 407 if ans:
395 408 if self.manager:
396 409 self.manager.restart_kernel(True)
397 self.wait_for_kernel(3)
410 self.wait_for_kernel(10)
398 411 else:
399 412 self.exit_now = True
400 413 continue
General Comments 0
You need to be logged in to leave comments. Login now