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