##// END OF EJS Templates
%qtconsole implied bind_kernel on engines
MinRK -
Show More
@@ -1,549 +1,559 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 os
19 import os
20 import sys
20 import sys
21 import time
21 import time
22
22
23 # System library imports
23 # System library imports
24 from zmq.eventloop import ioloop
24 from zmq.eventloop import ioloop
25
25
26 # Our own
26 # Our own
27 from IPython.core.interactiveshell import (
27 from IPython.core.interactiveshell import (
28 InteractiveShell, InteractiveShellABC
28 InteractiveShell, InteractiveShellABC
29 )
29 )
30 from IPython.core import page
30 from IPython.core import page
31 from IPython.core.autocall import ZMQExitAutocall
31 from IPython.core.autocall import ZMQExitAutocall
32 from IPython.core.displaypub import DisplayPublisher
32 from IPython.core.displaypub import DisplayPublisher
33 from IPython.core.magics import MacroToEdit, CodeMagics
33 from IPython.core.magics import MacroToEdit, CodeMagics
34 from IPython.core.magic import magics_class, line_magic, Magics
34 from IPython.core.magic import magics_class, line_magic, Magics
35 from IPython.core.payloadpage import install_payload_page
35 from IPython.core.payloadpage import install_payload_page
36 from IPython.lib.kernel import (
36 from IPython.lib.kernel import (
37 get_connection_file, get_connection_info, connect_qtconsole
37 get_connection_file, get_connection_info, connect_qtconsole
38 )
38 )
39 from IPython.testing.skipdoctest import skip_doctest
39 from IPython.testing.skipdoctest import skip_doctest
40 from IPython.utils import io
40 from IPython.utils import io
41 from IPython.utils.jsonutil import json_clean
41 from IPython.utils.jsonutil import json_clean
42 from IPython.utils.process import arg_split
42 from IPython.utils.process import arg_split
43 from IPython.utils.traitlets import Instance, Type, Dict, CBool, CBytes
43 from IPython.utils.traitlets import Instance, Type, Dict, CBool, CBytes
44 from IPython.utils.warn import warn, error
44 from IPython.utils.warn import warn, error
45 from IPython.zmq.displayhook import ZMQShellDisplayHook, _encode_binary
45 from IPython.zmq.displayhook import ZMQShellDisplayHook, _encode_binary
46 from IPython.zmq.session import extract_header
46 from IPython.zmq.session import extract_header
47 from session import Session
47 from session import Session
48
48
49 #-----------------------------------------------------------------------------
49 #-----------------------------------------------------------------------------
50 # Functions and classes
50 # Functions and classes
51 #-----------------------------------------------------------------------------
51 #-----------------------------------------------------------------------------
52
52
53 class ZMQDisplayPublisher(DisplayPublisher):
53 class ZMQDisplayPublisher(DisplayPublisher):
54 """A display publisher that publishes data using a ZeroMQ PUB socket."""
54 """A display publisher that publishes data using a ZeroMQ PUB socket."""
55
55
56 session = Instance(Session)
56 session = Instance(Session)
57 pub_socket = Instance('zmq.Socket')
57 pub_socket = Instance('zmq.Socket')
58 parent_header = Dict({})
58 parent_header = Dict({})
59 topic = CBytes(b'displaypub')
59 topic = CBytes(b'displaypub')
60
60
61 def set_parent(self, parent):
61 def set_parent(self, parent):
62 """Set the parent for outbound messages."""
62 """Set the parent for outbound messages."""
63 self.parent_header = extract_header(parent)
63 self.parent_header = extract_header(parent)
64
64
65 def _flush_streams(self):
65 def _flush_streams(self):
66 """flush IO Streams prior to display"""
66 """flush IO Streams prior to display"""
67 sys.stdout.flush()
67 sys.stdout.flush()
68 sys.stderr.flush()
68 sys.stderr.flush()
69
69
70 def publish(self, source, data, metadata=None):
70 def publish(self, source, data, metadata=None):
71 self._flush_streams()
71 self._flush_streams()
72 if metadata is None:
72 if metadata is None:
73 metadata = {}
73 metadata = {}
74 self._validate_data(source, data, metadata)
74 self._validate_data(source, data, metadata)
75 content = {}
75 content = {}
76 content['source'] = source
76 content['source'] = source
77 content['data'] = _encode_binary(data)
77 content['data'] = _encode_binary(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, ident=self.topic,
81 parent=self.parent_header, ident=self.topic,
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
86
87 if stdout:
87 if stdout:
88 print('\r', file=sys.stdout, end='')
88 print('\r', file=sys.stdout, end='')
89 if stderr:
89 if stderr:
90 print('\r', file=sys.stderr, end='')
90 print('\r', file=sys.stderr, end='')
91
91
92 self._flush_streams()
92 self._flush_streams()
93
93
94 self.session.send(
94 self.session.send(
95 self.pub_socket, u'clear_output', content,
95 self.pub_socket, u'clear_output', content,
96 parent=self.parent_header, ident=self.topic,
96 parent=self.parent_header, ident=self.topic,
97 )
97 )
98
98
99 @magics_class
99 @magics_class
100 class KernelMagics(Magics):
100 class KernelMagics(Magics):
101 #------------------------------------------------------------------------
101 #------------------------------------------------------------------------
102 # Magic overrides
102 # Magic overrides
103 #------------------------------------------------------------------------
103 #------------------------------------------------------------------------
104 # Once the base class stops inheriting from magic, this code needs to be
104 # Once the base class stops inheriting from magic, this code needs to be
105 # moved into a separate machinery as well. For now, at least isolate here
105 # moved into a separate machinery as well. For now, at least isolate here
106 # the magics which this class needs to implement differently from the base
106 # the magics which this class needs to implement differently from the base
107 # class, or that are unique to it.
107 # class, or that are unique to it.
108
108
109 @line_magic
109 @line_magic
110 def doctest_mode(self, parameter_s=''):
110 def doctest_mode(self, parameter_s=''):
111 """Toggle doctest mode on and off.
111 """Toggle doctest mode on and off.
112
112
113 This mode is intended to make IPython behave as much as possible like a
113 This mode is intended to make IPython behave as much as possible like a
114 plain Python shell, from the perspective of how its prompts, exceptions
114 plain Python shell, from the perspective of how its prompts, exceptions
115 and output look. This makes it easy to copy and paste parts of a
115 and output look. This makes it easy to copy and paste parts of a
116 session into doctests. It does so by:
116 session into doctests. It does so by:
117
117
118 - Changing the prompts to the classic ``>>>`` ones.
118 - Changing the prompts to the classic ``>>>`` ones.
119 - Changing the exception reporting mode to 'Plain'.
119 - Changing the exception reporting mode to 'Plain'.
120 - Disabling pretty-printing of output.
120 - Disabling pretty-printing of output.
121
121
122 Note that IPython also supports the pasting of code snippets that have
122 Note that IPython also supports the pasting of code snippets that have
123 leading '>>>' and '...' prompts in them. This means that you can paste
123 leading '>>>' and '...' prompts in them. This means that you can paste
124 doctests from files or docstrings (even if they have leading
124 doctests from files or docstrings (even if they have leading
125 whitespace), and the code will execute correctly. You can then use
125 whitespace), and the code will execute correctly. You can then use
126 '%history -t' to see the translated history; this will give you the
126 '%history -t' to see the translated history; this will give you the
127 input after removal of all the leading prompts and whitespace, which
127 input after removal of all the leading prompts and whitespace, which
128 can be pasted back into an editor.
128 can be pasted back into an editor.
129
129
130 With these features, you can switch into this mode easily whenever you
130 With these features, you can switch into this mode easily whenever you
131 need to do testing and changes to doctests, without having to leave
131 need to do testing and changes to doctests, without having to leave
132 your existing IPython session.
132 your existing IPython session.
133 """
133 """
134
134
135 from IPython.utils.ipstruct import Struct
135 from IPython.utils.ipstruct import Struct
136
136
137 # Shorthands
137 # Shorthands
138 shell = self.shell
138 shell = self.shell
139 disp_formatter = self.shell.display_formatter
139 disp_formatter = self.shell.display_formatter
140 ptformatter = disp_formatter.formatters['text/plain']
140 ptformatter = disp_formatter.formatters['text/plain']
141 # dstore is a data store kept in the instance metadata bag to track any
141 # dstore is a data store kept in the instance metadata bag to track any
142 # changes we make, so we can undo them later.
142 # changes we make, so we can undo them later.
143 dstore = shell.meta.setdefault('doctest_mode', Struct())
143 dstore = shell.meta.setdefault('doctest_mode', Struct())
144 save_dstore = dstore.setdefault
144 save_dstore = dstore.setdefault
145
145
146 # save a few values we'll need to recover later
146 # save a few values we'll need to recover later
147 mode = save_dstore('mode', False)
147 mode = save_dstore('mode', False)
148 save_dstore('rc_pprint', ptformatter.pprint)
148 save_dstore('rc_pprint', ptformatter.pprint)
149 save_dstore('rc_plain_text_only',disp_formatter.plain_text_only)
149 save_dstore('rc_plain_text_only',disp_formatter.plain_text_only)
150 save_dstore('xmode', shell.InteractiveTB.mode)
150 save_dstore('xmode', shell.InteractiveTB.mode)
151
151
152 if mode == False:
152 if mode == False:
153 # turn on
153 # turn on
154 ptformatter.pprint = False
154 ptformatter.pprint = False
155 disp_formatter.plain_text_only = True
155 disp_formatter.plain_text_only = True
156 shell.magic('xmode Plain')
156 shell.magic('xmode Plain')
157 else:
157 else:
158 # turn off
158 # turn off
159 ptformatter.pprint = dstore.rc_pprint
159 ptformatter.pprint = dstore.rc_pprint
160 disp_formatter.plain_text_only = dstore.rc_plain_text_only
160 disp_formatter.plain_text_only = dstore.rc_plain_text_only
161 shell.magic("xmode " + dstore.xmode)
161 shell.magic("xmode " + dstore.xmode)
162
162
163 # Store new mode and inform on console
163 # Store new mode and inform on console
164 dstore.mode = bool(1-int(mode))
164 dstore.mode = bool(1-int(mode))
165 mode_label = ['OFF','ON'][dstore.mode]
165 mode_label = ['OFF','ON'][dstore.mode]
166 print('Doctest mode is:', mode_label)
166 print('Doctest mode is:', mode_label)
167
167
168 # Send the payload back so that clients can modify their prompt display
168 # Send the payload back so that clients can modify their prompt display
169 payload = dict(
169 payload = dict(
170 source='IPython.zmq.zmqshell.ZMQInteractiveShell.doctest_mode',
170 source='IPython.zmq.zmqshell.ZMQInteractiveShell.doctest_mode',
171 mode=dstore.mode)
171 mode=dstore.mode)
172 shell.payload_manager.write_payload(payload)
172 shell.payload_manager.write_payload(payload)
173
173
174
174
175 _find_edit_target = CodeMagics._find_edit_target
175 _find_edit_target = CodeMagics._find_edit_target
176
176
177 @skip_doctest
177 @skip_doctest
178 @line_magic
178 @line_magic
179 def edit(self, parameter_s='', last_call=['','']):
179 def edit(self, parameter_s='', last_call=['','']):
180 """Bring up an editor and execute the resulting code.
180 """Bring up an editor and execute the resulting code.
181
181
182 Usage:
182 Usage:
183 %edit [options] [args]
183 %edit [options] [args]
184
184
185 %edit runs an external text editor. You will need to set the command for
185 %edit runs an external text editor. You will need to set the command for
186 this editor via the ``TerminalInteractiveShell.editor`` option in your
186 this editor via the ``TerminalInteractiveShell.editor`` option in your
187 configuration file before it will work.
187 configuration file before it will work.
188
188
189 This command allows you to conveniently edit multi-line code right in
189 This command allows you to conveniently edit multi-line code right in
190 your IPython session.
190 your IPython session.
191
191
192 If called without arguments, %edit opens up an empty editor with a
192 If called without arguments, %edit opens up an empty editor with a
193 temporary file and will execute the contents of this file when you
193 temporary file and will execute the contents of this file when you
194 close it (don't forget to save it!).
194 close it (don't forget to save it!).
195
195
196
196
197 Options:
197 Options:
198
198
199 -n <number>: open the editor at a specified line number. By default,
199 -n <number>: open the editor at a specified line number. By default,
200 the IPython editor hook uses the unix syntax 'editor +N filename', but
200 the IPython editor hook uses the unix syntax 'editor +N filename', but
201 you can configure this by providing your own modified hook if your
201 you can configure this by providing your own modified hook if your
202 favorite editor supports line-number specifications with a different
202 favorite editor supports line-number specifications with a different
203 syntax.
203 syntax.
204
204
205 -p: this will call the editor with the same data as the previous time
205 -p: this will call the editor with the same data as the previous time
206 it was used, regardless of how long ago (in your current session) it
206 it was used, regardless of how long ago (in your current session) it
207 was.
207 was.
208
208
209 -r: use 'raw' input. This option only applies to input taken from the
209 -r: use 'raw' input. This option only applies to input taken from the
210 user's history. By default, the 'processed' history is used, so that
210 user's history. By default, the 'processed' history is used, so that
211 magics are loaded in their transformed version to valid Python. If
211 magics are loaded in their transformed version to valid Python. If
212 this option is given, the raw input as typed as the command line is
212 this option is given, the raw input as typed as the command line is
213 used instead. When you exit the editor, it will be executed by
213 used instead. When you exit the editor, it will be executed by
214 IPython's own processor.
214 IPython's own processor.
215
215
216 -x: do not execute the edited code immediately upon exit. This is
216 -x: do not execute the edited code immediately upon exit. This is
217 mainly useful if you are editing programs which need to be called with
217 mainly useful if you are editing programs which need to be called with
218 command line arguments, which you can then do using %run.
218 command line arguments, which you can then do using %run.
219
219
220
220
221 Arguments:
221 Arguments:
222
222
223 If arguments are given, the following possibilites exist:
223 If arguments are given, the following possibilites exist:
224
224
225 - The arguments are numbers or pairs of colon-separated numbers (like
225 - The arguments are numbers or pairs of colon-separated numbers (like
226 1 4:8 9). These are interpreted as lines of previous input to be
226 1 4:8 9). These are interpreted as lines of previous input to be
227 loaded into the editor. The syntax is the same of the %macro command.
227 loaded into the editor. The syntax is the same of the %macro command.
228
228
229 - If the argument doesn't start with a number, it is evaluated as a
229 - If the argument doesn't start with a number, it is evaluated as a
230 variable and its contents loaded into the editor. You can thus edit
230 variable and its contents loaded into the editor. You can thus edit
231 any string which contains python code (including the result of
231 any string which contains python code (including the result of
232 previous edits).
232 previous edits).
233
233
234 - If the argument is the name of an object (other than a string),
234 - If the argument is the name of an object (other than a string),
235 IPython will try to locate the file where it was defined and open the
235 IPython will try to locate the file where it was defined and open the
236 editor at the point where it is defined. You can use `%edit function`
236 editor at the point where it is defined. You can use `%edit function`
237 to load an editor exactly at the point where 'function' is defined,
237 to load an editor exactly at the point where 'function' is defined,
238 edit it and have the file be executed automatically.
238 edit it and have the file be executed automatically.
239
239
240 If the object is a macro (see %macro for details), this opens up your
240 If the object is a macro (see %macro for details), this opens up your
241 specified editor with a temporary file containing the macro's data.
241 specified editor with a temporary file containing the macro's data.
242 Upon exit, the macro is reloaded with the contents of the file.
242 Upon exit, the macro is reloaded with the contents of the file.
243
243
244 Note: opening at an exact line is only supported under Unix, and some
244 Note: opening at an exact line is only supported under Unix, and some
245 editors (like kedit and gedit up to Gnome 2.8) do not understand the
245 editors (like kedit and gedit up to Gnome 2.8) do not understand the
246 '+NUMBER' parameter necessary for this feature. Good editors like
246 '+NUMBER' parameter necessary for this feature. Good editors like
247 (X)Emacs, vi, jed, pico and joe all do.
247 (X)Emacs, vi, jed, pico and joe all do.
248
248
249 - If the argument is not found as a variable, IPython will look for a
249 - If the argument is not found as a variable, IPython will look for a
250 file with that name (adding .py if necessary) and load it into the
250 file with that name (adding .py if necessary) and load it into the
251 editor. It will execute its contents with execfile() when you exit,
251 editor. It will execute its contents with execfile() when you exit,
252 loading any code in the file into your interactive namespace.
252 loading any code in the file into your interactive namespace.
253
253
254 After executing your code, %edit will return as output the code you
254 After executing your code, %edit will return as output the code you
255 typed in the editor (except when it was an existing file). This way
255 typed in the editor (except when it was an existing file). This way
256 you can reload the code in further invocations of %edit as a variable,
256 you can reload the code in further invocations of %edit as a variable,
257 via _<NUMBER> or Out[<NUMBER>], where <NUMBER> is the prompt number of
257 via _<NUMBER> or Out[<NUMBER>], where <NUMBER> is the prompt number of
258 the output.
258 the output.
259
259
260 Note that %edit is also available through the alias %ed.
260 Note that %edit is also available through the alias %ed.
261
261
262 This is an example of creating a simple function inside the editor and
262 This is an example of creating a simple function inside the editor and
263 then modifying it. First, start up the editor:
263 then modifying it. First, start up the editor:
264
264
265 In [1]: ed
265 In [1]: ed
266 Editing... done. Executing edited code...
266 Editing... done. Executing edited code...
267 Out[1]: 'def foo():n print "foo() was defined in an editing session"n'
267 Out[1]: 'def foo():n print "foo() was defined in an editing session"n'
268
268
269 We can then call the function foo():
269 We can then call the function foo():
270
270
271 In [2]: foo()
271 In [2]: foo()
272 foo() was defined in an editing session
272 foo() was defined in an editing session
273
273
274 Now we edit foo. IPython automatically loads the editor with the
274 Now we edit foo. IPython automatically loads the editor with the
275 (temporary) file where foo() was previously defined:
275 (temporary) file where foo() was previously defined:
276
276
277 In [3]: ed foo
277 In [3]: ed foo
278 Editing... done. Executing edited code...
278 Editing... done. Executing edited code...
279
279
280 And if we call foo() again we get the modified version:
280 And if we call foo() again we get the modified version:
281
281
282 In [4]: foo()
282 In [4]: foo()
283 foo() has now been changed!
283 foo() has now been changed!
284
284
285 Here is an example of how to edit a code snippet successive
285 Here is an example of how to edit a code snippet successive
286 times. First we call the editor:
286 times. First we call the editor:
287
287
288 In [5]: ed
288 In [5]: ed
289 Editing... done. Executing edited code...
289 Editing... done. Executing edited code...
290 hello
290 hello
291 Out[5]: "print 'hello'n"
291 Out[5]: "print 'hello'n"
292
292
293 Now we call it again with the previous output (stored in _):
293 Now we call it again with the previous output (stored in _):
294
294
295 In [6]: ed _
295 In [6]: ed _
296 Editing... done. Executing edited code...
296 Editing... done. Executing edited code...
297 hello world
297 hello world
298 Out[6]: "print 'hello world'n"
298 Out[6]: "print 'hello world'n"
299
299
300 Now we call it with the output #8 (stored in _8, also as Out[8]):
300 Now we call it with the output #8 (stored in _8, also as Out[8]):
301
301
302 In [7]: ed _8
302 In [7]: ed _8
303 Editing... done. Executing edited code...
303 Editing... done. Executing edited code...
304 hello again
304 hello again
305 Out[7]: "print 'hello again'n"
305 Out[7]: "print 'hello again'n"
306 """
306 """
307
307
308 opts,args = self.parse_options(parameter_s,'prn:')
308 opts,args = self.parse_options(parameter_s,'prn:')
309
309
310 try:
310 try:
311 filename, lineno, _ = CodeMagics._find_edit_target(self.shell, args, opts, last_call)
311 filename, lineno, _ = CodeMagics._find_edit_target(self.shell, args, opts, last_call)
312 except MacroToEdit as e:
312 except MacroToEdit as e:
313 # TODO: Implement macro editing over 2 processes.
313 # TODO: Implement macro editing over 2 processes.
314 print("Macro editing not yet implemented in 2-process model.")
314 print("Macro editing not yet implemented in 2-process model.")
315 return
315 return
316
316
317 # Make sure we send to the client an absolute path, in case the working
317 # Make sure we send to the client an absolute path, in case the working
318 # directory of client and kernel don't match
318 # directory of client and kernel don't match
319 filename = os.path.abspath(filename)
319 filename = os.path.abspath(filename)
320
320
321 payload = {
321 payload = {
322 'source' : 'IPython.zmq.zmqshell.ZMQInteractiveShell.edit_magic',
322 'source' : 'IPython.zmq.zmqshell.ZMQInteractiveShell.edit_magic',
323 'filename' : filename,
323 'filename' : filename,
324 'line_number' : lineno
324 'line_number' : lineno
325 }
325 }
326 self.shell.payload_manager.write_payload(payload)
326 self.shell.payload_manager.write_payload(payload)
327
327
328 # A few magics that are adapted to the specifics of using pexpect and a
328 # A few magics that are adapted to the specifics of using pexpect and a
329 # remote terminal
329 # remote terminal
330
330
331 @line_magic
331 @line_magic
332 def clear(self, arg_s):
332 def clear(self, arg_s):
333 """Clear the terminal."""
333 """Clear the terminal."""
334 if os.name == 'posix':
334 if os.name == 'posix':
335 self.shell.system("clear")
335 self.shell.system("clear")
336 else:
336 else:
337 self.shell.system("cls")
337 self.shell.system("cls")
338
338
339 if os.name == 'nt':
339 if os.name == 'nt':
340 # This is the usual name in windows
340 # This is the usual name in windows
341 cls = line_magic('cls')(clear)
341 cls = line_magic('cls')(clear)
342
342
343 # Terminal pagers won't work over pexpect, but we do have our own pager
343 # Terminal pagers won't work over pexpect, but we do have our own pager
344
344
345 @line_magic
345 @line_magic
346 def less(self, arg_s):
346 def less(self, arg_s):
347 """Show a file through the pager.
347 """Show a file through the pager.
348
348
349 Files ending in .py are syntax-highlighted."""
349 Files ending in .py are syntax-highlighted."""
350 cont = open(arg_s).read()
350 cont = open(arg_s).read()
351 if arg_s.endswith('.py'):
351 if arg_s.endswith('.py'):
352 cont = self.shell.pycolorize(cont)
352 cont = self.shell.pycolorize(cont)
353 page.page(cont)
353 page.page(cont)
354
354
355 more = line_magic('more')(less)
355 more = line_magic('more')(less)
356
356
357 # Man calls a pager, so we also need to redefine it
357 # Man calls a pager, so we also need to redefine it
358 if os.name == 'posix':
358 if os.name == 'posix':
359 @line_magic
359 @line_magic
360 def man(self, arg_s):
360 def man(self, arg_s):
361 """Find the man page for the given command and display in pager."""
361 """Find the man page for the given command and display in pager."""
362 page.page(self.shell.getoutput('man %s | col -b' % arg_s,
362 page.page(self.shell.getoutput('man %s | col -b' % arg_s,
363 split=False))
363 split=False))
364
364
365 @line_magic
365 @line_magic
366 def connect_info(self, arg_s):
366 def connect_info(self, arg_s):
367 """Print information for connecting other clients to this kernel
367 """Print information for connecting other clients to this kernel
368
368
369 It will print the contents of this session's connection file, as well as
369 It will print the contents of this session's connection file, as well as
370 shortcuts for local clients.
370 shortcuts for local clients.
371
371
372 In the simplest case, when called from the most recently launched kernel,
372 In the simplest case, when called from the most recently launched kernel,
373 secondary clients can be connected, simply with:
373 secondary clients can be connected, simply with:
374
374
375 $> ipython <app> --existing
375 $> ipython <app> --existing
376
376
377 """
377 """
378
378
379 from IPython.core.application import BaseIPythonApplication as BaseIPApp
379 from IPython.core.application import BaseIPythonApplication as BaseIPApp
380
380
381 if BaseIPApp.initialized():
381 if BaseIPApp.initialized():
382 app = BaseIPApp.instance()
382 app = BaseIPApp.instance()
383 security_dir = app.profile_dir.security_dir
383 security_dir = app.profile_dir.security_dir
384 profile = app.profile
384 profile = app.profile
385 else:
385 else:
386 profile = 'default'
386 profile = 'default'
387 security_dir = ''
387 security_dir = ''
388
388
389 try:
389 try:
390 connection_file = get_connection_file()
390 connection_file = get_connection_file()
391 info = get_connection_info(unpack=False)
391 info = get_connection_info(unpack=False)
392 except Exception as e:
392 except Exception as e:
393 error("Could not get connection info: %r" % e)
393 error("Could not get connection info: %r" % e)
394 return
394 return
395
395
396 # add profile flag for non-default profile
396 # add profile flag for non-default profile
397 profile_flag = "--profile %s" % profile if profile != 'default' else ""
397 profile_flag = "--profile %s" % profile if profile != 'default' else ""
398
398
399 # if it's in the security dir, truncate to basename
399 # if it's in the security dir, truncate to basename
400 if security_dir == os.path.dirname(connection_file):
400 if security_dir == os.path.dirname(connection_file):
401 connection_file = os.path.basename(connection_file)
401 connection_file = os.path.basename(connection_file)
402
402
403
403
404 print (info + '\n')
404 print (info + '\n')
405 print ("Paste the above JSON into a file, and connect with:\n"
405 print ("Paste the above JSON into a file, and connect with:\n"
406 " $> ipython <app> --existing <file>\n"
406 " $> ipython <app> --existing <file>\n"
407 "or, if you are local, you can connect with just:\n"
407 "or, if you are local, you can connect with just:\n"
408 " $> ipython <app> --existing {0} {1}\n"
408 " $> ipython <app> --existing {0} {1}\n"
409 "or even just:\n"
409 "or even just:\n"
410 " $> ipython <app> --existing {1}\n"
410 " $> ipython <app> --existing {1}\n"
411 "if this is the most recent IPython session you have started.".format(
411 "if this is the most recent IPython session you have started.".format(
412 connection_file, profile_flag
412 connection_file, profile_flag
413 )
413 )
414 )
414 )
415
415
416 @line_magic
416 @line_magic
417 def qtconsole(self, arg_s):
417 def qtconsole(self, arg_s):
418 """Open a qtconsole connected to this kernel.
418 """Open a qtconsole connected to this kernel.
419
419
420 Useful for connecting a qtconsole to running notebooks, for better
420 Useful for connecting a qtconsole to running notebooks, for better
421 debugging.
421 debugging.
422 """
422 """
423
424 # %qtconsole should imply bind_kernel for engines:
425 try:
426 from IPython.parallel import bind_kernel
427 except ImportError:
428 # technically possible, because parallel has higher pyzmq min-version
429 pass
430 else:
431 bind_kernel()
432
423 try:
433 try:
424 p = connect_qtconsole(argv=arg_split(arg_s, os.name=='posix'))
434 p = connect_qtconsole(argv=arg_split(arg_s, os.name=='posix'))
425 except Exception as e:
435 except Exception as e:
426 error("Could not start qtconsole: %r" % e)
436 error("Could not start qtconsole: %r" % e)
427 return
437 return
428
438
429
439
430 class ZMQInteractiveShell(InteractiveShell):
440 class ZMQInteractiveShell(InteractiveShell):
431 """A subclass of InteractiveShell for ZMQ."""
441 """A subclass of InteractiveShell for ZMQ."""
432
442
433 displayhook_class = Type(ZMQShellDisplayHook)
443 displayhook_class = Type(ZMQShellDisplayHook)
434 display_pub_class = Type(ZMQDisplayPublisher)
444 display_pub_class = Type(ZMQDisplayPublisher)
435
445
436 # Override the traitlet in the parent class, because there's no point using
446 # Override the traitlet in the parent class, because there's no point using
437 # readline for the kernel. Can be removed when the readline code is moved
447 # readline for the kernel. Can be removed when the readline code is moved
438 # to the terminal frontend.
448 # to the terminal frontend.
439 colors_force = CBool(True)
449 colors_force = CBool(True)
440 readline_use = CBool(False)
450 readline_use = CBool(False)
441 # autoindent has no meaning in a zmqshell, and attempting to enable it
451 # autoindent has no meaning in a zmqshell, and attempting to enable it
442 # will print a warning in the absence of readline.
452 # will print a warning in the absence of readline.
443 autoindent = CBool(False)
453 autoindent = CBool(False)
444
454
445 exiter = Instance(ZMQExitAutocall)
455 exiter = Instance(ZMQExitAutocall)
446 def _exiter_default(self):
456 def _exiter_default(self):
447 return ZMQExitAutocall(self)
457 return ZMQExitAutocall(self)
448
458
449 def _exit_now_changed(self, name, old, new):
459 def _exit_now_changed(self, name, old, new):
450 """stop eventloop when exit_now fires"""
460 """stop eventloop when exit_now fires"""
451 if new:
461 if new:
452 loop = ioloop.IOLoop.instance()
462 loop = ioloop.IOLoop.instance()
453 loop.add_timeout(time.time()+0.1, loop.stop)
463 loop.add_timeout(time.time()+0.1, loop.stop)
454
464
455 keepkernel_on_exit = None
465 keepkernel_on_exit = None
456
466
457 # Over ZeroMQ, GUI control isn't done with PyOS_InputHook as there is no
467 # Over ZeroMQ, GUI control isn't done with PyOS_InputHook as there is no
458 # interactive input being read; we provide event loop support in ipkernel
468 # interactive input being read; we provide event loop support in ipkernel
459 from .eventloops import enable_gui
469 from .eventloops import enable_gui
460 enable_gui = staticmethod(enable_gui)
470 enable_gui = staticmethod(enable_gui)
461
471
462 def init_environment(self):
472 def init_environment(self):
463 """Configure the user's environment.
473 """Configure the user's environment.
464
474
465 """
475 """
466 env = os.environ
476 env = os.environ
467 # These two ensure 'ls' produces nice coloring on BSD-derived systems
477 # These two ensure 'ls' produces nice coloring on BSD-derived systems
468 env['TERM'] = 'xterm-color'
478 env['TERM'] = 'xterm-color'
469 env['CLICOLOR'] = '1'
479 env['CLICOLOR'] = '1'
470 # Since normal pagers don't work at all (over pexpect we don't have
480 # Since normal pagers don't work at all (over pexpect we don't have
471 # single-key control of the subprocess), try to disable paging in
481 # single-key control of the subprocess), try to disable paging in
472 # subprocesses as much as possible.
482 # subprocesses as much as possible.
473 env['PAGER'] = 'cat'
483 env['PAGER'] = 'cat'
474 env['GIT_PAGER'] = 'cat'
484 env['GIT_PAGER'] = 'cat'
475
485
476 # And install the payload version of page.
486 # And install the payload version of page.
477 install_payload_page()
487 install_payload_page()
478
488
479 def auto_rewrite_input(self, cmd):
489 def auto_rewrite_input(self, cmd):
480 """Called to show the auto-rewritten input for autocall and friends.
490 """Called to show the auto-rewritten input for autocall and friends.
481
491
482 FIXME: this payload is currently not correctly processed by the
492 FIXME: this payload is currently not correctly processed by the
483 frontend.
493 frontend.
484 """
494 """
485 new = self.prompt_manager.render('rewrite') + cmd
495 new = self.prompt_manager.render('rewrite') + cmd
486 payload = dict(
496 payload = dict(
487 source='IPython.zmq.zmqshell.ZMQInteractiveShell.auto_rewrite_input',
497 source='IPython.zmq.zmqshell.ZMQInteractiveShell.auto_rewrite_input',
488 transformed_input=new,
498 transformed_input=new,
489 )
499 )
490 self.payload_manager.write_payload(payload)
500 self.payload_manager.write_payload(payload)
491
501
492 def ask_exit(self):
502 def ask_exit(self):
493 """Engage the exit actions."""
503 """Engage the exit actions."""
494 self.exit_now = True
504 self.exit_now = True
495 payload = dict(
505 payload = dict(
496 source='IPython.zmq.zmqshell.ZMQInteractiveShell.ask_exit',
506 source='IPython.zmq.zmqshell.ZMQInteractiveShell.ask_exit',
497 exit=True,
507 exit=True,
498 keepkernel=self.keepkernel_on_exit,
508 keepkernel=self.keepkernel_on_exit,
499 )
509 )
500 self.payload_manager.write_payload(payload)
510 self.payload_manager.write_payload(payload)
501
511
502 def _showtraceback(self, etype, evalue, stb):
512 def _showtraceback(self, etype, evalue, stb):
503
513
504 exc_content = {
514 exc_content = {
505 u'traceback' : stb,
515 u'traceback' : stb,
506 u'ename' : unicode(etype.__name__),
516 u'ename' : unicode(etype.__name__),
507 u'evalue' : unicode(evalue)
517 u'evalue' : unicode(evalue)
508 }
518 }
509
519
510 dh = self.displayhook
520 dh = self.displayhook
511 # Send exception info over pub socket for other clients than the caller
521 # Send exception info over pub socket for other clients than the caller
512 # to pick up
522 # to pick up
513 topic = None
523 topic = None
514 if dh.topic:
524 if dh.topic:
515 topic = dh.topic.replace(b'pyout', b'pyerr')
525 topic = dh.topic.replace(b'pyout', b'pyerr')
516
526
517 exc_msg = dh.session.send(dh.pub_socket, u'pyerr', json_clean(exc_content), dh.parent_header, ident=topic)
527 exc_msg = dh.session.send(dh.pub_socket, u'pyerr', json_clean(exc_content), dh.parent_header, ident=topic)
518
528
519 # FIXME - Hack: store exception info in shell object. Right now, the
529 # FIXME - Hack: store exception info in shell object. Right now, the
520 # caller is reading this info after the fact, we need to fix this logic
530 # caller is reading this info after the fact, we need to fix this logic
521 # to remove this hack. Even uglier, we need to store the error status
531 # to remove this hack. Even uglier, we need to store the error status
522 # here, because in the main loop, the logic that sets it is being
532 # here, because in the main loop, the logic that sets it is being
523 # skipped because runlines swallows the exceptions.
533 # skipped because runlines swallows the exceptions.
524 exc_content[u'status'] = u'error'
534 exc_content[u'status'] = u'error'
525 self._reply_content = exc_content
535 self._reply_content = exc_content
526 # /FIXME
536 # /FIXME
527
537
528 return exc_content
538 return exc_content
529
539
530 def set_next_input(self, text):
540 def set_next_input(self, text):
531 """Send the specified text to the frontend to be presented at the next
541 """Send the specified text to the frontend to be presented at the next
532 input cell."""
542 input cell."""
533 payload = dict(
543 payload = dict(
534 source='IPython.zmq.zmqshell.ZMQInteractiveShell.set_next_input',
544 source='IPython.zmq.zmqshell.ZMQInteractiveShell.set_next_input',
535 text=text
545 text=text
536 )
546 )
537 self.payload_manager.write_payload(payload)
547 self.payload_manager.write_payload(payload)
538
548
539 #-------------------------------------------------------------------------
549 #-------------------------------------------------------------------------
540 # Things related to magics
550 # Things related to magics
541 #-------------------------------------------------------------------------
551 #-------------------------------------------------------------------------
542
552
543 def init_magics(self):
553 def init_magics(self):
544 super(ZMQInteractiveShell, self).init_magics()
554 super(ZMQInteractiveShell, self).init_magics()
545 self.register_magics(KernelMagics)
555 self.register_magics(KernelMagics)
546
556
547
557
548
558
549 InteractiveShellABC.register(ZMQInteractiveShell)
559 InteractiveShellABC.register(ZMQInteractiveShell)
General Comments 0
You need to be logged in to leave comments. Login now