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