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