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