##// END OF EJS Templates
Fix long-standing and elusive terminal bug, where sometimes after issuing foo?, the terminal would get badly corrupted
Fernando Perez -
Show More

The requested changes are too big and content was truncated. Show full diff

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