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