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