##// END OF EJS Templates
quiet error messages instead of tracebacks in %pylab/%gui...
MinRK -
Show More
@@ -1,612 +1,616 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Subclass of InteractiveShell for terminal based frontends."""
2 """Subclass of InteractiveShell for terminal based frontends."""
3
3
4 #-----------------------------------------------------------------------------
4 #-----------------------------------------------------------------------------
5 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de>
5 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de>
6 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
6 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
7 # Copyright (C) 2008-2010 The IPython Development Team
7 # Copyright (C) 2008-2010 The IPython Development Team
8 #
8 #
9 # Distributed under the terms of the BSD License. The full license is in
9 # Distributed under the terms of the BSD License. The full license is in
10 # the file COPYING, distributed as part of this software.
10 # the file COPYING, distributed as part of this software.
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12
12
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 # Imports
14 # Imports
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16
16
17 import __builtin__
17 import __builtin__
18 import bdb
18 import bdb
19 import os
19 import os
20 import re
20 import re
21 import sys
21 import sys
22
22
23 try:
23 try:
24 from contextlib import nested
24 from contextlib import nested
25 except:
25 except:
26 from IPython.utils.nested_context import nested
26 from IPython.utils.nested_context import nested
27
27
28 from IPython.core.error import TryNext
28 from IPython.core.error import TryNext
29 from IPython.core.usage import interactive_usage, default_banner
29 from IPython.core.usage import interactive_usage, default_banner
30 from IPython.core.interactiveshell import InteractiveShell, InteractiveShellABC
30 from IPython.core.interactiveshell import InteractiveShell, InteractiveShellABC
31 from IPython.lib.inputhook import enable_gui
31 from IPython.lib.inputhook import enable_gui
32 from IPython.lib.pylabtools import pylab_activate
32 from IPython.lib.pylabtools import pylab_activate
33 from IPython.testing.skipdoctest import skip_doctest
33 from IPython.testing.skipdoctest import skip_doctest
34 from IPython.utils import py3compat
34 from IPython.utils import py3compat
35 from IPython.utils.terminal import toggle_set_term_title, set_term_title
35 from IPython.utils.terminal import toggle_set_term_title, set_term_title
36 from IPython.utils.process import abbrev_cwd
36 from IPython.utils.process import abbrev_cwd
37 from IPython.utils.warn import warn
37 from IPython.utils.warn import warn
38 from IPython.utils.text import num_ini_spaces
38 from IPython.utils.text import num_ini_spaces
39 from IPython.utils.traitlets import Int, CBool, Unicode
39 from IPython.utils.traitlets import Int, CBool, Unicode
40
40
41 #-----------------------------------------------------------------------------
41 #-----------------------------------------------------------------------------
42 # Utilities
42 # Utilities
43 #-----------------------------------------------------------------------------
43 #-----------------------------------------------------------------------------
44
44
45 def get_default_editor():
45 def get_default_editor():
46 try:
46 try:
47 ed = os.environ['EDITOR']
47 ed = os.environ['EDITOR']
48 except KeyError:
48 except KeyError:
49 if os.name == 'posix':
49 if os.name == 'posix':
50 ed = 'vi' # the only one guaranteed to be there!
50 ed = 'vi' # the only one guaranteed to be there!
51 else:
51 else:
52 ed = 'notepad' # same in Windows!
52 ed = 'notepad' # same in Windows!
53 return ed
53 return ed
54
54
55 #-----------------------------------------------------------------------------
55 #-----------------------------------------------------------------------------
56 # Main class
56 # Main class
57 #-----------------------------------------------------------------------------
57 #-----------------------------------------------------------------------------
58
58
59 class TerminalInteractiveShell(InteractiveShell):
59 class TerminalInteractiveShell(InteractiveShell):
60
60
61 autoedit_syntax = CBool(False, config=True,
61 autoedit_syntax = CBool(False, config=True,
62 help="auto editing of files with syntax errors.")
62 help="auto editing of files with syntax errors.")
63 banner = Unicode('')
63 banner = Unicode('')
64 banner1 = Unicode(default_banner, config=True,
64 banner1 = Unicode(default_banner, config=True,
65 help="""The part of the banner to be printed before the profile"""
65 help="""The part of the banner to be printed before the profile"""
66 )
66 )
67 banner2 = Unicode('', config=True,
67 banner2 = Unicode('', config=True,
68 help="""The part of the banner to be printed after the profile"""
68 help="""The part of the banner to be printed after the profile"""
69 )
69 )
70 confirm_exit = CBool(True, config=True,
70 confirm_exit = CBool(True, config=True,
71 help="""
71 help="""
72 Set to confirm when you try to exit IPython with an EOF (Control-D
72 Set to confirm when you try to exit IPython with an EOF (Control-D
73 in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
73 in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
74 you can force a direct exit without any confirmation.""",
74 you can force a direct exit without any confirmation.""",
75 )
75 )
76 # This display_banner only controls whether or not self.show_banner()
76 # This display_banner only controls whether or not self.show_banner()
77 # is called when mainloop/interact are called. The default is False
77 # is called when mainloop/interact are called. The default is False
78 # because for the terminal based application, the banner behavior
78 # because for the terminal based application, the banner behavior
79 # is controlled by Global.display_banner, which IPythonApp looks at
79 # is controlled by Global.display_banner, which IPythonApp looks at
80 # to determine if *it* should call show_banner() by hand or not.
80 # to determine if *it* should call show_banner() by hand or not.
81 display_banner = CBool(False) # This isn't configurable!
81 display_banner = CBool(False) # This isn't configurable!
82 embedded = CBool(False)
82 embedded = CBool(False)
83 embedded_active = CBool(False)
83 embedded_active = CBool(False)
84 editor = Unicode(get_default_editor(), config=True,
84 editor = Unicode(get_default_editor(), config=True,
85 help="Set the editor used by IPython (default to $EDITOR/vi/notepad)."
85 help="Set the editor used by IPython (default to $EDITOR/vi/notepad)."
86 )
86 )
87 pager = Unicode('less', config=True,
87 pager = Unicode('less', config=True,
88 help="The shell program to be used for paging.")
88 help="The shell program to be used for paging.")
89
89
90 screen_length = Int(0, config=True,
90 screen_length = Int(0, config=True,
91 help=
91 help=
92 """Number of lines of your screen, used to control printing of very
92 """Number of lines of your screen, used to control printing of very
93 long strings. Strings longer than this number of lines will be sent
93 long strings. Strings longer than this number of lines will be sent
94 through a pager instead of directly printed. The default value for
94 through a pager instead of directly printed. The default value for
95 this is 0, which means IPython will auto-detect your screen size every
95 this is 0, which means IPython will auto-detect your screen size every
96 time it needs to print certain potentially long strings (this doesn't
96 time it needs to print certain potentially long strings (this doesn't
97 change the behavior of the 'print' keyword, it's only triggered
97 change the behavior of the 'print' keyword, it's only triggered
98 internally). If for some reason this isn't working well (it needs
98 internally). If for some reason this isn't working well (it needs
99 curses support), specify it yourself. Otherwise don't change the
99 curses support), specify it yourself. Otherwise don't change the
100 default.""",
100 default.""",
101 )
101 )
102 term_title = CBool(False, config=True,
102 term_title = CBool(False, config=True,
103 help="Enable auto setting the terminal title."
103 help="Enable auto setting the terminal title."
104 )
104 )
105
105
106 def __init__(self, config=None, ipython_dir=None, profile_dir=None, user_ns=None,
106 def __init__(self, config=None, ipython_dir=None, profile_dir=None, user_ns=None,
107 user_global_ns=None, custom_exceptions=((),None),
107 user_global_ns=None, custom_exceptions=((),None),
108 usage=None, banner1=None, banner2=None,
108 usage=None, banner1=None, banner2=None,
109 display_banner=None):
109 display_banner=None):
110
110
111 super(TerminalInteractiveShell, self).__init__(
111 super(TerminalInteractiveShell, self).__init__(
112 config=config, profile_dir=profile_dir, user_ns=user_ns,
112 config=config, profile_dir=profile_dir, user_ns=user_ns,
113 user_global_ns=user_global_ns, custom_exceptions=custom_exceptions
113 user_global_ns=user_global_ns, custom_exceptions=custom_exceptions
114 )
114 )
115 # use os.system instead of utils.process.system by default, except on Windows
115 # use os.system instead of utils.process.system by default, except on Windows
116 if os.name == 'nt':
116 if os.name == 'nt':
117 self.system = self.system_piped
117 self.system = self.system_piped
118 else:
118 else:
119 self.system = self.system_raw
119 self.system = self.system_raw
120
120
121 self.init_term_title()
121 self.init_term_title()
122 self.init_usage(usage)
122 self.init_usage(usage)
123 self.init_banner(banner1, banner2, display_banner)
123 self.init_banner(banner1, banner2, display_banner)
124
124
125 #-------------------------------------------------------------------------
125 #-------------------------------------------------------------------------
126 # Things related to the terminal
126 # Things related to the terminal
127 #-------------------------------------------------------------------------
127 #-------------------------------------------------------------------------
128
128
129 @property
129 @property
130 def usable_screen_length(self):
130 def usable_screen_length(self):
131 if self.screen_length == 0:
131 if self.screen_length == 0:
132 return 0
132 return 0
133 else:
133 else:
134 num_lines_bot = self.separate_in.count('\n')+1
134 num_lines_bot = self.separate_in.count('\n')+1
135 return self.screen_length - num_lines_bot
135 return self.screen_length - num_lines_bot
136
136
137 def init_term_title(self):
137 def init_term_title(self):
138 # Enable or disable the terminal title.
138 # Enable or disable the terminal title.
139 if self.term_title:
139 if self.term_title:
140 toggle_set_term_title(True)
140 toggle_set_term_title(True)
141 set_term_title('IPython: ' + abbrev_cwd())
141 set_term_title('IPython: ' + abbrev_cwd())
142 else:
142 else:
143 toggle_set_term_title(False)
143 toggle_set_term_title(False)
144
144
145 #-------------------------------------------------------------------------
145 #-------------------------------------------------------------------------
146 # Things related to aliases
146 # Things related to aliases
147 #-------------------------------------------------------------------------
147 #-------------------------------------------------------------------------
148
148
149 def init_alias(self):
149 def init_alias(self):
150 # The parent class defines aliases that can be safely used with any
150 # The parent class defines aliases that can be safely used with any
151 # frontend.
151 # frontend.
152 super(TerminalInteractiveShell, self).init_alias()
152 super(TerminalInteractiveShell, self).init_alias()
153
153
154 # Now define aliases that only make sense on the terminal, because they
154 # Now define aliases that only make sense on the terminal, because they
155 # need direct access to the console in a way that we can't emulate in
155 # need direct access to the console in a way that we can't emulate in
156 # GUI or web frontend
156 # GUI or web frontend
157 if os.name == 'posix':
157 if os.name == 'posix':
158 aliases = [('clear', 'clear'), ('more', 'more'), ('less', 'less'),
158 aliases = [('clear', 'clear'), ('more', 'more'), ('less', 'less'),
159 ('man', 'man')]
159 ('man', 'man')]
160 elif os.name == 'nt':
160 elif os.name == 'nt':
161 aliases = [('cls', 'cls')]
161 aliases = [('cls', 'cls')]
162
162
163
163
164 for name, cmd in aliases:
164 for name, cmd in aliases:
165 self.alias_manager.define_alias(name, cmd)
165 self.alias_manager.define_alias(name, cmd)
166
166
167 #-------------------------------------------------------------------------
167 #-------------------------------------------------------------------------
168 # Things related to the banner and usage
168 # Things related to the banner and usage
169 #-------------------------------------------------------------------------
169 #-------------------------------------------------------------------------
170
170
171 def _banner1_changed(self):
171 def _banner1_changed(self):
172 self.compute_banner()
172 self.compute_banner()
173
173
174 def _banner2_changed(self):
174 def _banner2_changed(self):
175 self.compute_banner()
175 self.compute_banner()
176
176
177 def _term_title_changed(self, name, new_value):
177 def _term_title_changed(self, name, new_value):
178 self.init_term_title()
178 self.init_term_title()
179
179
180 def init_banner(self, banner1, banner2, display_banner):
180 def init_banner(self, banner1, banner2, display_banner):
181 if banner1 is not None:
181 if banner1 is not None:
182 self.banner1 = banner1
182 self.banner1 = banner1
183 if banner2 is not None:
183 if banner2 is not None:
184 self.banner2 = banner2
184 self.banner2 = banner2
185 if display_banner is not None:
185 if display_banner is not None:
186 self.display_banner = display_banner
186 self.display_banner = display_banner
187 self.compute_banner()
187 self.compute_banner()
188
188
189 def show_banner(self, banner=None):
189 def show_banner(self, banner=None):
190 if banner is None:
190 if banner is None:
191 banner = self.banner
191 banner = self.banner
192 self.write(banner)
192 self.write(banner)
193
193
194 def compute_banner(self):
194 def compute_banner(self):
195 self.banner = self.banner1
195 self.banner = self.banner1
196 if self.profile and self.profile != 'default':
196 if self.profile and self.profile != 'default':
197 self.banner += '\nIPython profile: %s\n' % self.profile
197 self.banner += '\nIPython profile: %s\n' % self.profile
198 if self.banner2:
198 if self.banner2:
199 self.banner += '\n' + self.banner2
199 self.banner += '\n' + self.banner2
200
200
201 def init_usage(self, usage=None):
201 def init_usage(self, usage=None):
202 if usage is None:
202 if usage is None:
203 self.usage = interactive_usage
203 self.usage = interactive_usage
204 else:
204 else:
205 self.usage = usage
205 self.usage = usage
206
206
207 #-------------------------------------------------------------------------
207 #-------------------------------------------------------------------------
208 # Mainloop and code execution logic
208 # Mainloop and code execution logic
209 #-------------------------------------------------------------------------
209 #-------------------------------------------------------------------------
210
210
211 def mainloop(self, display_banner=None):
211 def mainloop(self, display_banner=None):
212 """Start the mainloop.
212 """Start the mainloop.
213
213
214 If an optional banner argument is given, it will override the
214 If an optional banner argument is given, it will override the
215 internally created default banner.
215 internally created default banner.
216 """
216 """
217
217
218 with nested(self.builtin_trap, self.display_trap):
218 with nested(self.builtin_trap, self.display_trap):
219
219
220 while 1:
220 while 1:
221 try:
221 try:
222 self.interact(display_banner=display_banner)
222 self.interact(display_banner=display_banner)
223 #self.interact_with_readline()
223 #self.interact_with_readline()
224 # XXX for testing of a readline-decoupled repl loop, call
224 # XXX for testing of a readline-decoupled repl loop, call
225 # interact_with_readline above
225 # interact_with_readline above
226 break
226 break
227 except KeyboardInterrupt:
227 except KeyboardInterrupt:
228 # this should not be necessary, but KeyboardInterrupt
228 # this should not be necessary, but KeyboardInterrupt
229 # handling seems rather unpredictable...
229 # handling seems rather unpredictable...
230 self.write("\nKeyboardInterrupt in interact()\n")
230 self.write("\nKeyboardInterrupt in interact()\n")
231
231
232 def _replace_rlhist_multiline(self, source_raw, hlen_before_cell):
232 def _replace_rlhist_multiline(self, source_raw, hlen_before_cell):
233 """Store multiple lines as a single entry in history"""
233 """Store multiple lines as a single entry in history"""
234 if self.multiline_history and self.has_readline:
234 if self.multiline_history and self.has_readline:
235 hlen = self.readline.get_current_history_length()
235 hlen = self.readline.get_current_history_length()
236 for i in range(hlen - hlen_before_cell):
236 for i in range(hlen - hlen_before_cell):
237 self.readline.remove_history_item(hlen - i - 1)
237 self.readline.remove_history_item(hlen - i - 1)
238 stdin_encoding = sys.stdin.encoding or "utf-8"
238 stdin_encoding = sys.stdin.encoding or "utf-8"
239 self.readline.add_history(py3compat.unicode_to_str(source_raw.rstrip(),
239 self.readline.add_history(py3compat.unicode_to_str(source_raw.rstrip(),
240 stdin_encoding))
240 stdin_encoding))
241
241
242 def interact(self, display_banner=None):
242 def interact(self, display_banner=None):
243 """Closely emulate the interactive Python console."""
243 """Closely emulate the interactive Python console."""
244
244
245 # batch run -> do not interact
245 # batch run -> do not interact
246 if self.exit_now:
246 if self.exit_now:
247 return
247 return
248
248
249 if display_banner is None:
249 if display_banner is None:
250 display_banner = self.display_banner
250 display_banner = self.display_banner
251
251
252 if isinstance(display_banner, basestring):
252 if isinstance(display_banner, basestring):
253 self.show_banner(display_banner)
253 self.show_banner(display_banner)
254 elif display_banner:
254 elif display_banner:
255 self.show_banner()
255 self.show_banner()
256
256
257 more = False
257 more = False
258 hlen_before_cell = self.readline.get_current_history_length()
258 hlen_before_cell = self.readline.get_current_history_length()
259
259
260 # Mark activity in the builtins
260 # Mark activity in the builtins
261 __builtin__.__dict__['__IPYTHON__active'] += 1
261 __builtin__.__dict__['__IPYTHON__active'] += 1
262
262
263 if self.has_readline:
263 if self.has_readline:
264 self.readline_startup_hook(self.pre_readline)
264 self.readline_startup_hook(self.pre_readline)
265 # exit_now is set by a call to %Exit or %Quit, through the
265 # exit_now is set by a call to %Exit or %Quit, through the
266 # ask_exit callback.
266 # ask_exit callback.
267
267
268 while not self.exit_now:
268 while not self.exit_now:
269 self.hooks.pre_prompt_hook()
269 self.hooks.pre_prompt_hook()
270 if more:
270 if more:
271 try:
271 try:
272 prompt = self.hooks.generate_prompt(True)
272 prompt = self.hooks.generate_prompt(True)
273 except:
273 except:
274 self.showtraceback()
274 self.showtraceback()
275 if self.autoindent:
275 if self.autoindent:
276 self.rl_do_indent = True
276 self.rl_do_indent = True
277
277
278 else:
278 else:
279 try:
279 try:
280 prompt = self.hooks.generate_prompt(False)
280 prompt = self.hooks.generate_prompt(False)
281 except:
281 except:
282 self.showtraceback()
282 self.showtraceback()
283 try:
283 try:
284 line = self.raw_input(prompt)
284 line = self.raw_input(prompt)
285 if self.exit_now:
285 if self.exit_now:
286 # quick exit on sys.std[in|out] close
286 # quick exit on sys.std[in|out] close
287 break
287 break
288 if self.autoindent:
288 if self.autoindent:
289 self.rl_do_indent = False
289 self.rl_do_indent = False
290
290
291 except KeyboardInterrupt:
291 except KeyboardInterrupt:
292 #double-guard against keyboardinterrupts during kbdint handling
292 #double-guard against keyboardinterrupts during kbdint handling
293 try:
293 try:
294 self.write('\nKeyboardInterrupt\n')
294 self.write('\nKeyboardInterrupt\n')
295 source_raw = self.input_splitter.source_raw_reset()[1]
295 source_raw = self.input_splitter.source_raw_reset()[1]
296 self._replace_rlhist_multiline(source_raw, hlen_before_cell)
296 self._replace_rlhist_multiline(source_raw, hlen_before_cell)
297 hlen_before_cell = self.readline.get_current_history_length()
297 hlen_before_cell = self.readline.get_current_history_length()
298 more = False
298 more = False
299 except KeyboardInterrupt:
299 except KeyboardInterrupt:
300 pass
300 pass
301 except EOFError:
301 except EOFError:
302 if self.autoindent:
302 if self.autoindent:
303 self.rl_do_indent = False
303 self.rl_do_indent = False
304 if self.has_readline:
304 if self.has_readline:
305 self.readline_startup_hook(None)
305 self.readline_startup_hook(None)
306 self.write('\n')
306 self.write('\n')
307 self.exit()
307 self.exit()
308 except bdb.BdbQuit:
308 except bdb.BdbQuit:
309 warn('The Python debugger has exited with a BdbQuit exception.\n'
309 warn('The Python debugger has exited with a BdbQuit exception.\n'
310 'Because of how pdb handles the stack, it is impossible\n'
310 'Because of how pdb handles the stack, it is impossible\n'
311 'for IPython to properly format this particular exception.\n'
311 'for IPython to properly format this particular exception.\n'
312 'IPython will resume normal operation.')
312 'IPython will resume normal operation.')
313 except:
313 except:
314 # exceptions here are VERY RARE, but they can be triggered
314 # exceptions here are VERY RARE, but they can be triggered
315 # asynchronously by signal handlers, for example.
315 # asynchronously by signal handlers, for example.
316 self.showtraceback()
316 self.showtraceback()
317 else:
317 else:
318 self.input_splitter.push(line)
318 self.input_splitter.push(line)
319 more = self.input_splitter.push_accepts_more()
319 more = self.input_splitter.push_accepts_more()
320 if (self.SyntaxTB.last_syntax_error and
320 if (self.SyntaxTB.last_syntax_error and
321 self.autoedit_syntax):
321 self.autoedit_syntax):
322 self.edit_syntax_error()
322 self.edit_syntax_error()
323 if not more:
323 if not more:
324 source_raw = self.input_splitter.source_raw_reset()[1]
324 source_raw = self.input_splitter.source_raw_reset()[1]
325 self._replace_rlhist_multiline(source_raw, hlen_before_cell)
325 self._replace_rlhist_multiline(source_raw, hlen_before_cell)
326 hlen_before_cell = self.readline.get_current_history_length()
326 hlen_before_cell = self.readline.get_current_history_length()
327 self.run_cell(source_raw, store_history=True)
327 self.run_cell(source_raw, store_history=True)
328
328
329 # We are off again...
329 # We are off again...
330 __builtin__.__dict__['__IPYTHON__active'] -= 1
330 __builtin__.__dict__['__IPYTHON__active'] -= 1
331
331
332 # Turn off the exit flag, so the mainloop can be restarted if desired
332 # Turn off the exit flag, so the mainloop can be restarted if desired
333 self.exit_now = False
333 self.exit_now = False
334
334
335 def raw_input(self, prompt=''):
335 def raw_input(self, prompt=''):
336 """Write a prompt and read a line.
336 """Write a prompt and read a line.
337
337
338 The returned line does not include the trailing newline.
338 The returned line does not include the trailing newline.
339 When the user enters the EOF key sequence, EOFError is raised.
339 When the user enters the EOF key sequence, EOFError is raised.
340
340
341 Optional inputs:
341 Optional inputs:
342
342
343 - prompt(''): a string to be printed to prompt the user.
343 - prompt(''): a string to be printed to prompt the user.
344
344
345 - continue_prompt(False): whether this line is the first one or a
345 - continue_prompt(False): whether this line is the first one or a
346 continuation in a sequence of inputs.
346 continuation in a sequence of inputs.
347 """
347 """
348 # Code run by the user may have modified the readline completer state.
348 # Code run by the user may have modified the readline completer state.
349 # We must ensure that our completer is back in place.
349 # We must ensure that our completer is back in place.
350
350
351 if self.has_readline:
351 if self.has_readline:
352 self.set_readline_completer()
352 self.set_readline_completer()
353
353
354 try:
354 try:
355 line = py3compat.str_to_unicode(self.raw_input_original(prompt))
355 line = py3compat.str_to_unicode(self.raw_input_original(prompt))
356 except ValueError:
356 except ValueError:
357 warn("\n********\nYou or a %run:ed script called sys.stdin.close()"
357 warn("\n********\nYou or a %run:ed script called sys.stdin.close()"
358 " or sys.stdout.close()!\nExiting IPython!")
358 " or sys.stdout.close()!\nExiting IPython!")
359 self.ask_exit()
359 self.ask_exit()
360 return ""
360 return ""
361
361
362 # Try to be reasonably smart about not re-indenting pasted input more
362 # Try to be reasonably smart about not re-indenting pasted input more
363 # than necessary. We do this by trimming out the auto-indent initial
363 # than necessary. We do this by trimming out the auto-indent initial
364 # spaces, if the user's actual input started itself with whitespace.
364 # spaces, if the user's actual input started itself with whitespace.
365 if self.autoindent:
365 if self.autoindent:
366 if num_ini_spaces(line) > self.indent_current_nsp:
366 if num_ini_spaces(line) > self.indent_current_nsp:
367 line = line[self.indent_current_nsp:]
367 line = line[self.indent_current_nsp:]
368 self.indent_current_nsp = 0
368 self.indent_current_nsp = 0
369
369
370 return line
370 return line
371
371
372 #-------------------------------------------------------------------------
372 #-------------------------------------------------------------------------
373 # Methods to support auto-editing of SyntaxErrors.
373 # Methods to support auto-editing of SyntaxErrors.
374 #-------------------------------------------------------------------------
374 #-------------------------------------------------------------------------
375
375
376 def edit_syntax_error(self):
376 def edit_syntax_error(self):
377 """The bottom half of the syntax error handler called in the main loop.
377 """The bottom half of the syntax error handler called in the main loop.
378
378
379 Loop until syntax error is fixed or user cancels.
379 Loop until syntax error is fixed or user cancels.
380 """
380 """
381
381
382 while self.SyntaxTB.last_syntax_error:
382 while self.SyntaxTB.last_syntax_error:
383 # copy and clear last_syntax_error
383 # copy and clear last_syntax_error
384 err = self.SyntaxTB.clear_err_state()
384 err = self.SyntaxTB.clear_err_state()
385 if not self._should_recompile(err):
385 if not self._should_recompile(err):
386 return
386 return
387 try:
387 try:
388 # may set last_syntax_error again if a SyntaxError is raised
388 # may set last_syntax_error again if a SyntaxError is raised
389 self.safe_execfile(err.filename,self.user_ns)
389 self.safe_execfile(err.filename,self.user_ns)
390 except:
390 except:
391 self.showtraceback()
391 self.showtraceback()
392 else:
392 else:
393 try:
393 try:
394 f = file(err.filename)
394 f = file(err.filename)
395 try:
395 try:
396 # This should be inside a display_trap block and I
396 # This should be inside a display_trap block and I
397 # think it is.
397 # think it is.
398 sys.displayhook(f.read())
398 sys.displayhook(f.read())
399 finally:
399 finally:
400 f.close()
400 f.close()
401 except:
401 except:
402 self.showtraceback()
402 self.showtraceback()
403
403
404 def _should_recompile(self,e):
404 def _should_recompile(self,e):
405 """Utility routine for edit_syntax_error"""
405 """Utility routine for edit_syntax_error"""
406
406
407 if e.filename in ('<ipython console>','<input>','<string>',
407 if e.filename in ('<ipython console>','<input>','<string>',
408 '<console>','<BackgroundJob compilation>',
408 '<console>','<BackgroundJob compilation>',
409 None):
409 None):
410
410
411 return False
411 return False
412 try:
412 try:
413 if (self.autoedit_syntax and
413 if (self.autoedit_syntax and
414 not self.ask_yes_no('Return to editor to correct syntax error? '
414 not self.ask_yes_no('Return to editor to correct syntax error? '
415 '[Y/n] ','y')):
415 '[Y/n] ','y')):
416 return False
416 return False
417 except EOFError:
417 except EOFError:
418 return False
418 return False
419
419
420 def int0(x):
420 def int0(x):
421 try:
421 try:
422 return int(x)
422 return int(x)
423 except TypeError:
423 except TypeError:
424 return 0
424 return 0
425 # always pass integer line and offset values to editor hook
425 # always pass integer line and offset values to editor hook
426 try:
426 try:
427 self.hooks.fix_error_editor(e.filename,
427 self.hooks.fix_error_editor(e.filename,
428 int0(e.lineno),int0(e.offset),e.msg)
428 int0(e.lineno),int0(e.offset),e.msg)
429 except TryNext:
429 except TryNext:
430 warn('Could not open editor')
430 warn('Could not open editor')
431 return False
431 return False
432 return True
432 return True
433
433
434 #-------------------------------------------------------------------------
434 #-------------------------------------------------------------------------
435 # Things related to GUI support and pylab
435 # Things related to GUI support and pylab
436 #-------------------------------------------------------------------------
436 #-------------------------------------------------------------------------
437
437
438 def enable_pylab(self, gui=None, import_all=True):
438 def enable_pylab(self, gui=None, import_all=True):
439 """Activate pylab support at runtime.
439 """Activate pylab support at runtime.
440
440
441 This turns on support for matplotlib, preloads into the interactive
441 This turns on support for matplotlib, preloads into the interactive
442 namespace all of numpy and pylab, and configures IPython to correcdtly
442 namespace all of numpy and pylab, and configures IPython to correcdtly
443 interact with the GUI event loop. The GUI backend to be used can be
443 interact with the GUI event loop. The GUI backend to be used can be
444 optionally selected with the optional :param:`gui` argument.
444 optionally selected with the optional :param:`gui` argument.
445
445
446 Parameters
446 Parameters
447 ----------
447 ----------
448 gui : optional, string
448 gui : optional, string
449
449
450 If given, dictates the choice of matplotlib GUI backend to use
450 If given, dictates the choice of matplotlib GUI backend to use
451 (should be one of IPython's supported backends, 'tk', 'qt', 'wx' or
451 (should be one of IPython's supported backends, 'tk', 'qt', 'wx' or
452 'gtk'), otherwise we use the default chosen by matplotlib (as
452 'gtk'), otherwise we use the default chosen by matplotlib (as
453 dictated by the matplotlib build-time options plus the user's
453 dictated by the matplotlib build-time options plus the user's
454 matplotlibrc configuration file).
454 matplotlibrc configuration file).
455 """
455 """
456 # We want to prevent the loading of pylab to pollute the user's
456 # We want to prevent the loading of pylab to pollute the user's
457 # namespace as shown by the %who* magics, so we execute the activation
457 # namespace as shown by the %who* magics, so we execute the activation
458 # code in an empty namespace, and we update *both* user_ns and
458 # code in an empty namespace, and we update *both* user_ns and
459 # user_ns_hidden with this information.
459 # user_ns_hidden with this information.
460 ns = {}
460 ns = {}
461 gui = pylab_activate(ns, gui, import_all)
461 try:
462 gui = pylab_activate(ns, gui, import_all)
463 except KeyError:
464 error("Backend %r not supported" % gui)
465 return
462 self.user_ns.update(ns)
466 self.user_ns.update(ns)
463 self.user_ns_hidden.update(ns)
467 self.user_ns_hidden.update(ns)
464 # Now we must activate the gui pylab wants to use, and fix %run to take
468 # Now we must activate the gui pylab wants to use, and fix %run to take
465 # plot updates into account
469 # plot updates into account
466 enable_gui(gui)
470 enable_gui(gui)
467 self.magic_run = self._pylab_magic_run
471 self.magic_run = self._pylab_magic_run
468
472
469 #-------------------------------------------------------------------------
473 #-------------------------------------------------------------------------
470 # Things related to exiting
474 # Things related to exiting
471 #-------------------------------------------------------------------------
475 #-------------------------------------------------------------------------
472
476
473 def ask_exit(self):
477 def ask_exit(self):
474 """ Ask the shell to exit. Can be overiden and used as a callback. """
478 """ Ask the shell to exit. Can be overiden and used as a callback. """
475 self.exit_now = True
479 self.exit_now = True
476
480
477 def exit(self):
481 def exit(self):
478 """Handle interactive exit.
482 """Handle interactive exit.
479
483
480 This method calls the ask_exit callback."""
484 This method calls the ask_exit callback."""
481 if self.confirm_exit:
485 if self.confirm_exit:
482 if self.ask_yes_no('Do you really want to exit ([y]/n)?','y'):
486 if self.ask_yes_no('Do you really want to exit ([y]/n)?','y'):
483 self.ask_exit()
487 self.ask_exit()
484 else:
488 else:
485 self.ask_exit()
489 self.ask_exit()
486
490
487 #------------------------------------------------------------------------
491 #------------------------------------------------------------------------
488 # Magic overrides
492 # Magic overrides
489 #------------------------------------------------------------------------
493 #------------------------------------------------------------------------
490 # Once the base class stops inheriting from magic, this code needs to be
494 # Once the base class stops inheriting from magic, this code needs to be
491 # moved into a separate machinery as well. For now, at least isolate here
495 # moved into a separate machinery as well. For now, at least isolate here
492 # the magics which this class needs to implement differently from the base
496 # the magics which this class needs to implement differently from the base
493 # class, or that are unique to it.
497 # class, or that are unique to it.
494
498
495 def magic_autoindent(self, parameter_s = ''):
499 def magic_autoindent(self, parameter_s = ''):
496 """Toggle autoindent on/off (if available)."""
500 """Toggle autoindent on/off (if available)."""
497
501
498 self.shell.set_autoindent()
502 self.shell.set_autoindent()
499 print "Automatic indentation is:",['OFF','ON'][self.shell.autoindent]
503 print "Automatic indentation is:",['OFF','ON'][self.shell.autoindent]
500
504
501 @skip_doctest
505 @skip_doctest
502 def magic_cpaste(self, parameter_s=''):
506 def magic_cpaste(self, parameter_s=''):
503 """Paste & execute a pre-formatted code block from clipboard.
507 """Paste & execute a pre-formatted code block from clipboard.
504
508
505 You must terminate the block with '--' (two minus-signs) or Ctrl-D alone on the
509 You must terminate the block with '--' (two minus-signs) or Ctrl-D alone on the
506 line. You can also provide your own sentinel with '%paste -s %%' ('%%'
510 line. You can also provide your own sentinel with '%paste -s %%' ('%%'
507 is the new sentinel for this operation)
511 is the new sentinel for this operation)
508
512
509 The block is dedented prior to execution to enable execution of method
513 The block is dedented prior to execution to enable execution of method
510 definitions. '>' and '+' characters at the beginning of a line are
514 definitions. '>' and '+' characters at the beginning of a line are
511 ignored, to allow pasting directly from e-mails, diff files and
515 ignored, to allow pasting directly from e-mails, diff files and
512 doctests (the '...' continuation prompt is also stripped). The
516 doctests (the '...' continuation prompt is also stripped). The
513 executed block is also assigned to variable named 'pasted_block' for
517 executed block is also assigned to variable named 'pasted_block' for
514 later editing with '%edit pasted_block'.
518 later editing with '%edit pasted_block'.
515
519
516 You can also pass a variable name as an argument, e.g. '%cpaste foo'.
520 You can also pass a variable name as an argument, e.g. '%cpaste foo'.
517 This assigns the pasted block to variable 'foo' as string, without
521 This assigns the pasted block to variable 'foo' as string, without
518 dedenting or executing it (preceding >>> and + is still stripped)
522 dedenting or executing it (preceding >>> and + is still stripped)
519
523
520 '%cpaste -r' re-executes the block previously entered by cpaste.
524 '%cpaste -r' re-executes the block previously entered by cpaste.
521
525
522 Do not be alarmed by garbled output on Windows (it's a readline bug).
526 Do not be alarmed by garbled output on Windows (it's a readline bug).
523 Just press enter and type -- (and press enter again) and the block
527 Just press enter and type -- (and press enter again) and the block
524 will be what was just pasted.
528 will be what was just pasted.
525
529
526 IPython statements (magics, shell escapes) are not supported (yet).
530 IPython statements (magics, shell escapes) are not supported (yet).
527
531
528 See also
532 See also
529 --------
533 --------
530 paste: automatically pull code from clipboard.
534 paste: automatically pull code from clipboard.
531
535
532 Examples
536 Examples
533 --------
537 --------
534 ::
538 ::
535
539
536 In [8]: %cpaste
540 In [8]: %cpaste
537 Pasting code; enter '--' alone on the line to stop.
541 Pasting code; enter '--' alone on the line to stop.
538 :>>> a = ["world!", "Hello"]
542 :>>> a = ["world!", "Hello"]
539 :>>> print " ".join(sorted(a))
543 :>>> print " ".join(sorted(a))
540 :--
544 :--
541 Hello world!
545 Hello world!
542 """
546 """
543
547
544 opts,args = self.parse_options(parameter_s,'rs:',mode='string')
548 opts,args = self.parse_options(parameter_s,'rs:',mode='string')
545 par = args.strip()
549 par = args.strip()
546 if opts.has_key('r'):
550 if opts.has_key('r'):
547 self._rerun_pasted()
551 self._rerun_pasted()
548 return
552 return
549
553
550 sentinel = opts.get('s','--')
554 sentinel = opts.get('s','--')
551
555
552 block = self._strip_pasted_lines_for_code(
556 block = self._strip_pasted_lines_for_code(
553 self._get_pasted_lines(sentinel))
557 self._get_pasted_lines(sentinel))
554
558
555 self._execute_block(block, par)
559 self._execute_block(block, par)
556
560
557 def magic_paste(self, parameter_s=''):
561 def magic_paste(self, parameter_s=''):
558 """Paste & execute a pre-formatted code block from clipboard.
562 """Paste & execute a pre-formatted code block from clipboard.
559
563
560 The text is pulled directly from the clipboard without user
564 The text is pulled directly from the clipboard without user
561 intervention and printed back on the screen before execution (unless
565 intervention and printed back on the screen before execution (unless
562 the -q flag is given to force quiet mode).
566 the -q flag is given to force quiet mode).
563
567
564 The block is dedented prior to execution to enable execution of method
568 The block is dedented prior to execution to enable execution of method
565 definitions. '>' and '+' characters at the beginning of a line are
569 definitions. '>' and '+' characters at the beginning of a line are
566 ignored, to allow pasting directly from e-mails, diff files and
570 ignored, to allow pasting directly from e-mails, diff files and
567 doctests (the '...' continuation prompt is also stripped). The
571 doctests (the '...' continuation prompt is also stripped). The
568 executed block is also assigned to variable named 'pasted_block' for
572 executed block is also assigned to variable named 'pasted_block' for
569 later editing with '%edit pasted_block'.
573 later editing with '%edit pasted_block'.
570
574
571 You can also pass a variable name as an argument, e.g. '%paste foo'.
575 You can also pass a variable name as an argument, e.g. '%paste foo'.
572 This assigns the pasted block to variable 'foo' as string, without
576 This assigns the pasted block to variable 'foo' as string, without
573 dedenting or executing it (preceding >>> and + is still stripped)
577 dedenting or executing it (preceding >>> and + is still stripped)
574
578
575 Options
579 Options
576 -------
580 -------
577
581
578 -r: re-executes the block previously entered by cpaste.
582 -r: re-executes the block previously entered by cpaste.
579
583
580 -q: quiet mode: do not echo the pasted text back to the terminal.
584 -q: quiet mode: do not echo the pasted text back to the terminal.
581
585
582 IPython statements (magics, shell escapes) are not supported (yet).
586 IPython statements (magics, shell escapes) are not supported (yet).
583
587
584 See also
588 See also
585 --------
589 --------
586 cpaste: manually paste code into terminal until you mark its end.
590 cpaste: manually paste code into terminal until you mark its end.
587 """
591 """
588 opts,args = self.parse_options(parameter_s,'rq',mode='string')
592 opts,args = self.parse_options(parameter_s,'rq',mode='string')
589 par = args.strip()
593 par = args.strip()
590 if opts.has_key('r'):
594 if opts.has_key('r'):
591 self._rerun_pasted()
595 self._rerun_pasted()
592 return
596 return
593
597
594 text = self.shell.hooks.clipboard_get()
598 text = self.shell.hooks.clipboard_get()
595 block = self._strip_pasted_lines_for_code(text.splitlines())
599 block = self._strip_pasted_lines_for_code(text.splitlines())
596
600
597 # By default, echo back to terminal unless quiet mode is requested
601 # By default, echo back to terminal unless quiet mode is requested
598 if not opts.has_key('q'):
602 if not opts.has_key('q'):
599 write = self.shell.write
603 write = self.shell.write
600 write(self.shell.pycolorize(block))
604 write(self.shell.pycolorize(block))
601 if not block.endswith('\n'):
605 if not block.endswith('\n'):
602 write('\n')
606 write('\n')
603 write("## -- End pasted text --\n")
607 write("## -- End pasted text --\n")
604
608
605 self._execute_block(block, par)
609 self._execute_block(block, par)
606
610
607 def showindentationerror(self):
611 def showindentationerror(self):
608 super(TerminalInteractiveShell, self).showindentationerror()
612 super(TerminalInteractiveShell, self).showindentationerror()
609 print("If you want to paste code into IPython, try the %paste magic function.")
613 print("If you want to paste code into IPython, try the %paste magic function.")
610
614
611
615
612 InteractiveShellABC.register(TerminalInteractiveShell)
616 InteractiveShellABC.register(TerminalInteractiveShell)
@@ -1,322 +1,322 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Pylab (matplotlib) support utilities.
2 """Pylab (matplotlib) support utilities.
3
3
4 Authors
4 Authors
5 -------
5 -------
6
6
7 * Fernando Perez.
7 * Fernando Perez.
8 * Brian Granger
8 * Brian Granger
9 """
9 """
10
10
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Copyright (C) 2009 The IPython Development Team
12 # Copyright (C) 2009 The IPython Development Team
13 #
13 #
14 # Distributed under the terms of the BSD License. The full license is in
14 # Distributed under the terms of the BSD License. The full license is in
15 # the file COPYING, distributed as part of this software.
15 # the file COPYING, distributed as part of this software.
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17
17
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19 # Imports
19 # Imports
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21
21
22 from io import BytesIO
22 from io import BytesIO
23
23
24 from IPython.utils.decorators import flag_calls
24 from IPython.utils.decorators import flag_calls
25
25
26 # If user specifies a GUI, that dictates the backend, otherwise we read the
26 # If user specifies a GUI, that dictates the backend, otherwise we read the
27 # user's mpl default from the mpl rc structure
27 # user's mpl default from the mpl rc structure
28 backends = {'tk': 'TkAgg',
28 backends = {'tk': 'TkAgg',
29 'gtk': 'GTKAgg',
29 'gtk': 'GTKAgg',
30 'wx': 'WXAgg',
30 'wx': 'WXAgg',
31 'qt': 'Qt4Agg', # qt3 not supported
31 'qt': 'Qt4Agg', # qt3 not supported
32 'qt4': 'Qt4Agg',
32 'qt4': 'Qt4Agg',
33 'osx': 'MacOSX',
33 'osx': 'MacOSX',
34 'inline' : 'module://IPython.zmq.pylab.backend_inline'}
34 'inline' : 'module://IPython.zmq.pylab.backend_inline'}
35
35
36 # We also need a reverse backends2guis mapping that will properly choose which
36 # We also need a reverse backends2guis mapping that will properly choose which
37 # GUI support to activate based on the desired matplotlib backend. For the
37 # GUI support to activate based on the desired matplotlib backend. For the
38 # most part it's just a reverse of the above dict, but we also need to add a
38 # most part it's just a reverse of the above dict, but we also need to add a
39 # few others that map to the same GUI manually:
39 # few others that map to the same GUI manually:
40 backend2gui = dict(zip(backends.values(), backends.keys()))
40 backend2gui = dict(zip(backends.values(), backends.keys()))
41 # In the reverse mapping, there are a few extra valid matplotlib backends that
41 # In the reverse mapping, there are a few extra valid matplotlib backends that
42 # map to the same GUI support
42 # map to the same GUI support
43 backend2gui['GTK'] = backend2gui['GTKCairo'] = 'gtk'
43 backend2gui['GTK'] = backend2gui['GTKCairo'] = 'gtk'
44 backend2gui['WX'] = 'wx'
44 backend2gui['WX'] = 'wx'
45 backend2gui['CocoaAgg'] = 'osx'
45 backend2gui['CocoaAgg'] = 'osx'
46
46
47 #-----------------------------------------------------------------------------
47 #-----------------------------------------------------------------------------
48 # Matplotlib utilities
48 # Matplotlib utilities
49 #-----------------------------------------------------------------------------
49 #-----------------------------------------------------------------------------
50
50
51
51
52 def getfigs(*fig_nums):
52 def getfigs(*fig_nums):
53 """Get a list of matplotlib figures by figure numbers.
53 """Get a list of matplotlib figures by figure numbers.
54
54
55 If no arguments are given, all available figures are returned. If the
55 If no arguments are given, all available figures are returned. If the
56 argument list contains references to invalid figures, a warning is printed
56 argument list contains references to invalid figures, a warning is printed
57 but the function continues pasting further figures.
57 but the function continues pasting further figures.
58
58
59 Parameters
59 Parameters
60 ----------
60 ----------
61 figs : tuple
61 figs : tuple
62 A tuple of ints giving the figure numbers of the figures to return.
62 A tuple of ints giving the figure numbers of the figures to return.
63 """
63 """
64 from matplotlib._pylab_helpers import Gcf
64 from matplotlib._pylab_helpers import Gcf
65 if not fig_nums:
65 if not fig_nums:
66 fig_managers = Gcf.get_all_fig_managers()
66 fig_managers = Gcf.get_all_fig_managers()
67 return [fm.canvas.figure for fm in fig_managers]
67 return [fm.canvas.figure for fm in fig_managers]
68 else:
68 else:
69 figs = []
69 figs = []
70 for num in fig_nums:
70 for num in fig_nums:
71 f = Gcf.figs.get(num)
71 f = Gcf.figs.get(num)
72 if f is None:
72 if f is None:
73 print('Warning: figure %s not available.' % num)
73 print('Warning: figure %s not available.' % num)
74 else:
74 else:
75 figs.append(f.canvas.figure)
75 figs.append(f.canvas.figure)
76 return figs
76 return figs
77
77
78
78
79 def figsize(sizex, sizey):
79 def figsize(sizex, sizey):
80 """Set the default figure size to be [sizex, sizey].
80 """Set the default figure size to be [sizex, sizey].
81
81
82 This is just an easy to remember, convenience wrapper that sets::
82 This is just an easy to remember, convenience wrapper that sets::
83
83
84 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
84 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
85 """
85 """
86 import matplotlib
86 import matplotlib
87 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
87 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
88
88
89
89
90 def print_figure(fig, fmt='png'):
90 def print_figure(fig, fmt='png'):
91 """Convert a figure to svg or png for inline display."""
91 """Convert a figure to svg or png for inline display."""
92 # When there's an empty figure, we shouldn't return anything, otherwise we
92 # When there's an empty figure, we shouldn't return anything, otherwise we
93 # get big blank areas in the qt console.
93 # get big blank areas in the qt console.
94 if not fig.axes:
94 if not fig.axes:
95 return
95 return
96
96
97 fc = fig.get_facecolor()
97 fc = fig.get_facecolor()
98 ec = fig.get_edgecolor()
98 ec = fig.get_edgecolor()
99 fig.set_facecolor('white')
99 fig.set_facecolor('white')
100 fig.set_edgecolor('white')
100 fig.set_edgecolor('white')
101 try:
101 try:
102 bytes_io = BytesIO()
102 bytes_io = BytesIO()
103 # use 72 dpi to match QTConsole's dpi
103 # use 72 dpi to match QTConsole's dpi
104 fig.canvas.print_figure(bytes_io, format=fmt, dpi=72,
104 fig.canvas.print_figure(bytes_io, format=fmt, dpi=72,
105 bbox_inches='tight')
105 bbox_inches='tight')
106 data = bytes_io.getvalue()
106 data = bytes_io.getvalue()
107 finally:
107 finally:
108 fig.set_facecolor(fc)
108 fig.set_facecolor(fc)
109 fig.set_edgecolor(ec)
109 fig.set_edgecolor(ec)
110 return data
110 return data
111
111
112
112
113 # We need a little factory function here to create the closure where
113 # We need a little factory function here to create the closure where
114 # safe_execfile can live.
114 # safe_execfile can live.
115 def mpl_runner(safe_execfile):
115 def mpl_runner(safe_execfile):
116 """Factory to return a matplotlib-enabled runner for %run.
116 """Factory to return a matplotlib-enabled runner for %run.
117
117
118 Parameters
118 Parameters
119 ----------
119 ----------
120 safe_execfile : function
120 safe_execfile : function
121 This must be a function with the same interface as the
121 This must be a function with the same interface as the
122 :meth:`safe_execfile` method of IPython.
122 :meth:`safe_execfile` method of IPython.
123
123
124 Returns
124 Returns
125 -------
125 -------
126 A function suitable for use as the ``runner`` argument of the %run magic
126 A function suitable for use as the ``runner`` argument of the %run magic
127 function.
127 function.
128 """
128 """
129
129
130 def mpl_execfile(fname,*where,**kw):
130 def mpl_execfile(fname,*where,**kw):
131 """matplotlib-aware wrapper around safe_execfile.
131 """matplotlib-aware wrapper around safe_execfile.
132
132
133 Its interface is identical to that of the :func:`execfile` builtin.
133 Its interface is identical to that of the :func:`execfile` builtin.
134
134
135 This is ultimately a call to execfile(), but wrapped in safeties to
135 This is ultimately a call to execfile(), but wrapped in safeties to
136 properly handle interactive rendering."""
136 properly handle interactive rendering."""
137
137
138 import matplotlib
138 import matplotlib
139 import matplotlib.pylab as pylab
139 import matplotlib.pylab as pylab
140
140
141 #print '*** Matplotlib runner ***' # dbg
141 #print '*** Matplotlib runner ***' # dbg
142 # turn off rendering until end of script
142 # turn off rendering until end of script
143 is_interactive = matplotlib.rcParams['interactive']
143 is_interactive = matplotlib.rcParams['interactive']
144 matplotlib.interactive(False)
144 matplotlib.interactive(False)
145 safe_execfile(fname,*where,**kw)
145 safe_execfile(fname,*where,**kw)
146 matplotlib.interactive(is_interactive)
146 matplotlib.interactive(is_interactive)
147 # make rendering call now, if the user tried to do it
147 # make rendering call now, if the user tried to do it
148 if pylab.draw_if_interactive.called:
148 if pylab.draw_if_interactive.called:
149 pylab.draw()
149 pylab.draw()
150 pylab.draw_if_interactive.called = False
150 pylab.draw_if_interactive.called = False
151
151
152 return mpl_execfile
152 return mpl_execfile
153
153
154
154
155 def select_figure_format(shell, fmt):
155 def select_figure_format(shell, fmt):
156 """Select figure format for inline backend, either 'png' or 'svg'.
156 """Select figure format for inline backend, either 'png' or 'svg'.
157
157
158 Using this method ensures only one figure format is active at a time.
158 Using this method ensures only one figure format is active at a time.
159 """
159 """
160 from matplotlib.figure import Figure
160 from matplotlib.figure import Figure
161 from IPython.zmq.pylab import backend_inline
161 from IPython.zmq.pylab import backend_inline
162
162
163 svg_formatter = shell.display_formatter.formatters['image/svg+xml']
163 svg_formatter = shell.display_formatter.formatters['image/svg+xml']
164 png_formatter = shell.display_formatter.formatters['image/png']
164 png_formatter = shell.display_formatter.formatters['image/png']
165
165
166 if fmt=='png':
166 if fmt=='png':
167 svg_formatter.type_printers.pop(Figure, None)
167 svg_formatter.type_printers.pop(Figure, None)
168 png_formatter.for_type(Figure, lambda fig: print_figure(fig, 'png'))
168 png_formatter.for_type(Figure, lambda fig: print_figure(fig, 'png'))
169 elif fmt=='svg':
169 elif fmt=='svg':
170 png_formatter.type_printers.pop(Figure, None)
170 png_formatter.type_printers.pop(Figure, None)
171 svg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'svg'))
171 svg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'svg'))
172 else:
172 else:
173 raise ValueError("supported formats are: 'png', 'svg', not %r"%fmt)
173 raise ValueError("supported formats are: 'png', 'svg', not %r"%fmt)
174
174
175 # set the format to be used in the backend()
175 # set the format to be used in the backend()
176 backend_inline._figure_format = fmt
176 backend_inline._figure_format = fmt
177
177
178 #-----------------------------------------------------------------------------
178 #-----------------------------------------------------------------------------
179 # Code for initializing matplotlib and importing pylab
179 # Code for initializing matplotlib and importing pylab
180 #-----------------------------------------------------------------------------
180 #-----------------------------------------------------------------------------
181
181
182
182
183 def find_gui_and_backend(gui=None):
183 def find_gui_and_backend(gui=None):
184 """Given a gui string return the gui and mpl backend.
184 """Given a gui string return the gui and mpl backend.
185
185
186 Parameters
186 Parameters
187 ----------
187 ----------
188 gui : str
188 gui : str
189 Can be one of ('tk','gtk','wx','qt','qt4','inline').
189 Can be one of ('tk','gtk','wx','qt','qt4','inline').
190
190
191 Returns
191 Returns
192 -------
192 -------
193 A tuple of (gui, backend) where backend is one of ('TkAgg','GTKAgg',
193 A tuple of (gui, backend) where backend is one of ('TkAgg','GTKAgg',
194 'WXAgg','Qt4Agg','module://IPython.zmq.pylab.backend_inline').
194 'WXAgg','Qt4Agg','module://IPython.zmq.pylab.backend_inline').
195 """
195 """
196
196
197 import matplotlib
197 import matplotlib
198
198
199 if gui:
199 if gui and gui != 'auto':
200 # select backend based on requested gui
200 # select backend based on requested gui
201 backend = backends[gui]
201 backend = backends[gui]
202 else:
202 else:
203 backend = matplotlib.rcParams['backend']
203 backend = matplotlib.rcParams['backend']
204 # In this case, we need to find what the appropriate gui selection call
204 # In this case, we need to find what the appropriate gui selection call
205 # should be for IPython, so we can activate inputhook accordingly
205 # should be for IPython, so we can activate inputhook accordingly
206 gui = backend2gui.get(backend, None)
206 gui = backend2gui.get(backend, None)
207 return gui, backend
207 return gui, backend
208
208
209
209
210 def activate_matplotlib(backend):
210 def activate_matplotlib(backend):
211 """Activate the given backend and set interactive to True."""
211 """Activate the given backend and set interactive to True."""
212
212
213 import matplotlib
213 import matplotlib
214 if backend.startswith('module://'):
214 if backend.startswith('module://'):
215 # Work around bug in matplotlib: matplotlib.use converts the
215 # Work around bug in matplotlib: matplotlib.use converts the
216 # backend_id to lowercase even if a module name is specified!
216 # backend_id to lowercase even if a module name is specified!
217 matplotlib.rcParams['backend'] = backend
217 matplotlib.rcParams['backend'] = backend
218 else:
218 else:
219 matplotlib.use(backend)
219 matplotlib.use(backend)
220 matplotlib.interactive(True)
220 matplotlib.interactive(True)
221
221
222 # This must be imported last in the matplotlib series, after
222 # This must be imported last in the matplotlib series, after
223 # backend/interactivity choices have been made
223 # backend/interactivity choices have been made
224 import matplotlib.pylab as pylab
224 import matplotlib.pylab as pylab
225
225
226 # XXX For now leave this commented out, but depending on discussions with
226 # XXX For now leave this commented out, but depending on discussions with
227 # mpl-dev, we may be able to allow interactive switching...
227 # mpl-dev, we may be able to allow interactive switching...
228 #import matplotlib.pyplot
228 #import matplotlib.pyplot
229 #matplotlib.pyplot.switch_backend(backend)
229 #matplotlib.pyplot.switch_backend(backend)
230
230
231 pylab.show._needmain = False
231 pylab.show._needmain = False
232 # We need to detect at runtime whether show() is called by the user.
232 # We need to detect at runtime whether show() is called by the user.
233 # For this, we wrap it into a decorator which adds a 'called' flag.
233 # For this, we wrap it into a decorator which adds a 'called' flag.
234 pylab.draw_if_interactive = flag_calls(pylab.draw_if_interactive)
234 pylab.draw_if_interactive = flag_calls(pylab.draw_if_interactive)
235
235
236 def import_pylab(user_ns, backend, import_all=True, shell=None):
236 def import_pylab(user_ns, backend, import_all=True, shell=None):
237 """Import the standard pylab symbols into user_ns."""
237 """Import the standard pylab symbols into user_ns."""
238
238
239 # Import numpy as np/pyplot as plt are conventions we're trying to
239 # Import numpy as np/pyplot as plt are conventions we're trying to
240 # somewhat standardize on. Making them available to users by default
240 # somewhat standardize on. Making them available to users by default
241 # will greatly help this.
241 # will greatly help this.
242 s = ("import numpy\n"
242 s = ("import numpy\n"
243 "import matplotlib\n"
243 "import matplotlib\n"
244 "from matplotlib import pylab, mlab, pyplot\n"
244 "from matplotlib import pylab, mlab, pyplot\n"
245 "np = numpy\n"
245 "np = numpy\n"
246 "plt = pyplot\n"
246 "plt = pyplot\n"
247 )
247 )
248 exec s in user_ns
248 exec s in user_ns
249
249
250 if shell is not None:
250 if shell is not None:
251 exec s in shell.user_ns_hidden
251 exec s in shell.user_ns_hidden
252 # If using our svg payload backend, register the post-execution
252 # If using our svg payload backend, register the post-execution
253 # function that will pick up the results for display. This can only be
253 # function that will pick up the results for display. This can only be
254 # done with access to the real shell object.
254 # done with access to the real shell object.
255 #
255 #
256 from IPython.zmq.pylab.backend_inline import InlineBackendConfig
256 from IPython.zmq.pylab.backend_inline import InlineBackendConfig
257
257
258 cfg = InlineBackendConfig.instance(config=shell.config)
258 cfg = InlineBackendConfig.instance(config=shell.config)
259 cfg.shell = shell
259 cfg.shell = shell
260
260
261 if backend == backends['inline']:
261 if backend == backends['inline']:
262 from IPython.zmq.pylab.backend_inline import flush_figures
262 from IPython.zmq.pylab.backend_inline import flush_figures
263 from matplotlib import pyplot
263 from matplotlib import pyplot
264 shell.register_post_execute(flush_figures)
264 shell.register_post_execute(flush_figures)
265 # load inline_rc
265 # load inline_rc
266 pyplot.rcParams.update(cfg.rc)
266 pyplot.rcParams.update(cfg.rc)
267
267
268 # Add 'figsize' to pyplot and to the user's namespace
268 # Add 'figsize' to pyplot and to the user's namespace
269 user_ns['figsize'] = pyplot.figsize = figsize
269 user_ns['figsize'] = pyplot.figsize = figsize
270 shell.user_ns_hidden['figsize'] = figsize
270 shell.user_ns_hidden['figsize'] = figsize
271
271
272 # Setup the default figure format
272 # Setup the default figure format
273 fmt = cfg.figure_format
273 fmt = cfg.figure_format
274 select_figure_format(shell, fmt)
274 select_figure_format(shell, fmt)
275
275
276 # The old pastefig function has been replaced by display
276 # The old pastefig function has been replaced by display
277 from IPython.core.display import display
277 from IPython.core.display import display
278 # Add display and display_png to the user's namespace
278 # Add display and display_png to the user's namespace
279 user_ns['display'] = display
279 user_ns['display'] = display
280 shell.user_ns_hidden['display'] = display
280 shell.user_ns_hidden['display'] = display
281 user_ns['getfigs'] = getfigs
281 user_ns['getfigs'] = getfigs
282 shell.user_ns_hidden['getfigs'] = getfigs
282 shell.user_ns_hidden['getfigs'] = getfigs
283
283
284 if import_all:
284 if import_all:
285 s = ("from matplotlib.pylab import *\n"
285 s = ("from matplotlib.pylab import *\n"
286 "from numpy import *\n")
286 "from numpy import *\n")
287 exec s in user_ns
287 exec s in user_ns
288 if shell is not None:
288 if shell is not None:
289 exec s in shell.user_ns_hidden
289 exec s in shell.user_ns_hidden
290
290
291
291
292 def pylab_activate(user_ns, gui=None, import_all=True, shell=None):
292 def pylab_activate(user_ns, gui=None, import_all=True, shell=None):
293 """Activate pylab mode in the user's namespace.
293 """Activate pylab mode in the user's namespace.
294
294
295 Loads and initializes numpy, matplotlib and friends for interactive use.
295 Loads and initializes numpy, matplotlib and friends for interactive use.
296
296
297 Parameters
297 Parameters
298 ----------
298 ----------
299 user_ns : dict
299 user_ns : dict
300 Namespace where the imports will occur.
300 Namespace where the imports will occur.
301
301
302 gui : optional, string
302 gui : optional, string
303 A valid gui name following the conventions of the %gui magic.
303 A valid gui name following the conventions of the %gui magic.
304
304
305 import_all : optional, boolean
305 import_all : optional, boolean
306 If true, an 'import *' is done from numpy and pylab.
306 If true, an 'import *' is done from numpy and pylab.
307
307
308 Returns
308 Returns
309 -------
309 -------
310 The actual gui used (if not given as input, it was obtained from matplotlib
310 The actual gui used (if not given as input, it was obtained from matplotlib
311 itself, and will be needed next to configure IPython's gui integration.
311 itself, and will be needed next to configure IPython's gui integration.
312 """
312 """
313 gui, backend = find_gui_and_backend(gui)
313 gui, backend = find_gui_and_backend(gui)
314 activate_matplotlib(backend)
314 activate_matplotlib(backend)
315 import_pylab(user_ns, backend, import_all, shell)
315 import_pylab(user_ns, backend, import_all, shell)
316
316
317 print """
317 print """
318 Welcome to pylab, a matplotlib-based Python environment [backend: %s].
318 Welcome to pylab, a matplotlib-based Python environment [backend: %s].
319 For more information, type 'help(pylab)'.""" % backend
319 For more information, type 'help(pylab)'.""" % backend
320
320
321 return gui
321 return gui
322
322
@@ -1,790 +1,789 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 """A simple interactive kernel that talks to a frontend over 0MQ.
2 """A simple interactive kernel that talks to a frontend over 0MQ.
3
3
4 Things to do:
4 Things to do:
5
5
6 * Implement `set_parent` logic. Right before doing exec, the Kernel should
6 * Implement `set_parent` logic. Right before doing exec, the Kernel should
7 call set_parent on all the PUB objects with the message about to be executed.
7 call set_parent on all the PUB objects with the message about to be executed.
8 * Implement random port and security key logic.
8 * Implement random port and security key logic.
9 * Implement control messages.
9 * Implement control messages.
10 * Implement event loop and poll version.
10 * Implement event loop and poll version.
11 """
11 """
12
12
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 # Imports
14 # Imports
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16 from __future__ import print_function
16 from __future__ import print_function
17
17
18 # Standard library imports.
18 # Standard library imports.
19 import __builtin__
19 import __builtin__
20 import atexit
20 import atexit
21 import sys
21 import sys
22 import time
22 import time
23 import traceback
23 import traceback
24 import logging
24 import logging
25
25
26 # System library imports.
26 # System library imports.
27 import zmq
27 import zmq
28
28
29 # Local imports.
29 # Local imports.
30 from IPython.config.configurable import Configurable
30 from IPython.config.configurable import Configurable
31 from IPython.config.application import boolean_flag
31 from IPython.config.application import boolean_flag
32 from IPython.core.application import ProfileDir
32 from IPython.core.application import ProfileDir
33 from IPython.core.error import StdinNotImplementedError
33 from IPython.core.error import StdinNotImplementedError
34 from IPython.core.shellapp import (
34 from IPython.core.shellapp import (
35 InteractiveShellApp, shell_flags, shell_aliases
35 InteractiveShellApp, shell_flags, shell_aliases
36 )
36 )
37 from IPython.utils import io
37 from IPython.utils import io
38 from IPython.utils import py3compat
38 from IPython.utils import py3compat
39 from IPython.utils.jsonutil import json_clean
39 from IPython.utils.jsonutil import json_clean
40 from IPython.lib import pylabtools
40 from IPython.lib import pylabtools
41 from IPython.utils.traitlets import (
41 from IPython.utils.traitlets import (
42 Any, List, Instance, Float, Dict, Bool, Int, Unicode, CaselessStrEnum
42 Any, List, Instance, Float, Dict, Bool, Int, Unicode, CaselessStrEnum
43 )
43 )
44
44
45 from entry_point import base_launch_kernel
45 from entry_point import base_launch_kernel
46 from kernelapp import KernelApp, kernel_flags, kernel_aliases
46 from kernelapp import KernelApp, kernel_flags, kernel_aliases
47 from iostream import OutStream
47 from iostream import OutStream
48 from session import Session, Message
48 from session import Session, Message
49 from zmqshell import ZMQInteractiveShell
49 from zmqshell import ZMQInteractiveShell
50
50
51
51
52 #-----------------------------------------------------------------------------
52 #-----------------------------------------------------------------------------
53 # Main kernel class
53 # Main kernel class
54 #-----------------------------------------------------------------------------
54 #-----------------------------------------------------------------------------
55
55
56 class Kernel(Configurable):
56 class Kernel(Configurable):
57
57
58 #---------------------------------------------------------------------------
58 #---------------------------------------------------------------------------
59 # Kernel interface
59 # Kernel interface
60 #---------------------------------------------------------------------------
60 #---------------------------------------------------------------------------
61
61
62 # attribute to override with a GUI
62 # attribute to override with a GUI
63 eventloop = Any(None)
63 eventloop = Any(None)
64
64
65 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
65 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
66 session = Instance(Session)
66 session = Instance(Session)
67 shell_socket = Instance('zmq.Socket')
67 shell_socket = Instance('zmq.Socket')
68 iopub_socket = Instance('zmq.Socket')
68 iopub_socket = Instance('zmq.Socket')
69 stdin_socket = Instance('zmq.Socket')
69 stdin_socket = Instance('zmq.Socket')
70 log = Instance(logging.Logger)
70 log = Instance(logging.Logger)
71
71
72 # Private interface
72 # Private interface
73
73
74 # Time to sleep after flushing the stdout/err buffers in each execute
74 # Time to sleep after flushing the stdout/err buffers in each execute
75 # cycle. While this introduces a hard limit on the minimal latency of the
75 # cycle. While this introduces a hard limit on the minimal latency of the
76 # execute cycle, it helps prevent output synchronization problems for
76 # execute cycle, it helps prevent output synchronization problems for
77 # clients.
77 # clients.
78 # Units are in seconds. The minimum zmq latency on local host is probably
78 # Units are in seconds. The minimum zmq latency on local host is probably
79 # ~150 microseconds, set this to 500us for now. We may need to increase it
79 # ~150 microseconds, set this to 500us for now. We may need to increase it
80 # a little if it's not enough after more interactive testing.
80 # a little if it's not enough after more interactive testing.
81 _execute_sleep = Float(0.0005, config=True)
81 _execute_sleep = Float(0.0005, config=True)
82
82
83 # Frequency of the kernel's event loop.
83 # Frequency of the kernel's event loop.
84 # Units are in seconds, kernel subclasses for GUI toolkits may need to
84 # Units are in seconds, kernel subclasses for GUI toolkits may need to
85 # adapt to milliseconds.
85 # adapt to milliseconds.
86 _poll_interval = Float(0.05, config=True)
86 _poll_interval = Float(0.05, config=True)
87
87
88 # If the shutdown was requested over the network, we leave here the
88 # If the shutdown was requested over the network, we leave here the
89 # necessary reply message so it can be sent by our registered atexit
89 # necessary reply message so it can be sent by our registered atexit
90 # handler. This ensures that the reply is only sent to clients truly at
90 # handler. This ensures that the reply is only sent to clients truly at
91 # the end of our shutdown process (which happens after the underlying
91 # the end of our shutdown process (which happens after the underlying
92 # IPython shell's own shutdown).
92 # IPython shell's own shutdown).
93 _shutdown_message = None
93 _shutdown_message = None
94
94
95 # This is a dict of port number that the kernel is listening on. It is set
95 # This is a dict of port number that the kernel is listening on. It is set
96 # by record_ports and used by connect_request.
96 # by record_ports and used by connect_request.
97 _recorded_ports = Dict()
97 _recorded_ports = Dict()
98
98
99
99
100
100
101 def __init__(self, **kwargs):
101 def __init__(self, **kwargs):
102 super(Kernel, self).__init__(**kwargs)
102 super(Kernel, self).__init__(**kwargs)
103
103
104 # Before we even start up the shell, register *first* our exit handlers
104 # Before we even start up the shell, register *first* our exit handlers
105 # so they come before the shell's
105 # so they come before the shell's
106 atexit.register(self._at_shutdown)
106 atexit.register(self._at_shutdown)
107
107
108 # Initialize the InteractiveShell subclass
108 # Initialize the InteractiveShell subclass
109 self.shell = ZMQInteractiveShell.instance(config=self.config)
109 self.shell = ZMQInteractiveShell.instance(config=self.config)
110 self.shell.displayhook.session = self.session
110 self.shell.displayhook.session = self.session
111 self.shell.displayhook.pub_socket = self.iopub_socket
111 self.shell.displayhook.pub_socket = self.iopub_socket
112 self.shell.display_pub.session = self.session
112 self.shell.display_pub.session = self.session
113 self.shell.display_pub.pub_socket = self.iopub_socket
113 self.shell.display_pub.pub_socket = self.iopub_socket
114
114
115 # TMP - hack while developing
115 # TMP - hack while developing
116 self.shell._reply_content = None
116 self.shell._reply_content = None
117
117
118 # Build dict of handlers for message types
118 # Build dict of handlers for message types
119 msg_types = [ 'execute_request', 'complete_request',
119 msg_types = [ 'execute_request', 'complete_request',
120 'object_info_request', 'history_request',
120 'object_info_request', 'history_request',
121 'connect_request', 'shutdown_request']
121 'connect_request', 'shutdown_request']
122 self.handlers = {}
122 self.handlers = {}
123 for msg_type in msg_types:
123 for msg_type in msg_types:
124 self.handlers[msg_type] = getattr(self, msg_type)
124 self.handlers[msg_type] = getattr(self, msg_type)
125
125
126 def do_one_iteration(self):
126 def do_one_iteration(self):
127 """Do one iteration of the kernel's evaluation loop.
127 """Do one iteration of the kernel's evaluation loop.
128 """
128 """
129 try:
129 try:
130 ident,msg = self.session.recv(self.shell_socket, zmq.NOBLOCK)
130 ident,msg = self.session.recv(self.shell_socket, zmq.NOBLOCK)
131 except Exception:
131 except Exception:
132 self.log.warn("Invalid Message:", exc_info=True)
132 self.log.warn("Invalid Message:", exc_info=True)
133 return
133 return
134 if msg is None:
134 if msg is None:
135 return
135 return
136
136
137 msg_type = msg['header']['msg_type']
137 msg_type = msg['header']['msg_type']
138
138
139 # This assert will raise in versions of zeromq 2.0.7 and lesser.
139 # This assert will raise in versions of zeromq 2.0.7 and lesser.
140 # We now require 2.0.8 or above, so we can uncomment for safety.
140 # We now require 2.0.8 or above, so we can uncomment for safety.
141 # print(ident,msg, file=sys.__stdout__)
141 # print(ident,msg, file=sys.__stdout__)
142 assert ident is not None, "Missing message part."
142 assert ident is not None, "Missing message part."
143
143
144 # Print some info about this message and leave a '--->' marker, so it's
144 # Print some info about this message and leave a '--->' marker, so it's
145 # easier to trace visually the message chain when debugging. Each
145 # easier to trace visually the message chain when debugging. Each
146 # handler prints its message at the end.
146 # handler prints its message at the end.
147 self.log.debug('\n*** MESSAGE TYPE:'+str(msg_type)+'***')
147 self.log.debug('\n*** MESSAGE TYPE:'+str(msg_type)+'***')
148 self.log.debug(' Content: '+str(msg['content'])+'\n --->\n ')
148 self.log.debug(' Content: '+str(msg['content'])+'\n --->\n ')
149
149
150 # Find and call actual handler for message
150 # Find and call actual handler for message
151 handler = self.handlers.get(msg_type, None)
151 handler = self.handlers.get(msg_type, None)
152 if handler is None:
152 if handler is None:
153 self.log.error("UNKNOWN MESSAGE TYPE:" +str(msg))
153 self.log.error("UNKNOWN MESSAGE TYPE:" +str(msg))
154 else:
154 else:
155 handler(ident, msg)
155 handler(ident, msg)
156
156
157 # Check whether we should exit, in case the incoming message set the
157 # Check whether we should exit, in case the incoming message set the
158 # exit flag on
158 # exit flag on
159 if self.shell.exit_now:
159 if self.shell.exit_now:
160 self.log.debug('\nExiting IPython kernel...')
160 self.log.debug('\nExiting IPython kernel...')
161 # We do a normal, clean exit, which allows any actions registered
161 # We do a normal, clean exit, which allows any actions registered
162 # via atexit (such as history saving) to take place.
162 # via atexit (such as history saving) to take place.
163 sys.exit(0)
163 sys.exit(0)
164
164
165
165
166 def start(self):
166 def start(self):
167 """ Start the kernel main loop.
167 """ Start the kernel main loop.
168 """
168 """
169 poller = zmq.Poller()
169 poller = zmq.Poller()
170 poller.register(self.shell_socket, zmq.POLLIN)
170 poller.register(self.shell_socket, zmq.POLLIN)
171 # loop while self.eventloop has not been overridden
171 # loop while self.eventloop has not been overridden
172 while self.eventloop is None:
172 while self.eventloop is None:
173 try:
173 try:
174 # scale by extra factor of 10, because there is no
174 # scale by extra factor of 10, because there is no
175 # reason for this to be anything less than ~ 0.1s
175 # reason for this to be anything less than ~ 0.1s
176 # since it is a real poller and will respond
176 # since it is a real poller and will respond
177 # to events immediately
177 # to events immediately
178
178
179 # double nested try/except, to properly catch KeyboardInterrupt
179 # double nested try/except, to properly catch KeyboardInterrupt
180 # due to pyzmq Issue #130
180 # due to pyzmq Issue #130
181 try:
181 try:
182 poller.poll(10*1000*self._poll_interval)
182 poller.poll(10*1000*self._poll_interval)
183 self.do_one_iteration()
183 self.do_one_iteration()
184 except:
184 except:
185 raise
185 raise
186 except KeyboardInterrupt:
186 except KeyboardInterrupt:
187 # Ctrl-C shouldn't crash the kernel
187 # Ctrl-C shouldn't crash the kernel
188 io.raw_print("KeyboardInterrupt caught in kernel")
188 io.raw_print("KeyboardInterrupt caught in kernel")
189 if self.eventloop is not None:
189 if self.eventloop is not None:
190 try:
190 try:
191 self.eventloop(self)
191 self.eventloop(self)
192 except KeyboardInterrupt:
192 except KeyboardInterrupt:
193 # Ctrl-C shouldn't crash the kernel
193 # Ctrl-C shouldn't crash the kernel
194 io.raw_print("KeyboardInterrupt caught in kernel")
194 io.raw_print("KeyboardInterrupt caught in kernel")
195
195
196
196
197 def record_ports(self, ports):
197 def record_ports(self, ports):
198 """Record the ports that this kernel is using.
198 """Record the ports that this kernel is using.
199
199
200 The creator of the Kernel instance must call this methods if they
200 The creator of the Kernel instance must call this methods if they
201 want the :meth:`connect_request` method to return the port numbers.
201 want the :meth:`connect_request` method to return the port numbers.
202 """
202 """
203 self._recorded_ports = ports
203 self._recorded_ports = ports
204
204
205 #---------------------------------------------------------------------------
205 #---------------------------------------------------------------------------
206 # Kernel request handlers
206 # Kernel request handlers
207 #---------------------------------------------------------------------------
207 #---------------------------------------------------------------------------
208
208
209 def _publish_pyin(self, code, parent):
209 def _publish_pyin(self, code, parent):
210 """Publish the code request on the pyin stream."""
210 """Publish the code request on the pyin stream."""
211
211
212 pyin_msg = self.session.send(self.iopub_socket, u'pyin',{u'code':code}, parent=parent)
212 pyin_msg = self.session.send(self.iopub_socket, u'pyin',{u'code':code}, parent=parent)
213
213
214 def execute_request(self, ident, parent):
214 def execute_request(self, ident, parent):
215
215
216 status_msg = self.session.send(self.iopub_socket,
216 status_msg = self.session.send(self.iopub_socket,
217 u'status',
217 u'status',
218 {u'execution_state':u'busy'},
218 {u'execution_state':u'busy'},
219 parent=parent
219 parent=parent
220 )
220 )
221
221
222 try:
222 try:
223 content = parent[u'content']
223 content = parent[u'content']
224 code = content[u'code']
224 code = content[u'code']
225 silent = content[u'silent']
225 silent = content[u'silent']
226 except:
226 except:
227 self.log.error("Got bad msg: ")
227 self.log.error("Got bad msg: ")
228 self.log.error(str(Message(parent)))
228 self.log.error(str(Message(parent)))
229 return
229 return
230
230
231 shell = self.shell # we'll need this a lot here
231 shell = self.shell # we'll need this a lot here
232
232
233 # Replace raw_input. Note that is not sufficient to replace
233 # Replace raw_input. Note that is not sufficient to replace
234 # raw_input in the user namespace.
234 # raw_input in the user namespace.
235 if content.get('allow_stdin', False):
235 if content.get('allow_stdin', False):
236 raw_input = lambda prompt='': self._raw_input(prompt, ident, parent)
236 raw_input = lambda prompt='': self._raw_input(prompt, ident, parent)
237 else:
237 else:
238 raw_input = lambda prompt='' : self._no_raw_input()
238 raw_input = lambda prompt='' : self._no_raw_input()
239
239
240 if py3compat.PY3:
240 if py3compat.PY3:
241 __builtin__.input = raw_input
241 __builtin__.input = raw_input
242 else:
242 else:
243 __builtin__.raw_input = raw_input
243 __builtin__.raw_input = raw_input
244
244
245 # Set the parent message of the display hook and out streams.
245 # Set the parent message of the display hook and out streams.
246 shell.displayhook.set_parent(parent)
246 shell.displayhook.set_parent(parent)
247 shell.display_pub.set_parent(parent)
247 shell.display_pub.set_parent(parent)
248 sys.stdout.set_parent(parent)
248 sys.stdout.set_parent(parent)
249 sys.stderr.set_parent(parent)
249 sys.stderr.set_parent(parent)
250
250
251 # Re-broadcast our input for the benefit of listening clients, and
251 # Re-broadcast our input for the benefit of listening clients, and
252 # start computing output
252 # start computing output
253 if not silent:
253 if not silent:
254 self._publish_pyin(code, parent)
254 self._publish_pyin(code, parent)
255
255
256 reply_content = {}
256 reply_content = {}
257 try:
257 try:
258 if silent:
258 if silent:
259 # run_code uses 'exec' mode, so no displayhook will fire, and it
259 # run_code uses 'exec' mode, so no displayhook will fire, and it
260 # doesn't call logging or history manipulations. Print
260 # doesn't call logging or history manipulations. Print
261 # statements in that code will obviously still execute.
261 # statements in that code will obviously still execute.
262 shell.run_code(code)
262 shell.run_code(code)
263 else:
263 else:
264 # FIXME: the shell calls the exception handler itself.
264 # FIXME: the shell calls the exception handler itself.
265 shell.run_cell(code, store_history=True)
265 shell.run_cell(code, store_history=True)
266 except:
266 except:
267 status = u'error'
267 status = u'error'
268 # FIXME: this code right now isn't being used yet by default,
268 # FIXME: this code right now isn't being used yet by default,
269 # because the run_cell() call above directly fires off exception
269 # because the run_cell() call above directly fires off exception
270 # reporting. This code, therefore, is only active in the scenario
270 # reporting. This code, therefore, is only active in the scenario
271 # where runlines itself has an unhandled exception. We need to
271 # where runlines itself has an unhandled exception. We need to
272 # uniformize this, for all exception construction to come from a
272 # uniformize this, for all exception construction to come from a
273 # single location in the codbase.
273 # single location in the codbase.
274 etype, evalue, tb = sys.exc_info()
274 etype, evalue, tb = sys.exc_info()
275 tb_list = traceback.format_exception(etype, evalue, tb)
275 tb_list = traceback.format_exception(etype, evalue, tb)
276 reply_content.update(shell._showtraceback(etype, evalue, tb_list))
276 reply_content.update(shell._showtraceback(etype, evalue, tb_list))
277 else:
277 else:
278 status = u'ok'
278 status = u'ok'
279
279
280 reply_content[u'status'] = status
280 reply_content[u'status'] = status
281
281
282 # Return the execution counter so clients can display prompts
282 # Return the execution counter so clients can display prompts
283 reply_content['execution_count'] = shell.execution_count -1
283 reply_content['execution_count'] = shell.execution_count -1
284
284
285 # FIXME - fish exception info out of shell, possibly left there by
285 # FIXME - fish exception info out of shell, possibly left there by
286 # runlines. We'll need to clean up this logic later.
286 # runlines. We'll need to clean up this logic later.
287 if shell._reply_content is not None:
287 if shell._reply_content is not None:
288 reply_content.update(shell._reply_content)
288 reply_content.update(shell._reply_content)
289 # reset after use
289 # reset after use
290 shell._reply_content = None
290 shell._reply_content = None
291
291
292 # At this point, we can tell whether the main code execution succeeded
292 # At this point, we can tell whether the main code execution succeeded
293 # or not. If it did, we proceed to evaluate user_variables/expressions
293 # or not. If it did, we proceed to evaluate user_variables/expressions
294 if reply_content['status'] == 'ok':
294 if reply_content['status'] == 'ok':
295 reply_content[u'user_variables'] = \
295 reply_content[u'user_variables'] = \
296 shell.user_variables(content[u'user_variables'])
296 shell.user_variables(content[u'user_variables'])
297 reply_content[u'user_expressions'] = \
297 reply_content[u'user_expressions'] = \
298 shell.user_expressions(content[u'user_expressions'])
298 shell.user_expressions(content[u'user_expressions'])
299 else:
299 else:
300 # If there was an error, don't even try to compute variables or
300 # If there was an error, don't even try to compute variables or
301 # expressions
301 # expressions
302 reply_content[u'user_variables'] = {}
302 reply_content[u'user_variables'] = {}
303 reply_content[u'user_expressions'] = {}
303 reply_content[u'user_expressions'] = {}
304
304
305 # Payloads should be retrieved regardless of outcome, so we can both
305 # Payloads should be retrieved regardless of outcome, so we can both
306 # recover partial output (that could have been generated early in a
306 # recover partial output (that could have been generated early in a
307 # block, before an error) and clear the payload system always.
307 # block, before an error) and clear the payload system always.
308 reply_content[u'payload'] = shell.payload_manager.read_payload()
308 reply_content[u'payload'] = shell.payload_manager.read_payload()
309 # Be agressive about clearing the payload because we don't want
309 # Be agressive about clearing the payload because we don't want
310 # it to sit in memory until the next execute_request comes in.
310 # it to sit in memory until the next execute_request comes in.
311 shell.payload_manager.clear_payload()
311 shell.payload_manager.clear_payload()
312
312
313 # Flush output before sending the reply.
313 # Flush output before sending the reply.
314 sys.stdout.flush()
314 sys.stdout.flush()
315 sys.stderr.flush()
315 sys.stderr.flush()
316 # FIXME: on rare occasions, the flush doesn't seem to make it to the
316 # FIXME: on rare occasions, the flush doesn't seem to make it to the
317 # clients... This seems to mitigate the problem, but we definitely need
317 # clients... This seems to mitigate the problem, but we definitely need
318 # to better understand what's going on.
318 # to better understand what's going on.
319 if self._execute_sleep:
319 if self._execute_sleep:
320 time.sleep(self._execute_sleep)
320 time.sleep(self._execute_sleep)
321
321
322 # Send the reply.
322 # Send the reply.
323 reply_content = json_clean(reply_content)
323 reply_content = json_clean(reply_content)
324 reply_msg = self.session.send(self.shell_socket, u'execute_reply',
324 reply_msg = self.session.send(self.shell_socket, u'execute_reply',
325 reply_content, parent, ident=ident)
325 reply_content, parent, ident=ident)
326 self.log.debug(str(reply_msg))
326 self.log.debug(str(reply_msg))
327
327
328 if reply_msg['content']['status'] == u'error':
328 if reply_msg['content']['status'] == u'error':
329 self._abort_queue()
329 self._abort_queue()
330
330
331 status_msg = self.session.send(self.iopub_socket,
331 status_msg = self.session.send(self.iopub_socket,
332 u'status',
332 u'status',
333 {u'execution_state':u'idle'},
333 {u'execution_state':u'idle'},
334 parent=parent
334 parent=parent
335 )
335 )
336
336
337 def complete_request(self, ident, parent):
337 def complete_request(self, ident, parent):
338 txt, matches = self._complete(parent)
338 txt, matches = self._complete(parent)
339 matches = {'matches' : matches,
339 matches = {'matches' : matches,
340 'matched_text' : txt,
340 'matched_text' : txt,
341 'status' : 'ok'}
341 'status' : 'ok'}
342 matches = json_clean(matches)
342 matches = json_clean(matches)
343 completion_msg = self.session.send(self.shell_socket, 'complete_reply',
343 completion_msg = self.session.send(self.shell_socket, 'complete_reply',
344 matches, parent, ident)
344 matches, parent, ident)
345 self.log.debug(str(completion_msg))
345 self.log.debug(str(completion_msg))
346
346
347 def object_info_request(self, ident, parent):
347 def object_info_request(self, ident, parent):
348 object_info = self.shell.object_inspect(parent['content']['oname'])
348 object_info = self.shell.object_inspect(parent['content']['oname'])
349 # Before we send this object over, we scrub it for JSON usage
349 # Before we send this object over, we scrub it for JSON usage
350 oinfo = json_clean(object_info)
350 oinfo = json_clean(object_info)
351 msg = self.session.send(self.shell_socket, 'object_info_reply',
351 msg = self.session.send(self.shell_socket, 'object_info_reply',
352 oinfo, parent, ident)
352 oinfo, parent, ident)
353 self.log.debug(msg)
353 self.log.debug(msg)
354
354
355 def history_request(self, ident, parent):
355 def history_request(self, ident, parent):
356 # We need to pull these out, as passing **kwargs doesn't work with
356 # We need to pull these out, as passing **kwargs doesn't work with
357 # unicode keys before Python 2.6.5.
357 # unicode keys before Python 2.6.5.
358 hist_access_type = parent['content']['hist_access_type']
358 hist_access_type = parent['content']['hist_access_type']
359 raw = parent['content']['raw']
359 raw = parent['content']['raw']
360 output = parent['content']['output']
360 output = parent['content']['output']
361 if hist_access_type == 'tail':
361 if hist_access_type == 'tail':
362 n = parent['content']['n']
362 n = parent['content']['n']
363 hist = self.shell.history_manager.get_tail(n, raw=raw, output=output,
363 hist = self.shell.history_manager.get_tail(n, raw=raw, output=output,
364 include_latest=True)
364 include_latest=True)
365
365
366 elif hist_access_type == 'range':
366 elif hist_access_type == 'range':
367 session = parent['content']['session']
367 session = parent['content']['session']
368 start = parent['content']['start']
368 start = parent['content']['start']
369 stop = parent['content']['stop']
369 stop = parent['content']['stop']
370 hist = self.shell.history_manager.get_range(session, start, stop,
370 hist = self.shell.history_manager.get_range(session, start, stop,
371 raw=raw, output=output)
371 raw=raw, output=output)
372
372
373 elif hist_access_type == 'search':
373 elif hist_access_type == 'search':
374 pattern = parent['content']['pattern']
374 pattern = parent['content']['pattern']
375 hist = self.shell.history_manager.search(pattern, raw=raw, output=output)
375 hist = self.shell.history_manager.search(pattern, raw=raw, output=output)
376
376
377 else:
377 else:
378 hist = []
378 hist = []
379 content = {'history' : list(hist)}
379 content = {'history' : list(hist)}
380 content = json_clean(content)
380 content = json_clean(content)
381 msg = self.session.send(self.shell_socket, 'history_reply',
381 msg = self.session.send(self.shell_socket, 'history_reply',
382 content, parent, ident)
382 content, parent, ident)
383 self.log.debug(str(msg))
383 self.log.debug(str(msg))
384
384
385 def connect_request(self, ident, parent):
385 def connect_request(self, ident, parent):
386 if self._recorded_ports is not None:
386 if self._recorded_ports is not None:
387 content = self._recorded_ports.copy()
387 content = self._recorded_ports.copy()
388 else:
388 else:
389 content = {}
389 content = {}
390 msg = self.session.send(self.shell_socket, 'connect_reply',
390 msg = self.session.send(self.shell_socket, 'connect_reply',
391 content, parent, ident)
391 content, parent, ident)
392 self.log.debug(msg)
392 self.log.debug(msg)
393
393
394 def shutdown_request(self, ident, parent):
394 def shutdown_request(self, ident, parent):
395 self.shell.exit_now = True
395 self.shell.exit_now = True
396 self._shutdown_message = self.session.msg(u'shutdown_reply', parent['content'], parent)
396 self._shutdown_message = self.session.msg(u'shutdown_reply', parent['content'], parent)
397 sys.exit(0)
397 sys.exit(0)
398
398
399 #---------------------------------------------------------------------------
399 #---------------------------------------------------------------------------
400 # Protected interface
400 # Protected interface
401 #---------------------------------------------------------------------------
401 #---------------------------------------------------------------------------
402
402
403 def _abort_queue(self):
403 def _abort_queue(self):
404 while True:
404 while True:
405 try:
405 try:
406 ident,msg = self.session.recv(self.shell_socket, zmq.NOBLOCK)
406 ident,msg = self.session.recv(self.shell_socket, zmq.NOBLOCK)
407 except Exception:
407 except Exception:
408 self.log.warn("Invalid Message:", exc_info=True)
408 self.log.warn("Invalid Message:", exc_info=True)
409 continue
409 continue
410 if msg is None:
410 if msg is None:
411 break
411 break
412 else:
412 else:
413 assert ident is not None, \
413 assert ident is not None, \
414 "Unexpected missing message part."
414 "Unexpected missing message part."
415
415
416 self.log.debug("Aborting:\n"+str(Message(msg)))
416 self.log.debug("Aborting:\n"+str(Message(msg)))
417 msg_type = msg['header']['msg_type']
417 msg_type = msg['header']['msg_type']
418 reply_type = msg_type.split('_')[0] + '_reply'
418 reply_type = msg_type.split('_')[0] + '_reply'
419 reply_msg = self.session.send(self.shell_socket, reply_type,
419 reply_msg = self.session.send(self.shell_socket, reply_type,
420 {'status' : 'aborted'}, msg, ident=ident)
420 {'status' : 'aborted'}, msg, ident=ident)
421 self.log.debug(reply_msg)
421 self.log.debug(reply_msg)
422 # We need to wait a bit for requests to come in. This can probably
422 # We need to wait a bit for requests to come in. This can probably
423 # be set shorter for true asynchronous clients.
423 # be set shorter for true asynchronous clients.
424 time.sleep(0.1)
424 time.sleep(0.1)
425
425
426 def _no_raw_input(self):
426 def _no_raw_input(self):
427 """Raise StdinNotImplentedError if active frontend doesn't support stdin."""
427 """Raise StdinNotImplentedError if active frontend doesn't support stdin."""
428 raise StdinNotImplementedError("raw_input was called, but this frontend does not support stdin.")
428 raise StdinNotImplementedError("raw_input was called, but this frontend does not support stdin.")
429
429
430 def _raw_input(self, prompt, ident, parent):
430 def _raw_input(self, prompt, ident, parent):
431 # Flush output before making the request.
431 # Flush output before making the request.
432 sys.stderr.flush()
432 sys.stderr.flush()
433 sys.stdout.flush()
433 sys.stdout.flush()
434
434
435 # Send the input request.
435 # Send the input request.
436 content = json_clean(dict(prompt=prompt))
436 content = json_clean(dict(prompt=prompt))
437 msg = self.session.send(self.stdin_socket, u'input_request', content, parent, ident=ident)
437 msg = self.session.send(self.stdin_socket, u'input_request', content, parent, ident=ident)
438
438
439 # Await a response.
439 # Await a response.
440 while True:
440 while True:
441 try:
441 try:
442 ident, reply = self.session.recv(self.stdin_socket, 0)
442 ident, reply = self.session.recv(self.stdin_socket, 0)
443 except Exception:
443 except Exception:
444 self.log.warn("Invalid Message:", exc_info=True)
444 self.log.warn("Invalid Message:", exc_info=True)
445 else:
445 else:
446 break
446 break
447 try:
447 try:
448 value = reply['content']['value']
448 value = reply['content']['value']
449 except:
449 except:
450 self.log.error("Got bad raw_input reply: ")
450 self.log.error("Got bad raw_input reply: ")
451 self.log.error(str(Message(parent)))
451 self.log.error(str(Message(parent)))
452 value = ''
452 value = ''
453 return value
453 return value
454
454
455 def _complete(self, msg):
455 def _complete(self, msg):
456 c = msg['content']
456 c = msg['content']
457 try:
457 try:
458 cpos = int(c['cursor_pos'])
458 cpos = int(c['cursor_pos'])
459 except:
459 except:
460 # If we don't get something that we can convert to an integer, at
460 # If we don't get something that we can convert to an integer, at
461 # least attempt the completion guessing the cursor is at the end of
461 # least attempt the completion guessing the cursor is at the end of
462 # the text, if there's any, and otherwise of the line
462 # the text, if there's any, and otherwise of the line
463 cpos = len(c['text'])
463 cpos = len(c['text'])
464 if cpos==0:
464 if cpos==0:
465 cpos = len(c['line'])
465 cpos = len(c['line'])
466 return self.shell.complete(c['text'], c['line'], cpos)
466 return self.shell.complete(c['text'], c['line'], cpos)
467
467
468 def _object_info(self, context):
468 def _object_info(self, context):
469 symbol, leftover = self._symbol_from_context(context)
469 symbol, leftover = self._symbol_from_context(context)
470 if symbol is not None and not leftover:
470 if symbol is not None and not leftover:
471 doc = getattr(symbol, '__doc__', '')
471 doc = getattr(symbol, '__doc__', '')
472 else:
472 else:
473 doc = ''
473 doc = ''
474 object_info = dict(docstring = doc)
474 object_info = dict(docstring = doc)
475 return object_info
475 return object_info
476
476
477 def _symbol_from_context(self, context):
477 def _symbol_from_context(self, context):
478 if not context:
478 if not context:
479 return None, context
479 return None, context
480
480
481 base_symbol_string = context[0]
481 base_symbol_string = context[0]
482 symbol = self.shell.user_ns.get(base_symbol_string, None)
482 symbol = self.shell.user_ns.get(base_symbol_string, None)
483 if symbol is None:
483 if symbol is None:
484 symbol = __builtin__.__dict__.get(base_symbol_string, None)
484 symbol = __builtin__.__dict__.get(base_symbol_string, None)
485 if symbol is None:
485 if symbol is None:
486 return None, context
486 return None, context
487
487
488 context = context[1:]
488 context = context[1:]
489 for i, name in enumerate(context):
489 for i, name in enumerate(context):
490 new_symbol = getattr(symbol, name, None)
490 new_symbol = getattr(symbol, name, None)
491 if new_symbol is None:
491 if new_symbol is None:
492 return symbol, context[i:]
492 return symbol, context[i:]
493 else:
493 else:
494 symbol = new_symbol
494 symbol = new_symbol
495
495
496 return symbol, []
496 return symbol, []
497
497
498 def _at_shutdown(self):
498 def _at_shutdown(self):
499 """Actions taken at shutdown by the kernel, called by python's atexit.
499 """Actions taken at shutdown by the kernel, called by python's atexit.
500 """
500 """
501 # io.rprint("Kernel at_shutdown") # dbg
501 # io.rprint("Kernel at_shutdown") # dbg
502 if self._shutdown_message is not None:
502 if self._shutdown_message is not None:
503 self.session.send(self.shell_socket, self._shutdown_message)
503 self.session.send(self.shell_socket, self._shutdown_message)
504 self.session.send(self.iopub_socket, self._shutdown_message)
504 self.session.send(self.iopub_socket, self._shutdown_message)
505 self.log.debug(str(self._shutdown_message))
505 self.log.debug(str(self._shutdown_message))
506 # A very short sleep to give zmq time to flush its message buffers
506 # A very short sleep to give zmq time to flush its message buffers
507 # before Python truly shuts down.
507 # before Python truly shuts down.
508 time.sleep(0.01)
508 time.sleep(0.01)
509
509
510
510
511 #------------------------------------------------------------------------------
511 #------------------------------------------------------------------------------
512 # Eventloops for integrating the Kernel into different GUIs
512 # Eventloops for integrating the Kernel into different GUIs
513 #------------------------------------------------------------------------------
513 #------------------------------------------------------------------------------
514
514
515
515
516 def loop_qt4(kernel):
516 def loop_qt4(kernel):
517 """Start a kernel with PyQt4 event loop integration."""
517 """Start a kernel with PyQt4 event loop integration."""
518
518
519 from IPython.external.qt_for_kernel import QtCore
519 from IPython.external.qt_for_kernel import QtCore
520 from IPython.lib.guisupport import get_app_qt4, start_event_loop_qt4
520 from IPython.lib.guisupport import get_app_qt4, start_event_loop_qt4
521
521
522 kernel.app = get_app_qt4([" "])
522 kernel.app = get_app_qt4([" "])
523 kernel.app.setQuitOnLastWindowClosed(False)
523 kernel.app.setQuitOnLastWindowClosed(False)
524 kernel.timer = QtCore.QTimer()
524 kernel.timer = QtCore.QTimer()
525 kernel.timer.timeout.connect(kernel.do_one_iteration)
525 kernel.timer.timeout.connect(kernel.do_one_iteration)
526 # Units for the timer are in milliseconds
526 # Units for the timer are in milliseconds
527 kernel.timer.start(1000*kernel._poll_interval)
527 kernel.timer.start(1000*kernel._poll_interval)
528 start_event_loop_qt4(kernel.app)
528 start_event_loop_qt4(kernel.app)
529
529
530
530
531 def loop_wx(kernel):
531 def loop_wx(kernel):
532 """Start a kernel with wx event loop support."""
532 """Start a kernel with wx event loop support."""
533
533
534 import wx
534 import wx
535 from IPython.lib.guisupport import start_event_loop_wx
535 from IPython.lib.guisupport import start_event_loop_wx
536
536
537 doi = kernel.do_one_iteration
537 doi = kernel.do_one_iteration
538 # Wx uses milliseconds
538 # Wx uses milliseconds
539 poll_interval = int(1000*kernel._poll_interval)
539 poll_interval = int(1000*kernel._poll_interval)
540
540
541 # We have to put the wx.Timer in a wx.Frame for it to fire properly.
541 # We have to put the wx.Timer in a wx.Frame for it to fire properly.
542 # We make the Frame hidden when we create it in the main app below.
542 # We make the Frame hidden when we create it in the main app below.
543 class TimerFrame(wx.Frame):
543 class TimerFrame(wx.Frame):
544 def __init__(self, func):
544 def __init__(self, func):
545 wx.Frame.__init__(self, None, -1)
545 wx.Frame.__init__(self, None, -1)
546 self.timer = wx.Timer(self)
546 self.timer = wx.Timer(self)
547 # Units for the timer are in milliseconds
547 # Units for the timer are in milliseconds
548 self.timer.Start(poll_interval)
548 self.timer.Start(poll_interval)
549 self.Bind(wx.EVT_TIMER, self.on_timer)
549 self.Bind(wx.EVT_TIMER, self.on_timer)
550 self.func = func
550 self.func = func
551
551
552 def on_timer(self, event):
552 def on_timer(self, event):
553 self.func()
553 self.func()
554
554
555 # We need a custom wx.App to create our Frame subclass that has the
555 # We need a custom wx.App to create our Frame subclass that has the
556 # wx.Timer to drive the ZMQ event loop.
556 # wx.Timer to drive the ZMQ event loop.
557 class IPWxApp(wx.App):
557 class IPWxApp(wx.App):
558 def OnInit(self):
558 def OnInit(self):
559 self.frame = TimerFrame(doi)
559 self.frame = TimerFrame(doi)
560 self.frame.Show(False)
560 self.frame.Show(False)
561 return True
561 return True
562
562
563 # The redirect=False here makes sure that wx doesn't replace
563 # The redirect=False here makes sure that wx doesn't replace
564 # sys.stdout/stderr with its own classes.
564 # sys.stdout/stderr with its own classes.
565 kernel.app = IPWxApp(redirect=False)
565 kernel.app = IPWxApp(redirect=False)
566 start_event_loop_wx(kernel.app)
566 start_event_loop_wx(kernel.app)
567
567
568
568
569 def loop_tk(kernel):
569 def loop_tk(kernel):
570 """Start a kernel with the Tk event loop."""
570 """Start a kernel with the Tk event loop."""
571
571
572 import Tkinter
572 import Tkinter
573 doi = kernel.do_one_iteration
573 doi = kernel.do_one_iteration
574 # Tk uses milliseconds
574 # Tk uses milliseconds
575 poll_interval = int(1000*kernel._poll_interval)
575 poll_interval = int(1000*kernel._poll_interval)
576 # For Tkinter, we create a Tk object and call its withdraw method.
576 # For Tkinter, we create a Tk object and call its withdraw method.
577 class Timer(object):
577 class Timer(object):
578 def __init__(self, func):
578 def __init__(self, func):
579 self.app = Tkinter.Tk()
579 self.app = Tkinter.Tk()
580 self.app.withdraw()
580 self.app.withdraw()
581 self.func = func
581 self.func = func
582
582
583 def on_timer(self):
583 def on_timer(self):
584 self.func()
584 self.func()
585 self.app.after(poll_interval, self.on_timer)
585 self.app.after(poll_interval, self.on_timer)
586
586
587 def start(self):
587 def start(self):
588 self.on_timer() # Call it once to get things going.
588 self.on_timer() # Call it once to get things going.
589 self.app.mainloop()
589 self.app.mainloop()
590
590
591 kernel.timer = Timer(doi)
591 kernel.timer = Timer(doi)
592 kernel.timer.start()
592 kernel.timer.start()
593
593
594
594
595 def loop_gtk(kernel):
595 def loop_gtk(kernel):
596 """Start the kernel, coordinating with the GTK event loop"""
596 """Start the kernel, coordinating with the GTK event loop"""
597 from .gui.gtkembed import GTKEmbed
597 from .gui.gtkembed import GTKEmbed
598
598
599 gtk_kernel = GTKEmbed(kernel)
599 gtk_kernel = GTKEmbed(kernel)
600 gtk_kernel.start()
600 gtk_kernel.start()
601
601
602
602
603 def loop_cocoa(kernel):
603 def loop_cocoa(kernel):
604 """Start the kernel, coordinating with the Cocoa CFRunLoop event loop
604 """Start the kernel, coordinating with the Cocoa CFRunLoop event loop
605 via the matplotlib MacOSX backend.
605 via the matplotlib MacOSX backend.
606 """
606 """
607 import matplotlib
607 import matplotlib
608 if matplotlib.__version__ < '1.1.0':
608 if matplotlib.__version__ < '1.1.0':
609 kernel.log.warn(
609 kernel.log.warn(
610 "MacOSX backend in matplotlib %s doesn't have a Timer, "
610 "MacOSX backend in matplotlib %s doesn't have a Timer, "
611 "falling back on Tk for CFRunLoop integration. Note that "
611 "falling back on Tk for CFRunLoop integration. Note that "
612 "even this won't work if Tk is linked against X11 instead of "
612 "even this won't work if Tk is linked against X11 instead of "
613 "Cocoa (e.g. EPD). To use the MacOSX backend in the kernel, "
613 "Cocoa (e.g. EPD). To use the MacOSX backend in the kernel, "
614 "you must use matplotlib >= 1.1.0, or a native libtk."
614 "you must use matplotlib >= 1.1.0, or a native libtk."
615 )
615 )
616 return loop_tk(kernel)
616 return loop_tk(kernel)
617
617
618 from matplotlib.backends.backend_macosx import TimerMac, show
618 from matplotlib.backends.backend_macosx import TimerMac, show
619
619
620 # scale interval for sec->ms
620 # scale interval for sec->ms
621 poll_interval = int(1000*kernel._poll_interval)
621 poll_interval = int(1000*kernel._poll_interval)
622
622
623 real_excepthook = sys.excepthook
623 real_excepthook = sys.excepthook
624 def handle_int(etype, value, tb):
624 def handle_int(etype, value, tb):
625 """don't let KeyboardInterrupts look like crashes"""
625 """don't let KeyboardInterrupts look like crashes"""
626 if etype is KeyboardInterrupt:
626 if etype is KeyboardInterrupt:
627 io.raw_print("KeyboardInterrupt caught in CFRunLoop")
627 io.raw_print("KeyboardInterrupt caught in CFRunLoop")
628 else:
628 else:
629 real_excepthook(etype, value, tb)
629 real_excepthook(etype, value, tb)
630
630
631 # add doi() as a Timer to the CFRunLoop
631 # add doi() as a Timer to the CFRunLoop
632 def doi():
632 def doi():
633 # restore excepthook during IPython code
633 # restore excepthook during IPython code
634 sys.excepthook = real_excepthook
634 sys.excepthook = real_excepthook
635 kernel.do_one_iteration()
635 kernel.do_one_iteration()
636 # and back:
636 # and back:
637 sys.excepthook = handle_int
637 sys.excepthook = handle_int
638
638
639 t = TimerMac(poll_interval)
639 t = TimerMac(poll_interval)
640 t.add_callback(doi)
640 t.add_callback(doi)
641 t.start()
641 t.start()
642
642
643 # but still need a Poller for when there are no active windows,
643 # but still need a Poller for when there are no active windows,
644 # during which time mainloop() returns immediately
644 # during which time mainloop() returns immediately
645 poller = zmq.Poller()
645 poller = zmq.Poller()
646 poller.register(kernel.shell_socket, zmq.POLLIN)
646 poller.register(kernel.shell_socket, zmq.POLLIN)
647
647
648 while True:
648 while True:
649 try:
649 try:
650 # double nested try/except, to properly catch KeyboardInterrupt
650 # double nested try/except, to properly catch KeyboardInterrupt
651 # due to pyzmq Issue #130
651 # due to pyzmq Issue #130
652 try:
652 try:
653 # don't let interrupts during mainloop invoke crash_handler:
653 # don't let interrupts during mainloop invoke crash_handler:
654 sys.excepthook = handle_int
654 sys.excepthook = handle_int
655 show.mainloop()
655 show.mainloop()
656 sys.excepthook = real_excepthook
656 sys.excepthook = real_excepthook
657 # use poller if mainloop returned (no windows)
657 # use poller if mainloop returned (no windows)
658 # scale by extra factor of 10, since it's a real poll
658 # scale by extra factor of 10, since it's a real poll
659 poller.poll(10*poll_interval)
659 poller.poll(10*poll_interval)
660 kernel.do_one_iteration()
660 kernel.do_one_iteration()
661 except:
661 except:
662 raise
662 raise
663 except KeyboardInterrupt:
663 except KeyboardInterrupt:
664 # Ctrl-C shouldn't crash the kernel
664 # Ctrl-C shouldn't crash the kernel
665 io.raw_print("KeyboardInterrupt caught in kernel")
665 io.raw_print("KeyboardInterrupt caught in kernel")
666 finally:
666 finally:
667 # ensure excepthook is restored
667 # ensure excepthook is restored
668 sys.excepthook = real_excepthook
668 sys.excepthook = real_excepthook
669
669
670 # mapping of keys to loop functions
670 # mapping of keys to loop functions
671 loop_map = {
671 loop_map = {
672 'qt' : loop_qt4,
672 'qt' : loop_qt4,
673 'qt4': loop_qt4,
673 'qt4': loop_qt4,
674 'inline': None,
674 'inline': None,
675 'osx': loop_cocoa,
675 'osx': loop_cocoa,
676 'wx' : loop_wx,
676 'wx' : loop_wx,
677 'tk' : loop_tk,
677 'tk' : loop_tk,
678 'gtk': loop_gtk,
678 'gtk': loop_gtk,
679 }
679 }
680
680
681 def enable_gui(gui, kernel=None):
681 def enable_gui(gui, kernel=None):
682 """Enable integration with a give GUI"""
682 """Enable integration with a give GUI"""
683 if kernel is None:
683 if kernel is None:
684 kernel = IPKernelApp.instance().kernel
684 kernel = IPKernelApp.instance().kernel
685 if gui not in loop_map:
685 if gui not in loop_map:
686 raise ValueError("GUI %r not supported" % gui)
686 raise ValueError("GUI %r not supported" % gui)
687 loop = loop_map[gui]
687 loop = loop_map[gui]
688 if kernel.eventloop is not None and kernel.eventloop is not loop:
688 if kernel.eventloop is not None and kernel.eventloop is not loop:
689 raise RuntimeError("Cannot activate multiple GUI eventloops")
689 raise RuntimeError("Cannot activate multiple GUI eventloops")
690 kernel.eventloop = loop
690 kernel.eventloop = loop
691
691
692
692
693 #-----------------------------------------------------------------------------
693 #-----------------------------------------------------------------------------
694 # Aliases and Flags for the IPKernelApp
694 # Aliases and Flags for the IPKernelApp
695 #-----------------------------------------------------------------------------
695 #-----------------------------------------------------------------------------
696
696
697 flags = dict(kernel_flags)
697 flags = dict(kernel_flags)
698 flags.update(shell_flags)
698 flags.update(shell_flags)
699
699
700 addflag = lambda *args: flags.update(boolean_flag(*args))
700 addflag = lambda *args: flags.update(boolean_flag(*args))
701
701
702 flags['pylab'] = (
702 flags['pylab'] = (
703 {'IPKernelApp' : {'pylab' : 'auto'}},
703 {'IPKernelApp' : {'pylab' : 'auto'}},
704 """Pre-load matplotlib and numpy for interactive use with
704 """Pre-load matplotlib and numpy for interactive use with
705 the default matplotlib backend."""
705 the default matplotlib backend."""
706 )
706 )
707
707
708 aliases = dict(kernel_aliases)
708 aliases = dict(kernel_aliases)
709 aliases.update(shell_aliases)
709 aliases.update(shell_aliases)
710
710
711 # it's possible we don't want short aliases for *all* of these:
711 # it's possible we don't want short aliases for *all* of these:
712 aliases.update(dict(
712 aliases.update(dict(
713 pylab='IPKernelApp.pylab',
713 pylab='IPKernelApp.pylab',
714 ))
714 ))
715
715
716 #-----------------------------------------------------------------------------
716 #-----------------------------------------------------------------------------
717 # The IPKernelApp class
717 # The IPKernelApp class
718 #-----------------------------------------------------------------------------
718 #-----------------------------------------------------------------------------
719
719
720 class IPKernelApp(KernelApp, InteractiveShellApp):
720 class IPKernelApp(KernelApp, InteractiveShellApp):
721 name = 'ipkernel'
721 name = 'ipkernel'
722
722
723 aliases = Dict(aliases)
723 aliases = Dict(aliases)
724 flags = Dict(flags)
724 flags = Dict(flags)
725 classes = [Kernel, ZMQInteractiveShell, ProfileDir, Session]
725 classes = [Kernel, ZMQInteractiveShell, ProfileDir, Session]
726 # configurables
726 # configurables
727 pylab = CaselessStrEnum(['tk', 'qt', 'wx', 'gtk', 'osx', 'inline', 'auto'],
727 pylab = CaselessStrEnum(['tk', 'qt', 'wx', 'gtk', 'osx', 'inline', 'auto'],
728 config=True,
728 config=True,
729 help="""Pre-load matplotlib and numpy for interactive use,
729 help="""Pre-load matplotlib and numpy for interactive use,
730 selecting a particular matplotlib backend and loop integration.
730 selecting a particular matplotlib backend and loop integration.
731 """
731 """
732 )
732 )
733 def initialize(self, argv=None):
733 def initialize(self, argv=None):
734 super(IPKernelApp, self).initialize(argv)
734 super(IPKernelApp, self).initialize(argv)
735 self.init_shell()
735 self.init_shell()
736 self.init_extensions()
736 self.init_extensions()
737 self.init_code()
737 self.init_code()
738
738
739 def init_kernel(self):
739 def init_kernel(self):
740 kernel_factory = Kernel
740 kernel_factory = Kernel
741
741
742 if self.pylab:
742 if self.pylab:
743 key = None if self.pylab == 'auto' else self.pylab
743 gui, backend = pylabtools.find_gui_and_backend(self.pylab)
744 gui, backend = pylabtools.find_gui_and_backend(key)
745
744
746 kernel = kernel_factory(config=self.config, session=self.session,
745 kernel = kernel_factory(config=self.config, session=self.session,
747 shell_socket=self.shell_socket,
746 shell_socket=self.shell_socket,
748 iopub_socket=self.iopub_socket,
747 iopub_socket=self.iopub_socket,
749 stdin_socket=self.stdin_socket,
748 stdin_socket=self.stdin_socket,
750 log=self.log,
749 log=self.log,
751 )
750 )
752 self.kernel = kernel
751 self.kernel = kernel
753 kernel.record_ports(self.ports)
752 kernel.record_ports(self.ports)
754
753
755 if self.pylab:
754 if self.pylab:
756 kernel.shell.enable_pylab(gui, import_all=self.pylab_import_all)
755 kernel.shell.enable_pylab(gui, import_all=self.pylab_import_all)
757
756
758 def init_shell(self):
757 def init_shell(self):
759 self.shell = self.kernel.shell
758 self.shell = self.kernel.shell
760
759
761
760
762 #-----------------------------------------------------------------------------
761 #-----------------------------------------------------------------------------
763 # Kernel main and launch functions
762 # Kernel main and launch functions
764 #-----------------------------------------------------------------------------
763 #-----------------------------------------------------------------------------
765
764
766 def launch_kernel(*args, **kwargs):
765 def launch_kernel(*args, **kwargs):
767 """Launches a localhost IPython kernel, binding to the specified ports.
766 """Launches a localhost IPython kernel, binding to the specified ports.
768
767
769 This function simply calls entry_point.base_launch_kernel with the right first
768 This function simply calls entry_point.base_launch_kernel with the right first
770 command to start an ipkernel. See base_launch_kernel for arguments.
769 command to start an ipkernel. See base_launch_kernel for arguments.
771
770
772 Returns
771 Returns
773 -------
772 -------
774 A tuple of form:
773 A tuple of form:
775 (kernel_process, shell_port, iopub_port, stdin_port, hb_port)
774 (kernel_process, shell_port, iopub_port, stdin_port, hb_port)
776 where kernel_process is a Popen object and the ports are integers.
775 where kernel_process is a Popen object and the ports are integers.
777 """
776 """
778 return base_launch_kernel('from IPython.zmq.ipkernel import main; main()',
777 return base_launch_kernel('from IPython.zmq.ipkernel import main; main()',
779 *args, **kwargs)
778 *args, **kwargs)
780
779
781
780
782 def main():
781 def main():
783 """Run an IPKernel as an application"""
782 """Run an IPKernel as an application"""
784 app = IPKernelApp.instance()
783 app = IPKernelApp.instance()
785 app.initialize()
784 app.initialize()
786 app.start()
785 app.start()
787
786
788
787
789 if __name__ == '__main__':
788 if __name__ == '__main__':
790 main()
789 main()
@@ -1,548 +1,561 b''
1 """A ZMQ-based subclass of InteractiveShell.
1 """A ZMQ-based subclass of InteractiveShell.
2
2
3 This code is meant to ease the refactoring of the base InteractiveShell into
3 This code is meant to ease the refactoring of the base InteractiveShell into
4 something with a cleaner architecture for 2-process use, without actually
4 something with a cleaner architecture for 2-process use, without actually
5 breaking InteractiveShell itself. So we're doing something a bit ugly, where
5 breaking InteractiveShell itself. So we're doing something a bit ugly, where
6 we subclass and override what we want to fix. Once this is working well, we
6 we subclass and override what we want to fix. Once this is working well, we
7 can go back to the base class and refactor the code for a cleaner inheritance
7 can go back to the base class and refactor the code for a cleaner inheritance
8 implementation that doesn't rely on so much monkeypatching.
8 implementation that doesn't rely on so much monkeypatching.
9
9
10 But this lets us maintain a fully working IPython as we develop the new
10 But this lets us maintain a fully working IPython as we develop the new
11 machinery. This should thus be thought of as scaffolding.
11 machinery. This should thus be thought of as scaffolding.
12 """
12 """
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 # Imports
14 # Imports
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16 from __future__ import print_function
16 from __future__ import print_function
17
17
18 # Stdlib
18 # Stdlib
19 import inspect
19 import inspect
20 import os
20 import os
21 import sys
21 import sys
22 from subprocess import Popen, PIPE
22 from subprocess import Popen, PIPE
23
23
24 # Our own
24 # Our own
25 from IPython.core.interactiveshell import (
25 from IPython.core.interactiveshell import (
26 InteractiveShell, InteractiveShellABC
26 InteractiveShell, InteractiveShellABC
27 )
27 )
28 from IPython.core import page
28 from IPython.core import page
29 from IPython.core.autocall import ZMQExitAutocall
29 from IPython.core.autocall import ZMQExitAutocall
30 from IPython.core.displaypub import DisplayPublisher
30 from IPython.core.displaypub import DisplayPublisher
31 from IPython.core.macro import Macro
31 from IPython.core.macro import Macro
32 from IPython.core.magic import MacroToEdit
32 from IPython.core.magic import MacroToEdit
33 from IPython.core.payloadpage import install_payload_page
33 from IPython.core.payloadpage import install_payload_page
34 from IPython.lib import pylabtools
34 from IPython.lib import pylabtools
35 from IPython.lib.kernel import (
35 from IPython.lib.kernel import (
36 get_connection_file, get_connection_info, connect_qtconsole
36 get_connection_file, get_connection_info, connect_qtconsole
37 )
37 )
38 from IPython.utils import io
38 from IPython.utils import io
39 from IPython.utils.jsonutil import json_clean
39 from IPython.utils.jsonutil import json_clean
40 from IPython.utils.path import get_py_filename
40 from IPython.utils.path import get_py_filename
41 from IPython.utils.process import arg_split
41 from IPython.utils.process import arg_split
42 from IPython.utils.traitlets import Instance, Type, Dict, CBool
42 from IPython.utils.traitlets import Instance, Type, Dict, CBool
43 from IPython.utils.warn import warn, error
43 from IPython.utils.warn import warn, error
44 from IPython.zmq.displayhook import ZMQShellDisplayHook, _encode_binary
44 from IPython.zmq.displayhook import ZMQShellDisplayHook, _encode_binary
45 from IPython.zmq.session import extract_header
45 from IPython.zmq.session import extract_header
46 from session import Session
46 from session import Session
47
47
48 #-----------------------------------------------------------------------------
48 #-----------------------------------------------------------------------------
49 # Globals and side-effects
49 # Globals and side-effects
50 #-----------------------------------------------------------------------------
50 #-----------------------------------------------------------------------------
51
51
52 # Install the payload version of page.
52 # Install the payload version of page.
53 install_payload_page()
53 install_payload_page()
54
54
55 #-----------------------------------------------------------------------------
55 #-----------------------------------------------------------------------------
56 # Functions and classes
56 # Functions and classes
57 #-----------------------------------------------------------------------------
57 #-----------------------------------------------------------------------------
58
58
59 class ZMQDisplayPublisher(DisplayPublisher):
59 class ZMQDisplayPublisher(DisplayPublisher):
60 """A display publisher that publishes data using a ZeroMQ PUB socket."""
60 """A display publisher that publishes data using a ZeroMQ PUB socket."""
61
61
62 session = Instance(Session)
62 session = Instance(Session)
63 pub_socket = Instance('zmq.Socket')
63 pub_socket = Instance('zmq.Socket')
64 parent_header = Dict({})
64 parent_header = Dict({})
65
65
66 def set_parent(self, parent):
66 def set_parent(self, parent):
67 """Set the parent for outbound messages."""
67 """Set the parent for outbound messages."""
68 self.parent_header = extract_header(parent)
68 self.parent_header = extract_header(parent)
69
69
70 def publish(self, source, data, metadata=None):
70 def publish(self, source, data, metadata=None):
71 if metadata is None:
71 if metadata is None:
72 metadata = {}
72 metadata = {}
73 self._validate_data(source, data, metadata)
73 self._validate_data(source, data, metadata)
74 content = {}
74 content = {}
75 content['source'] = source
75 content['source'] = source
76 _encode_binary(data)
76 _encode_binary(data)
77 content['data'] = data
77 content['data'] = data
78 content['metadata'] = metadata
78 content['metadata'] = metadata
79 self.session.send(
79 self.session.send(
80 self.pub_socket, u'display_data', json_clean(content),
80 self.pub_socket, u'display_data', json_clean(content),
81 parent=self.parent_header
81 parent=self.parent_header
82 )
82 )
83
83
84 def clear_output(self, stdout=True, stderr=True, other=True):
84 def clear_output(self, stdout=True, stderr=True, other=True):
85 content = dict(stdout=stdout, stderr=stderr, other=other)
85 content = dict(stdout=stdout, stderr=stderr, other=other)
86 self.session.send(
86 self.session.send(
87 self.pub_socket, u'clear_output', content,
87 self.pub_socket, u'clear_output', content,
88 parent=self.parent_header
88 parent=self.parent_header
89 )
89 )
90
90
91 class ZMQInteractiveShell(InteractiveShell):
91 class ZMQInteractiveShell(InteractiveShell):
92 """A subclass of InteractiveShell for ZMQ."""
92 """A subclass of InteractiveShell for ZMQ."""
93
93
94 displayhook_class = Type(ZMQShellDisplayHook)
94 displayhook_class = Type(ZMQShellDisplayHook)
95 display_pub_class = Type(ZMQDisplayPublisher)
95 display_pub_class = Type(ZMQDisplayPublisher)
96
96
97 # Override the traitlet in the parent class, because there's no point using
97 # Override the traitlet in the parent class, because there's no point using
98 # readline for the kernel. Can be removed when the readline code is moved
98 # readline for the kernel. Can be removed when the readline code is moved
99 # to the terminal frontend.
99 # to the terminal frontend.
100 colors_force = CBool(True)
100 colors_force = CBool(True)
101 readline_use = CBool(False)
101 readline_use = CBool(False)
102 # autoindent has no meaning in a zmqshell, and attempting to enable it
102 # autoindent has no meaning in a zmqshell, and attempting to enable it
103 # will print a warning in the absence of readline.
103 # will print a warning in the absence of readline.
104 autoindent = CBool(False)
104 autoindent = CBool(False)
105
105
106 exiter = Instance(ZMQExitAutocall)
106 exiter = Instance(ZMQExitAutocall)
107 def _exiter_default(self):
107 def _exiter_default(self):
108 return ZMQExitAutocall(self)
108 return ZMQExitAutocall(self)
109
109
110 keepkernel_on_exit = None
110 keepkernel_on_exit = None
111
111
112 def init_environment(self):
112 def init_environment(self):
113 """Configure the user's environment.
113 """Configure the user's environment.
114
114
115 """
115 """
116 env = os.environ
116 env = os.environ
117 # These two ensure 'ls' produces nice coloring on BSD-derived systems
117 # These two ensure 'ls' produces nice coloring on BSD-derived systems
118 env['TERM'] = 'xterm-color'
118 env['TERM'] = 'xterm-color'
119 env['CLICOLOR'] = '1'
119 env['CLICOLOR'] = '1'
120 # Since normal pagers don't work at all (over pexpect we don't have
120 # Since normal pagers don't work at all (over pexpect we don't have
121 # single-key control of the subprocess), try to disable paging in
121 # single-key control of the subprocess), try to disable paging in
122 # subprocesses as much as possible.
122 # subprocesses as much as possible.
123 env['PAGER'] = 'cat'
123 env['PAGER'] = 'cat'
124 env['GIT_PAGER'] = 'cat'
124 env['GIT_PAGER'] = 'cat'
125
125
126 def auto_rewrite_input(self, cmd):
126 def auto_rewrite_input(self, cmd):
127 """Called to show the auto-rewritten input for autocall and friends.
127 """Called to show the auto-rewritten input for autocall and friends.
128
128
129 FIXME: this payload is currently not correctly processed by the
129 FIXME: this payload is currently not correctly processed by the
130 frontend.
130 frontend.
131 """
131 """
132 new = self.displayhook.prompt1.auto_rewrite() + cmd
132 new = self.displayhook.prompt1.auto_rewrite() + cmd
133 payload = dict(
133 payload = dict(
134 source='IPython.zmq.zmqshell.ZMQInteractiveShell.auto_rewrite_input',
134 source='IPython.zmq.zmqshell.ZMQInteractiveShell.auto_rewrite_input',
135 transformed_input=new,
135 transformed_input=new,
136 )
136 )
137 self.payload_manager.write_payload(payload)
137 self.payload_manager.write_payload(payload)
138
138
139 def ask_exit(self):
139 def ask_exit(self):
140 """Engage the exit actions."""
140 """Engage the exit actions."""
141 payload = dict(
141 payload = dict(
142 source='IPython.zmq.zmqshell.ZMQInteractiveShell.ask_exit',
142 source='IPython.zmq.zmqshell.ZMQInteractiveShell.ask_exit',
143 exit=True,
143 exit=True,
144 keepkernel=self.keepkernel_on_exit,
144 keepkernel=self.keepkernel_on_exit,
145 )
145 )
146 self.payload_manager.write_payload(payload)
146 self.payload_manager.write_payload(payload)
147
147
148 def _showtraceback(self, etype, evalue, stb):
148 def _showtraceback(self, etype, evalue, stb):
149
149
150 exc_content = {
150 exc_content = {
151 u'traceback' : stb,
151 u'traceback' : stb,
152 u'ename' : unicode(etype.__name__),
152 u'ename' : unicode(etype.__name__),
153 u'evalue' : unicode(evalue)
153 u'evalue' : unicode(evalue)
154 }
154 }
155
155
156 dh = self.displayhook
156 dh = self.displayhook
157 # Send exception info over pub socket for other clients than the caller
157 # Send exception info over pub socket for other clients than the caller
158 # to pick up
158 # to pick up
159 exc_msg = dh.session.send(dh.pub_socket, u'pyerr', json_clean(exc_content), dh.parent_header)
159 exc_msg = dh.session.send(dh.pub_socket, u'pyerr', json_clean(exc_content), dh.parent_header)
160
160
161 # FIXME - Hack: store exception info in shell object. Right now, the
161 # FIXME - Hack: store exception info in shell object. Right now, the
162 # caller is reading this info after the fact, we need to fix this logic
162 # caller is reading this info after the fact, we need to fix this logic
163 # to remove this hack. Even uglier, we need to store the error status
163 # to remove this hack. Even uglier, we need to store the error status
164 # here, because in the main loop, the logic that sets it is being
164 # here, because in the main loop, the logic that sets it is being
165 # skipped because runlines swallows the exceptions.
165 # skipped because runlines swallows the exceptions.
166 exc_content[u'status'] = u'error'
166 exc_content[u'status'] = u'error'
167 self._reply_content = exc_content
167 self._reply_content = exc_content
168 # /FIXME
168 # /FIXME
169
169
170 return exc_content
170 return exc_content
171
171
172 #------------------------------------------------------------------------
172 #------------------------------------------------------------------------
173 # Magic overrides
173 # Magic overrides
174 #------------------------------------------------------------------------
174 #------------------------------------------------------------------------
175 # Once the base class stops inheriting from magic, this code needs to be
175 # Once the base class stops inheriting from magic, this code needs to be
176 # moved into a separate machinery as well. For now, at least isolate here
176 # moved into a separate machinery as well. For now, at least isolate here
177 # the magics which this class needs to implement differently from the base
177 # the magics which this class needs to implement differently from the base
178 # class, or that are unique to it.
178 # class, or that are unique to it.
179
179
180 def magic_doctest_mode(self,parameter_s=''):
180 def magic_doctest_mode(self,parameter_s=''):
181 """Toggle doctest mode on and off.
181 """Toggle doctest mode on and off.
182
182
183 This mode is intended to make IPython behave as much as possible like a
183 This mode is intended to make IPython behave as much as possible like a
184 plain Python shell, from the perspective of how its prompts, exceptions
184 plain Python shell, from the perspective of how its prompts, exceptions
185 and output look. This makes it easy to copy and paste parts of a
185 and output look. This makes it easy to copy and paste parts of a
186 session into doctests. It does so by:
186 session into doctests. It does so by:
187
187
188 - Changing the prompts to the classic ``>>>`` ones.
188 - Changing the prompts to the classic ``>>>`` ones.
189 - Changing the exception reporting mode to 'Plain'.
189 - Changing the exception reporting mode to 'Plain'.
190 - Disabling pretty-printing of output.
190 - Disabling pretty-printing of output.
191
191
192 Note that IPython also supports the pasting of code snippets that have
192 Note that IPython also supports the pasting of code snippets that have
193 leading '>>>' and '...' prompts in them. This means that you can paste
193 leading '>>>' and '...' prompts in them. This means that you can paste
194 doctests from files or docstrings (even if they have leading
194 doctests from files or docstrings (even if they have leading
195 whitespace), and the code will execute correctly. You can then use
195 whitespace), and the code will execute correctly. You can then use
196 '%history -t' to see the translated history; this will give you the
196 '%history -t' to see the translated history; this will give you the
197 input after removal of all the leading prompts and whitespace, which
197 input after removal of all the leading prompts and whitespace, which
198 can be pasted back into an editor.
198 can be pasted back into an editor.
199
199
200 With these features, you can switch into this mode easily whenever you
200 With these features, you can switch into this mode easily whenever you
201 need to do testing and changes to doctests, without having to leave
201 need to do testing and changes to doctests, without having to leave
202 your existing IPython session.
202 your existing IPython session.
203 """
203 """
204
204
205 from IPython.utils.ipstruct import Struct
205 from IPython.utils.ipstruct import Struct
206
206
207 # Shorthands
207 # Shorthands
208 shell = self.shell
208 shell = self.shell
209 disp_formatter = self.shell.display_formatter
209 disp_formatter = self.shell.display_formatter
210 ptformatter = disp_formatter.formatters['text/plain']
210 ptformatter = disp_formatter.formatters['text/plain']
211 # dstore is a data store kept in the instance metadata bag to track any
211 # dstore is a data store kept in the instance metadata bag to track any
212 # changes we make, so we can undo them later.
212 # changes we make, so we can undo them later.
213 dstore = shell.meta.setdefault('doctest_mode', Struct())
213 dstore = shell.meta.setdefault('doctest_mode', Struct())
214 save_dstore = dstore.setdefault
214 save_dstore = dstore.setdefault
215
215
216 # save a few values we'll need to recover later
216 # save a few values we'll need to recover later
217 mode = save_dstore('mode', False)
217 mode = save_dstore('mode', False)
218 save_dstore('rc_pprint', ptformatter.pprint)
218 save_dstore('rc_pprint', ptformatter.pprint)
219 save_dstore('rc_plain_text_only',disp_formatter.plain_text_only)
219 save_dstore('rc_plain_text_only',disp_formatter.plain_text_only)
220 save_dstore('xmode', shell.InteractiveTB.mode)
220 save_dstore('xmode', shell.InteractiveTB.mode)
221
221
222 if mode == False:
222 if mode == False:
223 # turn on
223 # turn on
224 ptformatter.pprint = False
224 ptformatter.pprint = False
225 disp_formatter.plain_text_only = True
225 disp_formatter.plain_text_only = True
226 shell.magic_xmode('Plain')
226 shell.magic_xmode('Plain')
227 else:
227 else:
228 # turn off
228 # turn off
229 ptformatter.pprint = dstore.rc_pprint
229 ptformatter.pprint = dstore.rc_pprint
230 disp_formatter.plain_text_only = dstore.rc_plain_text_only
230 disp_formatter.plain_text_only = dstore.rc_plain_text_only
231 shell.magic_xmode(dstore.xmode)
231 shell.magic_xmode(dstore.xmode)
232
232
233 # Store new mode and inform on console
233 # Store new mode and inform on console
234 dstore.mode = bool(1-int(mode))
234 dstore.mode = bool(1-int(mode))
235 mode_label = ['OFF','ON'][dstore.mode]
235 mode_label = ['OFF','ON'][dstore.mode]
236 print('Doctest mode is:', mode_label)
236 print('Doctest mode is:', mode_label)
237
237
238 # Send the payload back so that clients can modify their prompt display
238 # Send the payload back so that clients can modify their prompt display
239 payload = dict(
239 payload = dict(
240 source='IPython.zmq.zmqshell.ZMQInteractiveShell.magic_doctest_mode',
240 source='IPython.zmq.zmqshell.ZMQInteractiveShell.magic_doctest_mode',
241 mode=dstore.mode)
241 mode=dstore.mode)
242 self.payload_manager.write_payload(payload)
242 self.payload_manager.write_payload(payload)
243
243
244 def magic_edit(self,parameter_s='',last_call=['','']):
244 def magic_edit(self,parameter_s='',last_call=['','']):
245 """Bring up an editor and execute the resulting code.
245 """Bring up an editor and execute the resulting code.
246
246
247 Usage:
247 Usage:
248 %edit [options] [args]
248 %edit [options] [args]
249
249
250 %edit runs an external text editor. You will need to set the command for
250 %edit runs an external text editor. You will need to set the command for
251 this editor via the ``TerminalInteractiveShell.editor`` option in your
251 this editor via the ``TerminalInteractiveShell.editor`` option in your
252 configuration file before it will work.
252 configuration file before it will work.
253
253
254 This command allows you to conveniently edit multi-line code right in
254 This command allows you to conveniently edit multi-line code right in
255 your IPython session.
255 your IPython session.
256
256
257 If called without arguments, %edit opens up an empty editor with a
257 If called without arguments, %edit opens up an empty editor with a
258 temporary file and will execute the contents of this file when you
258 temporary file and will execute the contents of this file when you
259 close it (don't forget to save it!).
259 close it (don't forget to save it!).
260
260
261
261
262 Options:
262 Options:
263
263
264 -n <number>: open the editor at a specified line number. By default,
264 -n <number>: open the editor at a specified line number. By default,
265 the IPython editor hook uses the unix syntax 'editor +N filename', but
265 the IPython editor hook uses the unix syntax 'editor +N filename', but
266 you can configure this by providing your own modified hook if your
266 you can configure this by providing your own modified hook if your
267 favorite editor supports line-number specifications with a different
267 favorite editor supports line-number specifications with a different
268 syntax.
268 syntax.
269
269
270 -p: this will call the editor with the same data as the previous time
270 -p: this will call the editor with the same data as the previous time
271 it was used, regardless of how long ago (in your current session) it
271 it was used, regardless of how long ago (in your current session) it
272 was.
272 was.
273
273
274 -r: use 'raw' input. This option only applies to input taken from the
274 -r: use 'raw' input. This option only applies to input taken from the
275 user's history. By default, the 'processed' history is used, so that
275 user's history. By default, the 'processed' history is used, so that
276 magics are loaded in their transformed version to valid Python. If
276 magics are loaded in their transformed version to valid Python. If
277 this option is given, the raw input as typed as the command line is
277 this option is given, the raw input as typed as the command line is
278 used instead. When you exit the editor, it will be executed by
278 used instead. When you exit the editor, it will be executed by
279 IPython's own processor.
279 IPython's own processor.
280
280
281 -x: do not execute the edited code immediately upon exit. This is
281 -x: do not execute the edited code immediately upon exit. This is
282 mainly useful if you are editing programs which need to be called with
282 mainly useful if you are editing programs which need to be called with
283 command line arguments, which you can then do using %run.
283 command line arguments, which you can then do using %run.
284
284
285
285
286 Arguments:
286 Arguments:
287
287
288 If arguments are given, the following possibilites exist:
288 If arguments are given, the following possibilites exist:
289
289
290 - The arguments are numbers or pairs of colon-separated numbers (like
290 - The arguments are numbers or pairs of colon-separated numbers (like
291 1 4:8 9). These are interpreted as lines of previous input to be
291 1 4:8 9). These are interpreted as lines of previous input to be
292 loaded into the editor. The syntax is the same of the %macro command.
292 loaded into the editor. The syntax is the same of the %macro command.
293
293
294 - If the argument doesn't start with a number, it is evaluated as a
294 - If the argument doesn't start with a number, it is evaluated as a
295 variable and its contents loaded into the editor. You can thus edit
295 variable and its contents loaded into the editor. You can thus edit
296 any string which contains python code (including the result of
296 any string which contains python code (including the result of
297 previous edits).
297 previous edits).
298
298
299 - If the argument is the name of an object (other than a string),
299 - If the argument is the name of an object (other than a string),
300 IPython will try to locate the file where it was defined and open the
300 IPython will try to locate the file where it was defined and open the
301 editor at the point where it is defined. You can use `%edit function`
301 editor at the point where it is defined. You can use `%edit function`
302 to load an editor exactly at the point where 'function' is defined,
302 to load an editor exactly at the point where 'function' is defined,
303 edit it and have the file be executed automatically.
303 edit it and have the file be executed automatically.
304
304
305 If the object is a macro (see %macro for details), this opens up your
305 If the object is a macro (see %macro for details), this opens up your
306 specified editor with a temporary file containing the macro's data.
306 specified editor with a temporary file containing the macro's data.
307 Upon exit, the macro is reloaded with the contents of the file.
307 Upon exit, the macro is reloaded with the contents of the file.
308
308
309 Note: opening at an exact line is only supported under Unix, and some
309 Note: opening at an exact line is only supported under Unix, and some
310 editors (like kedit and gedit up to Gnome 2.8) do not understand the
310 editors (like kedit and gedit up to Gnome 2.8) do not understand the
311 '+NUMBER' parameter necessary for this feature. Good editors like
311 '+NUMBER' parameter necessary for this feature. Good editors like
312 (X)Emacs, vi, jed, pico and joe all do.
312 (X)Emacs, vi, jed, pico and joe all do.
313
313
314 - If the argument is not found as a variable, IPython will look for a
314 - If the argument is not found as a variable, IPython will look for a
315 file with that name (adding .py if necessary) and load it into the
315 file with that name (adding .py if necessary) and load it into the
316 editor. It will execute its contents with execfile() when you exit,
316 editor. It will execute its contents with execfile() when you exit,
317 loading any code in the file into your interactive namespace.
317 loading any code in the file into your interactive namespace.
318
318
319 After executing your code, %edit will return as output the code you
319 After executing your code, %edit will return as output the code you
320 typed in the editor (except when it was an existing file). This way
320 typed in the editor (except when it was an existing file). This way
321 you can reload the code in further invocations of %edit as a variable,
321 you can reload the code in further invocations of %edit as a variable,
322 via _<NUMBER> or Out[<NUMBER>], where <NUMBER> is the prompt number of
322 via _<NUMBER> or Out[<NUMBER>], where <NUMBER> is the prompt number of
323 the output.
323 the output.
324
324
325 Note that %edit is also available through the alias %ed.
325 Note that %edit is also available through the alias %ed.
326
326
327 This is an example of creating a simple function inside the editor and
327 This is an example of creating a simple function inside the editor and
328 then modifying it. First, start up the editor:
328 then modifying it. First, start up the editor:
329
329
330 In [1]: ed
330 In [1]: ed
331 Editing... done. Executing edited code...
331 Editing... done. Executing edited code...
332 Out[1]: 'def foo():n print "foo() was defined in an editing session"n'
332 Out[1]: 'def foo():n print "foo() was defined in an editing session"n'
333
333
334 We can then call the function foo():
334 We can then call the function foo():
335
335
336 In [2]: foo()
336 In [2]: foo()
337 foo() was defined in an editing session
337 foo() was defined in an editing session
338
338
339 Now we edit foo. IPython automatically loads the editor with the
339 Now we edit foo. IPython automatically loads the editor with the
340 (temporary) file where foo() was previously defined:
340 (temporary) file where foo() was previously defined:
341
341
342 In [3]: ed foo
342 In [3]: ed foo
343 Editing... done. Executing edited code...
343 Editing... done. Executing edited code...
344
344
345 And if we call foo() again we get the modified version:
345 And if we call foo() again we get the modified version:
346
346
347 In [4]: foo()
347 In [4]: foo()
348 foo() has now been changed!
348 foo() has now been changed!
349
349
350 Here is an example of how to edit a code snippet successive
350 Here is an example of how to edit a code snippet successive
351 times. First we call the editor:
351 times. First we call the editor:
352
352
353 In [5]: ed
353 In [5]: ed
354 Editing... done. Executing edited code...
354 Editing... done. Executing edited code...
355 hello
355 hello
356 Out[5]: "print 'hello'n"
356 Out[5]: "print 'hello'n"
357
357
358 Now we call it again with the previous output (stored in _):
358 Now we call it again with the previous output (stored in _):
359
359
360 In [6]: ed _
360 In [6]: ed _
361 Editing... done. Executing edited code...
361 Editing... done. Executing edited code...
362 hello world
362 hello world
363 Out[6]: "print 'hello world'n"
363 Out[6]: "print 'hello world'n"
364
364
365 Now we call it with the output #8 (stored in _8, also as Out[8]):
365 Now we call it with the output #8 (stored in _8, also as Out[8]):
366
366
367 In [7]: ed _8
367 In [7]: ed _8
368 Editing... done. Executing edited code...
368 Editing... done. Executing edited code...
369 hello again
369 hello again
370 Out[7]: "print 'hello again'n"
370 Out[7]: "print 'hello again'n"
371 """
371 """
372
372
373 opts,args = self.parse_options(parameter_s,'prn:')
373 opts,args = self.parse_options(parameter_s,'prn:')
374
374
375 try:
375 try:
376 filename, lineno, _ = self._find_edit_target(args, opts, last_call)
376 filename, lineno, _ = self._find_edit_target(args, opts, last_call)
377 except MacroToEdit as e:
377 except MacroToEdit as e:
378 # TODO: Implement macro editing over 2 processes.
378 # TODO: Implement macro editing over 2 processes.
379 print("Macro editing not yet implemented in 2-process model.")
379 print("Macro editing not yet implemented in 2-process model.")
380 return
380 return
381
381
382 # Make sure we send to the client an absolute path, in case the working
382 # Make sure we send to the client an absolute path, in case the working
383 # directory of client and kernel don't match
383 # directory of client and kernel don't match
384 filename = os.path.abspath(filename)
384 filename = os.path.abspath(filename)
385
385
386 payload = {
386 payload = {
387 'source' : 'IPython.zmq.zmqshell.ZMQInteractiveShell.edit_magic',
387 'source' : 'IPython.zmq.zmqshell.ZMQInteractiveShell.edit_magic',
388 'filename' : filename,
388 'filename' : filename,
389 'line_number' : lineno
389 'line_number' : lineno
390 }
390 }
391 self.payload_manager.write_payload(payload)
391 self.payload_manager.write_payload(payload)
392
392
393 def magic_gui(self, parameter_s=''):
393 def magic_gui(self, parameter_s=''):
394 """Enable or disable IPython GUI event loop integration.
394 """Enable or disable IPython GUI event loop integration.
395
395
396 %gui [GUINAME]
396 %gui [GUINAME]
397
397
398 This magic replaces IPython's threaded shells that were activated
398 This magic replaces IPython's threaded shells that were activated
399 using the (pylab/wthread/etc.) command line flags. GUI toolkits
399 using the (pylab/wthread/etc.) command line flags. GUI toolkits
400 can now be enabled at runtime and keyboard
400 can now be enabled at runtime and keyboard
401 interrupts should work without any problems. The following toolkits
401 interrupts should work without any problems. The following toolkits
402 are supported: wxPython, PyQt4, PyGTK, Cocoa, and Tk::
402 are supported: wxPython, PyQt4, PyGTK, Cocoa, and Tk::
403
403
404 %gui wx # enable wxPython event loop integration
404 %gui wx # enable wxPython event loop integration
405 %gui qt4|qt # enable PyQt4 event loop integration
405 %gui qt4|qt # enable PyQt4 event loop integration
406 %gui gtk # enable PyGTK event loop integration
406 %gui gtk # enable PyGTK event loop integration
407 %gui OSX # enable Cocoa event loop integration (requires matplotlib 1.1)
407 %gui OSX # enable Cocoa event loop integration (requires matplotlib 1.1)
408 %gui tk # enable Tk event loop integration
408 %gui tk # enable Tk event loop integration
409
409
410 WARNING: after any of these has been called you can simply create
410 WARNING: after any of these has been called you can simply create
411 an application object, but DO NOT start the event loop yourself, as
411 an application object, but DO NOT start the event loop yourself, as
412 we have already handled that.
412 we have already handled that.
413 """
413 """
414 from IPython.zmq.ipkernel import enable_gui
414 from IPython.zmq.ipkernel import enable_gui
415 opts, arg = self.parse_options(parameter_s, '')
415 opts, arg = self.parse_options(parameter_s, '')
416 if arg=='': arg = None
416 if arg=='': arg = None
417 return enable_gui(arg)
417 try:
418 enable_gui(arg)
419 except Exception as e:
420 # print simple error message, rather than traceback if we can't
421 # hook up the GUI
422 error(str(e))
418
423
419 def enable_pylab(self, gui=None, import_all=True):
424 def enable_pylab(self, gui=None, import_all=True):
420 """Activate pylab support at runtime.
425 """Activate pylab support at runtime.
421
426
422 This turns on support for matplotlib, preloads into the interactive
427 This turns on support for matplotlib, preloads into the interactive
423 namespace all of numpy and pylab, and configures IPython to correcdtly
428 namespace all of numpy and pylab, and configures IPython to correcdtly
424 interact with the GUI event loop. The GUI backend to be used can be
429 interact with the GUI event loop. The GUI backend to be used can be
425 optionally selected with the optional :param:`gui` argument.
430 optionally selected with the optional :param:`gui` argument.
426
431
427 Parameters
432 Parameters
428 ----------
433 ----------
429 gui : optional, string [default: inline]
434 gui : optional, string [default: inline]
430
435
431 If given, dictates the choice of matplotlib GUI backend to use
436 If given, dictates the choice of matplotlib GUI backend to use
432 (should be one of IPython's supported backends, 'inline', 'qt', 'osx',
437 (should be one of IPython's supported backends, 'inline', 'qt', 'osx',
433 'tk', or 'gtk'), otherwise we use the default chosen by matplotlib
438 'tk', or 'gtk'), otherwise we use the default chosen by matplotlib
434 (as dictated by the matplotlib build-time options plus the user's
439 (as dictated by the matplotlib build-time options plus the user's
435 matplotlibrc configuration file).
440 matplotlibrc configuration file).
436 """
441 """
437 from IPython.zmq.ipkernel import enable_gui
442 from IPython.zmq.ipkernel import enable_gui
438 # We want to prevent the loading of pylab to pollute the user's
443 # We want to prevent the loading of pylab to pollute the user's
439 # namespace as shown by the %who* magics, so we execute the activation
444 # namespace as shown by the %who* magics, so we execute the activation
440 # code in an empty namespace, and we update *both* user_ns and
445 # code in an empty namespace, and we update *both* user_ns and
441 # user_ns_hidden with this information.
446 # user_ns_hidden with this information.
442 ns = {}
447 ns = {}
443 # override default to inline, from auto-detect
448 try:
444 gui = pylabtools.pylab_activate(ns, gui or 'inline', import_all, self)
449 gui = pylabtools.pylab_activate(ns, gui, import_all, self)
450 except KeyError:
451 error("Backend %r not supported" % gui)
452 return
445 self.user_ns.update(ns)
453 self.user_ns.update(ns)
446 self.user_ns_hidden.update(ns)
454 self.user_ns_hidden.update(ns)
447 # Now we must activate the gui pylab wants to use, and fix %run to take
455 # Now we must activate the gui pylab wants to use, and fix %run to take
448 # plot updates into account
456 # plot updates into account
449 enable_gui(gui)
457 try:
458 enable_gui(gui)
459 except Exception as e:
460 # print simple error message, rather than traceback if we can't
461 # hook up the GUI
462 error(str(e))
450 self.magic_run = self._pylab_magic_run
463 self.magic_run = self._pylab_magic_run
451
464
452
465
453 # A few magics that are adapted to the specifics of using pexpect and a
466 # A few magics that are adapted to the specifics of using pexpect and a
454 # remote terminal
467 # remote terminal
455
468
456 def magic_clear(self, arg_s):
469 def magic_clear(self, arg_s):
457 """Clear the terminal."""
470 """Clear the terminal."""
458 if os.name == 'posix':
471 if os.name == 'posix':
459 self.shell.system("clear")
472 self.shell.system("clear")
460 else:
473 else:
461 self.shell.system("cls")
474 self.shell.system("cls")
462
475
463 if os.name == 'nt':
476 if os.name == 'nt':
464 # This is the usual name in windows
477 # This is the usual name in windows
465 magic_cls = magic_clear
478 magic_cls = magic_clear
466
479
467 # Terminal pagers won't work over pexpect, but we do have our own pager
480 # Terminal pagers won't work over pexpect, but we do have our own pager
468
481
469 def magic_less(self, arg_s):
482 def magic_less(self, arg_s):
470 """Show a file through the pager.
483 """Show a file through the pager.
471
484
472 Files ending in .py are syntax-highlighted."""
485 Files ending in .py are syntax-highlighted."""
473 cont = open(arg_s).read()
486 cont = open(arg_s).read()
474 if arg_s.endswith('.py'):
487 if arg_s.endswith('.py'):
475 cont = self.shell.pycolorize(cont)
488 cont = self.shell.pycolorize(cont)
476 page.page(cont)
489 page.page(cont)
477
490
478 magic_more = magic_less
491 magic_more = magic_less
479
492
480 # Man calls a pager, so we also need to redefine it
493 # Man calls a pager, so we also need to redefine it
481 if os.name == 'posix':
494 if os.name == 'posix':
482 def magic_man(self, arg_s):
495 def magic_man(self, arg_s):
483 """Find the man page for the given command and display in pager."""
496 """Find the man page for the given command and display in pager."""
484 page.page(self.shell.getoutput('man %s | col -b' % arg_s,
497 page.page(self.shell.getoutput('man %s | col -b' % arg_s,
485 split=False))
498 split=False))
486
499
487 # FIXME: this is specific to the GUI, so we should let the gui app load
500 # FIXME: this is specific to the GUI, so we should let the gui app load
488 # magics at startup that are only for the gui. Once the gui app has proper
501 # magics at startup that are only for the gui. Once the gui app has proper
489 # profile and configuration management, we can have it initialize a kernel
502 # profile and configuration management, we can have it initialize a kernel
490 # with a special config file that provides these.
503 # with a special config file that provides these.
491 def magic_guiref(self, arg_s):
504 def magic_guiref(self, arg_s):
492 """Show a basic reference about the GUI console."""
505 """Show a basic reference about the GUI console."""
493 from IPython.core.usage import gui_reference
506 from IPython.core.usage import gui_reference
494 page.page(gui_reference, auto_html=True)
507 page.page(gui_reference, auto_html=True)
495
508
496 def magic_connect_info(self, arg_s):
509 def magic_connect_info(self, arg_s):
497 """Print information for connecting other clients to this kernel
510 """Print information for connecting other clients to this kernel
498
511
499 It will print the contents of this session's connection file, as well as
512 It will print the contents of this session's connection file, as well as
500 shortcuts for local clients.
513 shortcuts for local clients.
501
514
502 In the simplest case, when called from the most recently launched kernel,
515 In the simplest case, when called from the most recently launched kernel,
503 secondary clients can be connected, simply with:
516 secondary clients can be connected, simply with:
504
517
505 $> ipython <app> --existing
518 $> ipython <app> --existing
506
519
507 """
520 """
508 try:
521 try:
509 connection_file = get_connection_file()
522 connection_file = get_connection_file()
510 info = get_connection_info(unpack=False)
523 info = get_connection_info(unpack=False)
511 except Exception as e:
524 except Exception as e:
512 error("Could not get connection info: %r" % e)
525 error("Could not get connection info: %r" % e)
513 return
526 return
514
527
515 print (info + '\n')
528 print (info + '\n')
516 print ("Paste the above JSON into a file, and connect with:\n"
529 print ("Paste the above JSON into a file, and connect with:\n"
517 " $> ipython <app> --existing <file>\n"
530 " $> ipython <app> --existing <file>\n"
518 "or, if you are local, you can connect with just:\n"
531 "or, if you are local, you can connect with just:\n"
519 " $> ipython <app> --existing %s\n"
532 " $> ipython <app> --existing %s\n"
520 "or even just:\n"
533 "or even just:\n"
521 " $> ipython <app> --existing\n"
534 " $> ipython <app> --existing\n"
522 "if this is the most recent IPython session you have started."
535 "if this is the most recent IPython session you have started."
523 % os.path.basename(connection_file)
536 % os.path.basename(connection_file)
524 )
537 )
525
538
526 def magic_qtconsole(self, arg_s):
539 def magic_qtconsole(self, arg_s):
527 """Open a qtconsole connected to this kernel.
540 """Open a qtconsole connected to this kernel.
528
541
529 Useful for connecting a qtconsole to running notebooks, for better
542 Useful for connecting a qtconsole to running notebooks, for better
530 debugging.
543 debugging.
531 """
544 """
532 try:
545 try:
533 p = connect_qtconsole(argv=arg_split(arg_s, os.name=='posix'))
546 p = connect_qtconsole(argv=arg_split(arg_s, os.name=='posix'))
534 except Exception as e:
547 except Exception as e:
535 error("Could not start qtconsole: %r" % e)
548 error("Could not start qtconsole: %r" % e)
536 return
549 return
537
550
538
551
539 def set_next_input(self, text):
552 def set_next_input(self, text):
540 """Send the specified text to the frontend to be presented at the next
553 """Send the specified text to the frontend to be presented at the next
541 input cell."""
554 input cell."""
542 payload = dict(
555 payload = dict(
543 source='IPython.zmq.zmqshell.ZMQInteractiveShell.set_next_input',
556 source='IPython.zmq.zmqshell.ZMQInteractiveShell.set_next_input',
544 text=text
557 text=text
545 )
558 )
546 self.payload_manager.write_payload(payload)
559 self.payload_manager.write_payload(payload)
547
560
548 InteractiveShellABC.register(ZMQInteractiveShell)
561 InteractiveShellABC.register(ZMQInteractiveShell)
General Comments 0
You need to be logged in to leave comments. Login now