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