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