##// END OF EJS Templates
Use Python 2.6 compatible with statement
Takafumi Arakaki -
Show More
@@ -1,462 +1,467 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Frontend of ipython working with python-zmq
2 """Frontend of ipython working with python-zmq
3
3
4 Ipython's frontend, is a ipython interface that send request to kernel and proccess the kernel's outputs.
4 Ipython's frontend, is a ipython interface that send request to kernel and proccess the kernel's outputs.
5
5
6 For more details, see the ipython-zmq design
6 For more details, see the ipython-zmq design
7 """
7 """
8 #-----------------------------------------------------------------------------
8 #-----------------------------------------------------------------------------
9 # Copyright (C) 2011 The IPython Development Team
9 # Copyright (C) 2011 The IPython Development Team
10 #
10 #
11 # Distributed under the terms of the BSD License. The full license is in
11 # Distributed under the terms of the BSD License. The full license is in
12 # the file COPYING, distributed as part of this software.
12 # the file COPYING, distributed as part of this software.
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16 # Imports
16 # Imports
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18 from __future__ import print_function
18 from __future__ import print_function
19
19
20 import bdb
20 import bdb
21 import signal
21 import signal
22 import os
22 import os
23 import sys
23 import sys
24 import time
24 import time
25 import tempfile
25 import tempfile
26 import subprocess
26 import subprocess
27 from io import BytesIO
27 from io import BytesIO
28 import base64
28 import base64
29
29
30 from Queue import Empty
30 from Queue import Empty
31
31
32 try:
33 from contextlib import nested
34 except:
35 from IPython.utils.nested_context import nested
36
32 from IPython.core.alias import AliasManager, AliasError
37 from IPython.core.alias import AliasManager, AliasError
33 from IPython.core import page
38 from IPython.core import page
34 from IPython.utils.warn import warn, error, fatal
39 from IPython.utils.warn import warn, error, fatal
35 from IPython.utils import io
40 from IPython.utils import io
36 from IPython.utils.traitlets import List, Enum, Any
41 from IPython.utils.traitlets import List, Enum, Any
37
42
38 from IPython.frontend.terminal.interactiveshell import TerminalInteractiveShell
43 from IPython.frontend.terminal.interactiveshell import TerminalInteractiveShell
39 from IPython.frontend.terminal.console.completer import ZMQCompleter
44 from IPython.frontend.terminal.console.completer import ZMQCompleter
40
45
41
46
42 class ZMQTerminalInteractiveShell(TerminalInteractiveShell):
47 class ZMQTerminalInteractiveShell(TerminalInteractiveShell):
43 """A subclass of TerminalInteractiveShell that uses the 0MQ kernel"""
48 """A subclass of TerminalInteractiveShell that uses the 0MQ kernel"""
44 _executing = False
49 _executing = False
45
50
46 image_handler = Enum(('PIL', 'stream', 'tempfile', 'callable'),
51 image_handler = Enum(('PIL', 'stream', 'tempfile', 'callable'),
47 config=True, help=
52 config=True, help=
48 """
53 """
49 Handler for image type output. This is useful, for example,
54 Handler for image type output. This is useful, for example,
50 when connecting to the kernel in which pylab inline backend is
55 when connecting to the kernel in which pylab inline backend is
51 activated. There are four handlers defined. 'PIL': Use
56 activated. There are four handlers defined. 'PIL': Use
52 Python Imaging Library to popup image; 'stream': Use an
57 Python Imaging Library to popup image; 'stream': Use an
53 external program to show the image. Image will be fed into
58 external program to show the image. Image will be fed into
54 the STDIN of the program. You will need to configure
59 the STDIN of the program. You will need to configure
55 `stream_image_handler`; 'tempfile': Use an external program to
60 `stream_image_handler`; 'tempfile': Use an external program to
56 show the image. Image will be saved in a temporally file and
61 show the image. Image will be saved in a temporally file and
57 the program is called with the temporally file. You will need
62 the program is called with the temporally file. You will need
58 to configure `tempfile_image_handler`; 'callable': You can set
63 to configure `tempfile_image_handler`; 'callable': You can set
59 any Python callable which is called with the image data. You
64 any Python callable which is called with the image data. You
60 will need to configure `callable_image_handler`.
65 will need to configure `callable_image_handler`.
61 """
66 """
62 )
67 )
63
68
64 stream_image_handler = List(config=True, help=
69 stream_image_handler = List(config=True, help=
65 """
70 """
66 Command to invoke an image viewer program when you are using
71 Command to invoke an image viewer program when you are using
67 'stream' image handler. This option is a list of string where
72 'stream' image handler. This option is a list of string where
68 the first element is the command itself and reminders are the
73 the first element is the command itself and reminders are the
69 options for the command. Raw image data is given as STDIN to
74 options for the command. Raw image data is given as STDIN to
70 the program.
75 the program.
71 """
76 """
72 )
77 )
73
78
74 tempfile_image_handler = List(config=True, help=
79 tempfile_image_handler = List(config=True, help=
75 """
80 """
76 Command to invoke an image viewer program when you are using
81 Command to invoke an image viewer program when you are using
77 'tempfile' image handler. This option is a list of string
82 'tempfile' image handler. This option is a list of string
78 where the first element is the command itself and reminders
83 where the first element is the command itself and reminders
79 are the options for the command. You can use {file} and
84 are the options for the command. You can use {file} and
80 {format} in the string to represent the location of the
85 {format} in the string to represent the location of the
81 generated image file and image format.
86 generated image file and image format.
82 """
87 """
83 )
88 )
84
89
85 callable_image_handler = Any(config=True, help=
90 callable_image_handler = Any(config=True, help=
86 """
91 """
87 Callable object called via 'callable' image handler with one
92 Callable object called via 'callable' image handler with one
88 argument, `data`, which is `msg["content"]["data"]` where
93 argument, `data`, which is `msg["content"]["data"]` where
89 `msg` is the message from iopub channel. For exmaple, you can
94 `msg` is the message from iopub channel. For exmaple, you can
90 find base64 encoded PNG data as `data['image/png']`. You can
95 find base64 encoded PNG data as `data['image/png']`. You can
91 use {format} in the string to represent the image format.
96 use {format} in the string to represent the image format.
92 """
97 """
93 )
98 )
94
99
95 mime_preference = List(
100 mime_preference = List(
96 default_value=['image/png', 'image/jpeg', 'image/svg+xml'],
101 default_value=['image/png', 'image/jpeg', 'image/svg+xml'],
97 config=True, allow_none=False, help=
102 config=True, allow_none=False, help=
98 """
103 """
99 Preferred object representation MIME type in order. First
104 Preferred object representation MIME type in order. First
100 matched MIME type will be used.
105 matched MIME type will be used.
101 """
106 """
102 )
107 )
103
108
104 def __init__(self, *args, **kwargs):
109 def __init__(self, *args, **kwargs):
105 self.km = kwargs.pop('kernel_manager')
110 self.km = kwargs.pop('kernel_manager')
106 self.session_id = self.km.session.session
111 self.session_id = self.km.session.session
107 super(ZMQTerminalInteractiveShell, self).__init__(*args, **kwargs)
112 super(ZMQTerminalInteractiveShell, self).__init__(*args, **kwargs)
108
113
109 def init_completer(self):
114 def init_completer(self):
110 """Initialize the completion machinery.
115 """Initialize the completion machinery.
111
116
112 This creates completion machinery that can be used by client code,
117 This creates completion machinery that can be used by client code,
113 either interactively in-process (typically triggered by the readline
118 either interactively in-process (typically triggered by the readline
114 library), programatically (such as in test suites) or out-of-prcess
119 library), programatically (such as in test suites) or out-of-prcess
115 (typically over the network by remote frontends).
120 (typically over the network by remote frontends).
116 """
121 """
117 from IPython.core.completerlib import (module_completer,
122 from IPython.core.completerlib import (module_completer,
118 magic_run_completer, cd_completer)
123 magic_run_completer, cd_completer)
119
124
120 self.Completer = ZMQCompleter(self, self.km)
125 self.Completer = ZMQCompleter(self, self.km)
121
126
122
127
123 self.set_hook('complete_command', module_completer, str_key = 'import')
128 self.set_hook('complete_command', module_completer, str_key = 'import')
124 self.set_hook('complete_command', module_completer, str_key = 'from')
129 self.set_hook('complete_command', module_completer, str_key = 'from')
125 self.set_hook('complete_command', magic_run_completer, str_key = '%run')
130 self.set_hook('complete_command', magic_run_completer, str_key = '%run')
126 self.set_hook('complete_command', cd_completer, str_key = '%cd')
131 self.set_hook('complete_command', cd_completer, str_key = '%cd')
127
132
128 # Only configure readline if we truly are using readline. IPython can
133 # Only configure readline if we truly are using readline. IPython can
129 # do tab-completion over the network, in GUIs, etc, where readline
134 # do tab-completion over the network, in GUIs, etc, where readline
130 # itself may be absent
135 # itself may be absent
131 if self.has_readline:
136 if self.has_readline:
132 self.set_readline_completer()
137 self.set_readline_completer()
133
138
134 def run_cell(self, cell, store_history=True):
139 def run_cell(self, cell, store_history=True):
135 """Run a complete IPython cell.
140 """Run a complete IPython cell.
136
141
137 Parameters
142 Parameters
138 ----------
143 ----------
139 cell : str
144 cell : str
140 The code (including IPython code such as %magic functions) to run.
145 The code (including IPython code such as %magic functions) to run.
141 store_history : bool
146 store_history : bool
142 If True, the raw and translated cell will be stored in IPython's
147 If True, the raw and translated cell will be stored in IPython's
143 history. For user code calling back into IPython's machinery, this
148 history. For user code calling back into IPython's machinery, this
144 should be set to False.
149 should be set to False.
145 """
150 """
146 if (not cell) or cell.isspace():
151 if (not cell) or cell.isspace():
147 return
152 return
148
153
149 if cell.strip() == 'exit':
154 if cell.strip() == 'exit':
150 # explicitly handle 'exit' command
155 # explicitly handle 'exit' command
151 return self.ask_exit()
156 return self.ask_exit()
152
157
153 self._executing = True
158 self._executing = True
154 # flush stale replies, which could have been ignored, due to missed heartbeats
159 # flush stale replies, which could have been ignored, due to missed heartbeats
155 while self.km.shell_channel.msg_ready():
160 while self.km.shell_channel.msg_ready():
156 self.km.shell_channel.get_msg()
161 self.km.shell_channel.get_msg()
157 # shell_channel.execute takes 'hidden', which is the inverse of store_hist
162 # shell_channel.execute takes 'hidden', which is the inverse of store_hist
158 msg_id = self.km.shell_channel.execute(cell, not store_history)
163 msg_id = self.km.shell_channel.execute(cell, not store_history)
159 while not self.km.shell_channel.msg_ready() and self.km.is_alive:
164 while not self.km.shell_channel.msg_ready() and self.km.is_alive:
160 try:
165 try:
161 self.handle_stdin_request(timeout=0.05)
166 self.handle_stdin_request(timeout=0.05)
162 except Empty:
167 except Empty:
163 # display intermediate print statements, etc.
168 # display intermediate print statements, etc.
164 self.handle_iopub()
169 self.handle_iopub()
165 pass
170 pass
166 if self.km.shell_channel.msg_ready():
171 if self.km.shell_channel.msg_ready():
167 self.handle_execute_reply(msg_id)
172 self.handle_execute_reply(msg_id)
168 self._executing = False
173 self._executing = False
169
174
170 #-----------------
175 #-----------------
171 # message handlers
176 # message handlers
172 #-----------------
177 #-----------------
173
178
174 def handle_execute_reply(self, msg_id):
179 def handle_execute_reply(self, msg_id):
175 msg = self.km.shell_channel.get_msg()
180 msg = self.km.shell_channel.get_msg()
176 if msg["parent_header"].get("msg_id", None) == msg_id:
181 if msg["parent_header"].get("msg_id", None) == msg_id:
177
182
178 self.handle_iopub()
183 self.handle_iopub()
179
184
180 content = msg["content"]
185 content = msg["content"]
181 status = content['status']
186 status = content['status']
182
187
183 if status == 'aborted':
188 if status == 'aborted':
184 self.write('Aborted\n')
189 self.write('Aborted\n')
185 return
190 return
186 elif status == 'ok':
191 elif status == 'ok':
187 # print execution payloads as well:
192 # print execution payloads as well:
188 for item in content["payload"]:
193 for item in content["payload"]:
189 text = item.get('text', None)
194 text = item.get('text', None)
190 if text:
195 if text:
191 page.page(text)
196 page.page(text)
192
197
193 elif status == 'error':
198 elif status == 'error':
194 for frame in content["traceback"]:
199 for frame in content["traceback"]:
195 print(frame, file=io.stderr)
200 print(frame, file=io.stderr)
196
201
197 self.execution_count = int(content["execution_count"] + 1)
202 self.execution_count = int(content["execution_count"] + 1)
198
203
199
204
200 def handle_iopub(self):
205 def handle_iopub(self):
201 """ Method to procces subscribe channel's messages
206 """ Method to procces subscribe channel's messages
202
207
203 This method reads a message and processes the content in different
208 This method reads a message and processes the content in different
204 outputs like stdout, stderr, pyout and status
209 outputs like stdout, stderr, pyout and status
205
210
206 Arguments:
211 Arguments:
207 sub_msg: message receive from kernel in the sub socket channel
212 sub_msg: message receive from kernel in the sub socket channel
208 capture by kernel manager.
213 capture by kernel manager.
209 """
214 """
210 while self.km.sub_channel.msg_ready():
215 while self.km.sub_channel.msg_ready():
211 sub_msg = self.km.sub_channel.get_msg()
216 sub_msg = self.km.sub_channel.get_msg()
212 msg_type = sub_msg['header']['msg_type']
217 msg_type = sub_msg['header']['msg_type']
213 parent = sub_msg["parent_header"]
218 parent = sub_msg["parent_header"]
214 if (not parent) or self.session_id == parent['session']:
219 if (not parent) or self.session_id == parent['session']:
215 if msg_type == 'status' :
220 if msg_type == 'status' :
216 if sub_msg["content"]["execution_state"] == "busy" :
221 if sub_msg["content"]["execution_state"] == "busy" :
217 pass
222 pass
218
223
219 elif msg_type == 'stream' :
224 elif msg_type == 'stream' :
220 if sub_msg["content"]["name"] == "stdout":
225 if sub_msg["content"]["name"] == "stdout":
221 print(sub_msg["content"]["data"], file=io.stdout, end="")
226 print(sub_msg["content"]["data"], file=io.stdout, end="")
222 io.stdout.flush()
227 io.stdout.flush()
223 elif sub_msg["content"]["name"] == "stderr" :
228 elif sub_msg["content"]["name"] == "stderr" :
224 print(sub_msg["content"]["data"], file=io.stderr, end="")
229 print(sub_msg["content"]["data"], file=io.stderr, end="")
225 io.stderr.flush()
230 io.stderr.flush()
226
231
227 elif msg_type == 'pyout':
232 elif msg_type == 'pyout':
228 self.execution_count = int(sub_msg["content"]["execution_count"])
233 self.execution_count = int(sub_msg["content"]["execution_count"])
229 format_dict = sub_msg["content"]["data"]
234 format_dict = sub_msg["content"]["data"]
230 self.handle_rich_data(format_dict)
235 self.handle_rich_data(format_dict)
231 # taken from DisplayHook.__call__:
236 # taken from DisplayHook.__call__:
232 hook = self.displayhook
237 hook = self.displayhook
233 hook.start_displayhook()
238 hook.start_displayhook()
234 hook.write_output_prompt()
239 hook.write_output_prompt()
235 hook.write_format_data(format_dict)
240 hook.write_format_data(format_dict)
236 hook.log_output(format_dict)
241 hook.log_output(format_dict)
237 hook.finish_displayhook()
242 hook.finish_displayhook()
238
243
239 elif msg_type == 'display_data':
244 elif msg_type == 'display_data':
240 self.handle_rich_data(sub_msg["content"]["data"])
245 self.handle_rich_data(sub_msg["content"]["data"])
241
246
242 _imagemime = {
247 _imagemime = {
243 'image/png': 'png',
248 'image/png': 'png',
244 'image/jpeg': 'jpeg',
249 'image/jpeg': 'jpeg',
245 'image/svg+xml': 'svg',
250 'image/svg+xml': 'svg',
246 }
251 }
247
252
248 def handle_rich_data(self, data):
253 def handle_rich_data(self, data):
249 for mime in self.mime_preference:
254 for mime in self.mime_preference:
250 if mime in data and mime in self._imagemime:
255 if mime in data and mime in self._imagemime:
251 self.handle_image(data, mime)
256 self.handle_image(data, mime)
252 return
257 return
253
258
254 def handle_image(self, data, mime):
259 def handle_image(self, data, mime):
255 handler = getattr(
260 handler = getattr(
256 self, 'handle_image_{0}'.format(self.image_handler), None)
261 self, 'handle_image_{0}'.format(self.image_handler), None)
257 if handler:
262 if handler:
258 handler(data, mime)
263 handler(data, mime)
259
264
260 def handle_image_PIL(self, data, mime):
265 def handle_image_PIL(self, data, mime):
261 if mime not in ('image/png', 'image/jpeg'):
266 if mime not in ('image/png', 'image/jpeg'):
262 return
267 return
263 import PIL
268 import PIL
264 raw = base64.decodestring(data[mime])
269 raw = base64.decodestring(data[mime])
265 img = PIL.Image.open(BytesIO(raw))
270 img = PIL.Image.open(BytesIO(raw))
266 img.show()
271 img.show()
267
272
268 def handle_image_stream(self, data, mime):
273 def handle_image_stream(self, data, mime):
269 raw = base64.decodestring(data[mime])
274 raw = base64.decodestring(data[mime])
270 imageformat = self._imagemime[mime]
275 imageformat = self._imagemime[mime]
271 fmt = dict(format=imageformat)
276 fmt = dict(format=imageformat)
272 args = [s.format(**fmt) for s in self.stream_image_handler]
277 args = [s.format(**fmt) for s in self.stream_image_handler]
273 with open(os.devnull, 'w') as devnull:
278 with open(os.devnull, 'w') as devnull:
274 proc = subprocess.Popen(
279 proc = subprocess.Popen(
275 args, stdin=subprocess.PIPE,
280 args, stdin=subprocess.PIPE,
276 stdout=devnull, stderr=devnull)
281 stdout=devnull, stderr=devnull)
277 proc.communicate(raw)
282 proc.communicate(raw)
278
283
279 def handle_image_tempfile(self, data, mime):
284 def handle_image_tempfile(self, data, mime):
280 raw = base64.decodestring(data[mime])
285 raw = base64.decodestring(data[mime])
281 imageformat = self._imagemime[mime]
286 imageformat = self._imagemime[mime]
282 ext = '.{0}'.format(imageformat)
287 ext = '.{0}'.format(imageformat)
283 with tempfile.NamedTemporaryFile(suffix=ext) as f, \
288 with nested(tempfile.NamedTemporaryFile(suffix=ext),
284 open(os.devnull, 'w') as devnull:
289 open(os.devnull, 'w')) as (f, devnull):
285 f.write(raw)
290 f.write(raw)
286 f.flush()
291 f.flush()
287 fmt = dict(file=f.name, format=imageformat)
292 fmt = dict(file=f.name, format=imageformat)
288 args = [s.format(**fmt) for s in self.tempfile_image_handler]
293 args = [s.format(**fmt) for s in self.tempfile_image_handler]
289 subprocess.call(args, stdout=devnull, stderr=devnull)
294 subprocess.call(args, stdout=devnull, stderr=devnull)
290
295
291 def handle_image_callable(self, data, mime):
296 def handle_image_callable(self, data, mime):
292 self.callable_image_handler(data)
297 self.callable_image_handler(data)
293
298
294 def handle_stdin_request(self, timeout=0.1):
299 def handle_stdin_request(self, timeout=0.1):
295 """ Method to capture raw_input
300 """ Method to capture raw_input
296 """
301 """
297 msg_rep = self.km.stdin_channel.get_msg(timeout=timeout)
302 msg_rep = self.km.stdin_channel.get_msg(timeout=timeout)
298 # in case any iopub came while we were waiting:
303 # in case any iopub came while we were waiting:
299 self.handle_iopub()
304 self.handle_iopub()
300 if self.session_id == msg_rep["parent_header"].get("session"):
305 if self.session_id == msg_rep["parent_header"].get("session"):
301 # wrap SIGINT handler
306 # wrap SIGINT handler
302 real_handler = signal.getsignal(signal.SIGINT)
307 real_handler = signal.getsignal(signal.SIGINT)
303 def double_int(sig,frame):
308 def double_int(sig,frame):
304 # call real handler (forwards sigint to kernel),
309 # call real handler (forwards sigint to kernel),
305 # then raise local interrupt, stopping local raw_input
310 # then raise local interrupt, stopping local raw_input
306 real_handler(sig,frame)
311 real_handler(sig,frame)
307 raise KeyboardInterrupt
312 raise KeyboardInterrupt
308 signal.signal(signal.SIGINT, double_int)
313 signal.signal(signal.SIGINT, double_int)
309
314
310 try:
315 try:
311 raw_data = raw_input(msg_rep["content"]["prompt"])
316 raw_data = raw_input(msg_rep["content"]["prompt"])
312 except EOFError:
317 except EOFError:
313 # turn EOFError into EOF character
318 # turn EOFError into EOF character
314 raw_data = '\x04'
319 raw_data = '\x04'
315 except KeyboardInterrupt:
320 except KeyboardInterrupt:
316 sys.stdout.write('\n')
321 sys.stdout.write('\n')
317 return
322 return
318 finally:
323 finally:
319 # restore SIGINT handler
324 # restore SIGINT handler
320 signal.signal(signal.SIGINT, real_handler)
325 signal.signal(signal.SIGINT, real_handler)
321
326
322 # only send stdin reply if there *was not* another request
327 # only send stdin reply if there *was not* another request
323 # or execution finished while we were reading.
328 # or execution finished while we were reading.
324 if not (self.km.stdin_channel.msg_ready() or self.km.shell_channel.msg_ready()):
329 if not (self.km.stdin_channel.msg_ready() or self.km.shell_channel.msg_ready()):
325 self.km.stdin_channel.input(raw_data)
330 self.km.stdin_channel.input(raw_data)
326
331
327 def mainloop(self, display_banner=False):
332 def mainloop(self, display_banner=False):
328 while True:
333 while True:
329 try:
334 try:
330 self.interact(display_banner=display_banner)
335 self.interact(display_banner=display_banner)
331 #self.interact_with_readline()
336 #self.interact_with_readline()
332 # XXX for testing of a readline-decoupled repl loop, call
337 # XXX for testing of a readline-decoupled repl loop, call
333 # interact_with_readline above
338 # interact_with_readline above
334 break
339 break
335 except KeyboardInterrupt:
340 except KeyboardInterrupt:
336 # this should not be necessary, but KeyboardInterrupt
341 # this should not be necessary, but KeyboardInterrupt
337 # handling seems rather unpredictable...
342 # handling seems rather unpredictable...
338 self.write("\nKeyboardInterrupt in interact()\n")
343 self.write("\nKeyboardInterrupt in interact()\n")
339
344
340 def wait_for_kernel(self, timeout=None):
345 def wait_for_kernel(self, timeout=None):
341 """method to wait for a kernel to be ready"""
346 """method to wait for a kernel to be ready"""
342 tic = time.time()
347 tic = time.time()
343 self.km.hb_channel.unpause()
348 self.km.hb_channel.unpause()
344 while True:
349 while True:
345 self.run_cell('1', False)
350 self.run_cell('1', False)
346 if self.km.hb_channel.is_beating():
351 if self.km.hb_channel.is_beating():
347 # heart failure was not the reason this returned
352 # heart failure was not the reason this returned
348 break
353 break
349 else:
354 else:
350 # heart failed
355 # heart failed
351 if timeout is not None and (time.time() - tic) > timeout:
356 if timeout is not None and (time.time() - tic) > timeout:
352 return False
357 return False
353 return True
358 return True
354
359
355 def interact(self, display_banner=None):
360 def interact(self, display_banner=None):
356 """Closely emulate the interactive Python console."""
361 """Closely emulate the interactive Python console."""
357
362
358 # batch run -> do not interact
363 # batch run -> do not interact
359 if self.exit_now:
364 if self.exit_now:
360 return
365 return
361
366
362 if display_banner is None:
367 if display_banner is None:
363 display_banner = self.display_banner
368 display_banner = self.display_banner
364
369
365 if isinstance(display_banner, basestring):
370 if isinstance(display_banner, basestring):
366 self.show_banner(display_banner)
371 self.show_banner(display_banner)
367 elif display_banner:
372 elif display_banner:
368 self.show_banner()
373 self.show_banner()
369
374
370 more = False
375 more = False
371
376
372 # run a non-empty no-op, so that we don't get a prompt until
377 # run a non-empty no-op, so that we don't get a prompt until
373 # we know the kernel is ready. This keeps the connection
378 # we know the kernel is ready. This keeps the connection
374 # message above the first prompt.
379 # message above the first prompt.
375 if not self.wait_for_kernel(3):
380 if not self.wait_for_kernel(3):
376 error("Kernel did not respond\n")
381 error("Kernel did not respond\n")
377 return
382 return
378
383
379 if self.has_readline:
384 if self.has_readline:
380 self.readline_startup_hook(self.pre_readline)
385 self.readline_startup_hook(self.pre_readline)
381 hlen_b4_cell = self.readline.get_current_history_length()
386 hlen_b4_cell = self.readline.get_current_history_length()
382 else:
387 else:
383 hlen_b4_cell = 0
388 hlen_b4_cell = 0
384 # exit_now is set by a call to %Exit or %Quit, through the
389 # exit_now is set by a call to %Exit or %Quit, through the
385 # ask_exit callback.
390 # ask_exit callback.
386
391
387 while not self.exit_now:
392 while not self.exit_now:
388 if not self.km.is_alive:
393 if not self.km.is_alive:
389 # kernel died, prompt for action or exit
394 # kernel died, prompt for action or exit
390 action = "restart" if self.km.has_kernel else "wait for restart"
395 action = "restart" if self.km.has_kernel else "wait for restart"
391 ans = self.ask_yes_no("kernel died, %s ([y]/n)?" % action, default='y')
396 ans = self.ask_yes_no("kernel died, %s ([y]/n)?" % action, default='y')
392 if ans:
397 if ans:
393 if self.km.has_kernel:
398 if self.km.has_kernel:
394 self.km.restart_kernel(True)
399 self.km.restart_kernel(True)
395 self.wait_for_kernel(3)
400 self.wait_for_kernel(3)
396 else:
401 else:
397 self.exit_now = True
402 self.exit_now = True
398 continue
403 continue
399 try:
404 try:
400 # protect prompt block from KeyboardInterrupt
405 # protect prompt block from KeyboardInterrupt
401 # when sitting on ctrl-C
406 # when sitting on ctrl-C
402 self.hooks.pre_prompt_hook()
407 self.hooks.pre_prompt_hook()
403 if more:
408 if more:
404 try:
409 try:
405 prompt = self.prompt_manager.render('in2')
410 prompt = self.prompt_manager.render('in2')
406 except Exception:
411 except Exception:
407 self.showtraceback()
412 self.showtraceback()
408 if self.autoindent:
413 if self.autoindent:
409 self.rl_do_indent = True
414 self.rl_do_indent = True
410
415
411 else:
416 else:
412 try:
417 try:
413 prompt = self.separate_in + self.prompt_manager.render('in')
418 prompt = self.separate_in + self.prompt_manager.render('in')
414 except Exception:
419 except Exception:
415 self.showtraceback()
420 self.showtraceback()
416
421
417 line = self.raw_input(prompt)
422 line = self.raw_input(prompt)
418 if self.exit_now:
423 if self.exit_now:
419 # quick exit on sys.std[in|out] close
424 # quick exit on sys.std[in|out] close
420 break
425 break
421 if self.autoindent:
426 if self.autoindent:
422 self.rl_do_indent = False
427 self.rl_do_indent = False
423
428
424 except KeyboardInterrupt:
429 except KeyboardInterrupt:
425 #double-guard against keyboardinterrupts during kbdint handling
430 #double-guard against keyboardinterrupts during kbdint handling
426 try:
431 try:
427 self.write('\nKeyboardInterrupt\n')
432 self.write('\nKeyboardInterrupt\n')
428 source_raw = self.input_splitter.source_raw_reset()[1]
433 source_raw = self.input_splitter.source_raw_reset()[1]
429 hlen_b4_cell = self._replace_rlhist_multiline(source_raw, hlen_b4_cell)
434 hlen_b4_cell = self._replace_rlhist_multiline(source_raw, hlen_b4_cell)
430 more = False
435 more = False
431 except KeyboardInterrupt:
436 except KeyboardInterrupt:
432 pass
437 pass
433 except EOFError:
438 except EOFError:
434 if self.autoindent:
439 if self.autoindent:
435 self.rl_do_indent = False
440 self.rl_do_indent = False
436 if self.has_readline:
441 if self.has_readline:
437 self.readline_startup_hook(None)
442 self.readline_startup_hook(None)
438 self.write('\n')
443 self.write('\n')
439 self.exit()
444 self.exit()
440 except bdb.BdbQuit:
445 except bdb.BdbQuit:
441 warn('The Python debugger has exited with a BdbQuit exception.\n'
446 warn('The Python debugger has exited with a BdbQuit exception.\n'
442 'Because of how pdb handles the stack, it is impossible\n'
447 'Because of how pdb handles the stack, it is impossible\n'
443 'for IPython to properly format this particular exception.\n'
448 'for IPython to properly format this particular exception.\n'
444 'IPython will resume normal operation.')
449 'IPython will resume normal operation.')
445 except:
450 except:
446 # exceptions here are VERY RARE, but they can be triggered
451 # exceptions here are VERY RARE, but they can be triggered
447 # asynchronously by signal handlers, for example.
452 # asynchronously by signal handlers, for example.
448 self.showtraceback()
453 self.showtraceback()
449 else:
454 else:
450 self.input_splitter.push(line)
455 self.input_splitter.push(line)
451 more = self.input_splitter.push_accepts_more()
456 more = self.input_splitter.push_accepts_more()
452 if (self.SyntaxTB.last_syntax_error and
457 if (self.SyntaxTB.last_syntax_error and
453 self.autoedit_syntax):
458 self.autoedit_syntax):
454 self.edit_syntax_error()
459 self.edit_syntax_error()
455 if not more:
460 if not more:
456 source_raw = self.input_splitter.source_raw_reset()[1]
461 source_raw = self.input_splitter.source_raw_reset()[1]
457 hlen_b4_cell = self._replace_rlhist_multiline(source_raw, hlen_b4_cell)
462 hlen_b4_cell = self._replace_rlhist_multiline(source_raw, hlen_b4_cell)
458 self.run_cell(source_raw)
463 self.run_cell(source_raw)
459
464
460
465
461 # Turn off the exit flag, so the mainloop can be restarted if desired
466 # Turn off the exit flag, so the mainloop can be restarted if desired
462 self.exit_now = False
467 self.exit_now = False
General Comments 0
You need to be logged in to leave comments. Login now