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