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