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