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