##// END OF EJS Templates
Fix deprecation warning from os.popen3....
Fernando Perez -
Show More
@@ -1,1807 +1,1814 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """General purpose utilities.
2 """General purpose utilities.
3
3
4 This is a grab-bag of stuff I find useful in most programs I write. Some of
4 This is a grab-bag of stuff I find useful in most programs I write. Some of
5 these things are also convenient when working at the command line.
5 these things are also convenient when working at the command line.
6 """
6 """
7
7
8 #*****************************************************************************
8 #*****************************************************************************
9 # Copyright (C) 2001-2006 Fernando Perez. <fperez@colorado.edu>
9 # Copyright (C) 2001-2006 Fernando Perez. <fperez@colorado.edu>
10 #
10 #
11 # Distributed under the terms of the BSD License. The full license is in
11 # Distributed under the terms of the BSD License. The full license is in
12 # the file COPYING, distributed as part of this software.
12 # the file COPYING, distributed as part of this software.
13 #*****************************************************************************
13 #*****************************************************************************
14
14
15 #****************************************************************************
15 #****************************************************************************
16 # required modules from the Python standard library
16 # required modules from the Python standard library
17 import __main__
17 import __main__
18
18
19 import os
19 import os
20 import platform
20 import platform
21 import re
21 import re
22 import shlex
22 import shlex
23 import shutil
23 import shutil
24 import subprocess
24 import subprocess
25 import sys
25 import sys
26 import time
26 import time
27 import types
27 import types
28 import warnings
28 import warnings
29
29
30 # Curses and termios are Unix-only modules
30 # Curses and termios are Unix-only modules
31 try:
31 try:
32 import curses
32 import curses
33 # We need termios as well, so if its import happens to raise, we bail on
33 # We need termios as well, so if its import happens to raise, we bail on
34 # using curses altogether.
34 # using curses altogether.
35 import termios
35 import termios
36 except ImportError:
36 except ImportError:
37 USE_CURSES = False
37 USE_CURSES = False
38 else:
38 else:
39 # Curses on Solaris may not be complete, so we can't use it there
39 # Curses on Solaris may not be complete, so we can't use it there
40 USE_CURSES = hasattr(curses,'initscr')
40 USE_CURSES = hasattr(curses,'initscr')
41
41
42 # Other IPython utilities
42 # Other IPython utilities
43 import IPython
43 import IPython
44 from IPython.external.Itpl import itpl,printpl
44 from IPython.external.Itpl import itpl,printpl
45 from IPython.utils import platutils
45 from IPython.utils import platutils
46 from IPython.utils.generics import result_display
46 from IPython.utils.generics import result_display
47 from IPython.external.path import path
47 from IPython.external.path import path
48
48
49
49
50 #****************************************************************************
50 #****************************************************************************
51 # Exceptions
51 # Exceptions
52 class Error(Exception):
52 class Error(Exception):
53 """Base class for exceptions in this module."""
53 """Base class for exceptions in this module."""
54 pass
54 pass
55
55
56 #----------------------------------------------------------------------------
56 #----------------------------------------------------------------------------
57 class IOStream:
57 class IOStream:
58 def __init__(self,stream,fallback):
58 def __init__(self,stream,fallback):
59 if not hasattr(stream,'write') or not hasattr(stream,'flush'):
59 if not hasattr(stream,'write') or not hasattr(stream,'flush'):
60 stream = fallback
60 stream = fallback
61 self.stream = stream
61 self.stream = stream
62 self._swrite = stream.write
62 self._swrite = stream.write
63 self.flush = stream.flush
63 self.flush = stream.flush
64
64
65 def write(self,data):
65 def write(self,data):
66 try:
66 try:
67 self._swrite(data)
67 self._swrite(data)
68 except:
68 except:
69 try:
69 try:
70 # print handles some unicode issues which may trip a plain
70 # print handles some unicode issues which may trip a plain
71 # write() call. Attempt to emulate write() by using a
71 # write() call. Attempt to emulate write() by using a
72 # trailing comma
72 # trailing comma
73 print >> self.stream, data,
73 print >> self.stream, data,
74 except:
74 except:
75 # if we get here, something is seriously broken.
75 # if we get here, something is seriously broken.
76 print >> sys.stderr, \
76 print >> sys.stderr, \
77 'ERROR - failed to write data to stream:', self.stream
77 'ERROR - failed to write data to stream:', self.stream
78
78
79 def close(self):
79 def close(self):
80 pass
80 pass
81
81
82
82
83 class IOTerm:
83 class IOTerm:
84 """ Term holds the file or file-like objects for handling I/O operations.
84 """ Term holds the file or file-like objects for handling I/O operations.
85
85
86 These are normally just sys.stdin, sys.stdout and sys.stderr but for
86 These are normally just sys.stdin, sys.stdout and sys.stderr but for
87 Windows they can can replaced to allow editing the strings before they are
87 Windows they can can replaced to allow editing the strings before they are
88 displayed."""
88 displayed."""
89
89
90 # In the future, having IPython channel all its I/O operations through
90 # In the future, having IPython channel all its I/O operations through
91 # this class will make it easier to embed it into other environments which
91 # this class will make it easier to embed it into other environments which
92 # are not a normal terminal (such as a GUI-based shell)
92 # are not a normal terminal (such as a GUI-based shell)
93 def __init__(self,cin=None,cout=None,cerr=None):
93 def __init__(self,cin=None,cout=None,cerr=None):
94 self.cin = IOStream(cin,sys.stdin)
94 self.cin = IOStream(cin,sys.stdin)
95 self.cout = IOStream(cout,sys.stdout)
95 self.cout = IOStream(cout,sys.stdout)
96 self.cerr = IOStream(cerr,sys.stderr)
96 self.cerr = IOStream(cerr,sys.stderr)
97
97
98 # Global variable to be used for all I/O
98 # Global variable to be used for all I/O
99 Term = IOTerm()
99 Term = IOTerm()
100
100
101 import IPython.utils.rlineimpl as readline
101 import IPython.utils.rlineimpl as readline
102 # Remake Term to use the readline i/o facilities
102 # Remake Term to use the readline i/o facilities
103 if sys.platform == 'win32' and readline.have_readline:
103 if sys.platform == 'win32' and readline.have_readline:
104
104
105 Term = IOTerm(cout=readline._outputfile,cerr=readline._outputfile)
105 Term = IOTerm(cout=readline._outputfile,cerr=readline._outputfile)
106
106
107
107
108 #****************************************************************************
108 #****************************************************************************
109 # Generic warning/error printer, used by everything else
109 # Generic warning/error printer, used by everything else
110 def warn(msg,level=2,exit_val=1):
110 def warn(msg,level=2,exit_val=1):
111 """Standard warning printer. Gives formatting consistency.
111 """Standard warning printer. Gives formatting consistency.
112
112
113 Output is sent to Term.cerr (sys.stderr by default).
113 Output is sent to Term.cerr (sys.stderr by default).
114
114
115 Options:
115 Options:
116
116
117 -level(2): allows finer control:
117 -level(2): allows finer control:
118 0 -> Do nothing, dummy function.
118 0 -> Do nothing, dummy function.
119 1 -> Print message.
119 1 -> Print message.
120 2 -> Print 'WARNING:' + message. (Default level).
120 2 -> Print 'WARNING:' + message. (Default level).
121 3 -> Print 'ERROR:' + message.
121 3 -> Print 'ERROR:' + message.
122 4 -> Print 'FATAL ERROR:' + message and trigger a sys.exit(exit_val).
122 4 -> Print 'FATAL ERROR:' + message and trigger a sys.exit(exit_val).
123
123
124 -exit_val (1): exit value returned by sys.exit() for a level 4
124 -exit_val (1): exit value returned by sys.exit() for a level 4
125 warning. Ignored for all other levels."""
125 warning. Ignored for all other levels."""
126
126
127 if level>0:
127 if level>0:
128 header = ['','','WARNING: ','ERROR: ','FATAL ERROR: ']
128 header = ['','','WARNING: ','ERROR: ','FATAL ERROR: ']
129 print >> Term.cerr, '%s%s' % (header[level],msg)
129 print >> Term.cerr, '%s%s' % (header[level],msg)
130 if level == 4:
130 if level == 4:
131 print >> Term.cerr,'Exiting.\n'
131 print >> Term.cerr,'Exiting.\n'
132 sys.exit(exit_val)
132 sys.exit(exit_val)
133
133
134 def info(msg):
134 def info(msg):
135 """Equivalent to warn(msg,level=1)."""
135 """Equivalent to warn(msg,level=1)."""
136
136
137 warn(msg,level=1)
137 warn(msg,level=1)
138
138
139 def error(msg):
139 def error(msg):
140 """Equivalent to warn(msg,level=3)."""
140 """Equivalent to warn(msg,level=3)."""
141
141
142 warn(msg,level=3)
142 warn(msg,level=3)
143
143
144 def fatal(msg,exit_val=1):
144 def fatal(msg,exit_val=1):
145 """Equivalent to warn(msg,exit_val=exit_val,level=4)."""
145 """Equivalent to warn(msg,exit_val=exit_val,level=4)."""
146
146
147 warn(msg,exit_val=exit_val,level=4)
147 warn(msg,exit_val=exit_val,level=4)
148
148
149 #---------------------------------------------------------------------------
149 #---------------------------------------------------------------------------
150 # Debugging routines
150 # Debugging routines
151 #
151 #
152 def debugx(expr,pre_msg=''):
152 def debugx(expr,pre_msg=''):
153 """Print the value of an expression from the caller's frame.
153 """Print the value of an expression from the caller's frame.
154
154
155 Takes an expression, evaluates it in the caller's frame and prints both
155 Takes an expression, evaluates it in the caller's frame and prints both
156 the given expression and the resulting value (as well as a debug mark
156 the given expression and the resulting value (as well as a debug mark
157 indicating the name of the calling function. The input must be of a form
157 indicating the name of the calling function. The input must be of a form
158 suitable for eval().
158 suitable for eval().
159
159
160 An optional message can be passed, which will be prepended to the printed
160 An optional message can be passed, which will be prepended to the printed
161 expr->value pair."""
161 expr->value pair."""
162
162
163 cf = sys._getframe(1)
163 cf = sys._getframe(1)
164 print '[DBG:%s] %s%s -> %r' % (cf.f_code.co_name,pre_msg,expr,
164 print '[DBG:%s] %s%s -> %r' % (cf.f_code.co_name,pre_msg,expr,
165 eval(expr,cf.f_globals,cf.f_locals))
165 eval(expr,cf.f_globals,cf.f_locals))
166
166
167 # deactivate it by uncommenting the following line, which makes it a no-op
167 # deactivate it by uncommenting the following line, which makes it a no-op
168 #def debugx(expr,pre_msg=''): pass
168 #def debugx(expr,pre_msg=''): pass
169
169
170 #----------------------------------------------------------------------------
170 #----------------------------------------------------------------------------
171 StringTypes = types.StringTypes
171 StringTypes = types.StringTypes
172
172
173 # Basic timing functionality
173 # Basic timing functionality
174
174
175 # If possible (Unix), use the resource module instead of time.clock()
175 # If possible (Unix), use the resource module instead of time.clock()
176 try:
176 try:
177 import resource
177 import resource
178 def clocku():
178 def clocku():
179 """clocku() -> floating point number
179 """clocku() -> floating point number
180
180
181 Return the *USER* CPU time in seconds since the start of the process.
181 Return the *USER* CPU time in seconds since the start of the process.
182 This is done via a call to resource.getrusage, so it avoids the
182 This is done via a call to resource.getrusage, so it avoids the
183 wraparound problems in time.clock()."""
183 wraparound problems in time.clock()."""
184
184
185 return resource.getrusage(resource.RUSAGE_SELF)[0]
185 return resource.getrusage(resource.RUSAGE_SELF)[0]
186
186
187 def clocks():
187 def clocks():
188 """clocks() -> floating point number
188 """clocks() -> floating point number
189
189
190 Return the *SYSTEM* CPU time in seconds since the start of the process.
190 Return the *SYSTEM* CPU time in seconds since the start of the process.
191 This is done via a call to resource.getrusage, so it avoids the
191 This is done via a call to resource.getrusage, so it avoids the
192 wraparound problems in time.clock()."""
192 wraparound problems in time.clock()."""
193
193
194 return resource.getrusage(resource.RUSAGE_SELF)[1]
194 return resource.getrusage(resource.RUSAGE_SELF)[1]
195
195
196 def clock():
196 def clock():
197 """clock() -> floating point number
197 """clock() -> floating point number
198
198
199 Return the *TOTAL USER+SYSTEM* CPU time in seconds since the start of
199 Return the *TOTAL USER+SYSTEM* CPU time in seconds since the start of
200 the process. This is done via a call to resource.getrusage, so it
200 the process. This is done via a call to resource.getrusage, so it
201 avoids the wraparound problems in time.clock()."""
201 avoids the wraparound problems in time.clock()."""
202
202
203 u,s = resource.getrusage(resource.RUSAGE_SELF)[:2]
203 u,s = resource.getrusage(resource.RUSAGE_SELF)[:2]
204 return u+s
204 return u+s
205
205
206 def clock2():
206 def clock2():
207 """clock2() -> (t_user,t_system)
207 """clock2() -> (t_user,t_system)
208
208
209 Similar to clock(), but return a tuple of user/system times."""
209 Similar to clock(), but return a tuple of user/system times."""
210 return resource.getrusage(resource.RUSAGE_SELF)[:2]
210 return resource.getrusage(resource.RUSAGE_SELF)[:2]
211
211
212 except ImportError:
212 except ImportError:
213 # There is no distinction of user/system time under windows, so we just use
213 # There is no distinction of user/system time under windows, so we just use
214 # time.clock() for everything...
214 # time.clock() for everything...
215 clocku = clocks = clock = time.clock
215 clocku = clocks = clock = time.clock
216 def clock2():
216 def clock2():
217 """Under windows, system CPU time can't be measured.
217 """Under windows, system CPU time can't be measured.
218
218
219 This just returns clock() and zero."""
219 This just returns clock() and zero."""
220 return time.clock(),0.0
220 return time.clock(),0.0
221
221
222 def timings_out(reps,func,*args,**kw):
222 def timings_out(reps,func,*args,**kw):
223 """timings_out(reps,func,*args,**kw) -> (t_total,t_per_call,output)
223 """timings_out(reps,func,*args,**kw) -> (t_total,t_per_call,output)
224
224
225 Execute a function reps times, return a tuple with the elapsed total
225 Execute a function reps times, return a tuple with the elapsed total
226 CPU time in seconds, the time per call and the function's output.
226 CPU time in seconds, the time per call and the function's output.
227
227
228 Under Unix, the return value is the sum of user+system time consumed by
228 Under Unix, the return value is the sum of user+system time consumed by
229 the process, computed via the resource module. This prevents problems
229 the process, computed via the resource module. This prevents problems
230 related to the wraparound effect which the time.clock() function has.
230 related to the wraparound effect which the time.clock() function has.
231
231
232 Under Windows the return value is in wall clock seconds. See the
232 Under Windows the return value is in wall clock seconds. See the
233 documentation for the time module for more details."""
233 documentation for the time module for more details."""
234
234
235 reps = int(reps)
235 reps = int(reps)
236 assert reps >=1, 'reps must be >= 1'
236 assert reps >=1, 'reps must be >= 1'
237 if reps==1:
237 if reps==1:
238 start = clock()
238 start = clock()
239 out = func(*args,**kw)
239 out = func(*args,**kw)
240 tot_time = clock()-start
240 tot_time = clock()-start
241 else:
241 else:
242 rng = xrange(reps-1) # the last time is executed separately to store output
242 rng = xrange(reps-1) # the last time is executed separately to store output
243 start = clock()
243 start = clock()
244 for dummy in rng: func(*args,**kw)
244 for dummy in rng: func(*args,**kw)
245 out = func(*args,**kw) # one last time
245 out = func(*args,**kw) # one last time
246 tot_time = clock()-start
246 tot_time = clock()-start
247 av_time = tot_time / reps
247 av_time = tot_time / reps
248 return tot_time,av_time,out
248 return tot_time,av_time,out
249
249
250 def timings(reps,func,*args,**kw):
250 def timings(reps,func,*args,**kw):
251 """timings(reps,func,*args,**kw) -> (t_total,t_per_call)
251 """timings(reps,func,*args,**kw) -> (t_total,t_per_call)
252
252
253 Execute a function reps times, return a tuple with the elapsed total CPU
253 Execute a function reps times, return a tuple with the elapsed total CPU
254 time in seconds and the time per call. These are just the first two values
254 time in seconds and the time per call. These are just the first two values
255 in timings_out()."""
255 in timings_out()."""
256
256
257 return timings_out(reps,func,*args,**kw)[0:2]
257 return timings_out(reps,func,*args,**kw)[0:2]
258
258
259 def timing(func,*args,**kw):
259 def timing(func,*args,**kw):
260 """timing(func,*args,**kw) -> t_total
260 """timing(func,*args,**kw) -> t_total
261
261
262 Execute a function once, return the elapsed total CPU time in
262 Execute a function once, return the elapsed total CPU time in
263 seconds. This is just the first value in timings_out()."""
263 seconds. This is just the first value in timings_out()."""
264
264
265 return timings_out(1,func,*args,**kw)[0]
265 return timings_out(1,func,*args,**kw)[0]
266
266
267 #****************************************************************************
267 #****************************************************************************
268 # file and system
268 # file and system
269
269
270 def arg_split(s,posix=False):
270 def arg_split(s,posix=False):
271 """Split a command line's arguments in a shell-like manner.
271 """Split a command line's arguments in a shell-like manner.
272
272
273 This is a modified version of the standard library's shlex.split()
273 This is a modified version of the standard library's shlex.split()
274 function, but with a default of posix=False for splitting, so that quotes
274 function, but with a default of posix=False for splitting, so that quotes
275 in inputs are respected."""
275 in inputs are respected."""
276
276
277 # XXX - there may be unicode-related problems here!!! I'm not sure that
277 # XXX - there may be unicode-related problems here!!! I'm not sure that
278 # shlex is truly unicode-safe, so it might be necessary to do
278 # shlex is truly unicode-safe, so it might be necessary to do
279 #
279 #
280 # s = s.encode(sys.stdin.encoding)
280 # s = s.encode(sys.stdin.encoding)
281 #
281 #
282 # first, to ensure that shlex gets a normal string. Input from anyone who
282 # first, to ensure that shlex gets a normal string. Input from anyone who
283 # knows more about unicode and shlex than I would be good to have here...
283 # knows more about unicode and shlex than I would be good to have here...
284 lex = shlex.shlex(s, posix=posix)
284 lex = shlex.shlex(s, posix=posix)
285 lex.whitespace_split = True
285 lex.whitespace_split = True
286 return list(lex)
286 return list(lex)
287
287
288 def system(cmd,verbose=0,debug=0,header=''):
288 def system(cmd,verbose=0,debug=0,header=''):
289 """Execute a system command, return its exit status.
289 """Execute a system command, return its exit status.
290
290
291 Options:
291 Options:
292
292
293 - verbose (0): print the command to be executed.
293 - verbose (0): print the command to be executed.
294
294
295 - debug (0): only print, do not actually execute.
295 - debug (0): only print, do not actually execute.
296
296
297 - header (''): Header to print on screen prior to the executed command (it
297 - header (''): Header to print on screen prior to the executed command (it
298 is only prepended to the command, no newlines are added).
298 is only prepended to the command, no newlines are added).
299
299
300 Note: a stateful version of this function is available through the
300 Note: a stateful version of this function is available through the
301 SystemExec class."""
301 SystemExec class."""
302
302
303 stat = 0
303 stat = 0
304 if verbose or debug: print header+cmd
304 if verbose or debug: print header+cmd
305 sys.stdout.flush()
305 sys.stdout.flush()
306 if not debug: stat = os.system(cmd)
306 if not debug: stat = os.system(cmd)
307 return stat
307 return stat
308
308
309 def abbrev_cwd():
309 def abbrev_cwd():
310 """ Return abbreviated version of cwd, e.g. d:mydir """
310 """ Return abbreviated version of cwd, e.g. d:mydir """
311 cwd = os.getcwd().replace('\\','/')
311 cwd = os.getcwd().replace('\\','/')
312 drivepart = ''
312 drivepart = ''
313 tail = cwd
313 tail = cwd
314 if sys.platform == 'win32':
314 if sys.platform == 'win32':
315 if len(cwd) < 4:
315 if len(cwd) < 4:
316 return cwd
316 return cwd
317 drivepart,tail = os.path.splitdrive(cwd)
317 drivepart,tail = os.path.splitdrive(cwd)
318
318
319
319
320 parts = tail.split('/')
320 parts = tail.split('/')
321 if len(parts) > 2:
321 if len(parts) > 2:
322 tail = '/'.join(parts[-2:])
322 tail = '/'.join(parts[-2:])
323
323
324 return (drivepart + (
324 return (drivepart + (
325 cwd == '/' and '/' or tail))
325 cwd == '/' and '/' or tail))
326
326
327
327
328 # This function is used by ipython in a lot of places to make system calls.
328 # This function is used by ipython in a lot of places to make system calls.
329 # We need it to be slightly different under win32, due to the vagaries of
329 # We need it to be slightly different under win32, due to the vagaries of
330 # 'network shares'. A win32 override is below.
330 # 'network shares'. A win32 override is below.
331
331
332 def shell(cmd,verbose=0,debug=0,header=''):
332 def shell(cmd,verbose=0,debug=0,header=''):
333 """Execute a command in the system shell, always return None.
333 """Execute a command in the system shell, always return None.
334
334
335 Options:
335 Options:
336
336
337 - verbose (0): print the command to be executed.
337 - verbose (0): print the command to be executed.
338
338
339 - debug (0): only print, do not actually execute.
339 - debug (0): only print, do not actually execute.
340
340
341 - header (''): Header to print on screen prior to the executed command (it
341 - header (''): Header to print on screen prior to the executed command (it
342 is only prepended to the command, no newlines are added).
342 is only prepended to the command, no newlines are added).
343
343
344 Note: this is similar to genutils.system(), but it returns None so it can
344 Note: this is similar to genutils.system(), but it returns None so it can
345 be conveniently used in interactive loops without getting the return value
345 be conveniently used in interactive loops without getting the return value
346 (typically 0) printed many times."""
346 (typically 0) printed many times."""
347
347
348 stat = 0
348 stat = 0
349 if verbose or debug: print header+cmd
349 if verbose or debug: print header+cmd
350 # flush stdout so we don't mangle python's buffering
350 # flush stdout so we don't mangle python's buffering
351 sys.stdout.flush()
351 sys.stdout.flush()
352
352
353 if not debug:
353 if not debug:
354 platutils.set_term_title("IPy " + cmd)
354 platutils.set_term_title("IPy " + cmd)
355 os.system(cmd)
355 os.system(cmd)
356 platutils.set_term_title("IPy " + abbrev_cwd())
356 platutils.set_term_title("IPy " + abbrev_cwd())
357
357
358 # override shell() for win32 to deal with network shares
358 # override shell() for win32 to deal with network shares
359 if os.name in ('nt','dos'):
359 if os.name in ('nt','dos'):
360
360
361 shell_ori = shell
361 shell_ori = shell
362
362
363 def shell(cmd,verbose=0,debug=0,header=''):
363 def shell(cmd,verbose=0,debug=0,header=''):
364 if os.getcwd().startswith(r"\\"):
364 if os.getcwd().startswith(r"\\"):
365 path = os.getcwd()
365 path = os.getcwd()
366 # change to c drive (cannot be on UNC-share when issuing os.system,
366 # change to c drive (cannot be on UNC-share when issuing os.system,
367 # as cmd.exe cannot handle UNC addresses)
367 # as cmd.exe cannot handle UNC addresses)
368 os.chdir("c:")
368 os.chdir("c:")
369 # issue pushd to the UNC-share and then run the command
369 # issue pushd to the UNC-share and then run the command
370 try:
370 try:
371 shell_ori('"pushd %s&&"'%path+cmd,verbose,debug,header)
371 shell_ori('"pushd %s&&"'%path+cmd,verbose,debug,header)
372 finally:
372 finally:
373 os.chdir(path)
373 os.chdir(path)
374 else:
374 else:
375 shell_ori(cmd,verbose,debug,header)
375 shell_ori(cmd,verbose,debug,header)
376
376
377 shell.__doc__ = shell_ori.__doc__
377 shell.__doc__ = shell_ori.__doc__
378
378
379 def getoutput(cmd,verbose=0,debug=0,header='',split=0):
379 def getoutput(cmd,verbose=0,debug=0,header='',split=0):
380 """Dummy substitute for perl's backquotes.
380 """Dummy substitute for perl's backquotes.
381
381
382 Executes a command and returns the output.
382 Executes a command and returns the output.
383
383
384 Accepts the same arguments as system(), plus:
384 Accepts the same arguments as system(), plus:
385
385
386 - split(0): if true, the output is returned as a list split on newlines.
386 - split(0): if true, the output is returned as a list split on newlines.
387
387
388 Note: a stateful version of this function is available through the
388 Note: a stateful version of this function is available through the
389 SystemExec class.
389 SystemExec class.
390
390
391 This is pretty much deprecated and rarely used,
391 This is pretty much deprecated and rarely used,
392 genutils.getoutputerror may be what you need.
392 genutils.getoutputerror may be what you need.
393
393
394 """
394 """
395
395
396 if verbose or debug: print header+cmd
396 if verbose or debug: print header+cmd
397 if not debug:
397 if not debug:
398 output = os.popen(cmd).read()
398 pipe = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE).stdout
399 output = pipe.read()
399 # stipping last \n is here for backwards compat.
400 # stipping last \n is here for backwards compat.
400 if output.endswith('\n'):
401 if output.endswith('\n'):
401 output = output[:-1]
402 output = output[:-1]
402 if split:
403 if split:
403 return output.split('\n')
404 return output.split('\n')
404 else:
405 else:
405 return output
406 return output
406
407
407 def getoutputerror(cmd,verbose=0,debug=0,header='',split=0):
408 def getoutputerror(cmd,verbose=0,debug=0,header='',split=0):
408 """Return (standard output,standard error) of executing cmd in a shell.
409 """Return (standard output,standard error) of executing cmd in a shell.
409
410
410 Accepts the same arguments as system(), plus:
411 Accepts the same arguments as system(), plus:
411
412
412 - split(0): if true, each of stdout/err is returned as a list split on
413 - split(0): if true, each of stdout/err is returned as a list split on
413 newlines.
414 newlines.
414
415
415 Note: a stateful version of this function is available through the
416 Note: a stateful version of this function is available through the
416 SystemExec class."""
417 SystemExec class."""
417
418
418 if verbose or debug: print header+cmd
419 if verbose or debug: print header+cmd
419 if not cmd:
420 if not cmd:
420 if split:
421 if split:
421 return [],[]
422 return [],[]
422 else:
423 else:
423 return '',''
424 return '',''
424 if not debug:
425 if not debug:
425 pin,pout,perr = os.popen3(cmd)
426 p = subprocess.Popen(cmd, shell=True,
427 stdin=subprocess.PIPE,
428 stdout=subprocess.PIPE,
429 stderr=subprocess.PIPE,
430 close_fds=True)
431 pin, pout, perr = (p.stdin, p.stdout, p.stderr)
432
426 tout = pout.read().rstrip()
433 tout = pout.read().rstrip()
427 terr = perr.read().rstrip()
434 terr = perr.read().rstrip()
428 pin.close()
435 pin.close()
429 pout.close()
436 pout.close()
430 perr.close()
437 perr.close()
431 if split:
438 if split:
432 return tout.split('\n'),terr.split('\n')
439 return tout.split('\n'),terr.split('\n')
433 else:
440 else:
434 return tout,terr
441 return tout,terr
435
442
436 # for compatibility with older naming conventions
443 # for compatibility with older naming conventions
437 xsys = system
444 xsys = system
438 bq = getoutput
445 bq = getoutput
439
446
440 class SystemExec:
447 class SystemExec:
441 """Access the system and getoutput functions through a stateful interface.
448 """Access the system and getoutput functions through a stateful interface.
442
449
443 Note: here we refer to the system and getoutput functions from this
450 Note: here we refer to the system and getoutput functions from this
444 library, not the ones from the standard python library.
451 library, not the ones from the standard python library.
445
452
446 This class offers the system and getoutput functions as methods, but the
453 This class offers the system and getoutput functions as methods, but the
447 verbose, debug and header parameters can be set for the instance (at
454 verbose, debug and header parameters can be set for the instance (at
448 creation time or later) so that they don't need to be specified on each
455 creation time or later) so that they don't need to be specified on each
449 call.
456 call.
450
457
451 For efficiency reasons, there's no way to override the parameters on a
458 For efficiency reasons, there's no way to override the parameters on a
452 per-call basis other than by setting instance attributes. If you need
459 per-call basis other than by setting instance attributes. If you need
453 local overrides, it's best to directly call system() or getoutput().
460 local overrides, it's best to directly call system() or getoutput().
454
461
455 The following names are provided as alternate options:
462 The following names are provided as alternate options:
456 - xsys: alias to system
463 - xsys: alias to system
457 - bq: alias to getoutput
464 - bq: alias to getoutput
458
465
459 An instance can then be created as:
466 An instance can then be created as:
460 >>> sysexec = SystemExec(verbose=1,debug=0,header='Calling: ')
467 >>> sysexec = SystemExec(verbose=1,debug=0,header='Calling: ')
461 """
468 """
462
469
463 def __init__(self,verbose=0,debug=0,header='',split=0):
470 def __init__(self,verbose=0,debug=0,header='',split=0):
464 """Specify the instance's values for verbose, debug and header."""
471 """Specify the instance's values for verbose, debug and header."""
465 setattr_list(self,'verbose debug header split')
472 setattr_list(self,'verbose debug header split')
466
473
467 def system(self,cmd):
474 def system(self,cmd):
468 """Stateful interface to system(), with the same keyword parameters."""
475 """Stateful interface to system(), with the same keyword parameters."""
469
476
470 system(cmd,self.verbose,self.debug,self.header)
477 system(cmd,self.verbose,self.debug,self.header)
471
478
472 def shell(self,cmd):
479 def shell(self,cmd):
473 """Stateful interface to shell(), with the same keyword parameters."""
480 """Stateful interface to shell(), with the same keyword parameters."""
474
481
475 shell(cmd,self.verbose,self.debug,self.header)
482 shell(cmd,self.verbose,self.debug,self.header)
476
483
477 xsys = system # alias
484 xsys = system # alias
478
485
479 def getoutput(self,cmd):
486 def getoutput(self,cmd):
480 """Stateful interface to getoutput()."""
487 """Stateful interface to getoutput()."""
481
488
482 return getoutput(cmd,self.verbose,self.debug,self.header,self.split)
489 return getoutput(cmd,self.verbose,self.debug,self.header,self.split)
483
490
484 def getoutputerror(self,cmd):
491 def getoutputerror(self,cmd):
485 """Stateful interface to getoutputerror()."""
492 """Stateful interface to getoutputerror()."""
486
493
487 return getoutputerror(cmd,self.verbose,self.debug,self.header,self.split)
494 return getoutputerror(cmd,self.verbose,self.debug,self.header,self.split)
488
495
489 bq = getoutput # alias
496 bq = getoutput # alias
490
497
491 #-----------------------------------------------------------------------------
498 #-----------------------------------------------------------------------------
492 def mutex_opts(dict,ex_op):
499 def mutex_opts(dict,ex_op):
493 """Check for presence of mutually exclusive keys in a dict.
500 """Check for presence of mutually exclusive keys in a dict.
494
501
495 Call: mutex_opts(dict,[[op1a,op1b],[op2a,op2b]...]"""
502 Call: mutex_opts(dict,[[op1a,op1b],[op2a,op2b]...]"""
496 for op1,op2 in ex_op:
503 for op1,op2 in ex_op:
497 if op1 in dict and op2 in dict:
504 if op1 in dict and op2 in dict:
498 raise ValueError,'\n*** ERROR in Arguments *** '\
505 raise ValueError,'\n*** ERROR in Arguments *** '\
499 'Options '+op1+' and '+op2+' are mutually exclusive.'
506 'Options '+op1+' and '+op2+' are mutually exclusive.'
500
507
501 #-----------------------------------------------------------------------------
508 #-----------------------------------------------------------------------------
502 def get_py_filename(name):
509 def get_py_filename(name):
503 """Return a valid python filename in the current directory.
510 """Return a valid python filename in the current directory.
504
511
505 If the given name is not a file, it adds '.py' and searches again.
512 If the given name is not a file, it adds '.py' and searches again.
506 Raises IOError with an informative message if the file isn't found."""
513 Raises IOError with an informative message if the file isn't found."""
507
514
508 name = os.path.expanduser(name)
515 name = os.path.expanduser(name)
509 if not os.path.isfile(name) and not name.endswith('.py'):
516 if not os.path.isfile(name) and not name.endswith('.py'):
510 name += '.py'
517 name += '.py'
511 if os.path.isfile(name):
518 if os.path.isfile(name):
512 return name
519 return name
513 else:
520 else:
514 raise IOError,'File `%s` not found.' % name
521 raise IOError,'File `%s` not found.' % name
515
522
516 #-----------------------------------------------------------------------------
523 #-----------------------------------------------------------------------------
517
524
518
525
519 def filefind(filename, path_dirs=None):
526 def filefind(filename, path_dirs=None):
520 """Find a file by looking through a sequence of paths.
527 """Find a file by looking through a sequence of paths.
521
528
522 This iterates through a sequence of paths looking for a file and returns
529 This iterates through a sequence of paths looking for a file and returns
523 the full, absolute path of the first occurence of the file. If no set of
530 the full, absolute path of the first occurence of the file. If no set of
524 path dirs is given, the filename is tested as is, after running through
531 path dirs is given, the filename is tested as is, after running through
525 :func:`expandvars` and :func:`expanduser`. Thus a simple call::
532 :func:`expandvars` and :func:`expanduser`. Thus a simple call::
526
533
527 filefind('myfile.txt')
534 filefind('myfile.txt')
528
535
529 will find the file in the current working dir, but::
536 will find the file in the current working dir, but::
530
537
531 filefind('~/myfile.txt')
538 filefind('~/myfile.txt')
532
539
533 Will find the file in the users home directory. This function does not
540 Will find the file in the users home directory. This function does not
534 automatically try any paths, such as the cwd or the user's home directory.
541 automatically try any paths, such as the cwd or the user's home directory.
535
542
536 Parameters
543 Parameters
537 ----------
544 ----------
538 filename : str
545 filename : str
539 The filename to look for.
546 The filename to look for.
540 path_dirs : str, None or sequence of str
547 path_dirs : str, None or sequence of str
541 The sequence of paths to look for the file in. If None, the filename
548 The sequence of paths to look for the file in. If None, the filename
542 need to be absolute or be in the cwd. If a string, the string is
549 need to be absolute or be in the cwd. If a string, the string is
543 put into a sequence and the searched. If a sequence, walk through
550 put into a sequence and the searched. If a sequence, walk through
544 each element and join with ``filename``, calling :func:`expandvars`
551 each element and join with ``filename``, calling :func:`expandvars`
545 and :func:`expanduser` before testing for existence.
552 and :func:`expanduser` before testing for existence.
546
553
547 Returns
554 Returns
548 -------
555 -------
549 Raises :exc:`IOError` or returns absolute path to file.
556 Raises :exc:`IOError` or returns absolute path to file.
550 """
557 """
551 if path_dirs is None:
558 if path_dirs is None:
552 path_dirs = ("",)
559 path_dirs = ("",)
553 elif isinstance(path_dirs, basestring):
560 elif isinstance(path_dirs, basestring):
554 path_dirs = (path_dirs,)
561 path_dirs = (path_dirs,)
555 for path in path_dirs:
562 for path in path_dirs:
556 if path == '.': path = os.getcwd()
563 if path == '.': path = os.getcwd()
557 testname = expand_path(os.path.join(path, filename))
564 testname = expand_path(os.path.join(path, filename))
558 if os.path.isfile(testname):
565 if os.path.isfile(testname):
559 return os.path.abspath(testname)
566 return os.path.abspath(testname)
560 raise IOError("File does not exist in any "
567 raise IOError("File does not exist in any "
561 "of the search paths: %r, %r" % \
568 "of the search paths: %r, %r" % \
562 (filename, path_dirs))
569 (filename, path_dirs))
563
570
564
571
565 #----------------------------------------------------------------------------
572 #----------------------------------------------------------------------------
566 def file_read(filename):
573 def file_read(filename):
567 """Read a file and close it. Returns the file source."""
574 """Read a file and close it. Returns the file source."""
568 fobj = open(filename,'r');
575 fobj = open(filename,'r');
569 source = fobj.read();
576 source = fobj.read();
570 fobj.close()
577 fobj.close()
571 return source
578 return source
572
579
573 def file_readlines(filename):
580 def file_readlines(filename):
574 """Read a file and close it. Returns the file source using readlines()."""
581 """Read a file and close it. Returns the file source using readlines()."""
575 fobj = open(filename,'r');
582 fobj = open(filename,'r');
576 lines = fobj.readlines();
583 lines = fobj.readlines();
577 fobj.close()
584 fobj.close()
578 return lines
585 return lines
579
586
580 #----------------------------------------------------------------------------
587 #----------------------------------------------------------------------------
581 def target_outdated(target,deps):
588 def target_outdated(target,deps):
582 """Determine whether a target is out of date.
589 """Determine whether a target is out of date.
583
590
584 target_outdated(target,deps) -> 1/0
591 target_outdated(target,deps) -> 1/0
585
592
586 deps: list of filenames which MUST exist.
593 deps: list of filenames which MUST exist.
587 target: single filename which may or may not exist.
594 target: single filename which may or may not exist.
588
595
589 If target doesn't exist or is older than any file listed in deps, return
596 If target doesn't exist or is older than any file listed in deps, return
590 true, otherwise return false.
597 true, otherwise return false.
591 """
598 """
592 try:
599 try:
593 target_time = os.path.getmtime(target)
600 target_time = os.path.getmtime(target)
594 except os.error:
601 except os.error:
595 return 1
602 return 1
596 for dep in deps:
603 for dep in deps:
597 dep_time = os.path.getmtime(dep)
604 dep_time = os.path.getmtime(dep)
598 if dep_time > target_time:
605 if dep_time > target_time:
599 #print "For target",target,"Dep failed:",dep # dbg
606 #print "For target",target,"Dep failed:",dep # dbg
600 #print "times (dep,tar):",dep_time,target_time # dbg
607 #print "times (dep,tar):",dep_time,target_time # dbg
601 return 1
608 return 1
602 return 0
609 return 0
603
610
604 #-----------------------------------------------------------------------------
611 #-----------------------------------------------------------------------------
605 def target_update(target,deps,cmd):
612 def target_update(target,deps,cmd):
606 """Update a target with a given command given a list of dependencies.
613 """Update a target with a given command given a list of dependencies.
607
614
608 target_update(target,deps,cmd) -> runs cmd if target is outdated.
615 target_update(target,deps,cmd) -> runs cmd if target is outdated.
609
616
610 This is just a wrapper around target_outdated() which calls the given
617 This is just a wrapper around target_outdated() which calls the given
611 command if target is outdated."""
618 command if target is outdated."""
612
619
613 if target_outdated(target,deps):
620 if target_outdated(target,deps):
614 xsys(cmd)
621 xsys(cmd)
615
622
616 #----------------------------------------------------------------------------
623 #----------------------------------------------------------------------------
617 def unquote_ends(istr):
624 def unquote_ends(istr):
618 """Remove a single pair of quotes from the endpoints of a string."""
625 """Remove a single pair of quotes from the endpoints of a string."""
619
626
620 if not istr:
627 if not istr:
621 return istr
628 return istr
622 if (istr[0]=="'" and istr[-1]=="'") or \
629 if (istr[0]=="'" and istr[-1]=="'") or \
623 (istr[0]=='"' and istr[-1]=='"'):
630 (istr[0]=='"' and istr[-1]=='"'):
624 return istr[1:-1]
631 return istr[1:-1]
625 else:
632 else:
626 return istr
633 return istr
627
634
628 #----------------------------------------------------------------------------
635 #----------------------------------------------------------------------------
629 def flag_calls(func):
636 def flag_calls(func):
630 """Wrap a function to detect and flag when it gets called.
637 """Wrap a function to detect and flag when it gets called.
631
638
632 This is a decorator which takes a function and wraps it in a function with
639 This is a decorator which takes a function and wraps it in a function with
633 a 'called' attribute. wrapper.called is initialized to False.
640 a 'called' attribute. wrapper.called is initialized to False.
634
641
635 The wrapper.called attribute is set to False right before each call to the
642 The wrapper.called attribute is set to False right before each call to the
636 wrapped function, so if the call fails it remains False. After the call
643 wrapped function, so if the call fails it remains False. After the call
637 completes, wrapper.called is set to True and the output is returned.
644 completes, wrapper.called is set to True and the output is returned.
638
645
639 Testing for truth in wrapper.called allows you to determine if a call to
646 Testing for truth in wrapper.called allows you to determine if a call to
640 func() was attempted and succeeded."""
647 func() was attempted and succeeded."""
641
648
642 def wrapper(*args,**kw):
649 def wrapper(*args,**kw):
643 wrapper.called = False
650 wrapper.called = False
644 out = func(*args,**kw)
651 out = func(*args,**kw)
645 wrapper.called = True
652 wrapper.called = True
646 return out
653 return out
647
654
648 wrapper.called = False
655 wrapper.called = False
649 wrapper.__doc__ = func.__doc__
656 wrapper.__doc__ = func.__doc__
650 return wrapper
657 return wrapper
651
658
652 #----------------------------------------------------------------------------
659 #----------------------------------------------------------------------------
653 def dhook_wrap(func,*a,**k):
660 def dhook_wrap(func,*a,**k):
654 """Wrap a function call in a sys.displayhook controller.
661 """Wrap a function call in a sys.displayhook controller.
655
662
656 Returns a wrapper around func which calls func, with all its arguments and
663 Returns a wrapper around func which calls func, with all its arguments and
657 keywords unmodified, using the default sys.displayhook. Since IPython
664 keywords unmodified, using the default sys.displayhook. Since IPython
658 modifies sys.displayhook, it breaks the behavior of certain systems that
665 modifies sys.displayhook, it breaks the behavior of certain systems that
659 rely on the default behavior, notably doctest.
666 rely on the default behavior, notably doctest.
660 """
667 """
661
668
662 def f(*a,**k):
669 def f(*a,**k):
663
670
664 dhook_s = sys.displayhook
671 dhook_s = sys.displayhook
665 sys.displayhook = sys.__displayhook__
672 sys.displayhook = sys.__displayhook__
666 try:
673 try:
667 out = func(*a,**k)
674 out = func(*a,**k)
668 finally:
675 finally:
669 sys.displayhook = dhook_s
676 sys.displayhook = dhook_s
670
677
671 return out
678 return out
672
679
673 f.__doc__ = func.__doc__
680 f.__doc__ = func.__doc__
674 return f
681 return f
675
682
676 #----------------------------------------------------------------------------
683 #----------------------------------------------------------------------------
677 def doctest_reload():
684 def doctest_reload():
678 """Properly reload doctest to reuse it interactively.
685 """Properly reload doctest to reuse it interactively.
679
686
680 This routine:
687 This routine:
681
688
682 - imports doctest but does NOT reload it (see below).
689 - imports doctest but does NOT reload it (see below).
683
690
684 - resets its global 'master' attribute to None, so that multiple uses of
691 - resets its global 'master' attribute to None, so that multiple uses of
685 the module interactively don't produce cumulative reports.
692 the module interactively don't produce cumulative reports.
686
693
687 - Monkeypatches its core test runner method to protect it from IPython's
694 - Monkeypatches its core test runner method to protect it from IPython's
688 modified displayhook. Doctest expects the default displayhook behavior
695 modified displayhook. Doctest expects the default displayhook behavior
689 deep down, so our modification breaks it completely. For this reason, a
696 deep down, so our modification breaks it completely. For this reason, a
690 hard monkeypatch seems like a reasonable solution rather than asking
697 hard monkeypatch seems like a reasonable solution rather than asking
691 users to manually use a different doctest runner when under IPython.
698 users to manually use a different doctest runner when under IPython.
692
699
693 Notes
700 Notes
694 -----
701 -----
695
702
696 This function *used to* reload doctest, but this has been disabled because
703 This function *used to* reload doctest, but this has been disabled because
697 reloading doctest unconditionally can cause massive breakage of other
704 reloading doctest unconditionally can cause massive breakage of other
698 doctest-dependent modules already in memory, such as those for IPython's
705 doctest-dependent modules already in memory, such as those for IPython's
699 own testing system. The name wasn't changed to avoid breaking people's
706 own testing system. The name wasn't changed to avoid breaking people's
700 code, but the reload call isn't actually made anymore."""
707 code, but the reload call isn't actually made anymore."""
701
708
702 import doctest
709 import doctest
703 doctest.master = None
710 doctest.master = None
704 doctest.DocTestRunner.run = dhook_wrap(doctest.DocTestRunner.run)
711 doctest.DocTestRunner.run = dhook_wrap(doctest.DocTestRunner.run)
705
712
706 #----------------------------------------------------------------------------
713 #----------------------------------------------------------------------------
707 class HomeDirError(Error):
714 class HomeDirError(Error):
708 pass
715 pass
709
716
710 def get_home_dir():
717 def get_home_dir():
711 """Return the closest possible equivalent to a 'home' directory.
718 """Return the closest possible equivalent to a 'home' directory.
712
719
713 * On POSIX, we try $HOME.
720 * On POSIX, we try $HOME.
714 * On Windows we try:
721 * On Windows we try:
715 - %HOMESHARE%
722 - %HOMESHARE%
716 - %HOMEDRIVE\%HOMEPATH%
723 - %HOMEDRIVE\%HOMEPATH%
717 - %USERPROFILE%
724 - %USERPROFILE%
718 - Registry hack
725 - Registry hack
719 * On Dos C:\
726 * On Dos C:\
720
727
721 Currently only Posix and NT are implemented, a HomeDirError exception is
728 Currently only Posix and NT are implemented, a HomeDirError exception is
722 raised for all other OSes.
729 raised for all other OSes.
723 """
730 """
724
731
725 isdir = os.path.isdir
732 isdir = os.path.isdir
726 env = os.environ
733 env = os.environ
727
734
728 # first, check py2exe distribution root directory for _ipython.
735 # first, check py2exe distribution root directory for _ipython.
729 # This overrides all. Normally does not exist.
736 # This overrides all. Normally does not exist.
730
737
731 if hasattr(sys, "frozen"): #Is frozen by py2exe
738 if hasattr(sys, "frozen"): #Is frozen by py2exe
732 if '\\library.zip\\' in IPython.__file__.lower():#libraries compressed to zip-file
739 if '\\library.zip\\' in IPython.__file__.lower():#libraries compressed to zip-file
733 root, rest = IPython.__file__.lower().split('library.zip')
740 root, rest = IPython.__file__.lower().split('library.zip')
734 else:
741 else:
735 root=os.path.join(os.path.split(IPython.__file__)[0],"../../")
742 root=os.path.join(os.path.split(IPython.__file__)[0],"../../")
736 root=os.path.abspath(root).rstrip('\\')
743 root=os.path.abspath(root).rstrip('\\')
737 if isdir(os.path.join(root, '_ipython')):
744 if isdir(os.path.join(root, '_ipython')):
738 os.environ["IPYKITROOT"] = root
745 os.environ["IPYKITROOT"] = root
739 return root.decode(sys.getfilesystemencoding())
746 return root.decode(sys.getfilesystemencoding())
740
747
741 if os.name == 'posix':
748 if os.name == 'posix':
742 # Linux, Unix, AIX, OS X
749 # Linux, Unix, AIX, OS X
743 try:
750 try:
744 homedir = env['HOME']
751 homedir = env['HOME']
745 except KeyError:
752 except KeyError:
746 raise HomeDirError('Undefined $HOME, IPython cannot proceed.')
753 raise HomeDirError('Undefined $HOME, IPython cannot proceed.')
747 else:
754 else:
748 return homedir.decode(sys.getfilesystemencoding())
755 return homedir.decode(sys.getfilesystemencoding())
749 elif os.name == 'nt':
756 elif os.name == 'nt':
750 # Now for win9x, XP, Vista, 7?
757 # Now for win9x, XP, Vista, 7?
751 # For some strange reason all of these return 'nt' for os.name.
758 # For some strange reason all of these return 'nt' for os.name.
752 # First look for a network home directory. This will return the UNC
759 # First look for a network home directory. This will return the UNC
753 # path (\\server\\Users\%username%) not the mapped path (Z:\). This
760 # path (\\server\\Users\%username%) not the mapped path (Z:\). This
754 # is needed when running IPython on cluster where all paths have to
761 # is needed when running IPython on cluster where all paths have to
755 # be UNC.
762 # be UNC.
756 try:
763 try:
757 homedir = env['HOMESHARE']
764 homedir = env['HOMESHARE']
758 except KeyError:
765 except KeyError:
759 pass
766 pass
760 else:
767 else:
761 if isdir(homedir):
768 if isdir(homedir):
762 return homedir.decode(sys.getfilesystemencoding())
769 return homedir.decode(sys.getfilesystemencoding())
763
770
764 # Now look for a local home directory
771 # Now look for a local home directory
765 try:
772 try:
766 homedir = os.path.join(env['HOMEDRIVE'],env['HOMEPATH'])
773 homedir = os.path.join(env['HOMEDRIVE'],env['HOMEPATH'])
767 except KeyError:
774 except KeyError:
768 pass
775 pass
769 else:
776 else:
770 if isdir(homedir):
777 if isdir(homedir):
771 return homedir.decode(sys.getfilesystemencoding())
778 return homedir.decode(sys.getfilesystemencoding())
772
779
773 # Now the users profile directory
780 # Now the users profile directory
774 try:
781 try:
775 homedir = os.path.join(env['USERPROFILE'])
782 homedir = os.path.join(env['USERPROFILE'])
776 except KeyError:
783 except KeyError:
777 pass
784 pass
778 else:
785 else:
779 if isdir(homedir):
786 if isdir(homedir):
780 return homedir.decode(sys.getfilesystemencoding())
787 return homedir.decode(sys.getfilesystemencoding())
781
788
782 # Use the registry to get the 'My Documents' folder.
789 # Use the registry to get the 'My Documents' folder.
783 try:
790 try:
784 import _winreg as wreg
791 import _winreg as wreg
785 key = wreg.OpenKey(
792 key = wreg.OpenKey(
786 wreg.HKEY_CURRENT_USER,
793 wreg.HKEY_CURRENT_USER,
787 "Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders"
794 "Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders"
788 )
795 )
789 homedir = wreg.QueryValueEx(key,'Personal')[0]
796 homedir = wreg.QueryValueEx(key,'Personal')[0]
790 key.Close()
797 key.Close()
791 except:
798 except:
792 pass
799 pass
793 else:
800 else:
794 if isdir(homedir):
801 if isdir(homedir):
795 return homedir.decode(sys.getfilesystemencoding())
802 return homedir.decode(sys.getfilesystemencoding())
796
803
797 # If all else fails, raise HomeDirError
804 # If all else fails, raise HomeDirError
798 raise HomeDirError('No valid home directory could be found')
805 raise HomeDirError('No valid home directory could be found')
799 elif os.name == 'dos':
806 elif os.name == 'dos':
800 # Desperate, may do absurd things in classic MacOS. May work under DOS.
807 # Desperate, may do absurd things in classic MacOS. May work under DOS.
801 return 'C:\\'.decode(sys.getfilesystemencoding())
808 return 'C:\\'.decode(sys.getfilesystemencoding())
802 else:
809 else:
803 raise HomeDirError('No valid home directory could be found for your OS')
810 raise HomeDirError('No valid home directory could be found for your OS')
804
811
805
812
806 def get_ipython_dir():
813 def get_ipython_dir():
807 """Get the IPython directory for this platform and user.
814 """Get the IPython directory for this platform and user.
808
815
809 This uses the logic in `get_home_dir` to find the home directory
816 This uses the logic in `get_home_dir` to find the home directory
810 and the adds .ipython to the end of the path.
817 and the adds .ipython to the end of the path.
811 """
818 """
812 ipdir_def = '.ipython'
819 ipdir_def = '.ipython'
813 home_dir = get_home_dir()
820 home_dir = get_home_dir()
814 ipdir = os.environ.get(
821 ipdir = os.environ.get(
815 'IPYTHON_DIR', os.environ.get(
822 'IPYTHON_DIR', os.environ.get(
816 'IPYTHONDIR', os.path.join(home_dir, ipdir_def)
823 'IPYTHONDIR', os.path.join(home_dir, ipdir_def)
817 )
824 )
818 )
825 )
819 return ipdir.decode(sys.getfilesystemencoding())
826 return ipdir.decode(sys.getfilesystemencoding())
820
827
821
828
822 def get_ipython_package_dir():
829 def get_ipython_package_dir():
823 """Get the base directory where IPython itself is installed."""
830 """Get the base directory where IPython itself is installed."""
824 ipdir = os.path.dirname(IPython.__file__)
831 ipdir = os.path.dirname(IPython.__file__)
825 return ipdir.decode(sys.getfilesystemencoding())
832 return ipdir.decode(sys.getfilesystemencoding())
826
833
827
834
828 #****************************************************************************
835 #****************************************************************************
829 # strings and text
836 # strings and text
830
837
831 class LSString(str):
838 class LSString(str):
832 """String derivative with a special access attributes.
839 """String derivative with a special access attributes.
833
840
834 These are normal strings, but with the special attributes:
841 These are normal strings, but with the special attributes:
835
842
836 .l (or .list) : value as list (split on newlines).
843 .l (or .list) : value as list (split on newlines).
837 .n (or .nlstr): original value (the string itself).
844 .n (or .nlstr): original value (the string itself).
838 .s (or .spstr): value as whitespace-separated string.
845 .s (or .spstr): value as whitespace-separated string.
839 .p (or .paths): list of path objects
846 .p (or .paths): list of path objects
840
847
841 Any values which require transformations are computed only once and
848 Any values which require transformations are computed only once and
842 cached.
849 cached.
843
850
844 Such strings are very useful to efficiently interact with the shell, which
851 Such strings are very useful to efficiently interact with the shell, which
845 typically only understands whitespace-separated options for commands."""
852 typically only understands whitespace-separated options for commands."""
846
853
847 def get_list(self):
854 def get_list(self):
848 try:
855 try:
849 return self.__list
856 return self.__list
850 except AttributeError:
857 except AttributeError:
851 self.__list = self.split('\n')
858 self.__list = self.split('\n')
852 return self.__list
859 return self.__list
853
860
854 l = list = property(get_list)
861 l = list = property(get_list)
855
862
856 def get_spstr(self):
863 def get_spstr(self):
857 try:
864 try:
858 return self.__spstr
865 return self.__spstr
859 except AttributeError:
866 except AttributeError:
860 self.__spstr = self.replace('\n',' ')
867 self.__spstr = self.replace('\n',' ')
861 return self.__spstr
868 return self.__spstr
862
869
863 s = spstr = property(get_spstr)
870 s = spstr = property(get_spstr)
864
871
865 def get_nlstr(self):
872 def get_nlstr(self):
866 return self
873 return self
867
874
868 n = nlstr = property(get_nlstr)
875 n = nlstr = property(get_nlstr)
869
876
870 def get_paths(self):
877 def get_paths(self):
871 try:
878 try:
872 return self.__paths
879 return self.__paths
873 except AttributeError:
880 except AttributeError:
874 self.__paths = [path(p) for p in self.split('\n') if os.path.exists(p)]
881 self.__paths = [path(p) for p in self.split('\n') if os.path.exists(p)]
875 return self.__paths
882 return self.__paths
876
883
877 p = paths = property(get_paths)
884 p = paths = property(get_paths)
878
885
879 def print_lsstring(arg):
886 def print_lsstring(arg):
880 """ Prettier (non-repr-like) and more informative printer for LSString """
887 """ Prettier (non-repr-like) and more informative printer for LSString """
881 print "LSString (.p, .n, .l, .s available). Value:"
888 print "LSString (.p, .n, .l, .s available). Value:"
882 print arg
889 print arg
883
890
884 print_lsstring = result_display.when_type(LSString)(print_lsstring)
891 print_lsstring = result_display.when_type(LSString)(print_lsstring)
885
892
886 #----------------------------------------------------------------------------
893 #----------------------------------------------------------------------------
887 class SList(list):
894 class SList(list):
888 """List derivative with a special access attributes.
895 """List derivative with a special access attributes.
889
896
890 These are normal lists, but with the special attributes:
897 These are normal lists, but with the special attributes:
891
898
892 .l (or .list) : value as list (the list itself).
899 .l (or .list) : value as list (the list itself).
893 .n (or .nlstr): value as a string, joined on newlines.
900 .n (or .nlstr): value as a string, joined on newlines.
894 .s (or .spstr): value as a string, joined on spaces.
901 .s (or .spstr): value as a string, joined on spaces.
895 .p (or .paths): list of path objects
902 .p (or .paths): list of path objects
896
903
897 Any values which require transformations are computed only once and
904 Any values which require transformations are computed only once and
898 cached."""
905 cached."""
899
906
900 def get_list(self):
907 def get_list(self):
901 return self
908 return self
902
909
903 l = list = property(get_list)
910 l = list = property(get_list)
904
911
905 def get_spstr(self):
912 def get_spstr(self):
906 try:
913 try:
907 return self.__spstr
914 return self.__spstr
908 except AttributeError:
915 except AttributeError:
909 self.__spstr = ' '.join(self)
916 self.__spstr = ' '.join(self)
910 return self.__spstr
917 return self.__spstr
911
918
912 s = spstr = property(get_spstr)
919 s = spstr = property(get_spstr)
913
920
914 def get_nlstr(self):
921 def get_nlstr(self):
915 try:
922 try:
916 return self.__nlstr
923 return self.__nlstr
917 except AttributeError:
924 except AttributeError:
918 self.__nlstr = '\n'.join(self)
925 self.__nlstr = '\n'.join(self)
919 return self.__nlstr
926 return self.__nlstr
920
927
921 n = nlstr = property(get_nlstr)
928 n = nlstr = property(get_nlstr)
922
929
923 def get_paths(self):
930 def get_paths(self):
924 try:
931 try:
925 return self.__paths
932 return self.__paths
926 except AttributeError:
933 except AttributeError:
927 self.__paths = [path(p) for p in self if os.path.exists(p)]
934 self.__paths = [path(p) for p in self if os.path.exists(p)]
928 return self.__paths
935 return self.__paths
929
936
930 p = paths = property(get_paths)
937 p = paths = property(get_paths)
931
938
932 def grep(self, pattern, prune = False, field = None):
939 def grep(self, pattern, prune = False, field = None):
933 """ Return all strings matching 'pattern' (a regex or callable)
940 """ Return all strings matching 'pattern' (a regex or callable)
934
941
935 This is case-insensitive. If prune is true, return all items
942 This is case-insensitive. If prune is true, return all items
936 NOT matching the pattern.
943 NOT matching the pattern.
937
944
938 If field is specified, the match must occur in the specified
945 If field is specified, the match must occur in the specified
939 whitespace-separated field.
946 whitespace-separated field.
940
947
941 Examples::
948 Examples::
942
949
943 a.grep( lambda x: x.startswith('C') )
950 a.grep( lambda x: x.startswith('C') )
944 a.grep('Cha.*log', prune=1)
951 a.grep('Cha.*log', prune=1)
945 a.grep('chm', field=-1)
952 a.grep('chm', field=-1)
946 """
953 """
947
954
948 def match_target(s):
955 def match_target(s):
949 if field is None:
956 if field is None:
950 return s
957 return s
951 parts = s.split()
958 parts = s.split()
952 try:
959 try:
953 tgt = parts[field]
960 tgt = parts[field]
954 return tgt
961 return tgt
955 except IndexError:
962 except IndexError:
956 return ""
963 return ""
957
964
958 if isinstance(pattern, basestring):
965 if isinstance(pattern, basestring):
959 pred = lambda x : re.search(pattern, x, re.IGNORECASE)
966 pred = lambda x : re.search(pattern, x, re.IGNORECASE)
960 else:
967 else:
961 pred = pattern
968 pred = pattern
962 if not prune:
969 if not prune:
963 return SList([el for el in self if pred(match_target(el))])
970 return SList([el for el in self if pred(match_target(el))])
964 else:
971 else:
965 return SList([el for el in self if not pred(match_target(el))])
972 return SList([el for el in self if not pred(match_target(el))])
966 def fields(self, *fields):
973 def fields(self, *fields):
967 """ Collect whitespace-separated fields from string list
974 """ Collect whitespace-separated fields from string list
968
975
969 Allows quick awk-like usage of string lists.
976 Allows quick awk-like usage of string lists.
970
977
971 Example data (in var a, created by 'a = !ls -l')::
978 Example data (in var a, created by 'a = !ls -l')::
972 -rwxrwxrwx 1 ville None 18 Dec 14 2006 ChangeLog
979 -rwxrwxrwx 1 ville None 18 Dec 14 2006 ChangeLog
973 drwxrwxrwx+ 6 ville None 0 Oct 24 18:05 IPython
980 drwxrwxrwx+ 6 ville None 0 Oct 24 18:05 IPython
974
981
975 a.fields(0) is ['-rwxrwxrwx', 'drwxrwxrwx+']
982 a.fields(0) is ['-rwxrwxrwx', 'drwxrwxrwx+']
976 a.fields(1,0) is ['1 -rwxrwxrwx', '6 drwxrwxrwx+']
983 a.fields(1,0) is ['1 -rwxrwxrwx', '6 drwxrwxrwx+']
977 (note the joining by space).
984 (note the joining by space).
978 a.fields(-1) is ['ChangeLog', 'IPython']
985 a.fields(-1) is ['ChangeLog', 'IPython']
979
986
980 IndexErrors are ignored.
987 IndexErrors are ignored.
981
988
982 Without args, fields() just split()'s the strings.
989 Without args, fields() just split()'s the strings.
983 """
990 """
984 if len(fields) == 0:
991 if len(fields) == 0:
985 return [el.split() for el in self]
992 return [el.split() for el in self]
986
993
987 res = SList()
994 res = SList()
988 for el in [f.split() for f in self]:
995 for el in [f.split() for f in self]:
989 lineparts = []
996 lineparts = []
990
997
991 for fd in fields:
998 for fd in fields:
992 try:
999 try:
993 lineparts.append(el[fd])
1000 lineparts.append(el[fd])
994 except IndexError:
1001 except IndexError:
995 pass
1002 pass
996 if lineparts:
1003 if lineparts:
997 res.append(" ".join(lineparts))
1004 res.append(" ".join(lineparts))
998
1005
999 return res
1006 return res
1000 def sort(self,field= None, nums = False):
1007 def sort(self,field= None, nums = False):
1001 """ sort by specified fields (see fields())
1008 """ sort by specified fields (see fields())
1002
1009
1003 Example::
1010 Example::
1004 a.sort(1, nums = True)
1011 a.sort(1, nums = True)
1005
1012
1006 Sorts a by second field, in numerical order (so that 21 > 3)
1013 Sorts a by second field, in numerical order (so that 21 > 3)
1007
1014
1008 """
1015 """
1009
1016
1010 #decorate, sort, undecorate
1017 #decorate, sort, undecorate
1011 if field is not None:
1018 if field is not None:
1012 dsu = [[SList([line]).fields(field), line] for line in self]
1019 dsu = [[SList([line]).fields(field), line] for line in self]
1013 else:
1020 else:
1014 dsu = [[line, line] for line in self]
1021 dsu = [[line, line] for line in self]
1015 if nums:
1022 if nums:
1016 for i in range(len(dsu)):
1023 for i in range(len(dsu)):
1017 numstr = "".join([ch for ch in dsu[i][0] if ch.isdigit()])
1024 numstr = "".join([ch for ch in dsu[i][0] if ch.isdigit()])
1018 try:
1025 try:
1019 n = int(numstr)
1026 n = int(numstr)
1020 except ValueError:
1027 except ValueError:
1021 n = 0;
1028 n = 0;
1022 dsu[i][0] = n
1029 dsu[i][0] = n
1023
1030
1024
1031
1025 dsu.sort()
1032 dsu.sort()
1026 return SList([t[1] for t in dsu])
1033 return SList([t[1] for t in dsu])
1027
1034
1028 def print_slist(arg):
1035 def print_slist(arg):
1029 """ Prettier (non-repr-like) and more informative printer for SList """
1036 """ Prettier (non-repr-like) and more informative printer for SList """
1030 print "SList (.p, .n, .l, .s, .grep(), .fields(), sort() available):"
1037 print "SList (.p, .n, .l, .s, .grep(), .fields(), sort() available):"
1031 if hasattr(arg, 'hideonce') and arg.hideonce:
1038 if hasattr(arg, 'hideonce') and arg.hideonce:
1032 arg.hideonce = False
1039 arg.hideonce = False
1033 return
1040 return
1034
1041
1035 nlprint(arg)
1042 nlprint(arg)
1036
1043
1037 print_slist = result_display.when_type(SList)(print_slist)
1044 print_slist = result_display.when_type(SList)(print_slist)
1038
1045
1039
1046
1040
1047
1041 #----------------------------------------------------------------------------
1048 #----------------------------------------------------------------------------
1042 def esc_quotes(strng):
1049 def esc_quotes(strng):
1043 """Return the input string with single and double quotes escaped out"""
1050 """Return the input string with single and double quotes escaped out"""
1044
1051
1045 return strng.replace('"','\\"').replace("'","\\'")
1052 return strng.replace('"','\\"').replace("'","\\'")
1046
1053
1047 #----------------------------------------------------------------------------
1054 #----------------------------------------------------------------------------
1048 def make_quoted_expr(s):
1055 def make_quoted_expr(s):
1049 """Return string s in appropriate quotes, using raw string if possible.
1056 """Return string s in appropriate quotes, using raw string if possible.
1050
1057
1051 XXX - example removed because it caused encoding errors in documentation
1058 XXX - example removed because it caused encoding errors in documentation
1052 generation. We need a new example that doesn't contain invalid chars.
1059 generation. We need a new example that doesn't contain invalid chars.
1053
1060
1054 Note the use of raw string and padding at the end to allow trailing
1061 Note the use of raw string and padding at the end to allow trailing
1055 backslash.
1062 backslash.
1056 """
1063 """
1057
1064
1058 tail = ''
1065 tail = ''
1059 tailpadding = ''
1066 tailpadding = ''
1060 raw = ''
1067 raw = ''
1061 if "\\" in s:
1068 if "\\" in s:
1062 raw = 'r'
1069 raw = 'r'
1063 if s.endswith('\\'):
1070 if s.endswith('\\'):
1064 tail = '[:-1]'
1071 tail = '[:-1]'
1065 tailpadding = '_'
1072 tailpadding = '_'
1066 if '"' not in s:
1073 if '"' not in s:
1067 quote = '"'
1074 quote = '"'
1068 elif "'" not in s:
1075 elif "'" not in s:
1069 quote = "'"
1076 quote = "'"
1070 elif '"""' not in s and not s.endswith('"'):
1077 elif '"""' not in s and not s.endswith('"'):
1071 quote = '"""'
1078 quote = '"""'
1072 elif "'''" not in s and not s.endswith("'"):
1079 elif "'''" not in s and not s.endswith("'"):
1073 quote = "'''"
1080 quote = "'''"
1074 else:
1081 else:
1075 # give up, backslash-escaped string will do
1082 # give up, backslash-escaped string will do
1076 return '"%s"' % esc_quotes(s)
1083 return '"%s"' % esc_quotes(s)
1077 res = raw + quote + s + tailpadding + quote + tail
1084 res = raw + quote + s + tailpadding + quote + tail
1078 return res
1085 return res
1079
1086
1080
1087
1081 #----------------------------------------------------------------------------
1088 #----------------------------------------------------------------------------
1082 def raw_input_multi(header='', ps1='==> ', ps2='..> ',terminate_str = '.'):
1089 def raw_input_multi(header='', ps1='==> ', ps2='..> ',terminate_str = '.'):
1083 """Take multiple lines of input.
1090 """Take multiple lines of input.
1084
1091
1085 A list with each line of input as a separate element is returned when a
1092 A list with each line of input as a separate element is returned when a
1086 termination string is entered (defaults to a single '.'). Input can also
1093 termination string is entered (defaults to a single '.'). Input can also
1087 terminate via EOF (^D in Unix, ^Z-RET in Windows).
1094 terminate via EOF (^D in Unix, ^Z-RET in Windows).
1088
1095
1089 Lines of input which end in \\ are joined into single entries (and a
1096 Lines of input which end in \\ are joined into single entries (and a
1090 secondary continuation prompt is issued as long as the user terminates
1097 secondary continuation prompt is issued as long as the user terminates
1091 lines with \\). This allows entering very long strings which are still
1098 lines with \\). This allows entering very long strings which are still
1092 meant to be treated as single entities.
1099 meant to be treated as single entities.
1093 """
1100 """
1094
1101
1095 try:
1102 try:
1096 if header:
1103 if header:
1097 header += '\n'
1104 header += '\n'
1098 lines = [raw_input(header + ps1)]
1105 lines = [raw_input(header + ps1)]
1099 except EOFError:
1106 except EOFError:
1100 return []
1107 return []
1101 terminate = [terminate_str]
1108 terminate = [terminate_str]
1102 try:
1109 try:
1103 while lines[-1:] != terminate:
1110 while lines[-1:] != terminate:
1104 new_line = raw_input(ps1)
1111 new_line = raw_input(ps1)
1105 while new_line.endswith('\\'):
1112 while new_line.endswith('\\'):
1106 new_line = new_line[:-1] + raw_input(ps2)
1113 new_line = new_line[:-1] + raw_input(ps2)
1107 lines.append(new_line)
1114 lines.append(new_line)
1108
1115
1109 return lines[:-1] # don't return the termination command
1116 return lines[:-1] # don't return the termination command
1110 except EOFError:
1117 except EOFError:
1111 print
1118 print
1112 return lines
1119 return lines
1113
1120
1114 #----------------------------------------------------------------------------
1121 #----------------------------------------------------------------------------
1115 def raw_input_ext(prompt='', ps2='... '):
1122 def raw_input_ext(prompt='', ps2='... '):
1116 """Similar to raw_input(), but accepts extended lines if input ends with \\."""
1123 """Similar to raw_input(), but accepts extended lines if input ends with \\."""
1117
1124
1118 line = raw_input(prompt)
1125 line = raw_input(prompt)
1119 while line.endswith('\\'):
1126 while line.endswith('\\'):
1120 line = line[:-1] + raw_input(ps2)
1127 line = line[:-1] + raw_input(ps2)
1121 return line
1128 return line
1122
1129
1123 #----------------------------------------------------------------------------
1130 #----------------------------------------------------------------------------
1124 def ask_yes_no(prompt,default=None):
1131 def ask_yes_no(prompt,default=None):
1125 """Asks a question and returns a boolean (y/n) answer.
1132 """Asks a question and returns a boolean (y/n) answer.
1126
1133
1127 If default is given (one of 'y','n'), it is used if the user input is
1134 If default is given (one of 'y','n'), it is used if the user input is
1128 empty. Otherwise the question is repeated until an answer is given.
1135 empty. Otherwise the question is repeated until an answer is given.
1129
1136
1130 An EOF is treated as the default answer. If there is no default, an
1137 An EOF is treated as the default answer. If there is no default, an
1131 exception is raised to prevent infinite loops.
1138 exception is raised to prevent infinite loops.
1132
1139
1133 Valid answers are: y/yes/n/no (match is not case sensitive)."""
1140 Valid answers are: y/yes/n/no (match is not case sensitive)."""
1134
1141
1135 answers = {'y':True,'n':False,'yes':True,'no':False}
1142 answers = {'y':True,'n':False,'yes':True,'no':False}
1136 ans = None
1143 ans = None
1137 while ans not in answers.keys():
1144 while ans not in answers.keys():
1138 try:
1145 try:
1139 ans = raw_input(prompt+' ').lower()
1146 ans = raw_input(prompt+' ').lower()
1140 if not ans: # response was an empty string
1147 if not ans: # response was an empty string
1141 ans = default
1148 ans = default
1142 except KeyboardInterrupt:
1149 except KeyboardInterrupt:
1143 pass
1150 pass
1144 except EOFError:
1151 except EOFError:
1145 if default in answers.keys():
1152 if default in answers.keys():
1146 ans = default
1153 ans = default
1147 print
1154 print
1148 else:
1155 else:
1149 raise
1156 raise
1150
1157
1151 return answers[ans]
1158 return answers[ans]
1152
1159
1153 #----------------------------------------------------------------------------
1160 #----------------------------------------------------------------------------
1154 class EvalDict:
1161 class EvalDict:
1155 """
1162 """
1156 Emulate a dict which evaluates its contents in the caller's frame.
1163 Emulate a dict which evaluates its contents in the caller's frame.
1157
1164
1158 Usage:
1165 Usage:
1159 >>> number = 19
1166 >>> number = 19
1160
1167
1161 >>> text = "python"
1168 >>> text = "python"
1162
1169
1163 >>> print "%(text.capitalize())s %(number/9.0).1f rules!" % EvalDict()
1170 >>> print "%(text.capitalize())s %(number/9.0).1f rules!" % EvalDict()
1164 Python 2.1 rules!
1171 Python 2.1 rules!
1165 """
1172 """
1166
1173
1167 # This version is due to sismex01@hebmex.com on c.l.py, and is basically a
1174 # This version is due to sismex01@hebmex.com on c.l.py, and is basically a
1168 # modified (shorter) version of:
1175 # modified (shorter) version of:
1169 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66018 by
1176 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66018 by
1170 # Skip Montanaro (skip@pobox.com).
1177 # Skip Montanaro (skip@pobox.com).
1171
1178
1172 def __getitem__(self, name):
1179 def __getitem__(self, name):
1173 frame = sys._getframe(1)
1180 frame = sys._getframe(1)
1174 return eval(name, frame.f_globals, frame.f_locals)
1181 return eval(name, frame.f_globals, frame.f_locals)
1175
1182
1176 EvalString = EvalDict # for backwards compatibility
1183 EvalString = EvalDict # for backwards compatibility
1177 #----------------------------------------------------------------------------
1184 #----------------------------------------------------------------------------
1178 def qw(words,flat=0,sep=None,maxsplit=-1):
1185 def qw(words,flat=0,sep=None,maxsplit=-1):
1179 """Similar to Perl's qw() operator, but with some more options.
1186 """Similar to Perl's qw() operator, but with some more options.
1180
1187
1181 qw(words,flat=0,sep=' ',maxsplit=-1) -> words.split(sep,maxsplit)
1188 qw(words,flat=0,sep=' ',maxsplit=-1) -> words.split(sep,maxsplit)
1182
1189
1183 words can also be a list itself, and with flat=1, the output will be
1190 words can also be a list itself, and with flat=1, the output will be
1184 recursively flattened.
1191 recursively flattened.
1185
1192
1186 Examples:
1193 Examples:
1187
1194
1188 >>> qw('1 2')
1195 >>> qw('1 2')
1189 ['1', '2']
1196 ['1', '2']
1190
1197
1191 >>> qw(['a b','1 2',['m n','p q']])
1198 >>> qw(['a b','1 2',['m n','p q']])
1192 [['a', 'b'], ['1', '2'], [['m', 'n'], ['p', 'q']]]
1199 [['a', 'b'], ['1', '2'], [['m', 'n'], ['p', 'q']]]
1193
1200
1194 >>> qw(['a b','1 2',['m n','p q']],flat=1)
1201 >>> qw(['a b','1 2',['m n','p q']],flat=1)
1195 ['a', 'b', '1', '2', 'm', 'n', 'p', 'q']
1202 ['a', 'b', '1', '2', 'm', 'n', 'p', 'q']
1196 """
1203 """
1197
1204
1198 if type(words) in StringTypes:
1205 if type(words) in StringTypes:
1199 return [word.strip() for word in words.split(sep,maxsplit)
1206 return [word.strip() for word in words.split(sep,maxsplit)
1200 if word and not word.isspace() ]
1207 if word and not word.isspace() ]
1201 if flat:
1208 if flat:
1202 return flatten(map(qw,words,[1]*len(words)))
1209 return flatten(map(qw,words,[1]*len(words)))
1203 return map(qw,words)
1210 return map(qw,words)
1204
1211
1205 #----------------------------------------------------------------------------
1212 #----------------------------------------------------------------------------
1206 def qwflat(words,sep=None,maxsplit=-1):
1213 def qwflat(words,sep=None,maxsplit=-1):
1207 """Calls qw(words) in flat mode. It's just a convenient shorthand."""
1214 """Calls qw(words) in flat mode. It's just a convenient shorthand."""
1208 return qw(words,1,sep,maxsplit)
1215 return qw(words,1,sep,maxsplit)
1209
1216
1210 #----------------------------------------------------------------------------
1217 #----------------------------------------------------------------------------
1211 def qw_lol(indata):
1218 def qw_lol(indata):
1212 """qw_lol('a b') -> [['a','b']],
1219 """qw_lol('a b') -> [['a','b']],
1213 otherwise it's just a call to qw().
1220 otherwise it's just a call to qw().
1214
1221
1215 We need this to make sure the modules_some keys *always* end up as a
1222 We need this to make sure the modules_some keys *always* end up as a
1216 list of lists."""
1223 list of lists."""
1217
1224
1218 if type(indata) in StringTypes:
1225 if type(indata) in StringTypes:
1219 return [qw(indata)]
1226 return [qw(indata)]
1220 else:
1227 else:
1221 return qw(indata)
1228 return qw(indata)
1222
1229
1223 #----------------------------------------------------------------------------
1230 #----------------------------------------------------------------------------
1224 def grep(pat,list,case=1):
1231 def grep(pat,list,case=1):
1225 """Simple minded grep-like function.
1232 """Simple minded grep-like function.
1226 grep(pat,list) returns occurrences of pat in list, None on failure.
1233 grep(pat,list) returns occurrences of pat in list, None on failure.
1227
1234
1228 It only does simple string matching, with no support for regexps. Use the
1235 It only does simple string matching, with no support for regexps. Use the
1229 option case=0 for case-insensitive matching."""
1236 option case=0 for case-insensitive matching."""
1230
1237
1231 # This is pretty crude. At least it should implement copying only references
1238 # This is pretty crude. At least it should implement copying only references
1232 # to the original data in case it's big. Now it copies the data for output.
1239 # to the original data in case it's big. Now it copies the data for output.
1233 out=[]
1240 out=[]
1234 if case:
1241 if case:
1235 for term in list:
1242 for term in list:
1236 if term.find(pat)>-1: out.append(term)
1243 if term.find(pat)>-1: out.append(term)
1237 else:
1244 else:
1238 lpat=pat.lower()
1245 lpat=pat.lower()
1239 for term in list:
1246 for term in list:
1240 if term.lower().find(lpat)>-1: out.append(term)
1247 if term.lower().find(lpat)>-1: out.append(term)
1241
1248
1242 if len(out): return out
1249 if len(out): return out
1243 else: return None
1250 else: return None
1244
1251
1245 #----------------------------------------------------------------------------
1252 #----------------------------------------------------------------------------
1246 def dgrep(pat,*opts):
1253 def dgrep(pat,*opts):
1247 """Return grep() on dir()+dir(__builtins__).
1254 """Return grep() on dir()+dir(__builtins__).
1248
1255
1249 A very common use of grep() when working interactively."""
1256 A very common use of grep() when working interactively."""
1250
1257
1251 return grep(pat,dir(__main__)+dir(__main__.__builtins__),*opts)
1258 return grep(pat,dir(__main__)+dir(__main__.__builtins__),*opts)
1252
1259
1253 #----------------------------------------------------------------------------
1260 #----------------------------------------------------------------------------
1254 def idgrep(pat):
1261 def idgrep(pat):
1255 """Case-insensitive dgrep()"""
1262 """Case-insensitive dgrep()"""
1256
1263
1257 return dgrep(pat,0)
1264 return dgrep(pat,0)
1258
1265
1259 #----------------------------------------------------------------------------
1266 #----------------------------------------------------------------------------
1260 def igrep(pat,list):
1267 def igrep(pat,list):
1261 """Synonym for case-insensitive grep."""
1268 """Synonym for case-insensitive grep."""
1262
1269
1263 return grep(pat,list,case=0)
1270 return grep(pat,list,case=0)
1264
1271
1265 #----------------------------------------------------------------------------
1272 #----------------------------------------------------------------------------
1266 def indent(str,nspaces=4,ntabs=0):
1273 def indent(str,nspaces=4,ntabs=0):
1267 """Indent a string a given number of spaces or tabstops.
1274 """Indent a string a given number of spaces or tabstops.
1268
1275
1269 indent(str,nspaces=4,ntabs=0) -> indent str by ntabs+nspaces.
1276 indent(str,nspaces=4,ntabs=0) -> indent str by ntabs+nspaces.
1270 """
1277 """
1271 if str is None:
1278 if str is None:
1272 return
1279 return
1273 ind = '\t'*ntabs+' '*nspaces
1280 ind = '\t'*ntabs+' '*nspaces
1274 outstr = '%s%s' % (ind,str.replace(os.linesep,os.linesep+ind))
1281 outstr = '%s%s' % (ind,str.replace(os.linesep,os.linesep+ind))
1275 if outstr.endswith(os.linesep+ind):
1282 if outstr.endswith(os.linesep+ind):
1276 return outstr[:-len(ind)]
1283 return outstr[:-len(ind)]
1277 else:
1284 else:
1278 return outstr
1285 return outstr
1279
1286
1280 #-----------------------------------------------------------------------------
1287 #-----------------------------------------------------------------------------
1281 def native_line_ends(filename,backup=1):
1288 def native_line_ends(filename,backup=1):
1282 """Convert (in-place) a file to line-ends native to the current OS.
1289 """Convert (in-place) a file to line-ends native to the current OS.
1283
1290
1284 If the optional backup argument is given as false, no backup of the
1291 If the optional backup argument is given as false, no backup of the
1285 original file is left. """
1292 original file is left. """
1286
1293
1287 backup_suffixes = {'posix':'~','dos':'.bak','nt':'.bak','mac':'.bak'}
1294 backup_suffixes = {'posix':'~','dos':'.bak','nt':'.bak','mac':'.bak'}
1288
1295
1289 bak_filename = filename + backup_suffixes[os.name]
1296 bak_filename = filename + backup_suffixes[os.name]
1290
1297
1291 original = open(filename).read()
1298 original = open(filename).read()
1292 shutil.copy2(filename,bak_filename)
1299 shutil.copy2(filename,bak_filename)
1293 try:
1300 try:
1294 new = open(filename,'wb')
1301 new = open(filename,'wb')
1295 new.write(os.linesep.join(original.splitlines()))
1302 new.write(os.linesep.join(original.splitlines()))
1296 new.write(os.linesep) # ALWAYS put an eol at the end of the file
1303 new.write(os.linesep) # ALWAYS put an eol at the end of the file
1297 new.close()
1304 new.close()
1298 except:
1305 except:
1299 os.rename(bak_filename,filename)
1306 os.rename(bak_filename,filename)
1300 if not backup:
1307 if not backup:
1301 try:
1308 try:
1302 os.remove(bak_filename)
1309 os.remove(bak_filename)
1303 except:
1310 except:
1304 pass
1311 pass
1305
1312
1306 #****************************************************************************
1313 #****************************************************************************
1307 # lists, dicts and structures
1314 # lists, dicts and structures
1308
1315
1309 def belong(candidates,checklist):
1316 def belong(candidates,checklist):
1310 """Check whether a list of items appear in a given list of options.
1317 """Check whether a list of items appear in a given list of options.
1311
1318
1312 Returns a list of 1 and 0, one for each candidate given."""
1319 Returns a list of 1 and 0, one for each candidate given."""
1313
1320
1314 return [x in checklist for x in candidates]
1321 return [x in checklist for x in candidates]
1315
1322
1316 #----------------------------------------------------------------------------
1323 #----------------------------------------------------------------------------
1317 def uniq_stable(elems):
1324 def uniq_stable(elems):
1318 """uniq_stable(elems) -> list
1325 """uniq_stable(elems) -> list
1319
1326
1320 Return from an iterable, a list of all the unique elements in the input,
1327 Return from an iterable, a list of all the unique elements in the input,
1321 but maintaining the order in which they first appear.
1328 but maintaining the order in which they first appear.
1322
1329
1323 A naive solution to this problem which just makes a dictionary with the
1330 A naive solution to this problem which just makes a dictionary with the
1324 elements as keys fails to respect the stability condition, since
1331 elements as keys fails to respect the stability condition, since
1325 dictionaries are unsorted by nature.
1332 dictionaries are unsorted by nature.
1326
1333
1327 Note: All elements in the input must be valid dictionary keys for this
1334 Note: All elements in the input must be valid dictionary keys for this
1328 routine to work, as it internally uses a dictionary for efficiency
1335 routine to work, as it internally uses a dictionary for efficiency
1329 reasons."""
1336 reasons."""
1330
1337
1331 unique = []
1338 unique = []
1332 unique_dict = {}
1339 unique_dict = {}
1333 for nn in elems:
1340 for nn in elems:
1334 if nn not in unique_dict:
1341 if nn not in unique_dict:
1335 unique.append(nn)
1342 unique.append(nn)
1336 unique_dict[nn] = None
1343 unique_dict[nn] = None
1337 return unique
1344 return unique
1338
1345
1339 #----------------------------------------------------------------------------
1346 #----------------------------------------------------------------------------
1340 class NLprinter:
1347 class NLprinter:
1341 """Print an arbitrarily nested list, indicating index numbers.
1348 """Print an arbitrarily nested list, indicating index numbers.
1342
1349
1343 An instance of this class called nlprint is available and callable as a
1350 An instance of this class called nlprint is available and callable as a
1344 function.
1351 function.
1345
1352
1346 nlprint(list,indent=' ',sep=': ') -> prints indenting each level by 'indent'
1353 nlprint(list,indent=' ',sep=': ') -> prints indenting each level by 'indent'
1347 and using 'sep' to separate the index from the value. """
1354 and using 'sep' to separate the index from the value. """
1348
1355
1349 def __init__(self):
1356 def __init__(self):
1350 self.depth = 0
1357 self.depth = 0
1351
1358
1352 def __call__(self,lst,pos='',**kw):
1359 def __call__(self,lst,pos='',**kw):
1353 """Prints the nested list numbering levels."""
1360 """Prints the nested list numbering levels."""
1354 kw.setdefault('indent',' ')
1361 kw.setdefault('indent',' ')
1355 kw.setdefault('sep',': ')
1362 kw.setdefault('sep',': ')
1356 kw.setdefault('start',0)
1363 kw.setdefault('start',0)
1357 kw.setdefault('stop',len(lst))
1364 kw.setdefault('stop',len(lst))
1358 # we need to remove start and stop from kw so they don't propagate
1365 # we need to remove start and stop from kw so they don't propagate
1359 # into a recursive call for a nested list.
1366 # into a recursive call for a nested list.
1360 start = kw['start']; del kw['start']
1367 start = kw['start']; del kw['start']
1361 stop = kw['stop']; del kw['stop']
1368 stop = kw['stop']; del kw['stop']
1362 if self.depth == 0 and 'header' in kw.keys():
1369 if self.depth == 0 and 'header' in kw.keys():
1363 print kw['header']
1370 print kw['header']
1364
1371
1365 for idx in range(start,stop):
1372 for idx in range(start,stop):
1366 elem = lst[idx]
1373 elem = lst[idx]
1367 if type(elem)==type([]):
1374 if type(elem)==type([]):
1368 self.depth += 1
1375 self.depth += 1
1369 self.__call__(elem,itpl('$pos$idx,'),**kw)
1376 self.__call__(elem,itpl('$pos$idx,'),**kw)
1370 self.depth -= 1
1377 self.depth -= 1
1371 else:
1378 else:
1372 printpl(kw['indent']*self.depth+'$pos$idx$kw["sep"]$elem')
1379 printpl(kw['indent']*self.depth+'$pos$idx$kw["sep"]$elem')
1373
1380
1374 nlprint = NLprinter()
1381 nlprint = NLprinter()
1375 #----------------------------------------------------------------------------
1382 #----------------------------------------------------------------------------
1376 def all_belong(candidates,checklist):
1383 def all_belong(candidates,checklist):
1377 """Check whether a list of items ALL appear in a given list of options.
1384 """Check whether a list of items ALL appear in a given list of options.
1378
1385
1379 Returns a single 1 or 0 value."""
1386 Returns a single 1 or 0 value."""
1380
1387
1381 return 1-(0 in [x in checklist for x in candidates])
1388 return 1-(0 in [x in checklist for x in candidates])
1382
1389
1383 #----------------------------------------------------------------------------
1390 #----------------------------------------------------------------------------
1384 def sort_compare(lst1,lst2,inplace = 1):
1391 def sort_compare(lst1,lst2,inplace = 1):
1385 """Sort and compare two lists.
1392 """Sort and compare two lists.
1386
1393
1387 By default it does it in place, thus modifying the lists. Use inplace = 0
1394 By default it does it in place, thus modifying the lists. Use inplace = 0
1388 to avoid that (at the cost of temporary copy creation)."""
1395 to avoid that (at the cost of temporary copy creation)."""
1389 if not inplace:
1396 if not inplace:
1390 lst1 = lst1[:]
1397 lst1 = lst1[:]
1391 lst2 = lst2[:]
1398 lst2 = lst2[:]
1392 lst1.sort(); lst2.sort()
1399 lst1.sort(); lst2.sort()
1393 return lst1 == lst2
1400 return lst1 == lst2
1394
1401
1395 #----------------------------------------------------------------------------
1402 #----------------------------------------------------------------------------
1396 def list2dict(lst):
1403 def list2dict(lst):
1397 """Takes a list of (key,value) pairs and turns it into a dict."""
1404 """Takes a list of (key,value) pairs and turns it into a dict."""
1398
1405
1399 dic = {}
1406 dic = {}
1400 for k,v in lst: dic[k] = v
1407 for k,v in lst: dic[k] = v
1401 return dic
1408 return dic
1402
1409
1403 #----------------------------------------------------------------------------
1410 #----------------------------------------------------------------------------
1404 def list2dict2(lst,default=''):
1411 def list2dict2(lst,default=''):
1405 """Takes a list and turns it into a dict.
1412 """Takes a list and turns it into a dict.
1406 Much slower than list2dict, but more versatile. This version can take
1413 Much slower than list2dict, but more versatile. This version can take
1407 lists with sublists of arbitrary length (including sclars)."""
1414 lists with sublists of arbitrary length (including sclars)."""
1408
1415
1409 dic = {}
1416 dic = {}
1410 for elem in lst:
1417 for elem in lst:
1411 if type(elem) in (types.ListType,types.TupleType):
1418 if type(elem) in (types.ListType,types.TupleType):
1412 size = len(elem)
1419 size = len(elem)
1413 if size == 0:
1420 if size == 0:
1414 pass
1421 pass
1415 elif size == 1:
1422 elif size == 1:
1416 dic[elem] = default
1423 dic[elem] = default
1417 else:
1424 else:
1418 k,v = elem[0], elem[1:]
1425 k,v = elem[0], elem[1:]
1419 if len(v) == 1: v = v[0]
1426 if len(v) == 1: v = v[0]
1420 dic[k] = v
1427 dic[k] = v
1421 else:
1428 else:
1422 dic[elem] = default
1429 dic[elem] = default
1423 return dic
1430 return dic
1424
1431
1425 #----------------------------------------------------------------------------
1432 #----------------------------------------------------------------------------
1426 def flatten(seq):
1433 def flatten(seq):
1427 """Flatten a list of lists (NOT recursive, only works for 2d lists)."""
1434 """Flatten a list of lists (NOT recursive, only works for 2d lists)."""
1428
1435
1429 return [x for subseq in seq for x in subseq]
1436 return [x for subseq in seq for x in subseq]
1430
1437
1431 #----------------------------------------------------------------------------
1438 #----------------------------------------------------------------------------
1432 def get_slice(seq,start=0,stop=None,step=1):
1439 def get_slice(seq,start=0,stop=None,step=1):
1433 """Get a slice of a sequence with variable step. Specify start,stop,step."""
1440 """Get a slice of a sequence with variable step. Specify start,stop,step."""
1434 if stop == None:
1441 if stop == None:
1435 stop = len(seq)
1442 stop = len(seq)
1436 item = lambda i: seq[i]
1443 item = lambda i: seq[i]
1437 return map(item,xrange(start,stop,step))
1444 return map(item,xrange(start,stop,step))
1438
1445
1439 #----------------------------------------------------------------------------
1446 #----------------------------------------------------------------------------
1440 def chop(seq,size):
1447 def chop(seq,size):
1441 """Chop a sequence into chunks of the given size."""
1448 """Chop a sequence into chunks of the given size."""
1442 chunk = lambda i: seq[i:i+size]
1449 chunk = lambda i: seq[i:i+size]
1443 return map(chunk,xrange(0,len(seq),size))
1450 return map(chunk,xrange(0,len(seq),size))
1444
1451
1445 #----------------------------------------------------------------------------
1452 #----------------------------------------------------------------------------
1446 # with is a keyword as of python 2.5, so this function is renamed to withobj
1453 # with is a keyword as of python 2.5, so this function is renamed to withobj
1447 # from its old 'with' name.
1454 # from its old 'with' name.
1448 def with_obj(object, **args):
1455 def with_obj(object, **args):
1449 """Set multiple attributes for an object, similar to Pascal's with.
1456 """Set multiple attributes for an object, similar to Pascal's with.
1450
1457
1451 Example:
1458 Example:
1452 with_obj(jim,
1459 with_obj(jim,
1453 born = 1960,
1460 born = 1960,
1454 haircolour = 'Brown',
1461 haircolour = 'Brown',
1455 eyecolour = 'Green')
1462 eyecolour = 'Green')
1456
1463
1457 Credit: Greg Ewing, in
1464 Credit: Greg Ewing, in
1458 http://mail.python.org/pipermail/python-list/2001-May/040703.html.
1465 http://mail.python.org/pipermail/python-list/2001-May/040703.html.
1459
1466
1460 NOTE: up until IPython 0.7.2, this was called simply 'with', but 'with'
1467 NOTE: up until IPython 0.7.2, this was called simply 'with', but 'with'
1461 has become a keyword for Python 2.5, so we had to rename it."""
1468 has become a keyword for Python 2.5, so we had to rename it."""
1462
1469
1463 object.__dict__.update(args)
1470 object.__dict__.update(args)
1464
1471
1465 #----------------------------------------------------------------------------
1472 #----------------------------------------------------------------------------
1466 def setattr_list(obj,alist,nspace = None):
1473 def setattr_list(obj,alist,nspace = None):
1467 """Set a list of attributes for an object taken from a namespace.
1474 """Set a list of attributes for an object taken from a namespace.
1468
1475
1469 setattr_list(obj,alist,nspace) -> sets in obj all the attributes listed in
1476 setattr_list(obj,alist,nspace) -> sets in obj all the attributes listed in
1470 alist with their values taken from nspace, which must be a dict (something
1477 alist with their values taken from nspace, which must be a dict (something
1471 like locals() will often do) If nspace isn't given, locals() of the
1478 like locals() will often do) If nspace isn't given, locals() of the
1472 *caller* is used, so in most cases you can omit it.
1479 *caller* is used, so in most cases you can omit it.
1473
1480
1474 Note that alist can be given as a string, which will be automatically
1481 Note that alist can be given as a string, which will be automatically
1475 split into a list on whitespace. If given as a list, it must be a list of
1482 split into a list on whitespace. If given as a list, it must be a list of
1476 *strings* (the variable names themselves), not of variables."""
1483 *strings* (the variable names themselves), not of variables."""
1477
1484
1478 # this grabs the local variables from the *previous* call frame -- that is
1485 # this grabs the local variables from the *previous* call frame -- that is
1479 # the locals from the function that called setattr_list().
1486 # the locals from the function that called setattr_list().
1480 # - snipped from weave.inline()
1487 # - snipped from weave.inline()
1481 if nspace is None:
1488 if nspace is None:
1482 call_frame = sys._getframe().f_back
1489 call_frame = sys._getframe().f_back
1483 nspace = call_frame.f_locals
1490 nspace = call_frame.f_locals
1484
1491
1485 if type(alist) in StringTypes:
1492 if type(alist) in StringTypes:
1486 alist = alist.split()
1493 alist = alist.split()
1487 for attr in alist:
1494 for attr in alist:
1488 val = eval(attr,nspace)
1495 val = eval(attr,nspace)
1489 setattr(obj,attr,val)
1496 setattr(obj,attr,val)
1490
1497
1491 #----------------------------------------------------------------------------
1498 #----------------------------------------------------------------------------
1492 def getattr_list(obj,alist,*args):
1499 def getattr_list(obj,alist,*args):
1493 """getattr_list(obj,alist[, default]) -> attribute list.
1500 """getattr_list(obj,alist[, default]) -> attribute list.
1494
1501
1495 Get a list of named attributes for an object. When a default argument is
1502 Get a list of named attributes for an object. When a default argument is
1496 given, it is returned when the attribute doesn't exist; without it, an
1503 given, it is returned when the attribute doesn't exist; without it, an
1497 exception is raised in that case.
1504 exception is raised in that case.
1498
1505
1499 Note that alist can be given as a string, which will be automatically
1506 Note that alist can be given as a string, which will be automatically
1500 split into a list on whitespace. If given as a list, it must be a list of
1507 split into a list on whitespace. If given as a list, it must be a list of
1501 *strings* (the variable names themselves), not of variables."""
1508 *strings* (the variable names themselves), not of variables."""
1502
1509
1503 if type(alist) in StringTypes:
1510 if type(alist) in StringTypes:
1504 alist = alist.split()
1511 alist = alist.split()
1505 if args:
1512 if args:
1506 if len(args)==1:
1513 if len(args)==1:
1507 default = args[0]
1514 default = args[0]
1508 return map(lambda attr: getattr(obj,attr,default),alist)
1515 return map(lambda attr: getattr(obj,attr,default),alist)
1509 else:
1516 else:
1510 raise ValueError,'getattr_list() takes only one optional argument'
1517 raise ValueError,'getattr_list() takes only one optional argument'
1511 else:
1518 else:
1512 return map(lambda attr: getattr(obj,attr),alist)
1519 return map(lambda attr: getattr(obj,attr),alist)
1513
1520
1514 #----------------------------------------------------------------------------
1521 #----------------------------------------------------------------------------
1515 def map_method(method,object_list,*argseq,**kw):
1522 def map_method(method,object_list,*argseq,**kw):
1516 """map_method(method,object_list,*args,**kw) -> list
1523 """map_method(method,object_list,*args,**kw) -> list
1517
1524
1518 Return a list of the results of applying the methods to the items of the
1525 Return a list of the results of applying the methods to the items of the
1519 argument sequence(s). If more than one sequence is given, the method is
1526 argument sequence(s). If more than one sequence is given, the method is
1520 called with an argument list consisting of the corresponding item of each
1527 called with an argument list consisting of the corresponding item of each
1521 sequence. All sequences must be of the same length.
1528 sequence. All sequences must be of the same length.
1522
1529
1523 Keyword arguments are passed verbatim to all objects called.
1530 Keyword arguments are passed verbatim to all objects called.
1524
1531
1525 This is Python code, so it's not nearly as fast as the builtin map()."""
1532 This is Python code, so it's not nearly as fast as the builtin map()."""
1526
1533
1527 out_list = []
1534 out_list = []
1528 idx = 0
1535 idx = 0
1529 for object in object_list:
1536 for object in object_list:
1530 try:
1537 try:
1531 handler = getattr(object, method)
1538 handler = getattr(object, method)
1532 except AttributeError:
1539 except AttributeError:
1533 out_list.append(None)
1540 out_list.append(None)
1534 else:
1541 else:
1535 if argseq:
1542 if argseq:
1536 args = map(lambda lst:lst[idx],argseq)
1543 args = map(lambda lst:lst[idx],argseq)
1537 #print 'ob',object,'hand',handler,'ar',args # dbg
1544 #print 'ob',object,'hand',handler,'ar',args # dbg
1538 out_list.append(handler(args,**kw))
1545 out_list.append(handler(args,**kw))
1539 else:
1546 else:
1540 out_list.append(handler(**kw))
1547 out_list.append(handler(**kw))
1541 idx += 1
1548 idx += 1
1542 return out_list
1549 return out_list
1543
1550
1544 #----------------------------------------------------------------------------
1551 #----------------------------------------------------------------------------
1545 def get_class_members(cls):
1552 def get_class_members(cls):
1546 ret = dir(cls)
1553 ret = dir(cls)
1547 if hasattr(cls,'__bases__'):
1554 if hasattr(cls,'__bases__'):
1548 for base in cls.__bases__:
1555 for base in cls.__bases__:
1549 ret.extend(get_class_members(base))
1556 ret.extend(get_class_members(base))
1550 return ret
1557 return ret
1551
1558
1552 #----------------------------------------------------------------------------
1559 #----------------------------------------------------------------------------
1553 def dir2(obj):
1560 def dir2(obj):
1554 """dir2(obj) -> list of strings
1561 """dir2(obj) -> list of strings
1555
1562
1556 Extended version of the Python builtin dir(), which does a few extra
1563 Extended version of the Python builtin dir(), which does a few extra
1557 checks, and supports common objects with unusual internals that confuse
1564 checks, and supports common objects with unusual internals that confuse
1558 dir(), such as Traits and PyCrust.
1565 dir(), such as Traits and PyCrust.
1559
1566
1560 This version is guaranteed to return only a list of true strings, whereas
1567 This version is guaranteed to return only a list of true strings, whereas
1561 dir() returns anything that objects inject into themselves, even if they
1568 dir() returns anything that objects inject into themselves, even if they
1562 are later not really valid for attribute access (many extension libraries
1569 are later not really valid for attribute access (many extension libraries
1563 have such bugs).
1570 have such bugs).
1564 """
1571 """
1565
1572
1566 # Start building the attribute list via dir(), and then complete it
1573 # Start building the attribute list via dir(), and then complete it
1567 # with a few extra special-purpose calls.
1574 # with a few extra special-purpose calls.
1568 words = dir(obj)
1575 words = dir(obj)
1569
1576
1570 if hasattr(obj,'__class__'):
1577 if hasattr(obj,'__class__'):
1571 words.append('__class__')
1578 words.append('__class__')
1572 words.extend(get_class_members(obj.__class__))
1579 words.extend(get_class_members(obj.__class__))
1573 #if '__base__' in words: 1/0
1580 #if '__base__' in words: 1/0
1574
1581
1575 # Some libraries (such as traits) may introduce duplicates, we want to
1582 # Some libraries (such as traits) may introduce duplicates, we want to
1576 # track and clean this up if it happens
1583 # track and clean this up if it happens
1577 may_have_dupes = False
1584 may_have_dupes = False
1578
1585
1579 # this is the 'dir' function for objects with Enthought's traits
1586 # this is the 'dir' function for objects with Enthought's traits
1580 if hasattr(obj, 'trait_names'):
1587 if hasattr(obj, 'trait_names'):
1581 try:
1588 try:
1582 words.extend(obj.trait_names())
1589 words.extend(obj.trait_names())
1583 may_have_dupes = True
1590 may_have_dupes = True
1584 except TypeError:
1591 except TypeError:
1585 # This will happen if `obj` is a class and not an instance.
1592 # This will happen if `obj` is a class and not an instance.
1586 pass
1593 pass
1587
1594
1588 # Support for PyCrust-style _getAttributeNames magic method.
1595 # Support for PyCrust-style _getAttributeNames magic method.
1589 if hasattr(obj, '_getAttributeNames'):
1596 if hasattr(obj, '_getAttributeNames'):
1590 try:
1597 try:
1591 words.extend(obj._getAttributeNames())
1598 words.extend(obj._getAttributeNames())
1592 may_have_dupes = True
1599 may_have_dupes = True
1593 except TypeError:
1600 except TypeError:
1594 # `obj` is a class and not an instance. Ignore
1601 # `obj` is a class and not an instance. Ignore
1595 # this error.
1602 # this error.
1596 pass
1603 pass
1597
1604
1598 if may_have_dupes:
1605 if may_have_dupes:
1599 # eliminate possible duplicates, as some traits may also
1606 # eliminate possible duplicates, as some traits may also
1600 # appear as normal attributes in the dir() call.
1607 # appear as normal attributes in the dir() call.
1601 words = list(set(words))
1608 words = list(set(words))
1602 words.sort()
1609 words.sort()
1603
1610
1604 # filter out non-string attributes which may be stuffed by dir() calls
1611 # filter out non-string attributes which may be stuffed by dir() calls
1605 # and poor coding in third-party modules
1612 # and poor coding in third-party modules
1606 return [w for w in words if isinstance(w, basestring)]
1613 return [w for w in words if isinstance(w, basestring)]
1607
1614
1608 #----------------------------------------------------------------------------
1615 #----------------------------------------------------------------------------
1609 def import_fail_info(mod_name,fns=None):
1616 def import_fail_info(mod_name,fns=None):
1610 """Inform load failure for a module."""
1617 """Inform load failure for a module."""
1611
1618
1612 if fns == None:
1619 if fns == None:
1613 warn("Loading of %s failed.\n" % (mod_name,))
1620 warn("Loading of %s failed.\n" % (mod_name,))
1614 else:
1621 else:
1615 warn("Loading of %s from %s failed.\n" % (fns,mod_name))
1622 warn("Loading of %s from %s failed.\n" % (fns,mod_name))
1616
1623
1617 #----------------------------------------------------------------------------
1624 #----------------------------------------------------------------------------
1618 # Proposed popitem() extension, written as a method
1625 # Proposed popitem() extension, written as a method
1619
1626
1620
1627
1621 class NotGiven: pass
1628 class NotGiven: pass
1622
1629
1623 def popkey(dct,key,default=NotGiven):
1630 def popkey(dct,key,default=NotGiven):
1624 """Return dct[key] and delete dct[key].
1631 """Return dct[key] and delete dct[key].
1625
1632
1626 If default is given, return it if dct[key] doesn't exist, otherwise raise
1633 If default is given, return it if dct[key] doesn't exist, otherwise raise
1627 KeyError. """
1634 KeyError. """
1628
1635
1629 try:
1636 try:
1630 val = dct[key]
1637 val = dct[key]
1631 except KeyError:
1638 except KeyError:
1632 if default is NotGiven:
1639 if default is NotGiven:
1633 raise
1640 raise
1634 else:
1641 else:
1635 return default
1642 return default
1636 else:
1643 else:
1637 del dct[key]
1644 del dct[key]
1638 return val
1645 return val
1639
1646
1640 def wrap_deprecated(func, suggest = '<nothing>'):
1647 def wrap_deprecated(func, suggest = '<nothing>'):
1641 def newFunc(*args, **kwargs):
1648 def newFunc(*args, **kwargs):
1642 warnings.warn("Call to deprecated function %s, use %s instead" %
1649 warnings.warn("Call to deprecated function %s, use %s instead" %
1643 ( func.__name__, suggest),
1650 ( func.__name__, suggest),
1644 category=DeprecationWarning,
1651 category=DeprecationWarning,
1645 stacklevel = 2)
1652 stacklevel = 2)
1646 return func(*args, **kwargs)
1653 return func(*args, **kwargs)
1647 return newFunc
1654 return newFunc
1648
1655
1649
1656
1650 def _num_cpus_unix():
1657 def _num_cpus_unix():
1651 """Return the number of active CPUs on a Unix system."""
1658 """Return the number of active CPUs on a Unix system."""
1652 return os.sysconf("SC_NPROCESSORS_ONLN")
1659 return os.sysconf("SC_NPROCESSORS_ONLN")
1653
1660
1654
1661
1655 def _num_cpus_darwin():
1662 def _num_cpus_darwin():
1656 """Return the number of active CPUs on a Darwin system."""
1663 """Return the number of active CPUs on a Darwin system."""
1657 p = subprocess.Popen(['sysctl','-n','hw.ncpu'],stdout=subprocess.PIPE)
1664 p = subprocess.Popen(['sysctl','-n','hw.ncpu'],stdout=subprocess.PIPE)
1658 return p.stdout.read()
1665 return p.stdout.read()
1659
1666
1660
1667
1661 def _num_cpus_windows():
1668 def _num_cpus_windows():
1662 """Return the number of active CPUs on a Windows system."""
1669 """Return the number of active CPUs on a Windows system."""
1663 return os.environ.get("NUMBER_OF_PROCESSORS")
1670 return os.environ.get("NUMBER_OF_PROCESSORS")
1664
1671
1665
1672
1666 def num_cpus():
1673 def num_cpus():
1667 """Return the effective number of CPUs in the system as an integer.
1674 """Return the effective number of CPUs in the system as an integer.
1668
1675
1669 This cross-platform function makes an attempt at finding the total number of
1676 This cross-platform function makes an attempt at finding the total number of
1670 available CPUs in the system, as returned by various underlying system and
1677 available CPUs in the system, as returned by various underlying system and
1671 python calls.
1678 python calls.
1672
1679
1673 If it can't find a sensible answer, it returns 1 (though an error *may* make
1680 If it can't find a sensible answer, it returns 1 (though an error *may* make
1674 it return a large positive number that's actually incorrect).
1681 it return a large positive number that's actually incorrect).
1675 """
1682 """
1676
1683
1677 # Many thanks to the Parallel Python project (http://www.parallelpython.com)
1684 # Many thanks to the Parallel Python project (http://www.parallelpython.com)
1678 # for the names of the keys we needed to look up for this function. This
1685 # for the names of the keys we needed to look up for this function. This
1679 # code was inspired by their equivalent function.
1686 # code was inspired by their equivalent function.
1680
1687
1681 ncpufuncs = {'Linux':_num_cpus_unix,
1688 ncpufuncs = {'Linux':_num_cpus_unix,
1682 'Darwin':_num_cpus_darwin,
1689 'Darwin':_num_cpus_darwin,
1683 'Windows':_num_cpus_windows,
1690 'Windows':_num_cpus_windows,
1684 # On Vista, python < 2.5.2 has a bug and returns 'Microsoft'
1691 # On Vista, python < 2.5.2 has a bug and returns 'Microsoft'
1685 # See http://bugs.python.org/issue1082 for details.
1692 # See http://bugs.python.org/issue1082 for details.
1686 'Microsoft':_num_cpus_windows,
1693 'Microsoft':_num_cpus_windows,
1687 }
1694 }
1688
1695
1689 ncpufunc = ncpufuncs.get(platform.system(),
1696 ncpufunc = ncpufuncs.get(platform.system(),
1690 # default to unix version (Solaris, AIX, etc)
1697 # default to unix version (Solaris, AIX, etc)
1691 _num_cpus_unix)
1698 _num_cpus_unix)
1692
1699
1693 try:
1700 try:
1694 ncpus = max(1,int(ncpufunc()))
1701 ncpus = max(1,int(ncpufunc()))
1695 except:
1702 except:
1696 ncpus = 1
1703 ncpus = 1
1697 return ncpus
1704 return ncpus
1698
1705
1699 def extract_vars(*names,**kw):
1706 def extract_vars(*names,**kw):
1700 """Extract a set of variables by name from another frame.
1707 """Extract a set of variables by name from another frame.
1701
1708
1702 :Parameters:
1709 :Parameters:
1703 - `*names`: strings
1710 - `*names`: strings
1704 One or more variable names which will be extracted from the caller's
1711 One or more variable names which will be extracted from the caller's
1705 frame.
1712 frame.
1706
1713
1707 :Keywords:
1714 :Keywords:
1708 - `depth`: integer (0)
1715 - `depth`: integer (0)
1709 How many frames in the stack to walk when looking for your variables.
1716 How many frames in the stack to walk when looking for your variables.
1710
1717
1711
1718
1712 Examples:
1719 Examples:
1713
1720
1714 In [2]: def func(x):
1721 In [2]: def func(x):
1715 ...: y = 1
1722 ...: y = 1
1716 ...: print extract_vars('x','y')
1723 ...: print extract_vars('x','y')
1717 ...:
1724 ...:
1718
1725
1719 In [3]: func('hello')
1726 In [3]: func('hello')
1720 {'y': 1, 'x': 'hello'}
1727 {'y': 1, 'x': 'hello'}
1721 """
1728 """
1722
1729
1723 depth = kw.get('depth',0)
1730 depth = kw.get('depth',0)
1724
1731
1725 callerNS = sys._getframe(depth+1).f_locals
1732 callerNS = sys._getframe(depth+1).f_locals
1726 return dict((k,callerNS[k]) for k in names)
1733 return dict((k,callerNS[k]) for k in names)
1727
1734
1728
1735
1729 def extract_vars_above(*names):
1736 def extract_vars_above(*names):
1730 """Extract a set of variables by name from another frame.
1737 """Extract a set of variables by name from another frame.
1731
1738
1732 Similar to extractVars(), but with a specified depth of 1, so that names
1739 Similar to extractVars(), but with a specified depth of 1, so that names
1733 are exctracted exactly from above the caller.
1740 are exctracted exactly from above the caller.
1734
1741
1735 This is simply a convenience function so that the very common case (for us)
1742 This is simply a convenience function so that the very common case (for us)
1736 of skipping exactly 1 frame doesn't have to construct a special dict for
1743 of skipping exactly 1 frame doesn't have to construct a special dict for
1737 keyword passing."""
1744 keyword passing."""
1738
1745
1739 callerNS = sys._getframe(2).f_locals
1746 callerNS = sys._getframe(2).f_locals
1740 return dict((k,callerNS[k]) for k in names)
1747 return dict((k,callerNS[k]) for k in names)
1741
1748
1742 def expand_path(s):
1749 def expand_path(s):
1743 """Expand $VARS and ~names in a string, like a shell
1750 """Expand $VARS and ~names in a string, like a shell
1744
1751
1745 :Examples:
1752 :Examples:
1746
1753
1747 In [2]: os.environ['FOO']='test'
1754 In [2]: os.environ['FOO']='test'
1748
1755
1749 In [3]: shexp('variable FOO is $FOO')
1756 In [3]: shexp('variable FOO is $FOO')
1750 Out[3]: 'variable FOO is test'
1757 Out[3]: 'variable FOO is test'
1751 """
1758 """
1752 # This is a pretty subtle hack. When expand user is given a UNC path
1759 # This is a pretty subtle hack. When expand user is given a UNC path
1753 # on Windows (\\server\share$\%username%), os.path.expandvars, removes
1760 # on Windows (\\server\share$\%username%), os.path.expandvars, removes
1754 # the $ to get (\\server\share\%username%). I think it considered $
1761 # the $ to get (\\server\share\%username%). I think it considered $
1755 # alone an empty var. But, we need the $ to remains there (it indicates
1762 # alone an empty var. But, we need the $ to remains there (it indicates
1756 # a hidden share).
1763 # a hidden share).
1757 if os.name=='nt':
1764 if os.name=='nt':
1758 s = s.replace('$\\', 'IPYTHON_TEMP')
1765 s = s.replace('$\\', 'IPYTHON_TEMP')
1759 s = os.path.expandvars(os.path.expanduser(s))
1766 s = os.path.expandvars(os.path.expanduser(s))
1760 if os.name=='nt':
1767 if os.name=='nt':
1761 s = s.replace('IPYTHON_TEMP', '$\\')
1768 s = s.replace('IPYTHON_TEMP', '$\\')
1762 return s
1769 return s
1763
1770
1764 def list_strings(arg):
1771 def list_strings(arg):
1765 """Always return a list of strings, given a string or list of strings
1772 """Always return a list of strings, given a string or list of strings
1766 as input.
1773 as input.
1767
1774
1768 :Examples:
1775 :Examples:
1769
1776
1770 In [7]: list_strings('A single string')
1777 In [7]: list_strings('A single string')
1771 Out[7]: ['A single string']
1778 Out[7]: ['A single string']
1772
1779
1773 In [8]: list_strings(['A single string in a list'])
1780 In [8]: list_strings(['A single string in a list'])
1774 Out[8]: ['A single string in a list']
1781 Out[8]: ['A single string in a list']
1775
1782
1776 In [9]: list_strings(['A','list','of','strings'])
1783 In [9]: list_strings(['A','list','of','strings'])
1777 Out[9]: ['A', 'list', 'of', 'strings']
1784 Out[9]: ['A', 'list', 'of', 'strings']
1778 """
1785 """
1779
1786
1780 if isinstance(arg,basestring): return [arg]
1787 if isinstance(arg,basestring): return [arg]
1781 else: return arg
1788 else: return arg
1782
1789
1783
1790
1784 #----------------------------------------------------------------------------
1791 #----------------------------------------------------------------------------
1785 def marquee(txt='',width=78,mark='*'):
1792 def marquee(txt='',width=78,mark='*'):
1786 """Return the input string centered in a 'marquee'.
1793 """Return the input string centered in a 'marquee'.
1787
1794
1788 :Examples:
1795 :Examples:
1789
1796
1790 In [16]: marquee('A test',40)
1797 In [16]: marquee('A test',40)
1791 Out[16]: '**************** A test ****************'
1798 Out[16]: '**************** A test ****************'
1792
1799
1793 In [17]: marquee('A test',40,'-')
1800 In [17]: marquee('A test',40,'-')
1794 Out[17]: '---------------- A test ----------------'
1801 Out[17]: '---------------- A test ----------------'
1795
1802
1796 In [18]: marquee('A test',40,' ')
1803 In [18]: marquee('A test',40,' ')
1797 Out[18]: ' A test '
1804 Out[18]: ' A test '
1798
1805
1799 """
1806 """
1800 if not txt:
1807 if not txt:
1801 return (mark*width)[:width]
1808 return (mark*width)[:width]
1802 nmark = (width-len(txt)-2)/len(mark)/2
1809 nmark = (width-len(txt)-2)/len(mark)/2
1803 if nmark < 0: nmark =0
1810 if nmark < 0: nmark =0
1804 marks = mark*nmark
1811 marks = mark*nmark
1805 return '%s %s %s' % (marks,txt,marks)
1812 return '%s %s %s' % (marks,txt,marks)
1806
1813
1807 #*************************** end of file <genutils.py> **********************
1814 #*************************** end of file <genutils.py> **********************
General Comments 0
You need to be logged in to leave comments. Login now