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