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