##// END OF EJS Templates
fixining bad attribute access and imports...
Jörgen Stenarson -
Show More
@@ -1,724 +1,725 b''
1 1 """Implementation of magic functions for interaction with the OS.
2 2
3 3 Note: this module is named 'osm' instead of 'os' to avoid a collision with the
4 4 builtin.
5 5 """
6 6 #-----------------------------------------------------------------------------
7 7 # Copyright (c) 2012 The IPython Development Team.
8 8 #
9 9 # Distributed under the terms of the Modified BSD License.
10 10 #
11 11 # The full license is in the file COPYING.txt, distributed with this software.
12 12 #-----------------------------------------------------------------------------
13 13
14 14 #-----------------------------------------------------------------------------
15 15 # Imports
16 16 #-----------------------------------------------------------------------------
17 17
18 18 # Stdlib
19 19 import io
20 20 import os
21 21 import re
22 22 import sys
23 23 from pprint import pformat
24 24
25 25 # Our own packages
26 26 from IPython.core import magic_arguments
27 27 from IPython.core import oinspect
28 28 from IPython.core import page
29 29 from IPython.core.error import UsageError, StdinNotImplementedError
30 30 from IPython.core.magic import (
31 31 Magics, compress_dhist, magics_class, line_magic, cell_magic, line_cell_magic
32 32 )
33 33 from IPython.testing.skipdoctest import skip_doctest
34 from IPython.utils.io import file_read, nlprint, source_to_unicode
34 from IPython.utils.io import file_read, nlprint
35 from IPython.utils.openpy import source_to_unicode
35 36 from IPython.utils.path import get_py_filename, unquote_filename
36 37 from IPython.utils.process import abbrev_cwd
37 38 from IPython.utils.terminal import set_term_title
38 39 #-----------------------------------------------------------------------------
39 40 # Magic implementation classes
40 41 #-----------------------------------------------------------------------------
41 42 @magics_class
42 43 class OSMagics(Magics):
43 44 """Magics to interact with the underlying OS (shell-type functionality).
44 45 """
45 46
46 47 @skip_doctest
47 48 @line_magic
48 49 def alias(self, parameter_s=''):
49 50 """Define an alias for a system command.
50 51
51 52 '%alias alias_name cmd' defines 'alias_name' as an alias for 'cmd'
52 53
53 54 Then, typing 'alias_name params' will execute the system command 'cmd
54 55 params' (from your underlying operating system).
55 56
56 57 Aliases have lower precedence than magic functions and Python normal
57 58 variables, so if 'foo' is both a Python variable and an alias, the
58 59 alias can not be executed until 'del foo' removes the Python variable.
59 60
60 61 You can use the %l specifier in an alias definition to represent the
61 62 whole line when the alias is called. For example::
62 63
63 64 In [2]: alias bracket echo "Input in brackets: <%l>"
64 65 In [3]: bracket hello world
65 66 Input in brackets: <hello world>
66 67
67 68 You can also define aliases with parameters using %s specifiers (one
68 69 per parameter)::
69 70
70 71 In [1]: alias parts echo first %s second %s
71 72 In [2]: %parts A B
72 73 first A second B
73 74 In [3]: %parts A
74 75 Incorrect number of arguments: 2 expected.
75 76 parts is an alias to: 'echo first %s second %s'
76 77
77 78 Note that %l and %s are mutually exclusive. You can only use one or
78 79 the other in your aliases.
79 80
80 81 Aliases expand Python variables just like system calls using ! or !!
81 82 do: all expressions prefixed with '$' get expanded. For details of
82 83 the semantic rules, see PEP-215:
83 84 http://www.python.org/peps/pep-0215.html. This is the library used by
84 85 IPython for variable expansion. If you want to access a true shell
85 86 variable, an extra $ is necessary to prevent its expansion by
86 87 IPython::
87 88
88 89 In [6]: alias show echo
89 90 In [7]: PATH='A Python string'
90 91 In [8]: show $PATH
91 92 A Python string
92 93 In [9]: show $$PATH
93 94 /usr/local/lf9560/bin:/usr/local/intel/compiler70/ia32/bin:...
94 95
95 96 You can use the alias facility to acess all of $PATH. See the %rehash
96 97 and %rehashx functions, which automatically create aliases for the
97 98 contents of your $PATH.
98 99
99 100 If called with no parameters, %alias prints the current alias table."""
100 101
101 102 par = parameter_s.strip()
102 103 if not par:
103 104 aliases = sorted(self.shell.alias_manager.aliases)
104 105 # stored = self.shell.db.get('stored_aliases', {} )
105 106 # for k, v in stored:
106 107 # atab.append(k, v[0])
107 108
108 109 print "Total number of aliases:", len(aliases)
109 110 sys.stdout.flush()
110 111 return aliases
111 112
112 113 # Now try to define a new one
113 114 try:
114 115 alias,cmd = par.split(None, 1)
115 116 except:
116 117 print oinspect.getdoc(self.alias)
117 118 else:
118 119 self.shell.alias_manager.soft_define_alias(alias, cmd)
119 120 # end magic_alias
120 121
121 122 @line_magic
122 123 def unalias(self, parameter_s=''):
123 124 """Remove an alias"""
124 125
125 126 aname = parameter_s.strip()
126 127 self.shell.alias_manager.undefine_alias(aname)
127 128 stored = self.shell.db.get('stored_aliases', {} )
128 129 if aname in stored:
129 130 print "Removing %stored alias",aname
130 131 del stored[aname]
131 132 self.shell.db['stored_aliases'] = stored
132 133
133 134 @line_magic
134 135 def rehashx(self, parameter_s=''):
135 136 """Update the alias table with all executable files in $PATH.
136 137
137 138 This version explicitly checks that every entry in $PATH is a file
138 139 with execute access (os.X_OK), so it is much slower than %rehash.
139 140
140 141 Under Windows, it checks executability as a match against a
141 142 '|'-separated string of extensions, stored in the IPython config
142 143 variable win_exec_ext. This defaults to 'exe|com|bat'.
143 144
144 145 This function also resets the root module cache of module completer,
145 146 used on slow filesystems.
146 147 """
147 148 from IPython.core.alias import InvalidAliasError
148 149
149 150 # for the benefit of module completer in ipy_completers.py
150 151 del self.shell.db['rootmodules']
151 152
152 153 path = [os.path.abspath(os.path.expanduser(p)) for p in
153 154 os.environ.get('PATH','').split(os.pathsep)]
154 155 path = filter(os.path.isdir,path)
155 156
156 157 syscmdlist = []
157 158 # Now define isexec in a cross platform manner.
158 159 if os.name == 'posix':
159 160 isexec = lambda fname:os.path.isfile(fname) and \
160 161 os.access(fname,os.X_OK)
161 162 else:
162 163 try:
163 164 winext = os.environ['pathext'].replace(';','|').replace('.','')
164 165 except KeyError:
165 166 winext = 'exe|com|bat|py'
166 167 if 'py' not in winext:
167 168 winext += '|py'
168 169 execre = re.compile(r'(.*)\.(%s)$' % winext,re.IGNORECASE)
169 170 isexec = lambda fname:os.path.isfile(fname) and execre.match(fname)
170 171 savedir = os.getcwdu()
171 172
172 173 # Now walk the paths looking for executables to alias.
173 174 try:
174 175 # write the whole loop for posix/Windows so we don't have an if in
175 176 # the innermost part
176 177 if os.name == 'posix':
177 178 for pdir in path:
178 179 os.chdir(pdir)
179 180 for ff in os.listdir(pdir):
180 181 if isexec(ff):
181 182 try:
182 183 # Removes dots from the name since ipython
183 184 # will assume names with dots to be python.
184 185 self.shell.alias_manager.define_alias(
185 186 ff.replace('.',''), ff)
186 187 except InvalidAliasError:
187 188 pass
188 189 else:
189 190 syscmdlist.append(ff)
190 191 else:
191 192 no_alias = self.shell.alias_manager.no_alias
192 193 for pdir in path:
193 194 os.chdir(pdir)
194 195 for ff in os.listdir(pdir):
195 196 base, ext = os.path.splitext(ff)
196 197 if isexec(ff) and base.lower() not in no_alias:
197 198 if ext.lower() == '.exe':
198 199 ff = base
199 200 try:
200 201 # Removes dots from the name since ipython
201 202 # will assume names with dots to be python.
202 203 self.shell.alias_manager.define_alias(
203 204 base.lower().replace('.',''), ff)
204 205 except InvalidAliasError:
205 206 pass
206 207 syscmdlist.append(ff)
207 208 self.shell.db['syscmdlist'] = syscmdlist
208 209 finally:
209 210 os.chdir(savedir)
210 211
211 212 @skip_doctest
212 213 @line_magic
213 214 def pwd(self, parameter_s=''):
214 215 """Return the current working directory path.
215 216
216 217 Examples
217 218 --------
218 219 ::
219 220
220 221 In [9]: pwd
221 222 Out[9]: '/home/tsuser/sprint/ipython'
222 223 """
223 224 return os.getcwdu()
224 225
225 226 @skip_doctest
226 227 @line_magic
227 228 def cd(self, parameter_s=''):
228 229 """Change the current working directory.
229 230
230 231 This command automatically maintains an internal list of directories
231 232 you visit during your IPython session, in the variable _dh. The
232 233 command %dhist shows this history nicely formatted. You can also
233 234 do 'cd -<tab>' to see directory history conveniently.
234 235
235 236 Usage:
236 237
237 238 cd 'dir': changes to directory 'dir'.
238 239
239 240 cd -: changes to the last visited directory.
240 241
241 242 cd -<n>: changes to the n-th directory in the directory history.
242 243
243 244 cd --foo: change to directory that matches 'foo' in history
244 245
245 246 cd -b <bookmark_name>: jump to a bookmark set by %bookmark
246 247 (note: cd <bookmark_name> is enough if there is no
247 248 directory <bookmark_name>, but a bookmark with the name exists.)
248 249 'cd -b <tab>' allows you to tab-complete bookmark names.
249 250
250 251 Options:
251 252
252 253 -q: quiet. Do not print the working directory after the cd command is
253 254 executed. By default IPython's cd command does print this directory,
254 255 since the default prompts do not display path information.
255 256
256 257 Note that !cd doesn't work for this purpose because the shell where
257 258 !command runs is immediately discarded after executing 'command'.
258 259
259 260 Examples
260 261 --------
261 262 ::
262 263
263 264 In [10]: cd parent/child
264 265 /home/tsuser/parent/child
265 266 """
266 267
267 268 oldcwd = os.getcwdu()
268 269 numcd = re.match(r'(-)(\d+)$',parameter_s)
269 270 # jump in directory history by number
270 271 if numcd:
271 272 nn = int(numcd.group(2))
272 273 try:
273 274 ps = self.shell.user_ns['_dh'][nn]
274 275 except IndexError:
275 276 print 'The requested directory does not exist in history.'
276 277 return
277 278 else:
278 279 opts = {}
279 280 elif parameter_s.startswith('--'):
280 281 ps = None
281 282 fallback = None
282 283 pat = parameter_s[2:]
283 284 dh = self.shell.user_ns['_dh']
284 285 # first search only by basename (last component)
285 286 for ent in reversed(dh):
286 287 if pat in os.path.basename(ent) and os.path.isdir(ent):
287 288 ps = ent
288 289 break
289 290
290 291 if fallback is None and pat in ent and os.path.isdir(ent):
291 292 fallback = ent
292 293
293 294 # if we have no last part match, pick the first full path match
294 295 if ps is None:
295 296 ps = fallback
296 297
297 298 if ps is None:
298 299 print "No matching entry in directory history"
299 300 return
300 301 else:
301 302 opts = {}
302 303
303 304
304 305 else:
305 306 #turn all non-space-escaping backslashes to slashes,
306 307 # for c:\windows\directory\names\
307 308 parameter_s = re.sub(r'\\(?! )','/', parameter_s)
308 309 opts,ps = self.parse_options(parameter_s,'qb',mode='string')
309 310 # jump to previous
310 311 if ps == '-':
311 312 try:
312 313 ps = self.shell.user_ns['_dh'][-2]
313 314 except IndexError:
314 315 raise UsageError('%cd -: No previous directory to change to.')
315 316 # jump to bookmark if needed
316 317 else:
317 318 if not os.path.isdir(ps) or 'b' in opts:
318 319 bkms = self.shell.db.get('bookmarks', {})
319 320
320 321 if ps in bkms:
321 322 target = bkms[ps]
322 323 print '(bookmark:%s) -> %s' % (ps, target)
323 324 ps = target
324 325 else:
325 326 if 'b' in opts:
326 327 raise UsageError("Bookmark '%s' not found. "
327 328 "Use '%%bookmark -l' to see your bookmarks." % ps)
328 329
329 330 # strip extra quotes on Windows, because os.chdir doesn't like them
330 331 ps = unquote_filename(ps)
331 332 # at this point ps should point to the target dir
332 333 if ps:
333 334 try:
334 335 os.chdir(os.path.expanduser(ps))
335 336 if hasattr(self.shell, 'term_title') and self.shell.term_title:
336 337 set_term_title('IPython: ' + abbrev_cwd())
337 338 except OSError:
338 339 print sys.exc_info()[1]
339 340 else:
340 341 cwd = os.getcwdu()
341 342 dhist = self.shell.user_ns['_dh']
342 343 if oldcwd != cwd:
343 344 dhist.append(cwd)
344 345 self.shell.db['dhist'] = compress_dhist(dhist)[-100:]
345 346
346 347 else:
347 348 os.chdir(self.shell.home_dir)
348 349 if hasattr(self.shell, 'term_title') and self.shell.term_title:
349 350 set_term_title('IPython: ' + '~')
350 351 cwd = os.getcwdu()
351 352 dhist = self.shell.user_ns['_dh']
352 353
353 354 if oldcwd != cwd:
354 355 dhist.append(cwd)
355 356 self.shell.db['dhist'] = compress_dhist(dhist)[-100:]
356 357 if not 'q' in opts and self.shell.user_ns['_dh']:
357 358 print self.shell.user_ns['_dh'][-1]
358 359
359 360
360 361 @line_magic
361 362 def env(self, parameter_s=''):
362 363 """List environment variables."""
363 364
364 365 return dict(os.environ)
365 366
366 367 @line_magic
367 368 def pushd(self, parameter_s=''):
368 369 """Place the current dir on stack and change directory.
369 370
370 371 Usage:\\
371 372 %pushd ['dirname']
372 373 """
373 374
374 375 dir_s = self.shell.dir_stack
375 376 tgt = os.path.expanduser(unquote_filename(parameter_s))
376 377 cwd = os.getcwdu().replace(self.shell.home_dir,'~')
377 378 if tgt:
378 379 self.cd(parameter_s)
379 380 dir_s.insert(0,cwd)
380 381 return self.shell.magic('dirs')
381 382
382 383 @line_magic
383 384 def popd(self, parameter_s=''):
384 385 """Change to directory popped off the top of the stack.
385 386 """
386 387 if not self.shell.dir_stack:
387 388 raise UsageError("%popd on empty stack")
388 389 top = self.shell.dir_stack.pop(0)
389 390 self.cd(top)
390 391 print "popd ->",top
391 392
392 393 @line_magic
393 394 def dirs(self, parameter_s=''):
394 395 """Return the current directory stack."""
395 396
396 397 return self.shell.dir_stack
397 398
398 399 @line_magic
399 400 def dhist(self, parameter_s=''):
400 401 """Print your history of visited directories.
401 402
402 403 %dhist -> print full history\\
403 404 %dhist n -> print last n entries only\\
404 405 %dhist n1 n2 -> print entries between n1 and n2 (n1 not included)\\
405 406
406 407 This history is automatically maintained by the %cd command, and
407 408 always available as the global list variable _dh. You can use %cd -<n>
408 409 to go to directory number <n>.
409 410
410 411 Note that most of time, you should view directory history by entering
411 412 cd -<TAB>.
412 413
413 414 """
414 415
415 416 dh = self.shell.user_ns['_dh']
416 417 if parameter_s:
417 418 try:
418 419 args = map(int,parameter_s.split())
419 420 except:
420 421 self.arg_err(self.dhist)
421 422 return
422 423 if len(args) == 1:
423 424 ini,fin = max(len(dh)-(args[0]),0),len(dh)
424 425 elif len(args) == 2:
425 426 ini,fin = args
426 427 else:
427 428 self.arg_err(self.dhist)
428 429 return
429 430 else:
430 431 ini,fin = 0,len(dh)
431 432 nlprint(dh,
432 433 header = 'Directory history (kept in _dh)',
433 434 start=ini,stop=fin)
434 435
435 436 @skip_doctest
436 437 @line_magic
437 438 def sc(self, parameter_s=''):
438 439 """Shell capture - run shell command and capture output (DEPRECATED use !).
439 440
440 441 DEPRECATED. Suboptimal, retained for backwards compatibility.
441 442
442 443 You should use the form 'var = !command' instead. Example:
443 444
444 445 "%sc -l myfiles = ls ~" should now be written as
445 446
446 447 "myfiles = !ls ~"
447 448
448 449 myfiles.s, myfiles.l and myfiles.n still apply as documented
449 450 below.
450 451
451 452 --
452 453 %sc [options] varname=command
453 454
454 455 IPython will run the given command using commands.getoutput(), and
455 456 will then update the user's interactive namespace with a variable
456 457 called varname, containing the value of the call. Your command can
457 458 contain shell wildcards, pipes, etc.
458 459
459 460 The '=' sign in the syntax is mandatory, and the variable name you
460 461 supply must follow Python's standard conventions for valid names.
461 462
462 463 (A special format without variable name exists for internal use)
463 464
464 465 Options:
465 466
466 467 -l: list output. Split the output on newlines into a list before
467 468 assigning it to the given variable. By default the output is stored
468 469 as a single string.
469 470
470 471 -v: verbose. Print the contents of the variable.
471 472
472 473 In most cases you should not need to split as a list, because the
473 474 returned value is a special type of string which can automatically
474 475 provide its contents either as a list (split on newlines) or as a
475 476 space-separated string. These are convenient, respectively, either
476 477 for sequential processing or to be passed to a shell command.
477 478
478 479 For example::
479 480
480 481 # Capture into variable a
481 482 In [1]: sc a=ls *py
482 483
483 484 # a is a string with embedded newlines
484 485 In [2]: a
485 486 Out[2]: 'setup.py\\nwin32_manual_post_install.py'
486 487
487 488 # which can be seen as a list:
488 489 In [3]: a.l
489 490 Out[3]: ['setup.py', 'win32_manual_post_install.py']
490 491
491 492 # or as a whitespace-separated string:
492 493 In [4]: a.s
493 494 Out[4]: 'setup.py win32_manual_post_install.py'
494 495
495 496 # a.s is useful to pass as a single command line:
496 497 In [5]: !wc -l $a.s
497 498 146 setup.py
498 499 130 win32_manual_post_install.py
499 500 276 total
500 501
501 502 # while the list form is useful to loop over:
502 503 In [6]: for f in a.l:
503 504 ...: !wc -l $f
504 505 ...:
505 506 146 setup.py
506 507 130 win32_manual_post_install.py
507 508
508 509 Similarly, the lists returned by the -l option are also special, in
509 510 the sense that you can equally invoke the .s attribute on them to
510 511 automatically get a whitespace-separated string from their contents::
511 512
512 513 In [7]: sc -l b=ls *py
513 514
514 515 In [8]: b
515 516 Out[8]: ['setup.py', 'win32_manual_post_install.py']
516 517
517 518 In [9]: b.s
518 519 Out[9]: 'setup.py win32_manual_post_install.py'
519 520
520 521 In summary, both the lists and strings used for output capture have
521 522 the following special attributes::
522 523
523 524 .l (or .list) : value as list.
524 525 .n (or .nlstr): value as newline-separated string.
525 526 .s (or .spstr): value as space-separated string.
526 527 """
527 528
528 529 opts,args = self.parse_options(parameter_s, 'lv')
529 530 # Try to get a variable name and command to run
530 531 try:
531 532 # the variable name must be obtained from the parse_options
532 533 # output, which uses shlex.split to strip options out.
533 534 var,_ = args.split('=', 1)
534 535 var = var.strip()
535 536 # But the command has to be extracted from the original input
536 537 # parameter_s, not on what parse_options returns, to avoid the
537 538 # quote stripping which shlex.split performs on it.
538 539 _,cmd = parameter_s.split('=', 1)
539 540 except ValueError:
540 541 var,cmd = '',''
541 542 # If all looks ok, proceed
542 543 split = 'l' in opts
543 544 out = self.shell.getoutput(cmd, split=split)
544 545 if 'v' in opts:
545 546 print '%s ==\n%s' % (var, pformat(out))
546 547 if var:
547 548 self.shell.user_ns.update({var:out})
548 549 else:
549 550 return out
550 551
551 552 @line_cell_magic
552 553 def sx(self, line='', cell=None):
553 554 """Shell execute - run shell command and capture output (!! is short-hand).
554 555
555 556 %sx command
556 557
557 558 IPython will run the given command using commands.getoutput(), and
558 559 return the result formatted as a list (split on '\\n'). Since the
559 560 output is _returned_, it will be stored in ipython's regular output
560 561 cache Out[N] and in the '_N' automatic variables.
561 562
562 563 Notes:
563 564
564 565 1) If an input line begins with '!!', then %sx is automatically
565 566 invoked. That is, while::
566 567
567 568 !ls
568 569
569 570 causes ipython to simply issue system('ls'), typing::
570 571
571 572 !!ls
572 573
573 574 is a shorthand equivalent to::
574 575
575 576 %sx ls
576 577
577 578 2) %sx differs from %sc in that %sx automatically splits into a list,
578 579 like '%sc -l'. The reason for this is to make it as easy as possible
579 580 to process line-oriented shell output via further python commands.
580 581 %sc is meant to provide much finer control, but requires more
581 582 typing.
582 583
583 584 3) Just like %sc -l, this is a list with special attributes:
584 585 ::
585 586
586 587 .l (or .list) : value as list.
587 588 .n (or .nlstr): value as newline-separated string.
588 589 .s (or .spstr): value as whitespace-separated string.
589 590
590 591 This is very useful when trying to use such lists as arguments to
591 592 system commands."""
592 593
593 594 if cell is None:
594 595 # line magic
595 596 return self.shell.getoutput(line)
596 597 else:
597 598 opts,args = self.parse_options(line, '', 'out=')
598 599 output = self.shell.getoutput(cell)
599 600 out_name = opts.get('out', opts.get('o'))
600 601 if out_name:
601 602 self.shell.user_ns[out_name] = output
602 603 else:
603 604 return output
604 605
605 606 system = line_cell_magic('system')(sx)
606 607 bang = cell_magic('!')(sx)
607 608
608 609 @line_magic
609 610 def bookmark(self, parameter_s=''):
610 611 """Manage IPython's bookmark system.
611 612
612 613 %bookmark <name> - set bookmark to current dir
613 614 %bookmark <name> <dir> - set bookmark to <dir>
614 615 %bookmark -l - list all bookmarks
615 616 %bookmark -d <name> - remove bookmark
616 617 %bookmark -r - remove all bookmarks
617 618
618 619 You can later on access a bookmarked folder with::
619 620
620 621 %cd -b <name>
621 622
622 623 or simply '%cd <name>' if there is no directory called <name> AND
623 624 there is such a bookmark defined.
624 625
625 626 Your bookmarks persist through IPython sessions, but they are
626 627 associated with each profile."""
627 628
628 629 opts,args = self.parse_options(parameter_s,'drl',mode='list')
629 630 if len(args) > 2:
630 631 raise UsageError("%bookmark: too many arguments")
631 632
632 633 bkms = self.shell.db.get('bookmarks',{})
633 634
634 635 if 'd' in opts:
635 636 try:
636 637 todel = args[0]
637 638 except IndexError:
638 639 raise UsageError(
639 640 "%bookmark -d: must provide a bookmark to delete")
640 641 else:
641 642 try:
642 643 del bkms[todel]
643 644 except KeyError:
644 645 raise UsageError(
645 646 "%%bookmark -d: Can't delete bookmark '%s'" % todel)
646 647
647 648 elif 'r' in opts:
648 649 bkms = {}
649 650 elif 'l' in opts:
650 651 bks = bkms.keys()
651 652 bks.sort()
652 653 if bks:
653 654 size = max(map(len, bks))
654 655 else:
655 656 size = 0
656 657 fmt = '%-'+str(size)+'s -> %s'
657 658 print 'Current bookmarks:'
658 659 for bk in bks:
659 660 print fmt % (bk, bkms[bk])
660 661 else:
661 662 if not args:
662 663 raise UsageError("%bookmark: You must specify the bookmark name")
663 664 elif len(args)==1:
664 665 bkms[args[0]] = os.getcwdu()
665 666 elif len(args)==2:
666 667 bkms[args[0]] = args[1]
667 668 self.shell.db['bookmarks'] = bkms
668 669
669 670 @line_magic
670 671 def pycat(self, parameter_s=''):
671 672 """Show a syntax-highlighted file through a pager.
672 673
673 674 This magic is similar to the cat utility, but it will assume the file
674 675 to be Python source and will show it with syntax highlighting.
675 676
676 677 This magic command can either take a local filename, an url,
677 678 an history range (see %history) or a macro as argument ::
678 679
679 680 %pycat myscript.py
680 681 %pycat 7-27
681 682 %pycat myMacro
682 683 %pycat http://www.example.com/myscript.py
683 684 """
684 685 if not parameter_s:
685 686 raise UsageError('Missing filename, URL, input history range, '
686 687 'or macro.')
687 688
688 689 try :
689 690 cont = self.shell.find_user_code(parameter_s)
690 691 except (ValueError, IOError):
691 692 print "Error: no such file, variable, URL, history range or macro"
692 693 return
693 694
694 695 page.page(self.shell.pycolorize(source_to_unicode(cont)))
695 696
696 697 @magic_arguments.magic_arguments()
697 698 @magic_arguments.argument(
698 699 '-a', '--amend', action='store_true', default=False,
699 700 help='Open file for amending if it exists'
700 701 )
701 702 @magic_arguments.argument(
702 703 'filename', type=unicode,
703 704 help='file to write'
704 705 )
705 706 @cell_magic
706 707 def file(self, line, cell):
707 708 """Write the contents of the cell to a file.
708 709
709 710 For frontends that do not support stdin (Notebook), -f is implied.
710 711 """
711 712 args = magic_arguments.parse_argstring(self.file, line)
712 713 filename = unquote_filename(args.filename)
713 714
714 715 if os.path.exists(filename):
715 716 if args.amend:
716 717 print "Amending to %s" % filename
717 718 else:
718 719 print "Overwriting %s" % filename
719 720 else:
720 721 print "Writing %s" % filename
721 722
722 723 mode = 'a' if args.amend else 'w'
723 724 with io.open(filename, mode, encoding='utf-8') as f:
724 725 f.write(cell)
General Comments 0
You need to be logged in to leave comments. Login now