##// END OF EJS Templates
improve docstring for %save -a
Dominik Dabrowski -
Show More
@@ -1,531 +1,531 b''
1 1 """Implementation of code management magic functions.
2 2 """
3 3 #-----------------------------------------------------------------------------
4 4 # Copyright (c) 2012 The IPython Development Team.
5 5 #
6 6 # Distributed under the terms of the Modified BSD License.
7 7 #
8 8 # The full license is in the file COPYING.txt, distributed with this software.
9 9 #-----------------------------------------------------------------------------
10 10
11 11 #-----------------------------------------------------------------------------
12 12 # Imports
13 13 #-----------------------------------------------------------------------------
14 14
15 15 # Stdlib
16 16 import inspect
17 17 import io
18 18 import json
19 19 import os
20 20 import sys
21 21 from urllib2 import urlopen
22 22
23 23 # Our own packages
24 24 from IPython.core.error import TryNext, StdinNotImplementedError
25 25 from IPython.core.macro import Macro
26 26 from IPython.core.magic import Magics, magics_class, line_magic
27 27 from IPython.core.oinspect import find_file, find_source_lines
28 28 from IPython.testing.skipdoctest import skip_doctest
29 29 from IPython.utils import openpy
30 30 from IPython.utils import py3compat
31 31 from IPython.utils.io import file_read
32 32 from IPython.utils.path import get_py_filename, unquote_filename
33 33 from IPython.utils.warn import warn
34 34
35 35 #-----------------------------------------------------------------------------
36 36 # Magic implementation classes
37 37 #-----------------------------------------------------------------------------
38 38
39 39 # Used for exception handling in magic_edit
40 40 class MacroToEdit(ValueError): pass
41 41
42 42
43 43 @magics_class
44 44 class CodeMagics(Magics):
45 45 """Magics related to code management (loading, saving, editing, ...)."""
46 46
47 47 @line_magic
48 48 def save(self, parameter_s=''):
49 49 """Save a set of lines or a macro to a given filename.
50 50
51 51 Usage:\\
52 52 %save [options] filename n1-n2 n3-n4 ... n5 .. n6 ...
53 53
54 54 Options:
55 55
56 56 -r: use 'raw' input. By default, the 'processed' history is used,
57 57 so that magics are loaded in their transformed version to valid
58 58 Python. If this option is given, the raw input as typed as the
59 59 command line is used instead.
60 60
61 61 -f: force overwrite. If file exists, %save will prompt for overwrite
62 62 unless -f is given.
63 63
64 -a: open file in append mode.
64 -a: append to the file instead of overwriting it.
65 65
66 66 This function uses the same syntax as %history for input ranges,
67 67 then saves the lines to the filename you specify.
68 68
69 69 It adds a '.py' extension to the file if you don't do so yourself, and
70 70 it asks for confirmation before overwriting existing files.
71 71
72 72 If `-r` option is used, the default extension is `.ipy`.
73 73 """
74 74
75 75 opts,args = self.parse_options(parameter_s,'fra',mode='list')
76 76 raw = 'r' in opts
77 77 force = 'f' in opts
78 78 append = 'a' in opts
79 79 mode = 'a' if append else 'w'
80 80 ext = u'.ipy' if raw else u'.py'
81 81 fname, codefrom = unquote_filename(args[0]), " ".join(args[1:])
82 82 if not fname.endswith((u'.py',u'.ipy')):
83 83 fname += ext
84 84 file_exists = os.path.isfile(fname)
85 85 if file_exists and not force and not append:
86 86 try:
87 87 overwrite = self.shell.ask_yes_no('File `%s` exists. Overwrite (y/[N])? ' % fname, default='n')
88 88 except StdinNotImplementedError:
89 89 print "File `%s` exists. Use `%%save -f %s` to force overwrite" % (fname, parameter_s)
90 90 return
91 91 if not overwrite :
92 92 print 'Operation cancelled.'
93 93 return
94 94 try:
95 95 cmds = self.shell.find_user_code(codefrom,raw)
96 96 except (TypeError, ValueError) as e:
97 97 print e.args[0]
98 98 return
99 99 out = py3compat.cast_unicode(cmds)
100 100 with io.open(fname, mode, encoding="utf-8") as f:
101 101 if not file_exists or not append:
102 102 f.write(u"# coding: utf-8\n")
103 103 f.write(out)
104 104 # make sure we end on a newline
105 105 if not out.endswith(u'\n'):
106 106 f.write(u'\n')
107 107 print 'The following commands were written to file `%s`:' % fname
108 108 print cmds
109 109
110 110 @line_magic
111 111 def pastebin(self, parameter_s=''):
112 112 """Upload code to Github's Gist paste bin, returning the URL.
113 113
114 114 Usage:\\
115 115 %pastebin [-d "Custom description"] 1-7
116 116
117 117 The argument can be an input history range, a filename, or the name of a
118 118 string or macro.
119 119
120 120 Options:
121 121
122 122 -d: Pass a custom description for the gist. The default will say
123 123 "Pasted from IPython".
124 124 """
125 125 opts, args = self.parse_options(parameter_s, 'd:')
126 126
127 127 try:
128 128 code = self.shell.find_user_code(args)
129 129 except (ValueError, TypeError) as e:
130 130 print e.args[0]
131 131 return
132 132
133 133 post_data = json.dumps({
134 134 "description": opts.get('d', "Pasted from IPython"),
135 135 "public": True,
136 136 "files": {
137 137 "file1.py": {
138 138 "content": code
139 139 }
140 140 }
141 141 }).encode('utf-8')
142 142
143 143 response = urlopen("https://api.github.com/gists", post_data)
144 144 response_data = json.loads(response.read().decode('utf-8'))
145 145 return response_data['html_url']
146 146
147 147 @line_magic
148 148 def loadpy(self, arg_s):
149 149 """Alias of `%load`
150 150
151 151 `%loadpy` has gained some flexibility and droped the requirement of a `.py`
152 152 extension. So it has been renamed simply into %load. You can look at
153 153 `%load`'s docstring for more info.
154 154 """
155 155 self.load(arg_s)
156 156
157 157 @line_magic
158 158 def load(self, arg_s):
159 159 """Load code into the current frontend.
160 160
161 161 Usage:\\
162 162 %load [options] source
163 163
164 164 where source can be a filename, URL, input history range or macro
165 165
166 166 Options:
167 167 --------
168 168 -y : Don't ask confirmation for loading source above 200 000 characters.
169 169
170 170 This magic command can either take a local filename, a URL, an history
171 171 range (see %history) or a macro as argument, it will prompt for
172 172 confirmation before loading source with more than 200 000 characters, unless
173 173 -y flag is passed or if the frontend does not support raw_input::
174 174
175 175 %load myscript.py
176 176 %load 7-27
177 177 %load myMacro
178 178 %load http://www.example.com/myscript.py
179 179 """
180 180 opts,args = self.parse_options(arg_s,'y')
181 181
182 182 contents = self.shell.find_user_code(args)
183 183 l = len(contents)
184 184
185 185 # 200 000 is ~ 2500 full 80 caracter lines
186 186 # so in average, more than 5000 lines
187 187 if l > 200000 and 'y' not in opts:
188 188 try:
189 189 ans = self.shell.ask_yes_no(("The text you're trying to load seems pretty big"\
190 190 " (%d characters). Continue (y/[N]) ?" % l), default='n' )
191 191 except StdinNotImplementedError:
192 192 #asume yes if raw input not implemented
193 193 ans = True
194 194
195 195 if ans is False :
196 196 print 'Operation cancelled.'
197 197 return
198 198
199 199 self.shell.set_next_input(contents)
200 200
201 201 @staticmethod
202 202 def _find_edit_target(shell, args, opts, last_call):
203 203 """Utility method used by magic_edit to find what to edit."""
204 204
205 205 def make_filename(arg):
206 206 "Make a filename from the given args"
207 207 arg = unquote_filename(arg)
208 208 try:
209 209 filename = get_py_filename(arg)
210 210 except IOError:
211 211 # If it ends with .py but doesn't already exist, assume we want
212 212 # a new file.
213 213 if arg.endswith('.py'):
214 214 filename = arg
215 215 else:
216 216 filename = None
217 217 return filename
218 218
219 219 # Set a few locals from the options for convenience:
220 220 opts_prev = 'p' in opts
221 221 opts_raw = 'r' in opts
222 222
223 223 # custom exceptions
224 224 class DataIsObject(Exception): pass
225 225
226 226 # Default line number value
227 227 lineno = opts.get('n',None)
228 228
229 229 if opts_prev:
230 230 args = '_%s' % last_call[0]
231 231 if not shell.user_ns.has_key(args):
232 232 args = last_call[1]
233 233
234 234 # use last_call to remember the state of the previous call, but don't
235 235 # let it be clobbered by successive '-p' calls.
236 236 try:
237 237 last_call[0] = shell.displayhook.prompt_count
238 238 if not opts_prev:
239 239 last_call[1] = args
240 240 except:
241 241 pass
242 242
243 243 # by default this is done with temp files, except when the given
244 244 # arg is a filename
245 245 use_temp = True
246 246
247 247 data = ''
248 248
249 249 # First, see if the arguments should be a filename.
250 250 filename = make_filename(args)
251 251 if filename:
252 252 use_temp = False
253 253 elif args:
254 254 # Mode where user specifies ranges of lines, like in %macro.
255 255 data = shell.extract_input_lines(args, opts_raw)
256 256 if not data:
257 257 try:
258 258 # Load the parameter given as a variable. If not a string,
259 259 # process it as an object instead (below)
260 260
261 261 #print '*** args',args,'type',type(args) # dbg
262 262 data = eval(args, shell.user_ns)
263 263 if not isinstance(data, basestring):
264 264 raise DataIsObject
265 265
266 266 except (NameError,SyntaxError):
267 267 # given argument is not a variable, try as a filename
268 268 filename = make_filename(args)
269 269 if filename is None:
270 270 warn("Argument given (%s) can't be found as a variable "
271 271 "or as a filename." % args)
272 272 return
273 273 use_temp = False
274 274
275 275 except DataIsObject:
276 276 # macros have a special edit function
277 277 if isinstance(data, Macro):
278 278 raise MacroToEdit(data)
279 279
280 280 # For objects, try to edit the file where they are defined
281 281 filename = find_file(data)
282 282 if filename:
283 283 if 'fakemodule' in filename.lower() and \
284 284 inspect.isclass(data):
285 285 # class created by %edit? Try to find source
286 286 # by looking for method definitions instead, the
287 287 # __module__ in those classes is FakeModule.
288 288 attrs = [getattr(data, aname) for aname in dir(data)]
289 289 for attr in attrs:
290 290 if not inspect.ismethod(attr):
291 291 continue
292 292 filename = find_file(attr)
293 293 if filename and \
294 294 'fakemodule' not in filename.lower():
295 295 # change the attribute to be the edit
296 296 # target instead
297 297 data = attr
298 298 break
299 299
300 300 datafile = 1
301 301 if filename is None:
302 302 filename = make_filename(args)
303 303 datafile = 1
304 304 warn('Could not find file where `%s` is defined.\n'
305 305 'Opening a file named `%s`' % (args, filename))
306 306 # Now, make sure we can actually read the source (if it was
307 307 # in a temp file it's gone by now).
308 308 if datafile:
309 309 if lineno is None:
310 310 lineno = find_source_lines(data)
311 311 if lineno is None:
312 312 filename = make_filename(args)
313 313 if filename is None:
314 314 warn('The file `%s` where `%s` was defined '
315 315 'cannot be read.' % (filename, data))
316 316 return
317 317 use_temp = False
318 318
319 319 if use_temp:
320 320 filename = shell.mktempfile(data)
321 321 print 'IPython will make a temporary file named:',filename
322 322
323 323 return filename, lineno, use_temp
324 324
325 325 def _edit_macro(self,mname,macro):
326 326 """open an editor with the macro data in a file"""
327 327 filename = self.shell.mktempfile(macro.value)
328 328 self.shell.hooks.editor(filename)
329 329
330 330 # and make a new macro object, to replace the old one
331 331 mfile = open(filename)
332 332 mvalue = mfile.read()
333 333 mfile.close()
334 334 self.shell.user_ns[mname] = Macro(mvalue)
335 335
336 336 @line_magic
337 337 def ed(self, parameter_s=''):
338 338 """Alias to %edit."""
339 339 return self.edit(parameter_s)
340 340
341 341 @skip_doctest
342 342 @line_magic
343 343 def edit(self, parameter_s='',last_call=['','']):
344 344 """Bring up an editor and execute the resulting code.
345 345
346 346 Usage:
347 347 %edit [options] [args]
348 348
349 349 %edit runs IPython's editor hook. The default version of this hook is
350 350 set to call the editor specified by your $EDITOR environment variable.
351 351 If this isn't found, it will default to vi under Linux/Unix and to
352 352 notepad under Windows. See the end of this docstring for how to change
353 353 the editor hook.
354 354
355 355 You can also set the value of this editor via the
356 356 ``TerminalInteractiveShell.editor`` option in your configuration file.
357 357 This is useful if you wish to use a different editor from your typical
358 358 default with IPython (and for Windows users who typically don't set
359 359 environment variables).
360 360
361 361 This command allows you to conveniently edit multi-line code right in
362 362 your IPython session.
363 363
364 364 If called without arguments, %edit opens up an empty editor with a
365 365 temporary file and will execute the contents of this file when you
366 366 close it (don't forget to save it!).
367 367
368 368
369 369 Options:
370 370
371 371 -n <number>: open the editor at a specified line number. By default,
372 372 the IPython editor hook uses the unix syntax 'editor +N filename', but
373 373 you can configure this by providing your own modified hook if your
374 374 favorite editor supports line-number specifications with a different
375 375 syntax.
376 376
377 377 -p: this will call the editor with the same data as the previous time
378 378 it was used, regardless of how long ago (in your current session) it
379 379 was.
380 380
381 381 -r: use 'raw' input. This option only applies to input taken from the
382 382 user's history. By default, the 'processed' history is used, so that
383 383 magics are loaded in their transformed version to valid Python. If
384 384 this option is given, the raw input as typed as the command line is
385 385 used instead. When you exit the editor, it will be executed by
386 386 IPython's own processor.
387 387
388 388 -x: do not execute the edited code immediately upon exit. This is
389 389 mainly useful if you are editing programs which need to be called with
390 390 command line arguments, which you can then do using %run.
391 391
392 392
393 393 Arguments:
394 394
395 395 If arguments are given, the following possibilities exist:
396 396
397 397 - If the argument is a filename, IPython will load that into the
398 398 editor. It will execute its contents with execfile() when you exit,
399 399 loading any code in the file into your interactive namespace.
400 400
401 401 - The arguments are ranges of input history, e.g. "7 ~1/4-6".
402 402 The syntax is the same as in the %history magic.
403 403
404 404 - If the argument is a string variable, its contents are loaded
405 405 into the editor. You can thus edit any string which contains
406 406 python code (including the result of previous edits).
407 407
408 408 - If the argument is the name of an object (other than a string),
409 409 IPython will try to locate the file where it was defined and open the
410 410 editor at the point where it is defined. You can use `%edit function`
411 411 to load an editor exactly at the point where 'function' is defined,
412 412 edit it and have the file be executed automatically.
413 413
414 414 - If the object is a macro (see %macro for details), this opens up your
415 415 specified editor with a temporary file containing the macro's data.
416 416 Upon exit, the macro is reloaded with the contents of the file.
417 417
418 418 Note: opening at an exact line is only supported under Unix, and some
419 419 editors (like kedit and gedit up to Gnome 2.8) do not understand the
420 420 '+NUMBER' parameter necessary for this feature. Good editors like
421 421 (X)Emacs, vi, jed, pico and joe all do.
422 422
423 423 After executing your code, %edit will return as output the code you
424 424 typed in the editor (except when it was an existing file). This way
425 425 you can reload the code in further invocations of %edit as a variable,
426 426 via _<NUMBER> or Out[<NUMBER>], where <NUMBER> is the prompt number of
427 427 the output.
428 428
429 429 Note that %edit is also available through the alias %ed.
430 430
431 431 This is an example of creating a simple function inside the editor and
432 432 then modifying it. First, start up the editor::
433 433
434 434 In [1]: ed
435 435 Editing... done. Executing edited code...
436 436 Out[1]: 'def foo():\\n print "foo() was defined in an editing
437 437 session"\\n'
438 438
439 439 We can then call the function foo()::
440 440
441 441 In [2]: foo()
442 442 foo() was defined in an editing session
443 443
444 444 Now we edit foo. IPython automatically loads the editor with the
445 445 (temporary) file where foo() was previously defined::
446 446
447 447 In [3]: ed foo
448 448 Editing... done. Executing edited code...
449 449
450 450 And if we call foo() again we get the modified version::
451 451
452 452 In [4]: foo()
453 453 foo() has now been changed!
454 454
455 455 Here is an example of how to edit a code snippet successive
456 456 times. First we call the editor::
457 457
458 458 In [5]: ed
459 459 Editing... done. Executing edited code...
460 460 hello
461 461 Out[5]: "print 'hello'\\n"
462 462
463 463 Now we call it again with the previous output (stored in _)::
464 464
465 465 In [6]: ed _
466 466 Editing... done. Executing edited code...
467 467 hello world
468 468 Out[6]: "print 'hello world'\\n"
469 469
470 470 Now we call it with the output #8 (stored in _8, also as Out[8])::
471 471
472 472 In [7]: ed _8
473 473 Editing... done. Executing edited code...
474 474 hello again
475 475 Out[7]: "print 'hello again'\\n"
476 476
477 477
478 478 Changing the default editor hook:
479 479
480 480 If you wish to write your own editor hook, you can put it in a
481 481 configuration file which you load at startup time. The default hook
482 482 is defined in the IPython.core.hooks module, and you can use that as a
483 483 starting example for further modifications. That file also has
484 484 general instructions on how to set a new hook for use once you've
485 485 defined it."""
486 486 opts,args = self.parse_options(parameter_s,'prxn:')
487 487
488 488 try:
489 489 filename, lineno, is_temp = self._find_edit_target(self.shell,
490 490 args, opts, last_call)
491 491 except MacroToEdit as e:
492 492 self._edit_macro(args, e.args[0])
493 493 return
494 494
495 495 # do actual editing here
496 496 print 'Editing...',
497 497 sys.stdout.flush()
498 498 try:
499 499 # Quote filenames that may have spaces in them
500 500 if ' ' in filename:
501 501 filename = "'%s'" % filename
502 502 self.shell.hooks.editor(filename,lineno)
503 503 except TryNext:
504 504 warn('Could not open editor')
505 505 return
506 506
507 507 # XXX TODO: should this be generalized for all string vars?
508 508 # For now, this is special-cased to blocks created by cpaste
509 509 if args.strip() == 'pasted_block':
510 510 self.shell.user_ns['pasted_block'] = file_read(filename)
511 511
512 512 if 'x' in opts: # -x prevents actual execution
513 513 print
514 514 else:
515 515 print 'done. Executing edited code...'
516 516 if 'r' in opts: # Untranslated IPython code
517 517 self.shell.run_cell(file_read(filename),
518 518 store_history=False)
519 519 else:
520 520 self.shell.safe_execfile(filename, self.shell.user_ns,
521 521 self.shell.user_ns)
522 522
523 523 if is_temp:
524 524 try:
525 525 return open(filename).read()
526 526 except IOError as msg:
527 527 if msg.filename == filename:
528 528 warn('File not found. Did you forget to save?')
529 529 return
530 530 else:
531 531 self.shell.showtraceback()
General Comments 0
You need to be logged in to leave comments. Login now