Show More
@@ -19,10 +19,12 b' from __future__ import print_function' | |||||
19 |
|
19 | |||
20 | import bdb |
|
20 | import bdb | |
21 | import sys |
|
21 | import sys | |
|
22 | import time | |||
22 |
|
23 | |||
23 | from Queue import Empty |
|
24 | from Queue import Empty | |
24 |
|
25 | |||
25 | from IPython.core.alias import AliasManager, AliasError |
|
26 | from IPython.core.alias import AliasManager, AliasError | |
|
27 | from IPython.core import page | |||
26 | from IPython.utils.warn import warn, error, fatal |
|
28 | from IPython.utils.warn import warn, error, fatal | |
27 | from IPython.utils import io |
|
29 | from IPython.utils import io | |
28 |
|
30 | |||
@@ -31,7 +33,8 b' from IPython.frontend.terminal.console.completer import ZMQCompleter' | |||||
31 |
|
33 | |||
32 |
|
34 | |||
33 | class ZMQTerminalInteractiveShell(TerminalInteractiveShell): |
|
35 | class ZMQTerminalInteractiveShell(TerminalInteractiveShell): | |
34 | """A subclass of TerminalInteractiveShell that """ |
|
36 | """A subclass of TerminalInteractiveShell that uses the 0MQ kernel""" | |
|
37 | _executing = False | |||
35 |
|
38 | |||
36 | def __init__(self, *args, **kwargs): |
|
39 | def __init__(self, *args, **kwargs): | |
37 | self.km = kwargs.pop('kernel_manager') |
|
40 | self.km = kwargs.pop('kernel_manager') | |
@@ -78,14 +81,22 b' class ZMQTerminalInteractiveShell(TerminalInteractiveShell):' | |||||
78 | if (not cell) or cell.isspace(): |
|
81 | if (not cell) or cell.isspace(): | |
79 | return |
|
82 | return | |
80 |
|
83 | |||
|
84 | self._executing = True | |||
|
85 | # flush stale replies, which could have been ignored, due to missed heartbeats | |||
|
86 | while self.km.shell_channel.msg_ready(): | |||
|
87 | self.km.shell_channel.get_msg() | |||
81 | # shell_channel.execute takes 'hidden', which is the inverse of store_hist |
|
88 | # shell_channel.execute takes 'hidden', which is the inverse of store_hist | |
82 | msg_id = self.km.shell_channel.execute(cell, not store_history) |
|
89 | msg_id = self.km.shell_channel.execute(cell, not store_history) | |
83 | while not self.km.shell_channel.msg_ready(): |
|
90 | while not self.km.shell_channel.msg_ready() and self.km.is_alive: | |
84 | try: |
|
91 | try: | |
85 | self.handle_stdin_request(timeout=0.05) |
|
92 | self.handle_stdin_request(timeout=0.05) | |
86 | except Empty: |
|
93 | except Empty: | |
|
94 | # display intermediate print statements, etc. | |||
|
95 | self.handle_iopub() | |||
87 | pass |
|
96 | pass | |
88 | self.handle_execute_reply(msg_id) |
|
97 | if self.km.shell_channel.msg_ready(): | |
|
98 | self.handle_execute_reply(msg_id) | |||
|
99 | self._executing = False | |||
89 |
|
100 | |||
90 | #----------------- |
|
101 | #----------------- | |
91 | # message handlers |
|
102 | # message handlers | |
@@ -93,15 +104,28 b' class ZMQTerminalInteractiveShell(TerminalInteractiveShell):' | |||||
93 |
|
104 | |||
94 | def handle_execute_reply(self, msg_id): |
|
105 | def handle_execute_reply(self, msg_id): | |
95 | msg = self.km.shell_channel.get_msg() |
|
106 | msg = self.km.shell_channel.get_msg() | |
96 |
if msg["parent_header"] |
|
107 | if msg["parent_header"].get("msg_id", None) == msg_id: | |
97 | if msg["content"]["status"] == 'ok' : |
|
108 | ||
98 |
|
|
109 | self.handle_iopub() | |
|
110 | ||||
|
111 | content = msg["content"] | |||
|
112 | status = content['status'] | |||
|
113 | ||||
|
114 | if status == 'aborted': | |||
|
115 | self.write('Aborted\n') | |||
|
116 | return | |||
|
117 | elif status == 'ok': | |||
|
118 | # print execution payloads as well: | |||
|
119 | for item in content["payload"]: | |||
|
120 | text = item.get('text', None) | |||
|
121 | if text: | |||
|
122 | page.page(text) | |||
99 |
|
123 | |||
100 |
elif |
|
124 | elif status == 'error': | |
101 |
for frame in |
|
125 | for frame in content["traceback"]: | |
102 | print(frame, file=io.stderr) |
|
126 | print(frame, file=io.stderr) | |
103 |
|
127 | |||
104 |
self.execution_count = int( |
|
128 | self.execution_count = int(content["execution_count"] + 1) | |
105 |
|
129 | |||
106 |
|
130 | |||
107 | def handle_iopub(self): |
|
131 | def handle_iopub(self): | |
@@ -162,6 +186,21 b' class ZMQTerminalInteractiveShell(TerminalInteractiveShell):' | |||||
162 | # handling seems rather unpredictable... |
|
186 | # handling seems rather unpredictable... | |
163 | self.write("\nKeyboardInterrupt in interact()\n") |
|
187 | self.write("\nKeyboardInterrupt in interact()\n") | |
164 |
|
188 | |||
|
189 | def wait_for_kernel(self, timeout=None): | |||
|
190 | """method to wait for a kernel to be ready""" | |||
|
191 | tic = time.time() | |||
|
192 | self.km.hb_channel.unpause() | |||
|
193 | while True: | |||
|
194 | self.run_cell('1', False) | |||
|
195 | if self.km.hb_channel.is_beating(): | |||
|
196 | # heart failure was not the reason this returned | |||
|
197 | break | |||
|
198 | else: | |||
|
199 | # heart failed | |||
|
200 | if timeout is not None and (time.time() - tic) > timeout: | |||
|
201 | return False | |||
|
202 | return True | |||
|
203 | ||||
165 | def interact(self, display_banner=None): |
|
204 | def interact(self, display_banner=None): | |
166 | """Closely emulate the interactive Python console.""" |
|
205 | """Closely emulate the interactive Python console.""" | |
167 |
|
206 | |||
@@ -179,6 +218,13 b' class ZMQTerminalInteractiveShell(TerminalInteractiveShell):' | |||||
179 |
|
218 | |||
180 | more = False |
|
219 | more = False | |
181 |
|
220 | |||
|
221 | # run a non-empty no-op, so that we don't get a prompt until | |||
|
222 | # we know the kernel is ready. This keeps the connection | |||
|
223 | # message above the first prompt. | |||
|
224 | if not self.wait_for_kernel(3): | |||
|
225 | error("Kernel did not respond\n") | |||
|
226 | return | |||
|
227 | ||||
182 | if self.has_readline: |
|
228 | if self.has_readline: | |
183 | self.readline_startup_hook(self.pre_readline) |
|
229 | self.readline_startup_hook(self.pre_readline) | |
184 | # exit_now is set by a call to %Exit or %Quit, through the |
|
230 | # exit_now is set by a call to %Exit or %Quit, through the | |
@@ -186,27 +232,34 b' class ZMQTerminalInteractiveShell(TerminalInteractiveShell):' | |||||
186 |
|
232 | |||
187 | while not self.exit_now: |
|
233 | while not self.exit_now: | |
188 | if not self.km.is_alive: |
|
234 | if not self.km.is_alive: | |
189 | ans = self.raw_input("kernel died, restart ([y]/n)?") |
|
235 | # kernel died, prompt for action or exit | |
190 | if not ans.lower().startswith('n'): |
|
236 | action = "restart" if self.km.has_kernel else "wait for restart" | |
191 | self.km.restart_kernel(True) |
|
237 | ans = self.ask_yes_no("kernel died, %s ([y]/n)?" % action, default='y') | |
|
238 | if ans: | |||
|
239 | if self.km.has_kernel: | |||
|
240 | self.km.restart_kernel(True) | |||
|
241 | self.wait_for_kernel(3) | |||
192 | else: |
|
242 | else: | |
193 | self.exit_now=True |
|
243 | self.exit_now = True | |
194 | continue |
|
244 | continue | |
195 | self.hooks.pre_prompt_hook() |
|
|||
196 | if more: |
|
|||
197 | try: |
|
|||
198 | prompt = self.hooks.generate_prompt(True) |
|
|||
199 | except: |
|
|||
200 | self.showtraceback() |
|
|||
201 | if self.autoindent: |
|
|||
202 | self.rl_do_indent = True |
|
|||
203 |
|
||||
204 | else: |
|
|||
205 | try: |
|
|||
206 | prompt = self.hooks.generate_prompt(False) |
|
|||
207 | except: |
|
|||
208 | self.showtraceback() |
|
|||
209 | try: |
|
245 | try: | |
|
246 | # protect prompt block from KeyboardInterrupt | |||
|
247 | # when sitting on ctrl-C | |||
|
248 | self.hooks.pre_prompt_hook() | |||
|
249 | if more: | |||
|
250 | try: | |||
|
251 | prompt = self.hooks.generate_prompt(True) | |||
|
252 | except Exception: | |||
|
253 | self.showtraceback() | |||
|
254 | if self.autoindent: | |||
|
255 | self.rl_do_indent = True | |||
|
256 | ||||
|
257 | else: | |||
|
258 | try: | |||
|
259 | prompt = self.hooks.generate_prompt(False) | |||
|
260 | except Exception: | |||
|
261 | self.showtraceback() | |||
|
262 | ||||
210 | line = self.raw_input(prompt) |
|
263 | line = self.raw_input(prompt) | |
211 | if self.exit_now: |
|
264 | if self.exit_now: | |
212 | # quick exit on sys.std[in|out] close |
|
265 | # quick exit on sys.std[in|out] close |
General Comments 0
You need to be logged in to leave comments.
Login now