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