##// END OF EJS Templates
Small fixes as per @certik's review.
Fernando Perez -
Show More
1 NO CONTENT: modified file
NO CONTENT: modified file
@@ -1,513 +1,513 b''
1 """Implementation of basic magic functions.
1 """Implementation of basic magic functions.
2 """
2 """
3 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
4 # Copyright (c) 2012 The IPython Development Team.
4 # Copyright (c) 2012 The IPython Development Team.
5 #
5 #
6 # Distributed under the terms of the Modified BSD License.
6 # Distributed under the terms of the Modified BSD License.
7 #
7 #
8 # The full license is in the file COPYING.txt, distributed with this software.
8 # The full license is in the file COPYING.txt, distributed with this software.
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10
10
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Imports
12 # Imports
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 from __future__ import print_function
14 from __future__ import print_function
15
15
16 # Stdlib
16 # Stdlib
17 import io
17 import io
18 import sys
18 import sys
19 from pprint import pformat
19 from pprint import pformat
20
20
21 # Our own packages
21 # Our own packages
22 from IPython.core.error import UsageError
22 from IPython.core.error import UsageError
23 from IPython.core.magic import Magics, magics_class, line_magic
23 from IPython.core.magic import Magics, magics_class, line_magic
24 from IPython.core.prefilter import ESC_MAGIC
24 from IPython.core.prefilter import ESC_MAGIC
25 from IPython.utils.text import format_screen
25 from IPython.utils.text import format_screen
26 from IPython.core import magic_arguments, page
26 from IPython.core import magic_arguments, page
27 from IPython.testing.skipdoctest import skip_doctest
27 from IPython.testing.skipdoctest import skip_doctest
28 from IPython.utils.ipstruct import Struct
28 from IPython.utils.ipstruct import Struct
29 from IPython.utils.path import unquote_filename
29 from IPython.utils.path import unquote_filename
30 from IPython.utils.warn import warn, error
30 from IPython.utils.warn import warn, error
31
31
32 #-----------------------------------------------------------------------------
32 #-----------------------------------------------------------------------------
33 # Magics class implementation
33 # Magics class implementation
34 #-----------------------------------------------------------------------------
34 #-----------------------------------------------------------------------------
35
35
36 @magics_class
36 @magics_class
37 class BasicMagics(Magics):
37 class BasicMagics(Magics):
38 """Magics that provide central IPython functionality.
38 """Magics that provide central IPython functionality.
39
39
40 These are various magics that don't fit into specific categories but that
40 These are various magics that don't fit into specific categories but that
41 are all part of the base 'IPython experience'."""
41 are all part of the base 'IPython experience'."""
42
42
43 def _lsmagic(self):
43 def _lsmagic(self):
44 mesc = ESC_MAGIC
44 mesc = ESC_MAGIC
45 cesc = mesc*2
45 cesc = mesc*2
46 mman = self.shell.magics_manager
46 mman = self.shell.magics_manager
47 magics = mman.lsmagic()
47 magics = mman.lsmagic()
48 out = ['Available line magics:',
48 out = ['Available line magics:',
49 mesc + (' '+mesc).join(magics['line']),
49 mesc + (' '+mesc).join(magics['line']),
50 '',
50 '',
51 'Available cell magics:',
51 'Available cell magics:',
52 cesc + (' '+cesc).join(magics['cell']),
52 cesc + (' '+cesc).join(magics['cell']),
53 '',
53 '',
54 mman.auto_status()]
54 mman.auto_status()]
55 return '\n'.join(out)
55 return '\n'.join(out)
56
56
57 @line_magic
57 @line_magic
58 def lsmagic(self, parameter_s=''):
58 def lsmagic(self, parameter_s=''):
59 """List currently available magic functions."""
59 """List currently available magic functions."""
60 print(self._lsmagic())
60 print(self._lsmagic())
61
61
62 @line_magic
62 @line_magic
63 def magic(self, parameter_s=''):
63 def magic(self, parameter_s=''):
64 """Print information about the magic function system.
64 """Print information about the magic function system.
65
65
66 Supported formats: -latex, -brief, -rest
66 Supported formats: -latex, -brief, -rest
67 """
67 """
68
68
69 mode = ''
69 mode = ''
70 try:
70 try:
71 mode = parameter_s.split()[0][1:]
71 mode = parameter_s.split()[0][1:]
72 if mode == 'rest':
72 if mode == 'rest':
73 rest_docs = []
73 rest_docs = []
74 except:
74 except IndexError:
75 pass
75 pass
76
76
77 magic_docs = []
77 magic_docs = []
78 escapes = dict(line=ESC_MAGIC, cell=ESC_MAGIC*2)
78 escapes = dict(line=ESC_MAGIC, cell=ESC_MAGIC*2)
79 magics = self.shell.magics_manager.magics
79 magics = self.shell.magics_manager.magics
80
80
81 for mtype in ('line', 'cell'):
81 for mtype in ('line', 'cell'):
82 escape = escapes[mtype]
82 escape = escapes[mtype]
83 for fname, fn in magics[mtype].iteritems():
83 for fname, fn in magics[mtype].iteritems():
84
84
85 if mode == 'brief':
85 if mode == 'brief':
86 # only first line
86 # only first line
87 if fn.__doc__:
87 if fn.__doc__:
88 fndoc = fn.__doc__.split('\n',1)[0]
88 fndoc = fn.__doc__.split('\n',1)[0]
89 else:
89 else:
90 fndoc = 'No documentation'
90 fndoc = 'No documentation'
91 else:
91 else:
92 if fn.__doc__:
92 if fn.__doc__:
93 fndoc = fn.__doc__.rstrip()
93 fndoc = fn.__doc__.rstrip()
94 else:
94 else:
95 fndoc = 'No documentation'
95 fndoc = 'No documentation'
96
96
97 if mode == 'rest':
97 if mode == 'rest':
98 rest_docs.append('**%s%s**::\n\n\t%s\n\n' %
98 rest_docs.append('**%s%s**::\n\n\t%s\n\n' %
99 (escape, fname, fndoc))
99 (escape, fname, fndoc))
100 else:
100 else:
101 magic_docs.append('%s%s:\n\t%s\n' %
101 magic_docs.append('%s%s:\n\t%s\n' %
102 (escape, fname, fndoc))
102 (escape, fname, fndoc))
103
103
104 magic_docs = ''.join(magic_docs)
104 magic_docs = ''.join(magic_docs)
105
105
106 if mode == 'rest':
106 if mode == 'rest':
107 return "".join(rest_docs)
107 return "".join(rest_docs)
108
108
109 if mode == 'latex':
109 if mode == 'latex':
110 print(self.format_latex(magic_docs))
110 print(self.format_latex(magic_docs))
111 return
111 return
112 else:
112 else:
113 magic_docs = format_screen(magic_docs)
113 magic_docs = format_screen(magic_docs)
114 if mode == 'brief':
114 if mode == 'brief':
115 return magic_docs
115 return magic_docs
116
116
117 out = ["""
117 out = ["""
118 IPython's 'magic' functions
118 IPython's 'magic' functions
119 ===========================
119 ===========================
120
120
121 The magic function system provides a series of functions which allow you to
121 The magic function system provides a series of functions which allow you to
122 control the behavior of IPython itself, plus a lot of system-type
122 control the behavior of IPython itself, plus a lot of system-type
123 features. All these functions are prefixed with a % character, but parameters
123 features. All these functions are prefixed with a % character, but parameters
124 are given without parentheses or quotes.
124 are given without parentheses or quotes.
125
125
126 NOTE: If you have 'automagic' enabled (via the command line option or with the
126 NOTE: If you have 'automagic' enabled (via the command line option or with the
127 %automagic function), you don't need to type in the % explicitly. By default,
127 %automagic function), you don't need to type in the % explicitly. By default,
128 IPython ships with automagic on, so you should only rarely need the % escape.
128 IPython ships with automagic on, so you should only rarely need the % escape.
129
129
130 Example: typing '%cd mydir' (without the quotes) changes you working directory
130 Example: typing '%cd mydir' (without the quotes) changes you working directory
131 to 'mydir', if it exists.
131 to 'mydir', if it exists.
132
132
133 For a list of the available magic functions, use %lsmagic. For a description
133 For a list of the available magic functions, use %lsmagic. For a description
134 of any of them, type %magic_name?, e.g. '%cd?'.
134 of any of them, type %magic_name?, e.g. '%cd?'.
135
135
136 Currently the magic system has the following functions:""",
136 Currently the magic system has the following functions:""",
137 magic_docs,
137 magic_docs,
138 "Summary of magic functions (from %slsmagic):",
138 "Summary of magic functions (from %slsmagic):",
139 self._lsmagic(),
139 self._lsmagic(),
140 ]
140 ]
141 page.page('\n'.join(out))
141 page.page('\n'.join(out))
142
142
143
143
144 @line_magic
144 @line_magic
145 def page(self, parameter_s=''):
145 def page(self, parameter_s=''):
146 """Pretty print the object and display it through a pager.
146 """Pretty print the object and display it through a pager.
147
147
148 %page [options] OBJECT
148 %page [options] OBJECT
149
149
150 If no object is given, use _ (last output).
150 If no object is given, use _ (last output).
151
151
152 Options:
152 Options:
153
153
154 -r: page str(object), don't pretty-print it."""
154 -r: page str(object), don't pretty-print it."""
155
155
156 # After a function contributed by Olivier Aubert, slightly modified.
156 # After a function contributed by Olivier Aubert, slightly modified.
157
157
158 # Process options/args
158 # Process options/args
159 opts, args = self.parse_options(parameter_s, 'r')
159 opts, args = self.parse_options(parameter_s, 'r')
160 raw = 'r' in opts
160 raw = 'r' in opts
161
161
162 oname = args and args or '_'
162 oname = args and args or '_'
163 info = self._ofind(oname)
163 info = self._ofind(oname)
164 if info['found']:
164 if info['found']:
165 txt = (raw and str or pformat)( info['obj'] )
165 txt = (raw and str or pformat)( info['obj'] )
166 page.page(txt)
166 page.page(txt)
167 else:
167 else:
168 print('Object `%s` not found' % oname)
168 print('Object `%s` not found' % oname)
169
169
170 @line_magic
170 @line_magic
171 def profile(self, parameter_s=''):
171 def profile(self, parameter_s=''):
172 """Print your currently active IPython profile."""
172 """Print your currently active IPython profile."""
173 from IPython.core.application import BaseIPythonApplication
173 from IPython.core.application import BaseIPythonApplication
174 if BaseIPythonApplication.initialized():
174 if BaseIPythonApplication.initialized():
175 print(BaseIPythonApplication.instance().profile)
175 print(BaseIPythonApplication.instance().profile)
176 else:
176 else:
177 error("profile is an application-level value, but you don't appear to be in an IPython application")
177 error("profile is an application-level value, but you don't appear to be in an IPython application")
178
178
179 @line_magic
179 @line_magic
180 def pprint(self, parameter_s=''):
180 def pprint(self, parameter_s=''):
181 """Toggle pretty printing on/off."""
181 """Toggle pretty printing on/off."""
182 ptformatter = self.shell.display_formatter.formatters['text/plain']
182 ptformatter = self.shell.display_formatter.formatters['text/plain']
183 ptformatter.pprint = bool(1 - ptformatter.pprint)
183 ptformatter.pprint = bool(1 - ptformatter.pprint)
184 print('Pretty printing has been turned',
184 print('Pretty printing has been turned',
185 ['OFF','ON'][ptformatter.pprint])
185 ['OFF','ON'][ptformatter.pprint])
186
186
187 @line_magic
187 @line_magic
188 def colors(self, parameter_s=''):
188 def colors(self, parameter_s=''):
189 """Switch color scheme for prompts, info system and exception handlers.
189 """Switch color scheme for prompts, info system and exception handlers.
190
190
191 Currently implemented schemes: NoColor, Linux, LightBG.
191 Currently implemented schemes: NoColor, Linux, LightBG.
192
192
193 Color scheme names are not case-sensitive.
193 Color scheme names are not case-sensitive.
194
194
195 Examples
195 Examples
196 --------
196 --------
197 To get a plain black and white terminal::
197 To get a plain black and white terminal::
198
198
199 %colors nocolor
199 %colors nocolor
200 """
200 """
201 def color_switch_err(name):
201 def color_switch_err(name):
202 warn('Error changing %s color schemes.\n%s' %
202 warn('Error changing %s color schemes.\n%s' %
203 (name, sys.exc_info()[1]))
203 (name, sys.exc_info()[1]))
204
204
205
205
206 new_scheme = parameter_s.strip()
206 new_scheme = parameter_s.strip()
207 if not new_scheme:
207 if not new_scheme:
208 raise UsageError(
208 raise UsageError(
209 "%colors: you must specify a color scheme. See '%colors?'")
209 "%colors: you must specify a color scheme. See '%colors?'")
210 return
210 return
211 # local shortcut
211 # local shortcut
212 shell = self.shell
212 shell = self.shell
213
213
214 import IPython.utils.rlineimpl as readline
214 import IPython.utils.rlineimpl as readline
215
215
216 if not shell.colors_force and \
216 if not shell.colors_force and \
217 not readline.have_readline and sys.platform == "win32":
217 not readline.have_readline and sys.platform == "win32":
218 msg = """\
218 msg = """\
219 Proper color support under MS Windows requires the pyreadline library.
219 Proper color support under MS Windows requires the pyreadline library.
220 You can find it at:
220 You can find it at:
221 http://ipython.org/pyreadline.html
221 http://ipython.org/pyreadline.html
222 Gary's readline needs the ctypes module, from:
222 Gary's readline needs the ctypes module, from:
223 http://starship.python.net/crew/theller/ctypes
223 http://starship.python.net/crew/theller/ctypes
224 (Note that ctypes is already part of Python versions 2.5 and newer).
224 (Note that ctypes is already part of Python versions 2.5 and newer).
225
225
226 Defaulting color scheme to 'NoColor'"""
226 Defaulting color scheme to 'NoColor'"""
227 new_scheme = 'NoColor'
227 new_scheme = 'NoColor'
228 warn(msg)
228 warn(msg)
229
229
230 # readline option is 0
230 # readline option is 0
231 if not shell.colors_force and not shell.has_readline:
231 if not shell.colors_force and not shell.has_readline:
232 new_scheme = 'NoColor'
232 new_scheme = 'NoColor'
233
233
234 # Set prompt colors
234 # Set prompt colors
235 try:
235 try:
236 shell.prompt_manager.color_scheme = new_scheme
236 shell.prompt_manager.color_scheme = new_scheme
237 except:
237 except:
238 color_switch_err('prompt')
238 color_switch_err('prompt')
239 else:
239 else:
240 shell.colors = \
240 shell.colors = \
241 shell.prompt_manager.color_scheme_table.active_scheme_name
241 shell.prompt_manager.color_scheme_table.active_scheme_name
242 # Set exception colors
242 # Set exception colors
243 try:
243 try:
244 shell.InteractiveTB.set_colors(scheme = new_scheme)
244 shell.InteractiveTB.set_colors(scheme = new_scheme)
245 shell.SyntaxTB.set_colors(scheme = new_scheme)
245 shell.SyntaxTB.set_colors(scheme = new_scheme)
246 except:
246 except:
247 color_switch_err('exception')
247 color_switch_err('exception')
248
248
249 # Set info (for 'object?') colors
249 # Set info (for 'object?') colors
250 if shell.color_info:
250 if shell.color_info:
251 try:
251 try:
252 shell.inspector.set_active_scheme(new_scheme)
252 shell.inspector.set_active_scheme(new_scheme)
253 except:
253 except:
254 color_switch_err('object inspector')
254 color_switch_err('object inspector')
255 else:
255 else:
256 shell.inspector.set_active_scheme('NoColor')
256 shell.inspector.set_active_scheme('NoColor')
257
257
258 @line_magic
258 @line_magic
259 def xmode(self, parameter_s=''):
259 def xmode(self, parameter_s=''):
260 """Switch modes for the exception handlers.
260 """Switch modes for the exception handlers.
261
261
262 Valid modes: Plain, Context and Verbose.
262 Valid modes: Plain, Context and Verbose.
263
263
264 If called without arguments, acts as a toggle."""
264 If called without arguments, acts as a toggle."""
265
265
266 def xmode_switch_err(name):
266 def xmode_switch_err(name):
267 warn('Error changing %s exception modes.\n%s' %
267 warn('Error changing %s exception modes.\n%s' %
268 (name,sys.exc_info()[1]))
268 (name,sys.exc_info()[1]))
269
269
270 shell = self.shell
270 shell = self.shell
271 new_mode = parameter_s.strip().capitalize()
271 new_mode = parameter_s.strip().capitalize()
272 try:
272 try:
273 shell.InteractiveTB.set_mode(mode=new_mode)
273 shell.InteractiveTB.set_mode(mode=new_mode)
274 print('Exception reporting mode:',shell.InteractiveTB.mode)
274 print('Exception reporting mode:',shell.InteractiveTB.mode)
275 except:
275 except:
276 xmode_switch_err('user')
276 xmode_switch_err('user')
277
277
278 @line_magic
278 @line_magic
279 def quickref(self,arg):
279 def quickref(self,arg):
280 """ Show a quick reference sheet """
280 """ Show a quick reference sheet """
281 from IPython.core.usage import quick_reference
281 from IPython.core.usage import quick_reference
282 qr = quick_reference + self.magic('-brief')
282 qr = quick_reference + self.magic('-brief')
283 page.page(qr)
283 page.page(qr)
284
284
285 @line_magic
285 @line_magic
286 def doctest_mode(self, parameter_s=''):
286 def doctest_mode(self, parameter_s=''):
287 """Toggle doctest mode on and off.
287 """Toggle doctest mode on and off.
288
288
289 This mode is intended to make IPython behave as much as possible like a
289 This mode is intended to make IPython behave as much as possible like a
290 plain Python shell, from the perspective of how its prompts, exceptions
290 plain Python shell, from the perspective of how its prompts, exceptions
291 and output look. This makes it easy to copy and paste parts of a
291 and output look. This makes it easy to copy and paste parts of a
292 session into doctests. It does so by:
292 session into doctests. It does so by:
293
293
294 - Changing the prompts to the classic ``>>>`` ones.
294 - Changing the prompts to the classic ``>>>`` ones.
295 - Changing the exception reporting mode to 'Plain'.
295 - Changing the exception reporting mode to 'Plain'.
296 - Disabling pretty-printing of output.
296 - Disabling pretty-printing of output.
297
297
298 Note that IPython also supports the pasting of code snippets that have
298 Note that IPython also supports the pasting of code snippets that have
299 leading '>>>' and '...' prompts in them. This means that you can paste
299 leading '>>>' and '...' prompts in them. This means that you can paste
300 doctests from files or docstrings (even if they have leading
300 doctests from files or docstrings (even if they have leading
301 whitespace), and the code will execute correctly. You can then use
301 whitespace), and the code will execute correctly. You can then use
302 '%history -t' to see the translated history; this will give you the
302 '%history -t' to see the translated history; this will give you the
303 input after removal of all the leading prompts and whitespace, which
303 input after removal of all the leading prompts and whitespace, which
304 can be pasted back into an editor.
304 can be pasted back into an editor.
305
305
306 With these features, you can switch into this mode easily whenever you
306 With these features, you can switch into this mode easily whenever you
307 need to do testing and changes to doctests, without having to leave
307 need to do testing and changes to doctests, without having to leave
308 your existing IPython session.
308 your existing IPython session.
309 """
309 """
310
310
311 # Shorthands
311 # Shorthands
312 shell = self.shell
312 shell = self.shell
313 pm = shell.prompt_manager
313 pm = shell.prompt_manager
314 meta = shell.meta
314 meta = shell.meta
315 disp_formatter = self.shell.display_formatter
315 disp_formatter = self.shell.display_formatter
316 ptformatter = disp_formatter.formatters['text/plain']
316 ptformatter = disp_formatter.formatters['text/plain']
317 # dstore is a data store kept in the instance metadata bag to track any
317 # dstore is a data store kept in the instance metadata bag to track any
318 # changes we make, so we can undo them later.
318 # changes we make, so we can undo them later.
319 dstore = meta.setdefault('doctest_mode',Struct())
319 dstore = meta.setdefault('doctest_mode',Struct())
320 save_dstore = dstore.setdefault
320 save_dstore = dstore.setdefault
321
321
322 # save a few values we'll need to recover later
322 # save a few values we'll need to recover later
323 mode = save_dstore('mode',False)
323 mode = save_dstore('mode',False)
324 save_dstore('rc_pprint',ptformatter.pprint)
324 save_dstore('rc_pprint',ptformatter.pprint)
325 save_dstore('xmode',shell.InteractiveTB.mode)
325 save_dstore('xmode',shell.InteractiveTB.mode)
326 save_dstore('rc_separate_out',shell.separate_out)
326 save_dstore('rc_separate_out',shell.separate_out)
327 save_dstore('rc_separate_out2',shell.separate_out2)
327 save_dstore('rc_separate_out2',shell.separate_out2)
328 save_dstore('rc_prompts_pad_left',pm.justify)
328 save_dstore('rc_prompts_pad_left',pm.justify)
329 save_dstore('rc_separate_in',shell.separate_in)
329 save_dstore('rc_separate_in',shell.separate_in)
330 save_dstore('rc_plain_text_only',disp_formatter.plain_text_only)
330 save_dstore('rc_plain_text_only',disp_formatter.plain_text_only)
331 save_dstore('prompt_templates',(pm.in_template, pm.in2_template, pm.out_template))
331 save_dstore('prompt_templates',(pm.in_template, pm.in2_template, pm.out_template))
332
332
333 if mode == False:
333 if mode == False:
334 # turn on
334 # turn on
335 pm.in_template = '>>> '
335 pm.in_template = '>>> '
336 pm.in2_template = '... '
336 pm.in2_template = '... '
337 pm.out_template = ''
337 pm.out_template = ''
338
338
339 # Prompt separators like plain python
339 # Prompt separators like plain python
340 shell.separate_in = ''
340 shell.separate_in = ''
341 shell.separate_out = ''
341 shell.separate_out = ''
342 shell.separate_out2 = ''
342 shell.separate_out2 = ''
343
343
344 pm.justify = False
344 pm.justify = False
345
345
346 ptformatter.pprint = False
346 ptformatter.pprint = False
347 disp_formatter.plain_text_only = True
347 disp_formatter.plain_text_only = True
348
348
349 shell.magic('xmode Plain')
349 shell.magic('xmode Plain')
350 else:
350 else:
351 # turn off
351 # turn off
352 pm.in_template, pm.in2_template, pm.out_template = dstore.prompt_templates
352 pm.in_template, pm.in2_template, pm.out_template = dstore.prompt_templates
353
353
354 shell.separate_in = dstore.rc_separate_in
354 shell.separate_in = dstore.rc_separate_in
355
355
356 shell.separate_out = dstore.rc_separate_out
356 shell.separate_out = dstore.rc_separate_out
357 shell.separate_out2 = dstore.rc_separate_out2
357 shell.separate_out2 = dstore.rc_separate_out2
358
358
359 pm.justify = dstore.rc_prompts_pad_left
359 pm.justify = dstore.rc_prompts_pad_left
360
360
361 ptformatter.pprint = dstore.rc_pprint
361 ptformatter.pprint = dstore.rc_pprint
362 disp_formatter.plain_text_only = dstore.rc_plain_text_only
362 disp_formatter.plain_text_only = dstore.rc_plain_text_only
363
363
364 shell.magic('xmode ' + dstore.xmode)
364 shell.magic('xmode ' + dstore.xmode)
365
365
366 # Store new mode and inform
366 # Store new mode and inform
367 dstore.mode = bool(1-int(mode))
367 dstore.mode = bool(1-int(mode))
368 mode_label = ['OFF','ON'][dstore.mode]
368 mode_label = ['OFF','ON'][dstore.mode]
369 print('Doctest mode is:', mode_label)
369 print('Doctest mode is:', mode_label)
370
370
371 @line_magic
371 @line_magic
372 def gui(self, parameter_s=''):
372 def gui(self, parameter_s=''):
373 """Enable or disable IPython GUI event loop integration.
373 """Enable or disable IPython GUI event loop integration.
374
374
375 %gui [GUINAME]
375 %gui [GUINAME]
376
376
377 This magic replaces IPython's threaded shells that were activated
377 This magic replaces IPython's threaded shells that were activated
378 using the (pylab/wthread/etc.) command line flags. GUI toolkits
378 using the (pylab/wthread/etc.) command line flags. GUI toolkits
379 can now be enabled at runtime and keyboard
379 can now be enabled at runtime and keyboard
380 interrupts should work without any problems. The following toolkits
380 interrupts should work without any problems. The following toolkits
381 are supported: wxPython, PyQt4, PyGTK, Tk and Cocoa (OSX)::
381 are supported: wxPython, PyQt4, PyGTK, Tk and Cocoa (OSX)::
382
382
383 %gui wx # enable wxPython event loop integration
383 %gui wx # enable wxPython event loop integration
384 %gui qt4|qt # enable PyQt4 event loop integration
384 %gui qt4|qt # enable PyQt4 event loop integration
385 %gui gtk # enable PyGTK event loop integration
385 %gui gtk # enable PyGTK event loop integration
386 %gui gtk3 # enable Gtk3 event loop integration
386 %gui gtk3 # enable Gtk3 event loop integration
387 %gui tk # enable Tk event loop integration
387 %gui tk # enable Tk event loop integration
388 %gui OSX # enable Cocoa event loop integration
388 %gui OSX # enable Cocoa event loop integration
389 # (requires %matplotlib 1.1)
389 # (requires %matplotlib 1.1)
390 %gui # disable all event loop integration
390 %gui # disable all event loop integration
391
391
392 WARNING: after any of these has been called you can simply create
392 WARNING: after any of these has been called you can simply create
393 an application object, but DO NOT start the event loop yourself, as
393 an application object, but DO NOT start the event loop yourself, as
394 we have already handled that.
394 we have already handled that.
395 """
395 """
396 opts, arg = self.parse_options(parameter_s, '')
396 opts, arg = self.parse_options(parameter_s, '')
397 if arg=='': arg = None
397 if arg=='': arg = None
398 try:
398 try:
399 return self.enable_gui(arg)
399 return self.enable_gui(arg)
400 except Exception as e:
400 except Exception as e:
401 # print simple error message, rather than traceback if we can't
401 # print simple error message, rather than traceback if we can't
402 # hook up the GUI
402 # hook up the GUI
403 error(str(e))
403 error(str(e))
404
404
405 @skip_doctest
405 @skip_doctest
406 @line_magic
406 @line_magic
407 def precision(self, s=''):
407 def precision(self, s=''):
408 """Set floating point precision for pretty printing.
408 """Set floating point precision for pretty printing.
409
409
410 Can set either integer precision or a format string.
410 Can set either integer precision or a format string.
411
411
412 If numpy has been imported and precision is an int,
412 If numpy has been imported and precision is an int,
413 numpy display precision will also be set, via ``numpy.set_printoptions``.
413 numpy display precision will also be set, via ``numpy.set_printoptions``.
414
414
415 If no argument is given, defaults will be restored.
415 If no argument is given, defaults will be restored.
416
416
417 Examples
417 Examples
418 --------
418 --------
419 ::
419 ::
420
420
421 In [1]: from math import pi
421 In [1]: from math import pi
422
422
423 In [2]: %precision 3
423 In [2]: %precision 3
424 Out[2]: u'%.3f'
424 Out[2]: u'%.3f'
425
425
426 In [3]: pi
426 In [3]: pi
427 Out[3]: 3.142
427 Out[3]: 3.142
428
428
429 In [4]: %precision %i
429 In [4]: %precision %i
430 Out[4]: u'%i'
430 Out[4]: u'%i'
431
431
432 In [5]: pi
432 In [5]: pi
433 Out[5]: 3
433 Out[5]: 3
434
434
435 In [6]: %precision %e
435 In [6]: %precision %e
436 Out[6]: u'%e'
436 Out[6]: u'%e'
437
437
438 In [7]: pi**10
438 In [7]: pi**10
439 Out[7]: 9.364805e+04
439 Out[7]: 9.364805e+04
440
440
441 In [8]: %precision
441 In [8]: %precision
442 Out[8]: u'%r'
442 Out[8]: u'%r'
443
443
444 In [9]: pi**10
444 In [9]: pi**10
445 Out[9]: 93648.047476082982
445 Out[9]: 93648.047476082982
446 """
446 """
447 ptformatter = self.shell.display_formatter.formatters['text/plain']
447 ptformatter = self.shell.display_formatter.formatters['text/plain']
448 ptformatter.float_precision = s
448 ptformatter.float_precision = s
449 return ptformatter.float_format
449 return ptformatter.float_format
450
450
451 @magic_arguments.magic_arguments()
451 @magic_arguments.magic_arguments()
452 @magic_arguments.argument(
452 @magic_arguments.argument(
453 '-e', '--export', action='store_true', default=False,
453 '-e', '--export', action='store_true', default=False,
454 help='Export IPython history as a notebook. The filename argument '
454 help='Export IPython history as a notebook. The filename argument '
455 'is used to specify the notebook name and format. For example '
455 'is used to specify the notebook name and format. For example '
456 'a filename of notebook.ipynb will result in a notebook name '
456 'a filename of notebook.ipynb will result in a notebook name '
457 'of "notebook" and a format of "xml". Likewise using a ".json" '
457 'of "notebook" and a format of "xml". Likewise using a ".json" '
458 'or ".py" file extension will write the notebook in the json '
458 'or ".py" file extension will write the notebook in the json '
459 'or py formats.'
459 'or py formats.'
460 )
460 )
461 @magic_arguments.argument(
461 @magic_arguments.argument(
462 '-f', '--format',
462 '-f', '--format',
463 help='Convert an existing IPython notebook to a new format. This option '
463 help='Convert an existing IPython notebook to a new format. This option '
464 'specifies the new format and can have the values: xml, json, py. '
464 'specifies the new format and can have the values: xml, json, py. '
465 'The target filename is chosen automatically based on the new '
465 'The target filename is chosen automatically based on the new '
466 'format. The filename argument gives the name of the source file.'
466 'format. The filename argument gives the name of the source file.'
467 )
467 )
468 @magic_arguments.argument(
468 @magic_arguments.argument(
469 'filename', type=unicode,
469 'filename', type=unicode,
470 help='Notebook name or filename'
470 help='Notebook name or filename'
471 )
471 )
472 @line_magic
472 @line_magic
473 def notebook(self, s):
473 def notebook(self, s):
474 """Export and convert IPython notebooks.
474 """Export and convert IPython notebooks.
475
475
476 This function can export the current IPython history to a notebook file
476 This function can export the current IPython history to a notebook file
477 or can convert an existing notebook file into a different format. For
477 or can convert an existing notebook file into a different format. For
478 example, to export the history to "foo.ipynb" do "%notebook -e foo.ipynb".
478 example, to export the history to "foo.ipynb" do "%notebook -e foo.ipynb".
479 To export the history to "foo.py" do "%notebook -e foo.py". To convert
479 To export the history to "foo.py" do "%notebook -e foo.py". To convert
480 "foo.ipynb" to "foo.json" do "%notebook -f json foo.ipynb". Possible
480 "foo.ipynb" to "foo.json" do "%notebook -f json foo.ipynb". Possible
481 formats include (json/ipynb, py).
481 formats include (json/ipynb, py).
482 """
482 """
483 args = magic_arguments.parse_argstring(self.notebook, s)
483 args = magic_arguments.parse_argstring(self.notebook, s)
484
484
485 from IPython.nbformat import current
485 from IPython.nbformat import current
486 args.filename = unquote_filename(args.filename)
486 args.filename = unquote_filename(args.filename)
487 if args.export:
487 if args.export:
488 fname, name, format = current.parse_filename(args.filename)
488 fname, name, format = current.parse_filename(args.filename)
489 cells = []
489 cells = []
490 hist = list(self.shell.history_manager.get_range())
490 hist = list(self.shell.history_manager.get_range())
491 for session, prompt_number, input in hist[:-1]:
491 for session, prompt_number, input in hist[:-1]:
492 cells.append(current.new_code_cell(prompt_number=prompt_number,
492 cells.append(current.new_code_cell(prompt_number=prompt_number,
493 input=input))
493 input=input))
494 worksheet = current.new_worksheet(cells=cells)
494 worksheet = current.new_worksheet(cells=cells)
495 nb = current.new_notebook(name=name,worksheets=[worksheet])
495 nb = current.new_notebook(name=name,worksheets=[worksheet])
496 with io.open(fname, 'w', encoding='utf-8') as f:
496 with io.open(fname, 'w', encoding='utf-8') as f:
497 current.write(nb, f, format);
497 current.write(nb, f, format);
498 elif args.format is not None:
498 elif args.format is not None:
499 old_fname, old_name, old_format = current.parse_filename(args.filename)
499 old_fname, old_name, old_format = current.parse_filename(args.filename)
500 new_format = args.format
500 new_format = args.format
501 if new_format == u'xml':
501 if new_format == u'xml':
502 raise ValueError('Notebooks cannot be written as xml.')
502 raise ValueError('Notebooks cannot be written as xml.')
503 elif new_format == u'ipynb' or new_format == u'json':
503 elif new_format == u'ipynb' or new_format == u'json':
504 new_fname = old_name + u'.ipynb'
504 new_fname = old_name + u'.ipynb'
505 new_format = u'json'
505 new_format = u'json'
506 elif new_format == u'py':
506 elif new_format == u'py':
507 new_fname = old_name + u'.py'
507 new_fname = old_name + u'.py'
508 else:
508 else:
509 raise ValueError('Invalid notebook format: %s' % new_format)
509 raise ValueError('Invalid notebook format: %s' % new_format)
510 with io.open(old_fname, 'r', encoding='utf-8') as f:
510 with io.open(old_fname, 'r', encoding='utf-8') as f:
511 nb = current.read(f, old_format)
511 nb = current.read(f, old_format)
512 with io.open(new_fname, 'w', encoding='utf-8') as f:
512 with io.open(new_fname, 'w', encoding='utf-8') as f:
513 current.write(nb, f, new_format)
513 current.write(nb, f, new_format)
@@ -1,478 +1,478 b''
1 """Implementation of code management magic functions.
1 """Implementation of code management magic functions.
2 """
2 """
3 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
4 # Copyright (c) 2012 The IPython Development Team.
4 # Copyright (c) 2012 The IPython Development Team.
5 #
5 #
6 # Distributed under the terms of the Modified BSD License.
6 # Distributed under the terms of the Modified BSD License.
7 #
7 #
8 # The full license is in the file COPYING.txt, distributed with this software.
8 # The full license is in the file COPYING.txt, distributed with this software.
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10
10
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Imports
12 # Imports
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 # Stdlib
15 # Stdlib
16 import inspect
16 import inspect
17 import io
17 import io
18 import json
18 import json
19 import os
19 import os
20 import sys
20 import sys
21 from urllib2 import urlopen
21 from urllib2 import urlopen
22
22
23 # Our own packages
23 # Our own packages
24 from IPython.core.error import TryNext
24 from IPython.core.error import TryNext
25 from IPython.core.macro import Macro
25 from IPython.core.macro import Macro
26 from IPython.core.magic import Magics, magics_class, line_magic
26 from IPython.core.magic import Magics, magics_class, line_magic
27 from IPython.testing.skipdoctest import skip_doctest
27 from IPython.testing.skipdoctest import skip_doctest
28 from IPython.utils import openpy
28 from IPython.utils import openpy
29 from IPython.utils import py3compat
29 from IPython.utils import py3compat
30 from IPython.utils.io import file_read
30 from IPython.utils.io import file_read
31 from IPython.utils.path import get_py_filename, unquote_filename
31 from IPython.utils.path import get_py_filename, unquote_filename
32 from IPython.utils.warn import warn
32 from IPython.utils.warn import warn
33
33
34 #-----------------------------------------------------------------------------
34 #-----------------------------------------------------------------------------
35 # Magic implementation classes
35 # Magic implementation classes
36 #-----------------------------------------------------------------------------
36 #-----------------------------------------------------------------------------
37
37
38 # Used for exception handling in magic_edit
38 # Used for exception handling in magic_edit
39 class MacroToEdit(ValueError): pass
39 class MacroToEdit(ValueError): pass
40
40
41
41
42 @magics_class
42 @magics_class
43 class CodeMagics(Magics):
43 class CodeMagics(Magics):
44 """Magics related to code management (loading, saving, editing, ...)."""
44 """Magics related to code management (loading, saving, editing, ...)."""
45
45
46 @line_magic
46 @line_magic
47 def save(self, parameter_s=''):
47 def save(self, parameter_s=''):
48 """Save a set of lines or a macro to a given filename.
48 """Save a set of lines or a macro to a given filename.
49
49
50 Usage:\\
50 Usage:\\
51 %save [options] filename n1-n2 n3-n4 ... n5 .. n6 ...
51 %save [options] filename n1-n2 n3-n4 ... n5 .. n6 ...
52
52
53 Options:
53 Options:
54
54
55 -r: use 'raw' input. By default, the 'processed' history is used,
55 -r: use 'raw' input. By default, the 'processed' history is used,
56 so that magics are loaded in their transformed version to valid
56 so that magics are loaded in their transformed version to valid
57 Python. If this option is given, the raw input as typed as the
57 Python. If this option is given, the raw input as typed as the
58 command line is used instead.
58 command line is used instead.
59
59
60 This function uses the same syntax as %history for input ranges,
60 This function uses the same syntax as %history for input ranges,
61 then saves the lines to the filename you specify.
61 then saves the lines to the filename you specify.
62
62
63 It adds a '.py' extension to the file if you don't do so yourself, and
63 It adds a '.py' extension to the file if you don't do so yourself, and
64 it asks for confirmation before overwriting existing files."""
64 it asks for confirmation before overwriting existing files."""
65
65
66 opts,args = self.parse_options(parameter_s,'r',mode='list')
66 opts,args = self.parse_options(parameter_s,'r',mode='list')
67 fname, codefrom = unquote_filename(args[0]), " ".join(args[1:])
67 fname, codefrom = unquote_filename(args[0]), " ".join(args[1:])
68 if not fname.endswith('.py'):
68 if not fname.endswith('.py'):
69 fname += '.py'
69 fname += '.py'
70 if os.path.isfile(fname):
70 if os.path.isfile(fname):
71 ans = raw_input('File `%s` exists. Overwrite (y/[N])? ' % fname)
71 ans = raw_input('File `%s` exists. Overwrite (y/[N])? ' % fname)
72 if ans.lower() not in ['y','yes']:
72 if ans.lower() not in ['y','yes']:
73 print 'Operation cancelled.'
73 print 'Operation cancelled.'
74 return
74 return
75 try:
75 try:
76 cmds = self.shell.find_user_code(codefrom, 'r' in opts)
76 cmds = self.shell.find_user_code(codefrom, 'r' in opts)
77 except (TypeError, ValueError) as e:
77 except (TypeError, ValueError) as e:
78 print e.args[0]
78 print e.args[0]
79 return
79 return
80 with io.open(fname,'w', encoding="utf-8") as f:
80 with io.open(fname,'w', encoding="utf-8") as f:
81 f.write(u"# coding: utf-8\n")
81 f.write(u"# coding: utf-8\n")
82 f.write(py3compat.cast_unicode(cmds))
82 f.write(py3compat.cast_unicode(cmds))
83 print 'The following commands were written to file `%s`:' % fname
83 print 'The following commands were written to file `%s`:' % fname
84 print cmds
84 print cmds
85
85
86 @line_magic
86 @line_magic
87 def pastebin(self, parameter_s=''):
87 def pastebin(self, parameter_s=''):
88 """Upload code to Github's Gist paste bin, returning the URL.
88 """Upload code to Github's Gist paste bin, returning the URL.
89
89
90 Usage:\\
90 Usage:\\
91 %pastebin [-d "Custom description"] 1-7
91 %pastebin [-d "Custom description"] 1-7
92
92
93 The argument can be an input history range, a filename, or the name of a
93 The argument can be an input history range, a filename, or the name of a
94 string or macro.
94 string or macro.
95
95
96 Options:
96 Options:
97
97
98 -d: Pass a custom description for the gist. The default will say
98 -d: Pass a custom description for the gist. The default will say
99 "Pasted from IPython".
99 "Pasted from IPython".
100 """
100 """
101 opts, args = self.parse_options(parameter_s, 'd:')
101 opts, args = self.parse_options(parameter_s, 'd:')
102
102
103 try:
103 try:
104 code = self.shell.find_user_code(args)
104 code = self.shell.find_user_code(args)
105 except (ValueError, TypeError) as e:
105 except (ValueError, TypeError) as e:
106 print e.args[0]
106 print e.args[0]
107 return
107 return
108
108
109 post_data = json.dumps({
109 post_data = json.dumps({
110 "description": opts.get('d', "Pasted from IPython"),
110 "description": opts.get('d', "Pasted from IPython"),
111 "public": True,
111 "public": True,
112 "files": {
112 "files": {
113 "file1.py": {
113 "file1.py": {
114 "content": code
114 "content": code
115 }
115 }
116 }
116 }
117 }).encode('utf-8')
117 }).encode('utf-8')
118
118
119 response = urlopen("https://api.github.com/gists", post_data)
119 response = urlopen("https://api.github.com/gists", post_data)
120 response_data = json.loads(response.read().decode('utf-8'))
120 response_data = json.loads(response.read().decode('utf-8'))
121 return response_data['html_url']
121 return response_data['html_url']
122
122
123 @line_magic
123 @line_magic
124 def loadpy(self, arg_s):
124 def loadpy(self, arg_s):
125 """Load a .py python script into the GUI console.
125 """Load a .py python script into the GUI console.
126
126
127 This magic command can either take a local filename or a url::
127 This magic command can either take a local filename or a url::
128
128
129 %loadpy myscript.py
129 %loadpy myscript.py
130 %loadpy http://www.example.com/myscript.py
130 %loadpy http://www.example.com/myscript.py
131 """
131 """
132 arg_s = unquote_filename(arg_s)
132 arg_s = unquote_filename(arg_s)
133 remote_url = arg_s.startswith(('http://', 'https://'))
133 remote_url = arg_s.startswith(('http://', 'https://'))
134 local_url = not remote_url
134 local_url = not remote_url
135 if local_url and not arg_s.endswith('.py'):
135 if local_url and not arg_s.endswith('.py'):
136 # Local files must be .py; for remote URLs it's possible that the
136 # Local files must be .py; for remote URLs it's possible that the
137 # fetch URL doesn't have a .py in it (many servers have an opaque
137 # fetch URL doesn't have a .py in it (many servers have an opaque
138 # URL, such as scipy-central.org).
138 # URL, such as scipy-central.org).
139 raise ValueError('%%loadpy only works with .py files: %s' % arg_s)
139 raise ValueError('%%loadpy only works with .py files: %s' % arg_s)
140
140
141 # openpy takes care of finding the source encoding (per PEP 263)
141 # openpy takes care of finding the source encoding (per PEP 263)
142 if remote_url:
142 if remote_url:
143 contents = openpy.read_py_url(arg_s, skip_encoding_cookie=True)
143 contents = openpy.read_py_url(arg_s, skip_encoding_cookie=True)
144 else:
144 else:
145 contents = openpy.read_py_file(arg_s, skip_encoding_cookie=True)
145 contents = openpy.read_py_file(arg_s, skip_encoding_cookie=True)
146
146
147 self.shell.set_next_input(contents)
147 self.shell.set_next_input(contents)
148
148
149 def _find_edit_target(self, args, opts, last_call):
149 def _find_edit_target(self, args, opts, last_call):
150 """Utility method used by magic_edit to find what to edit."""
150 """Utility method used by magic_edit to find what to edit."""
151
151
152 def make_filename(arg):
152 def make_filename(arg):
153 "Make a filename from the given args"
153 "Make a filename from the given args"
154 arg = unquote_filename(arg)
154 arg = unquote_filename(arg)
155 try:
155 try:
156 filename = get_py_filename(arg)
156 filename = get_py_filename(arg)
157 except IOError:
157 except IOError:
158 # If it ends with .py but doesn't already exist, assume we want
158 # If it ends with .py but doesn't already exist, assume we want
159 # a new file.
159 # a new file.
160 if arg.endswith('.py'):
160 if arg.endswith('.py'):
161 filename = arg
161 filename = arg
162 else:
162 else:
163 filename = None
163 filename = None
164 return filename
164 return filename
165
165
166 # Set a few locals from the options for convenience:
166 # Set a few locals from the options for convenience:
167 opts_prev = 'p' in opts
167 opts_prev = 'p' in opts
168 opts_raw = 'r' in opts
168 opts_raw = 'r' in opts
169
169
170 # custom exceptions
170 # custom exceptions
171 class DataIsObject(Exception): pass
171 class DataIsObject(Exception): pass
172
172
173 # Default line number value
173 # Default line number value
174 lineno = opts.get('n',None)
174 lineno = opts.get('n',None)
175
175
176 if opts_prev:
176 if opts_prev:
177 args = '_%s' % last_call[0]
177 args = '_%s' % last_call[0]
178 if not self.shell.user_ns.has_key(args):
178 if not self.shell.user_ns.has_key(args):
179 args = last_call[1]
179 args = last_call[1]
180
180
181 # use last_call to remember the state of the previous call, but don't
181 # use last_call to remember the state of the previous call, but don't
182 # let it be clobbered by successive '-p' calls.
182 # let it be clobbered by successive '-p' calls.
183 try:
183 try:
184 last_call[0] = self.shell.displayhook.prompt_count
184 last_call[0] = self.shell.displayhook.prompt_count
185 if not opts_prev:
185 if not opts_prev:
186 last_call[1] = args
186 last_call[1] = args
187 except:
187 except:
188 pass
188 pass
189
189
190 # by default this is done with temp files, except when the given
190 # by default this is done with temp files, except when the given
191 # arg is a filename
191 # arg is a filename
192 use_temp = True
192 use_temp = True
193
193
194 data = ''
194 data = ''
195
195
196 # First, see if the arguments should be a filename.
196 # First, see if the arguments should be a filename.
197 filename = make_filename(args)
197 filename = make_filename(args)
198 if filename:
198 if filename:
199 use_temp = False
199 use_temp = False
200 elif args:
200 elif args:
201 # Mode where user specifies ranges of lines, like in %macro.
201 # Mode where user specifies ranges of lines, like in %macro.
202 data = self.shell.extract_input_lines(args, opts_raw)
202 data = self.shell.extract_input_lines(args, opts_raw)
203 if not data:
203 if not data:
204 try:
204 try:
205 # Load the parameter given as a variable. If not a string,
205 # Load the parameter given as a variable. If not a string,
206 # process it as an object instead (below)
206 # process it as an object instead (below)
207
207
208 #print '*** args',args,'type',type(args) # dbg
208 #print '*** args',args,'type',type(args) # dbg
209 data = eval(args, self.shell.user_ns)
209 data = eval(args, self.shell.user_ns)
210 if not isinstance(data, basestring):
210 if not isinstance(data, basestring):
211 raise DataIsObject
211 raise DataIsObject
212
212
213 except (NameError,SyntaxError):
213 except (NameError,SyntaxError):
214 # given argument is not a variable, try as a filename
214 # given argument is not a variable, try as a filename
215 filename = make_filename(args)
215 filename = make_filename(args)
216 if filename is None:
216 if filename is None:
217 warn("Argument given (%s) can't be found as a variable "
217 warn("Argument given (%s) can't be found as a variable "
218 "or as a filename." % args)
218 "or as a filename." % args)
219 return
219 return
220 use_temp = False
220 use_temp = False
221
221
222 except DataIsObject:
222 except DataIsObject:
223 # macros have a special edit function
223 # macros have a special edit function
224 if isinstance(data, Macro):
224 if isinstance(data, Macro):
225 raise MacroToEdit(data)
225 raise MacroToEdit(data)
226
226
227 # For objects, try to edit the file where they are defined
227 # For objects, try to edit the file where they are defined
228 try:
228 try:
229 filename = inspect.getabsfile(data)
229 filename = inspect.getabsfile(data)
230 if 'fakemodule' in filename.lower() and \
230 if 'fakemodule' in filename.lower() and \
231 inspect.isclass(data):
231 inspect.isclass(data):
232 # class created by %edit? Try to find source
232 # class created by %edit? Try to find source
233 # by looking for method definitions instead, the
233 # by looking for method definitions instead, the
234 # __module__ in those classes is FakeModule.
234 # __module__ in those classes is FakeModule.
235 attrs = [getattr(data, aname) for aname in dir(data)]
235 attrs = [getattr(data, aname) for aname in dir(data)]
236 for attr in attrs:
236 for attr in attrs:
237 if not inspect.ismethod(attr):
237 if not inspect.ismethod(attr):
238 continue
238 continue
239 filename = inspect.getabsfile(attr)
239 filename = inspect.getabsfile(attr)
240 if filename and \
240 if filename and \
241 'fakemodule' not in filename.lower():
241 'fakemodule' not in filename.lower():
242 # change the attribute to be the edit
242 # change the attribute to be the edit
243 # target instead
243 # target instead
244 data = attr
244 data = attr
245 break
245 break
246
246
247 datafile = 1
247 datafile = 1
248 except TypeError:
248 except TypeError:
249 filename = make_filename(args)
249 filename = make_filename(args)
250 datafile = 1
250 datafile = 1
251 warn('Could not find file where `%s` is defined.\n'
251 warn('Could not find file where `%s` is defined.\n'
252 'Opening a file named `%s`' % (args,filename))
252 'Opening a file named `%s`' % (args, filename))
253 # Now, make sure we can actually read the source (if it was
253 # Now, make sure we can actually read the source (if it was
254 # in a temp file it's gone by now).
254 # in a temp file it's gone by now).
255 if datafile:
255 if datafile:
256 try:
256 try:
257 if lineno is None:
257 if lineno is None:
258 lineno = inspect.getsourcelines(data)[1]
258 lineno = inspect.getsourcelines(data)[1]
259 except IOError:
259 except IOError:
260 filename = make_filename(args)
260 filename = make_filename(args)
261 if filename is None:
261 if filename is None:
262 warn('The file `%s` where `%s` was defined cannot '
262 warn('The file `%s` where `%s` was defined '
263 'be read.' % (filename,data))
263 'cannot be read.' % (filename, data))
264 return
264 return
265 use_temp = False
265 use_temp = False
266
266
267 if use_temp:
267 if use_temp:
268 filename = self.shell.mktempfile(data)
268 filename = self.shell.mktempfile(data)
269 print 'IPython will make a temporary file named:',filename
269 print 'IPython will make a temporary file named:',filename
270
270
271 return filename, lineno, use_temp
271 return filename, lineno, use_temp
272
272
273 def _edit_macro(self,mname,macro):
273 def _edit_macro(self,mname,macro):
274 """open an editor with the macro data in a file"""
274 """open an editor with the macro data in a file"""
275 filename = self.shell.mktempfile(macro.value)
275 filename = self.shell.mktempfile(macro.value)
276 self.shell.hooks.editor(filename)
276 self.shell.hooks.editor(filename)
277
277
278 # and make a new macro object, to replace the old one
278 # and make a new macro object, to replace the old one
279 mfile = open(filename)
279 mfile = open(filename)
280 mvalue = mfile.read()
280 mvalue = mfile.read()
281 mfile.close()
281 mfile.close()
282 self.shell.user_ns[mname] = Macro(mvalue)
282 self.shell.user_ns[mname] = Macro(mvalue)
283
283
284 @line_magic
284 @line_magic
285 def ed(self, parameter_s=''):
285 def ed(self, parameter_s=''):
286 """Alias to %edit."""
286 """Alias to %edit."""
287 return self.edit(parameter_s)
287 return self.edit(parameter_s)
288
288
289 @skip_doctest
289 @skip_doctest
290 @line_magic
290 @line_magic
291 def edit(self, parameter_s='',last_call=['','']):
291 def edit(self, parameter_s='',last_call=['','']):
292 """Bring up an editor and execute the resulting code.
292 """Bring up an editor and execute the resulting code.
293
293
294 Usage:
294 Usage:
295 %edit [options] [args]
295 %edit [options] [args]
296
296
297 %edit runs IPython's editor hook. The default version of this hook is
297 %edit runs IPython's editor hook. The default version of this hook is
298 set to call the editor specified by your $EDITOR environment variable.
298 set to call the editor specified by your $EDITOR environment variable.
299 If this isn't found, it will default to vi under Linux/Unix and to
299 If this isn't found, it will default to vi under Linux/Unix and to
300 notepad under Windows. See the end of this docstring for how to change
300 notepad under Windows. See the end of this docstring for how to change
301 the editor hook.
301 the editor hook.
302
302
303 You can also set the value of this editor via the
303 You can also set the value of this editor via the
304 ``TerminalInteractiveShell.editor`` option in your configuration file.
304 ``TerminalInteractiveShell.editor`` option in your configuration file.
305 This is useful if you wish to use a different editor from your typical
305 This is useful if you wish to use a different editor from your typical
306 default with IPython (and for Windows users who typically don't set
306 default with IPython (and for Windows users who typically don't set
307 environment variables).
307 environment variables).
308
308
309 This command allows you to conveniently edit multi-line code right in
309 This command allows you to conveniently edit multi-line code right in
310 your IPython session.
310 your IPython session.
311
311
312 If called without arguments, %edit opens up an empty editor with a
312 If called without arguments, %edit opens up an empty editor with a
313 temporary file and will execute the contents of this file when you
313 temporary file and will execute the contents of this file when you
314 close it (don't forget to save it!).
314 close it (don't forget to save it!).
315
315
316
316
317 Options:
317 Options:
318
318
319 -n <number>: open the editor at a specified line number. By default,
319 -n <number>: open the editor at a specified line number. By default,
320 the IPython editor hook uses the unix syntax 'editor +N filename', but
320 the IPython editor hook uses the unix syntax 'editor +N filename', but
321 you can configure this by providing your own modified hook if your
321 you can configure this by providing your own modified hook if your
322 favorite editor supports line-number specifications with a different
322 favorite editor supports line-number specifications with a different
323 syntax.
323 syntax.
324
324
325 -p: this will call the editor with the same data as the previous time
325 -p: this will call the editor with the same data as the previous time
326 it was used, regardless of how long ago (in your current session) it
326 it was used, regardless of how long ago (in your current session) it
327 was.
327 was.
328
328
329 -r: use 'raw' input. This option only applies to input taken from the
329 -r: use 'raw' input. This option only applies to input taken from the
330 user's history. By default, the 'processed' history is used, so that
330 user's history. By default, the 'processed' history is used, so that
331 magics are loaded in their transformed version to valid Python. If
331 magics are loaded in their transformed version to valid Python. If
332 this option is given, the raw input as typed as the command line is
332 this option is given, the raw input as typed as the command line is
333 used instead. When you exit the editor, it will be executed by
333 used instead. When you exit the editor, it will be executed by
334 IPython's own processor.
334 IPython's own processor.
335
335
336 -x: do not execute the edited code immediately upon exit. This is
336 -x: do not execute the edited code immediately upon exit. This is
337 mainly useful if you are editing programs which need to be called with
337 mainly useful if you are editing programs which need to be called with
338 command line arguments, which you can then do using %run.
338 command line arguments, which you can then do using %run.
339
339
340
340
341 Arguments:
341 Arguments:
342
342
343 If arguments are given, the following possibilities exist:
343 If arguments are given, the following possibilities exist:
344
344
345 - If the argument is a filename, IPython will load that into the
345 - If the argument is a filename, IPython will load that into the
346 editor. It will execute its contents with execfile() when you exit,
346 editor. It will execute its contents with execfile() when you exit,
347 loading any code in the file into your interactive namespace.
347 loading any code in the file into your interactive namespace.
348
348
349 - The arguments are ranges of input history, e.g. "7 ~1/4-6".
349 - The arguments are ranges of input history, e.g. "7 ~1/4-6".
350 The syntax is the same as in the %history magic.
350 The syntax is the same as in the %history magic.
351
351
352 - If the argument is a string variable, its contents are loaded
352 - If the argument is a string variable, its contents are loaded
353 into the editor. You can thus edit any string which contains
353 into the editor. You can thus edit any string which contains
354 python code (including the result of previous edits).
354 python code (including the result of previous edits).
355
355
356 - If the argument is the name of an object (other than a string),
356 - If the argument is the name of an object (other than a string),
357 IPython will try to locate the file where it was defined and open the
357 IPython will try to locate the file where it was defined and open the
358 editor at the point where it is defined. You can use `%edit function`
358 editor at the point where it is defined. You can use `%edit function`
359 to load an editor exactly at the point where 'function' is defined,
359 to load an editor exactly at the point where 'function' is defined,
360 edit it and have the file be executed automatically.
360 edit it and have the file be executed automatically.
361
361
362 - If the object is a macro (see %macro for details), this opens up your
362 - If the object is a macro (see %macro for details), this opens up your
363 specified editor with a temporary file containing the macro's data.
363 specified editor with a temporary file containing the macro's data.
364 Upon exit, the macro is reloaded with the contents of the file.
364 Upon exit, the macro is reloaded with the contents of the file.
365
365
366 Note: opening at an exact line is only supported under Unix, and some
366 Note: opening at an exact line is only supported under Unix, and some
367 editors (like kedit and gedit up to Gnome 2.8) do not understand the
367 editors (like kedit and gedit up to Gnome 2.8) do not understand the
368 '+NUMBER' parameter necessary for this feature. Good editors like
368 '+NUMBER' parameter necessary for this feature. Good editors like
369 (X)Emacs, vi, jed, pico and joe all do.
369 (X)Emacs, vi, jed, pico and joe all do.
370
370
371 After executing your code, %edit will return as output the code you
371 After executing your code, %edit will return as output the code you
372 typed in the editor (except when it was an existing file). This way
372 typed in the editor (except when it was an existing file). This way
373 you can reload the code in further invocations of %edit as a variable,
373 you can reload the code in further invocations of %edit as a variable,
374 via _<NUMBER> or Out[<NUMBER>], where <NUMBER> is the prompt number of
374 via _<NUMBER> or Out[<NUMBER>], where <NUMBER> is the prompt number of
375 the output.
375 the output.
376
376
377 Note that %edit is also available through the alias %ed.
377 Note that %edit is also available through the alias %ed.
378
378
379 This is an example of creating a simple function inside the editor and
379 This is an example of creating a simple function inside the editor and
380 then modifying it. First, start up the editor::
380 then modifying it. First, start up the editor::
381
381
382 In [1]: ed
382 In [1]: ed
383 Editing... done. Executing edited code...
383 Editing... done. Executing edited code...
384 Out[1]: 'def foo():\\n print "foo() was defined in an editing
384 Out[1]: 'def foo():\\n print "foo() was defined in an editing
385 session"\\n'
385 session"\\n'
386
386
387 We can then call the function foo()::
387 We can then call the function foo()::
388
388
389 In [2]: foo()
389 In [2]: foo()
390 foo() was defined in an editing session
390 foo() was defined in an editing session
391
391
392 Now we edit foo. IPython automatically loads the editor with the
392 Now we edit foo. IPython automatically loads the editor with the
393 (temporary) file where foo() was previously defined::
393 (temporary) file where foo() was previously defined::
394
394
395 In [3]: ed foo
395 In [3]: ed foo
396 Editing... done. Executing edited code...
396 Editing... done. Executing edited code...
397
397
398 And if we call foo() again we get the modified version::
398 And if we call foo() again we get the modified version::
399
399
400 In [4]: foo()
400 In [4]: foo()
401 foo() has now been changed!
401 foo() has now been changed!
402
402
403 Here is an example of how to edit a code snippet successive
403 Here is an example of how to edit a code snippet successive
404 times. First we call the editor::
404 times. First we call the editor::
405
405
406 In [5]: ed
406 In [5]: ed
407 Editing... done. Executing edited code...
407 Editing... done. Executing edited code...
408 hello
408 hello
409 Out[5]: "print 'hello'\\n"
409 Out[5]: "print 'hello'\\n"
410
410
411 Now we call it again with the previous output (stored in _)::
411 Now we call it again with the previous output (stored in _)::
412
412
413 In [6]: ed _
413 In [6]: ed _
414 Editing... done. Executing edited code...
414 Editing... done. Executing edited code...
415 hello world
415 hello world
416 Out[6]: "print 'hello world'\\n"
416 Out[6]: "print 'hello world'\\n"
417
417
418 Now we call it with the output #8 (stored in _8, also as Out[8])::
418 Now we call it with the output #8 (stored in _8, also as Out[8])::
419
419
420 In [7]: ed _8
420 In [7]: ed _8
421 Editing... done. Executing edited code...
421 Editing... done. Executing edited code...
422 hello again
422 hello again
423 Out[7]: "print 'hello again'\\n"
423 Out[7]: "print 'hello again'\\n"
424
424
425
425
426 Changing the default editor hook:
426 Changing the default editor hook:
427
427
428 If you wish to write your own editor hook, you can put it in a
428 If you wish to write your own editor hook, you can put it in a
429 configuration file which you load at startup time. The default hook
429 configuration file which you load at startup time. The default hook
430 is defined in the IPython.core.hooks module, and you can use that as a
430 is defined in the IPython.core.hooks module, and you can use that as a
431 starting example for further modifications. That file also has
431 starting example for further modifications. That file also has
432 general instructions on how to set a new hook for use once you've
432 general instructions on how to set a new hook for use once you've
433 defined it."""
433 defined it."""
434 opts,args = self.parse_options(parameter_s,'prxn:')
434 opts,args = self.parse_options(parameter_s,'prxn:')
435
435
436 try:
436 try:
437 filename, lineno, is_temp = self._find_edit_target(args, opts, last_call)
437 filename, lineno, is_temp = self._find_edit_target(args, opts, last_call)
438 except MacroToEdit as e:
438 except MacroToEdit as e:
439 self._edit_macro(args, e.args[0])
439 self._edit_macro(args, e.args[0])
440 return
440 return
441
441
442 # do actual editing here
442 # do actual editing here
443 print 'Editing...',
443 print 'Editing...',
444 sys.stdout.flush()
444 sys.stdout.flush()
445 try:
445 try:
446 # Quote filenames that may have spaces in them
446 # Quote filenames that may have spaces in them
447 if ' ' in filename:
447 if ' ' in filename:
448 filename = "'%s'" % filename
448 filename = "'%s'" % filename
449 self.shell.hooks.editor(filename,lineno)
449 self.shell.hooks.editor(filename,lineno)
450 except TryNext:
450 except TryNext:
451 warn('Could not open editor')
451 warn('Could not open editor')
452 return
452 return
453
453
454 # XXX TODO: should this be generalized for all string vars?
454 # XXX TODO: should this be generalized for all string vars?
455 # For now, this is special-cased to blocks created by cpaste
455 # For now, this is special-cased to blocks created by cpaste
456 if args.strip() == 'pasted_block':
456 if args.strip() == 'pasted_block':
457 self.shell.user_ns['pasted_block'] = file_read(filename)
457 self.shell.user_ns['pasted_block'] = file_read(filename)
458
458
459 if 'x' in opts: # -x prevents actual execution
459 if 'x' in opts: # -x prevents actual execution
460 print
460 print
461 else:
461 else:
462 print 'done. Executing edited code...'
462 print 'done. Executing edited code...'
463 if 'r' in opts: # Untranslated IPython code
463 if 'r' in opts: # Untranslated IPython code
464 self.shell.run_cell(file_read(filename),
464 self.shell.run_cell(file_read(filename),
465 store_history=False)
465 store_history=False)
466 else:
466 else:
467 self.shell.safe_execfile(filename, self.shell.user_ns,
467 self.shell.safe_execfile(filename, self.shell.user_ns,
468 self.shell.user_ns)
468 self.shell.user_ns)
469
469
470 if is_temp:
470 if is_temp:
471 try:
471 try:
472 return open(filename).read()
472 return open(filename).read()
473 except IOError,msg:
473 except IOError,msg:
474 if msg.filename == filename:
474 if msg.filename == filename:
475 warn('File not found. Did you forget to save?')
475 warn('File not found. Did you forget to save?')
476 return
476 return
477 else:
477 else:
478 self.shell.showtraceback()
478 self.shell.showtraceback()
1 NO CONTENT: modified file
NO CONTENT: modified file
1 NO CONTENT: modified file
NO CONTENT: modified file
1 NO CONTENT: modified file
NO CONTENT: modified file
General Comments 0
You need to be logged in to leave comments. Login now