##// END OF EJS Templates
Added new Tee class, that works much like Unix's 'tee' command....
Fernando Perez -
Show More
@@ -1,313 +1,313 b''
1 """Decorators for labeling test objects.
1 """Decorators for labeling test objects.
2
2
3 Decorators that merely return a modified version of the original function
3 Decorators that merely return a modified version of the original function
4 object are straightforward. Decorators that return a new function object need
4 object are straightforward. Decorators that return a new function object need
5 to use nose.tools.make_decorator(original_function)(decorator) in returning the
5 to use nose.tools.make_decorator(original_function)(decorator) in returning the
6 decorator, in order to preserve metadata such as function name, setup and
6 decorator, in order to preserve metadata such as function name, setup and
7 teardown functions and so on - see nose.tools for more information.
7 teardown functions and so on - see nose.tools for more information.
8
8
9 This module provides a set of useful decorators meant to be ready to use in
9 This module provides a set of useful decorators meant to be ready to use in
10 your own tests. See the bottom of the file for the ready-made ones, and if you
10 your own tests. See the bottom of the file for the ready-made ones, and if you
11 find yourself writing a new one that may be of generic use, add it here.
11 find yourself writing a new one that may be of generic use, add it here.
12
12
13 Included decorators:
13 Included decorators:
14
14
15
15
16 Lightweight testing that remains unittest-compatible.
16 Lightweight testing that remains unittest-compatible.
17
17
18 - @parametric, for parametric test support that is vastly easier to use than
18 - @parametric, for parametric test support that is vastly easier to use than
19 nose's for debugging. With ours, if a test fails, the stack under inspection
19 nose's for debugging. With ours, if a test fails, the stack under inspection
20 is that of the test and not that of the test framework.
20 is that of the test and not that of the test framework.
21
21
22 - An @as_unittest decorator can be used to tag any normal parameter-less
22 - An @as_unittest decorator can be used to tag any normal parameter-less
23 function as a unittest TestCase. Then, both nose and normal unittest will
23 function as a unittest TestCase. Then, both nose and normal unittest will
24 recognize it as such. This will make it easier to migrate away from Nose if
24 recognize it as such. This will make it easier to migrate away from Nose if
25 we ever need/want to while maintaining very lightweight tests.
25 we ever need/want to while maintaining very lightweight tests.
26
26
27 NOTE: This file contains IPython-specific decorators and imports the
27 NOTE: This file contains IPython-specific decorators and imports the
28 numpy.testing.decorators file, which we've copied verbatim. Any of our own
28 numpy.testing.decorators file, which we've copied verbatim. Any of our own
29 code will be added at the bottom if we end up extending this.
29 code will be added at the bottom if we end up extending this.
30
30
31 Authors
31 Authors
32 -------
32 -------
33
33
34 - Fernando Perez <Fernando.Perez@berkeley.edu>
34 - Fernando Perez <Fernando.Perez@berkeley.edu>
35 """
35 """
36
36
37 #-----------------------------------------------------------------------------
37 #-----------------------------------------------------------------------------
38 # Copyright (C) 2009-2010 The IPython Development Team
38 # Copyright (C) 2009-2010 The IPython Development Team
39 #
39 #
40 # Distributed under the terms of the BSD License. The full license is in
40 # Distributed under the terms of the BSD License. The full license is in
41 # the file COPYING, distributed as part of this software.
41 # the file COPYING, distributed as part of this software.
42 #-----------------------------------------------------------------------------
42 #-----------------------------------------------------------------------------
43
43
44 #-----------------------------------------------------------------------------
44 #-----------------------------------------------------------------------------
45 # Imports
45 # Imports
46 #-----------------------------------------------------------------------------
46 #-----------------------------------------------------------------------------
47
47
48 # Stdlib imports
48 # Stdlib imports
49 import inspect
49 import inspect
50 import sys
50 import sys
51 import unittest
51 import unittest
52
52
53 # Third-party imports
53 # Third-party imports
54
54
55 # This is Michele Simionato's decorator module, kept verbatim.
55 # This is Michele Simionato's decorator module, kept verbatim.
56 from IPython.external.decorator import decorator, update_wrapper
56 from IPython.external.decorator import decorator, update_wrapper
57
57
58 # Our own modules
58 # Our own modules
59 import nosepatch # monkeypatch nose
59 import nosepatch # monkeypatch nose
60
60
61 # We already have python3-compliant code for parametric tests
61 # We already have python3-compliant code for parametric tests
62 if sys.version[0]=='2':
62 if sys.version[0]=='2':
63 from _paramtestpy2 import parametric
63 from _paramtestpy2 import parametric, ParametricTestCase
64 else:
64 else:
65 from _paramtestpy3 import parametric
65 from _paramtestpy3 import parametric, ParametricTestCase
66
66
67 # Expose the unittest-driven decorators
67 # Expose the unittest-driven decorators
68 from ipunittest import ipdoctest, ipdocstring
68 from ipunittest import ipdoctest, ipdocstring
69
69
70 # Grab the numpy-specific decorators which we keep in a file that we
70 # Grab the numpy-specific decorators which we keep in a file that we
71 # occasionally update from upstream: decorators.py is a copy of
71 # occasionally update from upstream: decorators.py is a copy of
72 # numpy.testing.decorators, we expose all of it here.
72 # numpy.testing.decorators, we expose all of it here.
73 from IPython.external.decorators import *
73 from IPython.external.decorators import *
74
74
75 #-----------------------------------------------------------------------------
75 #-----------------------------------------------------------------------------
76 # Classes and functions
76 # Classes and functions
77 #-----------------------------------------------------------------------------
77 #-----------------------------------------------------------------------------
78
78
79 # Simple example of the basic idea
79 # Simple example of the basic idea
80 def as_unittest(func):
80 def as_unittest(func):
81 """Decorator to make a simple function into a normal test via unittest."""
81 """Decorator to make a simple function into a normal test via unittest."""
82 class Tester(unittest.TestCase):
82 class Tester(unittest.TestCase):
83 def test(self):
83 def test(self):
84 func()
84 func()
85
85
86 Tester.__name__ = func.__name__
86 Tester.__name__ = func.__name__
87
87
88 return Tester
88 return Tester
89
89
90 # Utility functions
90 # Utility functions
91
91
92 def apply_wrapper(wrapper,func):
92 def apply_wrapper(wrapper,func):
93 """Apply a wrapper to a function for decoration.
93 """Apply a wrapper to a function for decoration.
94
94
95 This mixes Michele Simionato's decorator tool with nose's make_decorator,
95 This mixes Michele Simionato's decorator tool with nose's make_decorator,
96 to apply a wrapper in a decorator so that all nose attributes, as well as
96 to apply a wrapper in a decorator so that all nose attributes, as well as
97 function signature and other properties, survive the decoration cleanly.
97 function signature and other properties, survive the decoration cleanly.
98 This will ensure that wrapped functions can still be well introspected via
98 This will ensure that wrapped functions can still be well introspected via
99 IPython, for example.
99 IPython, for example.
100 """
100 """
101 import nose.tools
101 import nose.tools
102
102
103 return decorator(wrapper,nose.tools.make_decorator(func)(wrapper))
103 return decorator(wrapper,nose.tools.make_decorator(func)(wrapper))
104
104
105
105
106 def make_label_dec(label,ds=None):
106 def make_label_dec(label,ds=None):
107 """Factory function to create a decorator that applies one or more labels.
107 """Factory function to create a decorator that applies one or more labels.
108
108
109 Parameters
109 Parameters
110 ----------
110 ----------
111 label : string or sequence
111 label : string or sequence
112 One or more labels that will be applied by the decorator to the functions
112 One or more labels that will be applied by the decorator to the functions
113 it decorates. Labels are attributes of the decorated function with their
113 it decorates. Labels are attributes of the decorated function with their
114 value set to True.
114 value set to True.
115
115
116 ds : string
116 ds : string
117 An optional docstring for the resulting decorator. If not given, a
117 An optional docstring for the resulting decorator. If not given, a
118 default docstring is auto-generated.
118 default docstring is auto-generated.
119
119
120 Returns
120 Returns
121 -------
121 -------
122 A decorator.
122 A decorator.
123
123
124 Examples
124 Examples
125 --------
125 --------
126
126
127 A simple labeling decorator:
127 A simple labeling decorator:
128 >>> slow = make_label_dec('slow')
128 >>> slow = make_label_dec('slow')
129 >>> print slow.__doc__
129 >>> print slow.__doc__
130 Labels a test as 'slow'.
130 Labels a test as 'slow'.
131
131
132 And one that uses multiple labels and a custom docstring:
132 And one that uses multiple labels and a custom docstring:
133 >>> rare = make_label_dec(['slow','hard'],
133 >>> rare = make_label_dec(['slow','hard'],
134 ... "Mix labels 'slow' and 'hard' for rare tests.")
134 ... "Mix labels 'slow' and 'hard' for rare tests.")
135 >>> print rare.__doc__
135 >>> print rare.__doc__
136 Mix labels 'slow' and 'hard' for rare tests.
136 Mix labels 'slow' and 'hard' for rare tests.
137
137
138 Now, let's test using this one:
138 Now, let's test using this one:
139 >>> @rare
139 >>> @rare
140 ... def f(): pass
140 ... def f(): pass
141 ...
141 ...
142 >>>
142 >>>
143 >>> f.slow
143 >>> f.slow
144 True
144 True
145 >>> f.hard
145 >>> f.hard
146 True
146 True
147 """
147 """
148
148
149 if isinstance(label,basestring):
149 if isinstance(label,basestring):
150 labels = [label]
150 labels = [label]
151 else:
151 else:
152 labels = label
152 labels = label
153
153
154 # Validate that the given label(s) are OK for use in setattr() by doing a
154 # Validate that the given label(s) are OK for use in setattr() by doing a
155 # dry run on a dummy function.
155 # dry run on a dummy function.
156 tmp = lambda : None
156 tmp = lambda : None
157 for label in labels:
157 for label in labels:
158 setattr(tmp,label,True)
158 setattr(tmp,label,True)
159
159
160 # This is the actual decorator we'll return
160 # This is the actual decorator we'll return
161 def decor(f):
161 def decor(f):
162 for label in labels:
162 for label in labels:
163 setattr(f,label,True)
163 setattr(f,label,True)
164 return f
164 return f
165
165
166 # Apply the user's docstring, or autogenerate a basic one
166 # Apply the user's docstring, or autogenerate a basic one
167 if ds is None:
167 if ds is None:
168 ds = "Labels a test as %r." % label
168 ds = "Labels a test as %r." % label
169 decor.__doc__ = ds
169 decor.__doc__ = ds
170
170
171 return decor
171 return decor
172
172
173
173
174 # Inspired by numpy's skipif, but uses the full apply_wrapper utility to
174 # Inspired by numpy's skipif, but uses the full apply_wrapper utility to
175 # preserve function metadata better and allows the skip condition to be a
175 # preserve function metadata better and allows the skip condition to be a
176 # callable.
176 # callable.
177 def skipif(skip_condition, msg=None):
177 def skipif(skip_condition, msg=None):
178 ''' Make function raise SkipTest exception if skip_condition is true
178 ''' Make function raise SkipTest exception if skip_condition is true
179
179
180 Parameters
180 Parameters
181 ----------
181 ----------
182 skip_condition : bool or callable.
182 skip_condition : bool or callable.
183 Flag to determine whether to skip test. If the condition is a
183 Flag to determine whether to skip test. If the condition is a
184 callable, it is used at runtime to dynamically make the decision. This
184 callable, it is used at runtime to dynamically make the decision. This
185 is useful for tests that may require costly imports, to delay the cost
185 is useful for tests that may require costly imports, to delay the cost
186 until the test suite is actually executed.
186 until the test suite is actually executed.
187 msg : string
187 msg : string
188 Message to give on raising a SkipTest exception
188 Message to give on raising a SkipTest exception
189
189
190 Returns
190 Returns
191 -------
191 -------
192 decorator : function
192 decorator : function
193 Decorator, which, when applied to a function, causes SkipTest
193 Decorator, which, when applied to a function, causes SkipTest
194 to be raised when the skip_condition was True, and the function
194 to be raised when the skip_condition was True, and the function
195 to be called normally otherwise.
195 to be called normally otherwise.
196
196
197 Notes
197 Notes
198 -----
198 -----
199 You will see from the code that we had to further decorate the
199 You will see from the code that we had to further decorate the
200 decorator with the nose.tools.make_decorator function in order to
200 decorator with the nose.tools.make_decorator function in order to
201 transmit function name, and various other metadata.
201 transmit function name, and various other metadata.
202 '''
202 '''
203
203
204 def skip_decorator(f):
204 def skip_decorator(f):
205 # Local import to avoid a hard nose dependency and only incur the
205 # Local import to avoid a hard nose dependency and only incur the
206 # import time overhead at actual test-time.
206 # import time overhead at actual test-time.
207 import nose
207 import nose
208
208
209 # Allow for both boolean or callable skip conditions.
209 # Allow for both boolean or callable skip conditions.
210 if callable(skip_condition):
210 if callable(skip_condition):
211 skip_val = lambda : skip_condition()
211 skip_val = lambda : skip_condition()
212 else:
212 else:
213 skip_val = lambda : skip_condition
213 skip_val = lambda : skip_condition
214
214
215 def get_msg(func,msg=None):
215 def get_msg(func,msg=None):
216 """Skip message with information about function being skipped."""
216 """Skip message with information about function being skipped."""
217 if msg is None: out = 'Test skipped due to test condition.'
217 if msg is None: out = 'Test skipped due to test condition.'
218 else: out = msg
218 else: out = msg
219 return "Skipping test: %s. %s" % (func.__name__,out)
219 return "Skipping test: %s. %s" % (func.__name__,out)
220
220
221 # We need to define *two* skippers because Python doesn't allow both
221 # We need to define *two* skippers because Python doesn't allow both
222 # return with value and yield inside the same function.
222 # return with value and yield inside the same function.
223 def skipper_func(*args, **kwargs):
223 def skipper_func(*args, **kwargs):
224 """Skipper for normal test functions."""
224 """Skipper for normal test functions."""
225 if skip_val():
225 if skip_val():
226 raise nose.SkipTest(get_msg(f,msg))
226 raise nose.SkipTest(get_msg(f,msg))
227 else:
227 else:
228 return f(*args, **kwargs)
228 return f(*args, **kwargs)
229
229
230 def skipper_gen(*args, **kwargs):
230 def skipper_gen(*args, **kwargs):
231 """Skipper for test generators."""
231 """Skipper for test generators."""
232 if skip_val():
232 if skip_val():
233 raise nose.SkipTest(get_msg(f,msg))
233 raise nose.SkipTest(get_msg(f,msg))
234 else:
234 else:
235 for x in f(*args, **kwargs):
235 for x in f(*args, **kwargs):
236 yield x
236 yield x
237
237
238 # Choose the right skipper to use when building the actual generator.
238 # Choose the right skipper to use when building the actual generator.
239 if nose.util.isgenerator(f):
239 if nose.util.isgenerator(f):
240 skipper = skipper_gen
240 skipper = skipper_gen
241 else:
241 else:
242 skipper = skipper_func
242 skipper = skipper_func
243
243
244 return nose.tools.make_decorator(f)(skipper)
244 return nose.tools.make_decorator(f)(skipper)
245
245
246 return skip_decorator
246 return skip_decorator
247
247
248 # A version with the condition set to true, common case just to attacha message
248 # A version with the condition set to true, common case just to attacha message
249 # to a skip decorator
249 # to a skip decorator
250 def skip(msg=None):
250 def skip(msg=None):
251 """Decorator factory - mark a test function for skipping from test suite.
251 """Decorator factory - mark a test function for skipping from test suite.
252
252
253 Parameters
253 Parameters
254 ----------
254 ----------
255 msg : string
255 msg : string
256 Optional message to be added.
256 Optional message to be added.
257
257
258 Returns
258 Returns
259 -------
259 -------
260 decorator : function
260 decorator : function
261 Decorator, which, when applied to a function, causes SkipTest
261 Decorator, which, when applied to a function, causes SkipTest
262 to be raised, with the optional message added.
262 to be raised, with the optional message added.
263 """
263 """
264
264
265 return skipif(True,msg)
265 return skipif(True,msg)
266
266
267
267
268 #-----------------------------------------------------------------------------
268 #-----------------------------------------------------------------------------
269 # Utility functions for decorators
269 # Utility functions for decorators
270 def numpy_not_available():
270 def numpy_not_available():
271 """Can numpy be imported? Returns true if numpy does NOT import.
271 """Can numpy be imported? Returns true if numpy does NOT import.
272
272
273 This is used to make a decorator to skip tests that require numpy to be
273 This is used to make a decorator to skip tests that require numpy to be
274 available, but delay the 'import numpy' to test execution time.
274 available, but delay the 'import numpy' to test execution time.
275 """
275 """
276 try:
276 try:
277 import numpy
277 import numpy
278 np_not_avail = False
278 np_not_avail = False
279 except ImportError:
279 except ImportError:
280 np_not_avail = True
280 np_not_avail = True
281
281
282 return np_not_avail
282 return np_not_avail
283
283
284 #-----------------------------------------------------------------------------
284 #-----------------------------------------------------------------------------
285 # Decorators for public use
285 # Decorators for public use
286
286
287 skip_doctest = make_label_dec('skip_doctest',
287 skip_doctest = make_label_dec('skip_doctest',
288 """Decorator - mark a function or method for skipping its doctest.
288 """Decorator - mark a function or method for skipping its doctest.
289
289
290 This decorator allows you to mark a function whose docstring you wish to
290 This decorator allows you to mark a function whose docstring you wish to
291 omit from testing, while preserving the docstring for introspection, help,
291 omit from testing, while preserving the docstring for introspection, help,
292 etc.""")
292 etc.""")
293
293
294 # Decorators to skip certain tests on specific platforms.
294 # Decorators to skip certain tests on specific platforms.
295 skip_win32 = skipif(sys.platform == 'win32',
295 skip_win32 = skipif(sys.platform == 'win32',
296 "This test does not run under Windows")
296 "This test does not run under Windows")
297 skip_linux = skipif(sys.platform == 'linux2',
297 skip_linux = skipif(sys.platform == 'linux2',
298 "This test does not run under Linux")
298 "This test does not run under Linux")
299 skip_osx = skipif(sys.platform == 'darwin',"This test does not run under OS X")
299 skip_osx = skipif(sys.platform == 'darwin',"This test does not run under OS X")
300
300
301
301
302 # Decorators to skip tests if not on specific platforms.
302 # Decorators to skip tests if not on specific platforms.
303 skip_if_not_win32 = skipif(sys.platform != 'win32',
303 skip_if_not_win32 = skipif(sys.platform != 'win32',
304 "This test only runs under Windows")
304 "This test only runs under Windows")
305 skip_if_not_linux = skipif(sys.platform != 'linux2',
305 skip_if_not_linux = skipif(sys.platform != 'linux2',
306 "This test only runs under Linux")
306 "This test only runs under Linux")
307 skip_if_not_osx = skipif(sys.platform != 'darwin',
307 skip_if_not_osx = skipif(sys.platform != 'darwin',
308 "This test only runs under OSX")
308 "This test only runs under OSX")
309
309
310 # Other skip decorators
310 # Other skip decorators
311 skipif_not_numpy = skipif(numpy_not_available,"This test requires numpy")
311 skipif_not_numpy = skipif(numpy_not_available,"This test requires numpy")
312
312
313 skipknownfailure = skip('This test is known to fail')
313 skipknownfailure = skip('This test is known to fail')
@@ -1,1814 +1,1873 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """General purpose utilities.
2 """General purpose utilities.
3
3
4 This is a grab-bag of stuff I find useful in most programs I write. Some of
4 This is a grab-bag of stuff I find useful in most programs I write. Some of
5 these things are also convenient when working at the command line.
5 these things are also convenient when working at the command line.
6 """
6 """
7
7
8 #*****************************************************************************
8 #*****************************************************************************
9 # Copyright (C) 2001-2006 Fernando Perez. <fperez@colorado.edu>
9 # Copyright (C) 2001-2006 Fernando Perez. <fperez@colorado.edu>
10 #
10 #
11 # Distributed under the terms of the BSD License. The full license is in
11 # Distributed under the terms of the BSD License. The full license is in
12 # the file COPYING, distributed as part of this software.
12 # the file COPYING, distributed as part of this software.
13 #*****************************************************************************
13 #*****************************************************************************
14
14
15 #****************************************************************************
15 #****************************************************************************
16 # required modules from the Python standard library
16 # required modules from the Python standard library
17 import __main__
17 import __main__
18
18
19 import os
19 import os
20 import platform
20 import platform
21 import re
21 import re
22 import shlex
22 import shlex
23 import shutil
23 import shutil
24 import subprocess
24 import subprocess
25 import sys
25 import sys
26 import time
26 import time
27 import types
27 import types
28 import warnings
28 import warnings
29
29
30 # Curses and termios are Unix-only modules
30 # Curses and termios are Unix-only modules
31 try:
31 try:
32 import curses
32 import curses
33 # We need termios as well, so if its import happens to raise, we bail on
33 # We need termios as well, so if its import happens to raise, we bail on
34 # using curses altogether.
34 # using curses altogether.
35 import termios
35 import termios
36 except ImportError:
36 except ImportError:
37 USE_CURSES = False
37 USE_CURSES = False
38 else:
38 else:
39 # Curses on Solaris may not be complete, so we can't use it there
39 # Curses on Solaris may not be complete, so we can't use it there
40 USE_CURSES = hasattr(curses,'initscr')
40 USE_CURSES = hasattr(curses,'initscr')
41
41
42 # Other IPython utilities
42 # Other IPython utilities
43 import IPython
43 import IPython
44 from IPython.external.Itpl import itpl,printpl
44 from IPython.external.Itpl import itpl,printpl
45 from IPython.utils import platutils
45 from IPython.utils import platutils
46 from IPython.utils.generics import result_display
46 from IPython.utils.generics import result_display
47 from IPython.external.path import path
47 from IPython.external.path import path
48
48
49
49
50 #****************************************************************************
50 #****************************************************************************
51 # Exceptions
51 # Exceptions
52 class Error(Exception):
52 class Error(Exception):
53 """Base class for exceptions in this module."""
53 """Base class for exceptions in this module."""
54 pass
54 pass
55
55
56 #----------------------------------------------------------------------------
56 #----------------------------------------------------------------------------
57 class IOStream:
57 class IOStream:
58 def __init__(self,stream,fallback):
58 def __init__(self,stream,fallback):
59 if not hasattr(stream,'write') or not hasattr(stream,'flush'):
59 if not hasattr(stream,'write') or not hasattr(stream,'flush'):
60 stream = fallback
60 stream = fallback
61 self.stream = stream
61 self.stream = stream
62 self._swrite = stream.write
62 self._swrite = stream.write
63 self.flush = stream.flush
63 self.flush = stream.flush
64
64
65 def write(self,data):
65 def write(self,data):
66 try:
66 try:
67 self._swrite(data)
67 self._swrite(data)
68 except:
68 except:
69 try:
69 try:
70 # print handles some unicode issues which may trip a plain
70 # print handles some unicode issues which may trip a plain
71 # write() call. Attempt to emulate write() by using a
71 # write() call. Attempt to emulate write() by using a
72 # trailing comma
72 # trailing comma
73 print >> self.stream, data,
73 print >> self.stream, data,
74 except:
74 except:
75 # if we get here, something is seriously broken.
75 # if we get here, something is seriously broken.
76 print >> sys.stderr, \
76 print >> sys.stderr, \
77 'ERROR - failed to write data to stream:', self.stream
77 'ERROR - failed to write data to stream:', self.stream
78
78
79 def close(self):
79 def close(self):
80 pass
80 pass
81
81
82
82
83 class IOTerm:
83 class IOTerm:
84 """ Term holds the file or file-like objects for handling I/O operations.
84 """ Term holds the file or file-like objects for handling I/O operations.
85
85
86 These are normally just sys.stdin, sys.stdout and sys.stderr but for
86 These are normally just sys.stdin, sys.stdout and sys.stderr but for
87 Windows they can can replaced to allow editing the strings before they are
87 Windows they can can replaced to allow editing the strings before they are
88 displayed."""
88 displayed."""
89
89
90 # In the future, having IPython channel all its I/O operations through
90 # In the future, having IPython channel all its I/O operations through
91 # this class will make it easier to embed it into other environments which
91 # this class will make it easier to embed it into other environments which
92 # are not a normal terminal (such as a GUI-based shell)
92 # are not a normal terminal (such as a GUI-based shell)
93 def __init__(self,cin=None,cout=None,cerr=None):
93 def __init__(self,cin=None,cout=None,cerr=None):
94 self.cin = IOStream(cin,sys.stdin)
94 self.cin = IOStream(cin,sys.stdin)
95 self.cout = IOStream(cout,sys.stdout)
95 self.cout = IOStream(cout,sys.stdout)
96 self.cerr = IOStream(cerr,sys.stderr)
96 self.cerr = IOStream(cerr,sys.stderr)
97
97
98 # Global variable to be used for all I/O
98 # Global variable to be used for all I/O
99 Term = IOTerm()
99 Term = IOTerm()
100
100
101 import IPython.utils.rlineimpl as readline
101 import IPython.utils.rlineimpl as readline
102 # Remake Term to use the readline i/o facilities
102 # Remake Term to use the readline i/o facilities
103 if sys.platform == 'win32' and readline.have_readline:
103 if sys.platform == 'win32' and readline.have_readline:
104
104
105 Term = IOTerm(cout=readline._outputfile,cerr=readline._outputfile)
105 Term = IOTerm(cout=readline._outputfile,cerr=readline._outputfile)
106
106
107
107
108 class Tee(object):
109 """A class to duplicate an output stream to stdout/err.
110
111 This works in a manner very similar to the Unix 'tee' command.
112
113 When the object is closed or deleted, it closes the original file given to
114 it for duplication.
115 """
116 # Inspired by:
117 # http://mail.python.org/pipermail/python-list/2007-May/442737.html
118
119 def __init__(self, file, mode=None, channel='stdout'):
120 """Construct a new Tee object.
121
122 Parameters
123 ----------
124 file : filename or open filehandle (writable)
125 File that will be duplicated
126
127 mode : optional, valid mode for open().
128 If a filename was give, open with this mode.
129
130 channel : str, one of ['stdout', 'stderr']
131 """
132 if channel not in ['stdout', 'stderr']:
133 raise ValueError('Invalid channel spec %s' % channel)
134
135 if hasattr(file, 'write') and hasattr(file, 'seek'):
136 self.file = file
137 else:
138 self.file = open(name, mode)
139 self.channel = channel
140 self.ostream = getattr(sys, channel)
141 setattr(sys, channel, self)
142 self._closed = False
143
144 def close(self):
145 """Close the file and restore the channel."""
146 self.flush()
147 setattr(sys, self.channel, self.ostream)
148 self.file.close()
149 self._closed = True
150
151 def write(self, data):
152 """Write data to both channels."""
153 self.file.write(data)
154 self.ostream.write(data)
155 self.ostream.flush()
156
157 def flush(self):
158 """Flush both channels."""
159 self.file.flush()
160 self.ostream.flush()
161
162 def __del__(self):
163 if not self._closed:
164 self.close()
165
166
108 #****************************************************************************
167 #****************************************************************************
109 # Generic warning/error printer, used by everything else
168 # Generic warning/error printer, used by everything else
110 def warn(msg,level=2,exit_val=1):
169 def warn(msg,level=2,exit_val=1):
111 """Standard warning printer. Gives formatting consistency.
170 """Standard warning printer. Gives formatting consistency.
112
171
113 Output is sent to Term.cerr (sys.stderr by default).
172 Output is sent to Term.cerr (sys.stderr by default).
114
173
115 Options:
174 Options:
116
175
117 -level(2): allows finer control:
176 -level(2): allows finer control:
118 0 -> Do nothing, dummy function.
177 0 -> Do nothing, dummy function.
119 1 -> Print message.
178 1 -> Print message.
120 2 -> Print 'WARNING:' + message. (Default level).
179 2 -> Print 'WARNING:' + message. (Default level).
121 3 -> Print 'ERROR:' + message.
180 3 -> Print 'ERROR:' + message.
122 4 -> Print 'FATAL ERROR:' + message and trigger a sys.exit(exit_val).
181 4 -> Print 'FATAL ERROR:' + message and trigger a sys.exit(exit_val).
123
182
124 -exit_val (1): exit value returned by sys.exit() for a level 4
183 -exit_val (1): exit value returned by sys.exit() for a level 4
125 warning. Ignored for all other levels."""
184 warning. Ignored for all other levels."""
126
185
127 if level>0:
186 if level>0:
128 header = ['','','WARNING: ','ERROR: ','FATAL ERROR: ']
187 header = ['','','WARNING: ','ERROR: ','FATAL ERROR: ']
129 print >> Term.cerr, '%s%s' % (header[level],msg)
188 print >> Term.cerr, '%s%s' % (header[level],msg)
130 if level == 4:
189 if level == 4:
131 print >> Term.cerr,'Exiting.\n'
190 print >> Term.cerr,'Exiting.\n'
132 sys.exit(exit_val)
191 sys.exit(exit_val)
133
192
134 def info(msg):
193 def info(msg):
135 """Equivalent to warn(msg,level=1)."""
194 """Equivalent to warn(msg,level=1)."""
136
195
137 warn(msg,level=1)
196 warn(msg,level=1)
138
197
139 def error(msg):
198 def error(msg):
140 """Equivalent to warn(msg,level=3)."""
199 """Equivalent to warn(msg,level=3)."""
141
200
142 warn(msg,level=3)
201 warn(msg,level=3)
143
202
144 def fatal(msg,exit_val=1):
203 def fatal(msg,exit_val=1):
145 """Equivalent to warn(msg,exit_val=exit_val,level=4)."""
204 """Equivalent to warn(msg,exit_val=exit_val,level=4)."""
146
205
147 warn(msg,exit_val=exit_val,level=4)
206 warn(msg,exit_val=exit_val,level=4)
148
207
149 #---------------------------------------------------------------------------
208 #---------------------------------------------------------------------------
150 # Debugging routines
209 # Debugging routines
151 #
210 #
152 def debugx(expr,pre_msg=''):
211 def debugx(expr,pre_msg=''):
153 """Print the value of an expression from the caller's frame.
212 """Print the value of an expression from the caller's frame.
154
213
155 Takes an expression, evaluates it in the caller's frame and prints both
214 Takes an expression, evaluates it in the caller's frame and prints both
156 the given expression and the resulting value (as well as a debug mark
215 the given expression and the resulting value (as well as a debug mark
157 indicating the name of the calling function. The input must be of a form
216 indicating the name of the calling function. The input must be of a form
158 suitable for eval().
217 suitable for eval().
159
218
160 An optional message can be passed, which will be prepended to the printed
219 An optional message can be passed, which will be prepended to the printed
161 expr->value pair."""
220 expr->value pair."""
162
221
163 cf = sys._getframe(1)
222 cf = sys._getframe(1)
164 print '[DBG:%s] %s%s -> %r' % (cf.f_code.co_name,pre_msg,expr,
223 print '[DBG:%s] %s%s -> %r' % (cf.f_code.co_name,pre_msg,expr,
165 eval(expr,cf.f_globals,cf.f_locals))
224 eval(expr,cf.f_globals,cf.f_locals))
166
225
167 # deactivate it by uncommenting the following line, which makes it a no-op
226 # deactivate it by uncommenting the following line, which makes it a no-op
168 #def debugx(expr,pre_msg=''): pass
227 #def debugx(expr,pre_msg=''): pass
169
228
170 #----------------------------------------------------------------------------
229 #----------------------------------------------------------------------------
171 StringTypes = types.StringTypes
230 StringTypes = types.StringTypes
172
231
173 # Basic timing functionality
232 # Basic timing functionality
174
233
175 # If possible (Unix), use the resource module instead of time.clock()
234 # If possible (Unix), use the resource module instead of time.clock()
176 try:
235 try:
177 import resource
236 import resource
178 def clocku():
237 def clocku():
179 """clocku() -> floating point number
238 """clocku() -> floating point number
180
239
181 Return the *USER* CPU time in seconds since the start of the process.
240 Return the *USER* CPU time in seconds since the start of the process.
182 This is done via a call to resource.getrusage, so it avoids the
241 This is done via a call to resource.getrusage, so it avoids the
183 wraparound problems in time.clock()."""
242 wraparound problems in time.clock()."""
184
243
185 return resource.getrusage(resource.RUSAGE_SELF)[0]
244 return resource.getrusage(resource.RUSAGE_SELF)[0]
186
245
187 def clocks():
246 def clocks():
188 """clocks() -> floating point number
247 """clocks() -> floating point number
189
248
190 Return the *SYSTEM* CPU time in seconds since the start of the process.
249 Return the *SYSTEM* CPU time in seconds since the start of the process.
191 This is done via a call to resource.getrusage, so it avoids the
250 This is done via a call to resource.getrusage, so it avoids the
192 wraparound problems in time.clock()."""
251 wraparound problems in time.clock()."""
193
252
194 return resource.getrusage(resource.RUSAGE_SELF)[1]
253 return resource.getrusage(resource.RUSAGE_SELF)[1]
195
254
196 def clock():
255 def clock():
197 """clock() -> floating point number
256 """clock() -> floating point number
198
257
199 Return the *TOTAL USER+SYSTEM* CPU time in seconds since the start of
258 Return the *TOTAL USER+SYSTEM* CPU time in seconds since the start of
200 the process. This is done via a call to resource.getrusage, so it
259 the process. This is done via a call to resource.getrusage, so it
201 avoids the wraparound problems in time.clock()."""
260 avoids the wraparound problems in time.clock()."""
202
261
203 u,s = resource.getrusage(resource.RUSAGE_SELF)[:2]
262 u,s = resource.getrusage(resource.RUSAGE_SELF)[:2]
204 return u+s
263 return u+s
205
264
206 def clock2():
265 def clock2():
207 """clock2() -> (t_user,t_system)
266 """clock2() -> (t_user,t_system)
208
267
209 Similar to clock(), but return a tuple of user/system times."""
268 Similar to clock(), but return a tuple of user/system times."""
210 return resource.getrusage(resource.RUSAGE_SELF)[:2]
269 return resource.getrusage(resource.RUSAGE_SELF)[:2]
211
270
212 except ImportError:
271 except ImportError:
213 # There is no distinction of user/system time under windows, so we just use
272 # There is no distinction of user/system time under windows, so we just use
214 # time.clock() for everything...
273 # time.clock() for everything...
215 clocku = clocks = clock = time.clock
274 clocku = clocks = clock = time.clock
216 def clock2():
275 def clock2():
217 """Under windows, system CPU time can't be measured.
276 """Under windows, system CPU time can't be measured.
218
277
219 This just returns clock() and zero."""
278 This just returns clock() and zero."""
220 return time.clock(),0.0
279 return time.clock(),0.0
221
280
222 def timings_out(reps,func,*args,**kw):
281 def timings_out(reps,func,*args,**kw):
223 """timings_out(reps,func,*args,**kw) -> (t_total,t_per_call,output)
282 """timings_out(reps,func,*args,**kw) -> (t_total,t_per_call,output)
224
283
225 Execute a function reps times, return a tuple with the elapsed total
284 Execute a function reps times, return a tuple with the elapsed total
226 CPU time in seconds, the time per call and the function's output.
285 CPU time in seconds, the time per call and the function's output.
227
286
228 Under Unix, the return value is the sum of user+system time consumed by
287 Under Unix, the return value is the sum of user+system time consumed by
229 the process, computed via the resource module. This prevents problems
288 the process, computed via the resource module. This prevents problems
230 related to the wraparound effect which the time.clock() function has.
289 related to the wraparound effect which the time.clock() function has.
231
290
232 Under Windows the return value is in wall clock seconds. See the
291 Under Windows the return value is in wall clock seconds. See the
233 documentation for the time module for more details."""
292 documentation for the time module for more details."""
234
293
235 reps = int(reps)
294 reps = int(reps)
236 assert reps >=1, 'reps must be >= 1'
295 assert reps >=1, 'reps must be >= 1'
237 if reps==1:
296 if reps==1:
238 start = clock()
297 start = clock()
239 out = func(*args,**kw)
298 out = func(*args,**kw)
240 tot_time = clock()-start
299 tot_time = clock()-start
241 else:
300 else:
242 rng = xrange(reps-1) # the last time is executed separately to store output
301 rng = xrange(reps-1) # the last time is executed separately to store output
243 start = clock()
302 start = clock()
244 for dummy in rng: func(*args,**kw)
303 for dummy in rng: func(*args,**kw)
245 out = func(*args,**kw) # one last time
304 out = func(*args,**kw) # one last time
246 tot_time = clock()-start
305 tot_time = clock()-start
247 av_time = tot_time / reps
306 av_time = tot_time / reps
248 return tot_time,av_time,out
307 return tot_time,av_time,out
249
308
250 def timings(reps,func,*args,**kw):
309 def timings(reps,func,*args,**kw):
251 """timings(reps,func,*args,**kw) -> (t_total,t_per_call)
310 """timings(reps,func,*args,**kw) -> (t_total,t_per_call)
252
311
253 Execute a function reps times, return a tuple with the elapsed total CPU
312 Execute a function reps times, return a tuple with the elapsed total CPU
254 time in seconds and the time per call. These are just the first two values
313 time in seconds and the time per call. These are just the first two values
255 in timings_out()."""
314 in timings_out()."""
256
315
257 return timings_out(reps,func,*args,**kw)[0:2]
316 return timings_out(reps,func,*args,**kw)[0:2]
258
317
259 def timing(func,*args,**kw):
318 def timing(func,*args,**kw):
260 """timing(func,*args,**kw) -> t_total
319 """timing(func,*args,**kw) -> t_total
261
320
262 Execute a function once, return the elapsed total CPU time in
321 Execute a function once, return the elapsed total CPU time in
263 seconds. This is just the first value in timings_out()."""
322 seconds. This is just the first value in timings_out()."""
264
323
265 return timings_out(1,func,*args,**kw)[0]
324 return timings_out(1,func,*args,**kw)[0]
266
325
267 #****************************************************************************
326 #****************************************************************************
268 # file and system
327 # file and system
269
328
270 def arg_split(s,posix=False):
329 def arg_split(s,posix=False):
271 """Split a command line's arguments in a shell-like manner.
330 """Split a command line's arguments in a shell-like manner.
272
331
273 This is a modified version of the standard library's shlex.split()
332 This is a modified version of the standard library's shlex.split()
274 function, but with a default of posix=False for splitting, so that quotes
333 function, but with a default of posix=False for splitting, so that quotes
275 in inputs are respected."""
334 in inputs are respected."""
276
335
277 # XXX - there may be unicode-related problems here!!! I'm not sure that
336 # XXX - there may be unicode-related problems here!!! I'm not sure that
278 # shlex is truly unicode-safe, so it might be necessary to do
337 # shlex is truly unicode-safe, so it might be necessary to do
279 #
338 #
280 # s = s.encode(sys.stdin.encoding)
339 # s = s.encode(sys.stdin.encoding)
281 #
340 #
282 # first, to ensure that shlex gets a normal string. Input from anyone who
341 # first, to ensure that shlex gets a normal string. Input from anyone who
283 # knows more about unicode and shlex than I would be good to have here...
342 # knows more about unicode and shlex than I would be good to have here...
284 lex = shlex.shlex(s, posix=posix)
343 lex = shlex.shlex(s, posix=posix)
285 lex.whitespace_split = True
344 lex.whitespace_split = True
286 return list(lex)
345 return list(lex)
287
346
288 def system(cmd,verbose=0,debug=0,header=''):
347 def system(cmd,verbose=0,debug=0,header=''):
289 """Execute a system command, return its exit status.
348 """Execute a system command, return its exit status.
290
349
291 Options:
350 Options:
292
351
293 - verbose (0): print the command to be executed.
352 - verbose (0): print the command to be executed.
294
353
295 - debug (0): only print, do not actually execute.
354 - debug (0): only print, do not actually execute.
296
355
297 - header (''): Header to print on screen prior to the executed command (it
356 - header (''): Header to print on screen prior to the executed command (it
298 is only prepended to the command, no newlines are added).
357 is only prepended to the command, no newlines are added).
299
358
300 Note: a stateful version of this function is available through the
359 Note: a stateful version of this function is available through the
301 SystemExec class."""
360 SystemExec class."""
302
361
303 stat = 0
362 stat = 0
304 if verbose or debug: print header+cmd
363 if verbose or debug: print header+cmd
305 sys.stdout.flush()
364 sys.stdout.flush()
306 if not debug: stat = os.system(cmd)
365 if not debug: stat = os.system(cmd)
307 return stat
366 return stat
308
367
309 def abbrev_cwd():
368 def abbrev_cwd():
310 """ Return abbreviated version of cwd, e.g. d:mydir """
369 """ Return abbreviated version of cwd, e.g. d:mydir """
311 cwd = os.getcwd().replace('\\','/')
370 cwd = os.getcwd().replace('\\','/')
312 drivepart = ''
371 drivepart = ''
313 tail = cwd
372 tail = cwd
314 if sys.platform == 'win32':
373 if sys.platform == 'win32':
315 if len(cwd) < 4:
374 if len(cwd) < 4:
316 return cwd
375 return cwd
317 drivepart,tail = os.path.splitdrive(cwd)
376 drivepart,tail = os.path.splitdrive(cwd)
318
377
319
378
320 parts = tail.split('/')
379 parts = tail.split('/')
321 if len(parts) > 2:
380 if len(parts) > 2:
322 tail = '/'.join(parts[-2:])
381 tail = '/'.join(parts[-2:])
323
382
324 return (drivepart + (
383 return (drivepart + (
325 cwd == '/' and '/' or tail))
384 cwd == '/' and '/' or tail))
326
385
327
386
328 # This function is used by ipython in a lot of places to make system calls.
387 # This function is used by ipython in a lot of places to make system calls.
329 # We need it to be slightly different under win32, due to the vagaries of
388 # We need it to be slightly different under win32, due to the vagaries of
330 # 'network shares'. A win32 override is below.
389 # 'network shares'. A win32 override is below.
331
390
332 def shell(cmd,verbose=0,debug=0,header=''):
391 def shell(cmd,verbose=0,debug=0,header=''):
333 """Execute a command in the system shell, always return None.
392 """Execute a command in the system shell, always return None.
334
393
335 Options:
394 Options:
336
395
337 - verbose (0): print the command to be executed.
396 - verbose (0): print the command to be executed.
338
397
339 - debug (0): only print, do not actually execute.
398 - debug (0): only print, do not actually execute.
340
399
341 - header (''): Header to print on screen prior to the executed command (it
400 - header (''): Header to print on screen prior to the executed command (it
342 is only prepended to the command, no newlines are added).
401 is only prepended to the command, no newlines are added).
343
402
344 Note: this is similar to genutils.system(), but it returns None so it can
403 Note: this is similar to genutils.system(), but it returns None so it can
345 be conveniently used in interactive loops without getting the return value
404 be conveniently used in interactive loops without getting the return value
346 (typically 0) printed many times."""
405 (typically 0) printed many times."""
347
406
348 stat = 0
407 stat = 0
349 if verbose or debug: print header+cmd
408 if verbose or debug: print header+cmd
350 # flush stdout so we don't mangle python's buffering
409 # flush stdout so we don't mangle python's buffering
351 sys.stdout.flush()
410 sys.stdout.flush()
352
411
353 if not debug:
412 if not debug:
354 platutils.set_term_title("IPy " + cmd)
413 platutils.set_term_title("IPy " + cmd)
355 os.system(cmd)
414 os.system(cmd)
356 platutils.set_term_title("IPy " + abbrev_cwd())
415 platutils.set_term_title("IPy " + abbrev_cwd())
357
416
358 # override shell() for win32 to deal with network shares
417 # override shell() for win32 to deal with network shares
359 if os.name in ('nt','dos'):
418 if os.name in ('nt','dos'):
360
419
361 shell_ori = shell
420 shell_ori = shell
362
421
363 def shell(cmd,verbose=0,debug=0,header=''):
422 def shell(cmd,verbose=0,debug=0,header=''):
364 if os.getcwd().startswith(r"\\"):
423 if os.getcwd().startswith(r"\\"):
365 path = os.getcwd()
424 path = os.getcwd()
366 # change to c drive (cannot be on UNC-share when issuing os.system,
425 # change to c drive (cannot be on UNC-share when issuing os.system,
367 # as cmd.exe cannot handle UNC addresses)
426 # as cmd.exe cannot handle UNC addresses)
368 os.chdir("c:")
427 os.chdir("c:")
369 # issue pushd to the UNC-share and then run the command
428 # issue pushd to the UNC-share and then run the command
370 try:
429 try:
371 shell_ori('"pushd %s&&"'%path+cmd,verbose,debug,header)
430 shell_ori('"pushd %s&&"'%path+cmd,verbose,debug,header)
372 finally:
431 finally:
373 os.chdir(path)
432 os.chdir(path)
374 else:
433 else:
375 shell_ori(cmd,verbose,debug,header)
434 shell_ori(cmd,verbose,debug,header)
376
435
377 shell.__doc__ = shell_ori.__doc__
436 shell.__doc__ = shell_ori.__doc__
378
437
379 def getoutput(cmd,verbose=0,debug=0,header='',split=0):
438 def getoutput(cmd,verbose=0,debug=0,header='',split=0):
380 """Dummy substitute for perl's backquotes.
439 """Dummy substitute for perl's backquotes.
381
440
382 Executes a command and returns the output.
441 Executes a command and returns the output.
383
442
384 Accepts the same arguments as system(), plus:
443 Accepts the same arguments as system(), plus:
385
444
386 - split(0): if true, the output is returned as a list split on newlines.
445 - split(0): if true, the output is returned as a list split on newlines.
387
446
388 Note: a stateful version of this function is available through the
447 Note: a stateful version of this function is available through the
389 SystemExec class.
448 SystemExec class.
390
449
391 This is pretty much deprecated and rarely used,
450 This is pretty much deprecated and rarely used,
392 genutils.getoutputerror may be what you need.
451 genutils.getoutputerror may be what you need.
393
452
394 """
453 """
395
454
396 if verbose or debug: print header+cmd
455 if verbose or debug: print header+cmd
397 if not debug:
456 if not debug:
398 pipe = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE).stdout
457 pipe = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE).stdout
399 output = pipe.read()
458 output = pipe.read()
400 # stipping last \n is here for backwards compat.
459 # stipping last \n is here for backwards compat.
401 if output.endswith('\n'):
460 if output.endswith('\n'):
402 output = output[:-1]
461 output = output[:-1]
403 if split:
462 if split:
404 return output.split('\n')
463 return output.split('\n')
405 else:
464 else:
406 return output
465 return output
407
466
408 def getoutputerror(cmd,verbose=0,debug=0,header='',split=0):
467 def getoutputerror(cmd,verbose=0,debug=0,header='',split=0):
409 """Return (standard output,standard error) of executing cmd in a shell.
468 """Return (standard output,standard error) of executing cmd in a shell.
410
469
411 Accepts the same arguments as system(), plus:
470 Accepts the same arguments as system(), plus:
412
471
413 - split(0): if true, each of stdout/err is returned as a list split on
472 - split(0): if true, each of stdout/err is returned as a list split on
414 newlines.
473 newlines.
415
474
416 Note: a stateful version of this function is available through the
475 Note: a stateful version of this function is available through the
417 SystemExec class."""
476 SystemExec class."""
418
477
419 if verbose or debug: print header+cmd
478 if verbose or debug: print header+cmd
420 if not cmd:
479 if not cmd:
421 if split:
480 if split:
422 return [],[]
481 return [],[]
423 else:
482 else:
424 return '',''
483 return '',''
425 if not debug:
484 if not debug:
426 p = subprocess.Popen(cmd, shell=True,
485 p = subprocess.Popen(cmd, shell=True,
427 stdin=subprocess.PIPE,
486 stdin=subprocess.PIPE,
428 stdout=subprocess.PIPE,
487 stdout=subprocess.PIPE,
429 stderr=subprocess.PIPE,
488 stderr=subprocess.PIPE,
430 close_fds=True)
489 close_fds=True)
431 pin, pout, perr = (p.stdin, p.stdout, p.stderr)
490 pin, pout, perr = (p.stdin, p.stdout, p.stderr)
432
491
433 tout = pout.read().rstrip()
492 tout = pout.read().rstrip()
434 terr = perr.read().rstrip()
493 terr = perr.read().rstrip()
435 pin.close()
494 pin.close()
436 pout.close()
495 pout.close()
437 perr.close()
496 perr.close()
438 if split:
497 if split:
439 return tout.split('\n'),terr.split('\n')
498 return tout.split('\n'),terr.split('\n')
440 else:
499 else:
441 return tout,terr
500 return tout,terr
442
501
443 # for compatibility with older naming conventions
502 # for compatibility with older naming conventions
444 xsys = system
503 xsys = system
445 bq = getoutput
504 bq = getoutput
446
505
447 class SystemExec:
506 class SystemExec:
448 """Access the system and getoutput functions through a stateful interface.
507 """Access the system and getoutput functions through a stateful interface.
449
508
450 Note: here we refer to the system and getoutput functions from this
509 Note: here we refer to the system and getoutput functions from this
451 library, not the ones from the standard python library.
510 library, not the ones from the standard python library.
452
511
453 This class offers the system and getoutput functions as methods, but the
512 This class offers the system and getoutput functions as methods, but the
454 verbose, debug and header parameters can be set for the instance (at
513 verbose, debug and header parameters can be set for the instance (at
455 creation time or later) so that they don't need to be specified on each
514 creation time or later) so that they don't need to be specified on each
456 call.
515 call.
457
516
458 For efficiency reasons, there's no way to override the parameters on a
517 For efficiency reasons, there's no way to override the parameters on a
459 per-call basis other than by setting instance attributes. If you need
518 per-call basis other than by setting instance attributes. If you need
460 local overrides, it's best to directly call system() or getoutput().
519 local overrides, it's best to directly call system() or getoutput().
461
520
462 The following names are provided as alternate options:
521 The following names are provided as alternate options:
463 - xsys: alias to system
522 - xsys: alias to system
464 - bq: alias to getoutput
523 - bq: alias to getoutput
465
524
466 An instance can then be created as:
525 An instance can then be created as:
467 >>> sysexec = SystemExec(verbose=1,debug=0,header='Calling: ')
526 >>> sysexec = SystemExec(verbose=1,debug=0,header='Calling: ')
468 """
527 """
469
528
470 def __init__(self,verbose=0,debug=0,header='',split=0):
529 def __init__(self,verbose=0,debug=0,header='',split=0):
471 """Specify the instance's values for verbose, debug and header."""
530 """Specify the instance's values for verbose, debug and header."""
472 setattr_list(self,'verbose debug header split')
531 setattr_list(self,'verbose debug header split')
473
532
474 def system(self,cmd):
533 def system(self,cmd):
475 """Stateful interface to system(), with the same keyword parameters."""
534 """Stateful interface to system(), with the same keyword parameters."""
476
535
477 system(cmd,self.verbose,self.debug,self.header)
536 system(cmd,self.verbose,self.debug,self.header)
478
537
479 def shell(self,cmd):
538 def shell(self,cmd):
480 """Stateful interface to shell(), with the same keyword parameters."""
539 """Stateful interface to shell(), with the same keyword parameters."""
481
540
482 shell(cmd,self.verbose,self.debug,self.header)
541 shell(cmd,self.verbose,self.debug,self.header)
483
542
484 xsys = system # alias
543 xsys = system # alias
485
544
486 def getoutput(self,cmd):
545 def getoutput(self,cmd):
487 """Stateful interface to getoutput()."""
546 """Stateful interface to getoutput()."""
488
547
489 return getoutput(cmd,self.verbose,self.debug,self.header,self.split)
548 return getoutput(cmd,self.verbose,self.debug,self.header,self.split)
490
549
491 def getoutputerror(self,cmd):
550 def getoutputerror(self,cmd):
492 """Stateful interface to getoutputerror()."""
551 """Stateful interface to getoutputerror()."""
493
552
494 return getoutputerror(cmd,self.verbose,self.debug,self.header,self.split)
553 return getoutputerror(cmd,self.verbose,self.debug,self.header,self.split)
495
554
496 bq = getoutput # alias
555 bq = getoutput # alias
497
556
498 #-----------------------------------------------------------------------------
557 #-----------------------------------------------------------------------------
499 def mutex_opts(dict,ex_op):
558 def mutex_opts(dict,ex_op):
500 """Check for presence of mutually exclusive keys in a dict.
559 """Check for presence of mutually exclusive keys in a dict.
501
560
502 Call: mutex_opts(dict,[[op1a,op1b],[op2a,op2b]...]"""
561 Call: mutex_opts(dict,[[op1a,op1b],[op2a,op2b]...]"""
503 for op1,op2 in ex_op:
562 for op1,op2 in ex_op:
504 if op1 in dict and op2 in dict:
563 if op1 in dict and op2 in dict:
505 raise ValueError,'\n*** ERROR in Arguments *** '\
564 raise ValueError,'\n*** ERROR in Arguments *** '\
506 'Options '+op1+' and '+op2+' are mutually exclusive.'
565 'Options '+op1+' and '+op2+' are mutually exclusive.'
507
566
508 #-----------------------------------------------------------------------------
567 #-----------------------------------------------------------------------------
509 def get_py_filename(name):
568 def get_py_filename(name):
510 """Return a valid python filename in the current directory.
569 """Return a valid python filename in the current directory.
511
570
512 If the given name is not a file, it adds '.py' and searches again.
571 If the given name is not a file, it adds '.py' and searches again.
513 Raises IOError with an informative message if the file isn't found."""
572 Raises IOError with an informative message if the file isn't found."""
514
573
515 name = os.path.expanduser(name)
574 name = os.path.expanduser(name)
516 if not os.path.isfile(name) and not name.endswith('.py'):
575 if not os.path.isfile(name) and not name.endswith('.py'):
517 name += '.py'
576 name += '.py'
518 if os.path.isfile(name):
577 if os.path.isfile(name):
519 return name
578 return name
520 else:
579 else:
521 raise IOError,'File `%s` not found.' % name
580 raise IOError,'File `%s` not found.' % name
522
581
523 #-----------------------------------------------------------------------------
582 #-----------------------------------------------------------------------------
524
583
525
584
526 def filefind(filename, path_dirs=None):
585 def filefind(filename, path_dirs=None):
527 """Find a file by looking through a sequence of paths.
586 """Find a file by looking through a sequence of paths.
528
587
529 This iterates through a sequence of paths looking for a file and returns
588 This iterates through a sequence of paths looking for a file and returns
530 the full, absolute path of the first occurence of the file. If no set of
589 the full, absolute path of the first occurence of the file. If no set of
531 path dirs is given, the filename is tested as is, after running through
590 path dirs is given, the filename is tested as is, after running through
532 :func:`expandvars` and :func:`expanduser`. Thus a simple call::
591 :func:`expandvars` and :func:`expanduser`. Thus a simple call::
533
592
534 filefind('myfile.txt')
593 filefind('myfile.txt')
535
594
536 will find the file in the current working dir, but::
595 will find the file in the current working dir, but::
537
596
538 filefind('~/myfile.txt')
597 filefind('~/myfile.txt')
539
598
540 Will find the file in the users home directory. This function does not
599 Will find the file in the users home directory. This function does not
541 automatically try any paths, such as the cwd or the user's home directory.
600 automatically try any paths, such as the cwd or the user's home directory.
542
601
543 Parameters
602 Parameters
544 ----------
603 ----------
545 filename : str
604 filename : str
546 The filename to look for.
605 The filename to look for.
547 path_dirs : str, None or sequence of str
606 path_dirs : str, None or sequence of str
548 The sequence of paths to look for the file in. If None, the filename
607 The sequence of paths to look for the file in. If None, the filename
549 need to be absolute or be in the cwd. If a string, the string is
608 need to be absolute or be in the cwd. If a string, the string is
550 put into a sequence and the searched. If a sequence, walk through
609 put into a sequence and the searched. If a sequence, walk through
551 each element and join with ``filename``, calling :func:`expandvars`
610 each element and join with ``filename``, calling :func:`expandvars`
552 and :func:`expanduser` before testing for existence.
611 and :func:`expanduser` before testing for existence.
553
612
554 Returns
613 Returns
555 -------
614 -------
556 Raises :exc:`IOError` or returns absolute path to file.
615 Raises :exc:`IOError` or returns absolute path to file.
557 """
616 """
558 if path_dirs is None:
617 if path_dirs is None:
559 path_dirs = ("",)
618 path_dirs = ("",)
560 elif isinstance(path_dirs, basestring):
619 elif isinstance(path_dirs, basestring):
561 path_dirs = (path_dirs,)
620 path_dirs = (path_dirs,)
562 for path in path_dirs:
621 for path in path_dirs:
563 if path == '.': path = os.getcwd()
622 if path == '.': path = os.getcwd()
564 testname = expand_path(os.path.join(path, filename))
623 testname = expand_path(os.path.join(path, filename))
565 if os.path.isfile(testname):
624 if os.path.isfile(testname):
566 return os.path.abspath(testname)
625 return os.path.abspath(testname)
567 raise IOError("File does not exist in any "
626 raise IOError("File does not exist in any "
568 "of the search paths: %r, %r" % \
627 "of the search paths: %r, %r" % \
569 (filename, path_dirs))
628 (filename, path_dirs))
570
629
571
630
572 #----------------------------------------------------------------------------
631 #----------------------------------------------------------------------------
573 def file_read(filename):
632 def file_read(filename):
574 """Read a file and close it. Returns the file source."""
633 """Read a file and close it. Returns the file source."""
575 fobj = open(filename,'r');
634 fobj = open(filename,'r');
576 source = fobj.read();
635 source = fobj.read();
577 fobj.close()
636 fobj.close()
578 return source
637 return source
579
638
580 def file_readlines(filename):
639 def file_readlines(filename):
581 """Read a file and close it. Returns the file source using readlines()."""
640 """Read a file and close it. Returns the file source using readlines()."""
582 fobj = open(filename,'r');
641 fobj = open(filename,'r');
583 lines = fobj.readlines();
642 lines = fobj.readlines();
584 fobj.close()
643 fobj.close()
585 return lines
644 return lines
586
645
587 #----------------------------------------------------------------------------
646 #----------------------------------------------------------------------------
588 def target_outdated(target,deps):
647 def target_outdated(target,deps):
589 """Determine whether a target is out of date.
648 """Determine whether a target is out of date.
590
649
591 target_outdated(target,deps) -> 1/0
650 target_outdated(target,deps) -> 1/0
592
651
593 deps: list of filenames which MUST exist.
652 deps: list of filenames which MUST exist.
594 target: single filename which may or may not exist.
653 target: single filename which may or may not exist.
595
654
596 If target doesn't exist or is older than any file listed in deps, return
655 If target doesn't exist or is older than any file listed in deps, return
597 true, otherwise return false.
656 true, otherwise return false.
598 """
657 """
599 try:
658 try:
600 target_time = os.path.getmtime(target)
659 target_time = os.path.getmtime(target)
601 except os.error:
660 except os.error:
602 return 1
661 return 1
603 for dep in deps:
662 for dep in deps:
604 dep_time = os.path.getmtime(dep)
663 dep_time = os.path.getmtime(dep)
605 if dep_time > target_time:
664 if dep_time > target_time:
606 #print "For target",target,"Dep failed:",dep # dbg
665 #print "For target",target,"Dep failed:",dep # dbg
607 #print "times (dep,tar):",dep_time,target_time # dbg
666 #print "times (dep,tar):",dep_time,target_time # dbg
608 return 1
667 return 1
609 return 0
668 return 0
610
669
611 #-----------------------------------------------------------------------------
670 #-----------------------------------------------------------------------------
612 def target_update(target,deps,cmd):
671 def target_update(target,deps,cmd):
613 """Update a target with a given command given a list of dependencies.
672 """Update a target with a given command given a list of dependencies.
614
673
615 target_update(target,deps,cmd) -> runs cmd if target is outdated.
674 target_update(target,deps,cmd) -> runs cmd if target is outdated.
616
675
617 This is just a wrapper around target_outdated() which calls the given
676 This is just a wrapper around target_outdated() which calls the given
618 command if target is outdated."""
677 command if target is outdated."""
619
678
620 if target_outdated(target,deps):
679 if target_outdated(target,deps):
621 xsys(cmd)
680 xsys(cmd)
622
681
623 #----------------------------------------------------------------------------
682 #----------------------------------------------------------------------------
624 def unquote_ends(istr):
683 def unquote_ends(istr):
625 """Remove a single pair of quotes from the endpoints of a string."""
684 """Remove a single pair of quotes from the endpoints of a string."""
626
685
627 if not istr:
686 if not istr:
628 return istr
687 return istr
629 if (istr[0]=="'" and istr[-1]=="'") or \
688 if (istr[0]=="'" and istr[-1]=="'") or \
630 (istr[0]=='"' and istr[-1]=='"'):
689 (istr[0]=='"' and istr[-1]=='"'):
631 return istr[1:-1]
690 return istr[1:-1]
632 else:
691 else:
633 return istr
692 return istr
634
693
635 #----------------------------------------------------------------------------
694 #----------------------------------------------------------------------------
636 def flag_calls(func):
695 def flag_calls(func):
637 """Wrap a function to detect and flag when it gets called.
696 """Wrap a function to detect and flag when it gets called.
638
697
639 This is a decorator which takes a function and wraps it in a function with
698 This is a decorator which takes a function and wraps it in a function with
640 a 'called' attribute. wrapper.called is initialized to False.
699 a 'called' attribute. wrapper.called is initialized to False.
641
700
642 The wrapper.called attribute is set to False right before each call to the
701 The wrapper.called attribute is set to False right before each call to the
643 wrapped function, so if the call fails it remains False. After the call
702 wrapped function, so if the call fails it remains False. After the call
644 completes, wrapper.called is set to True and the output is returned.
703 completes, wrapper.called is set to True and the output is returned.
645
704
646 Testing for truth in wrapper.called allows you to determine if a call to
705 Testing for truth in wrapper.called allows you to determine if a call to
647 func() was attempted and succeeded."""
706 func() was attempted and succeeded."""
648
707
649 def wrapper(*args,**kw):
708 def wrapper(*args,**kw):
650 wrapper.called = False
709 wrapper.called = False
651 out = func(*args,**kw)
710 out = func(*args,**kw)
652 wrapper.called = True
711 wrapper.called = True
653 return out
712 return out
654
713
655 wrapper.called = False
714 wrapper.called = False
656 wrapper.__doc__ = func.__doc__
715 wrapper.__doc__ = func.__doc__
657 return wrapper
716 return wrapper
658
717
659 #----------------------------------------------------------------------------
718 #----------------------------------------------------------------------------
660 def dhook_wrap(func,*a,**k):
719 def dhook_wrap(func,*a,**k):
661 """Wrap a function call in a sys.displayhook controller.
720 """Wrap a function call in a sys.displayhook controller.
662
721
663 Returns a wrapper around func which calls func, with all its arguments and
722 Returns a wrapper around func which calls func, with all its arguments and
664 keywords unmodified, using the default sys.displayhook. Since IPython
723 keywords unmodified, using the default sys.displayhook. Since IPython
665 modifies sys.displayhook, it breaks the behavior of certain systems that
724 modifies sys.displayhook, it breaks the behavior of certain systems that
666 rely on the default behavior, notably doctest.
725 rely on the default behavior, notably doctest.
667 """
726 """
668
727
669 def f(*a,**k):
728 def f(*a,**k):
670
729
671 dhook_s = sys.displayhook
730 dhook_s = sys.displayhook
672 sys.displayhook = sys.__displayhook__
731 sys.displayhook = sys.__displayhook__
673 try:
732 try:
674 out = func(*a,**k)
733 out = func(*a,**k)
675 finally:
734 finally:
676 sys.displayhook = dhook_s
735 sys.displayhook = dhook_s
677
736
678 return out
737 return out
679
738
680 f.__doc__ = func.__doc__
739 f.__doc__ = func.__doc__
681 return f
740 return f
682
741
683 #----------------------------------------------------------------------------
742 #----------------------------------------------------------------------------
684 def doctest_reload():
743 def doctest_reload():
685 """Properly reload doctest to reuse it interactively.
744 """Properly reload doctest to reuse it interactively.
686
745
687 This routine:
746 This routine:
688
747
689 - imports doctest but does NOT reload it (see below).
748 - imports doctest but does NOT reload it (see below).
690
749
691 - resets its global 'master' attribute to None, so that multiple uses of
750 - resets its global 'master' attribute to None, so that multiple uses of
692 the module interactively don't produce cumulative reports.
751 the module interactively don't produce cumulative reports.
693
752
694 - Monkeypatches its core test runner method to protect it from IPython's
753 - Monkeypatches its core test runner method to protect it from IPython's
695 modified displayhook. Doctest expects the default displayhook behavior
754 modified displayhook. Doctest expects the default displayhook behavior
696 deep down, so our modification breaks it completely. For this reason, a
755 deep down, so our modification breaks it completely. For this reason, a
697 hard monkeypatch seems like a reasonable solution rather than asking
756 hard monkeypatch seems like a reasonable solution rather than asking
698 users to manually use a different doctest runner when under IPython.
757 users to manually use a different doctest runner when under IPython.
699
758
700 Notes
759 Notes
701 -----
760 -----
702
761
703 This function *used to* reload doctest, but this has been disabled because
762 This function *used to* reload doctest, but this has been disabled because
704 reloading doctest unconditionally can cause massive breakage of other
763 reloading doctest unconditionally can cause massive breakage of other
705 doctest-dependent modules already in memory, such as those for IPython's
764 doctest-dependent modules already in memory, such as those for IPython's
706 own testing system. The name wasn't changed to avoid breaking people's
765 own testing system. The name wasn't changed to avoid breaking people's
707 code, but the reload call isn't actually made anymore."""
766 code, but the reload call isn't actually made anymore."""
708
767
709 import doctest
768 import doctest
710 doctest.master = None
769 doctest.master = None
711 doctest.DocTestRunner.run = dhook_wrap(doctest.DocTestRunner.run)
770 doctest.DocTestRunner.run = dhook_wrap(doctest.DocTestRunner.run)
712
771
713 #----------------------------------------------------------------------------
772 #----------------------------------------------------------------------------
714 class HomeDirError(Error):
773 class HomeDirError(Error):
715 pass
774 pass
716
775
717 def get_home_dir():
776 def get_home_dir():
718 """Return the closest possible equivalent to a 'home' directory.
777 """Return the closest possible equivalent to a 'home' directory.
719
778
720 * On POSIX, we try $HOME.
779 * On POSIX, we try $HOME.
721 * On Windows we try:
780 * On Windows we try:
722 - %HOMESHARE%
781 - %HOMESHARE%
723 - %HOMEDRIVE\%HOMEPATH%
782 - %HOMEDRIVE\%HOMEPATH%
724 - %USERPROFILE%
783 - %USERPROFILE%
725 - Registry hack
784 - Registry hack
726 * On Dos C:\
785 * On Dos C:\
727
786
728 Currently only Posix and NT are implemented, a HomeDirError exception is
787 Currently only Posix and NT are implemented, a HomeDirError exception is
729 raised for all other OSes.
788 raised for all other OSes.
730 """
789 """
731
790
732 isdir = os.path.isdir
791 isdir = os.path.isdir
733 env = os.environ
792 env = os.environ
734
793
735 # first, check py2exe distribution root directory for _ipython.
794 # first, check py2exe distribution root directory for _ipython.
736 # This overrides all. Normally does not exist.
795 # This overrides all. Normally does not exist.
737
796
738 if hasattr(sys, "frozen"): #Is frozen by py2exe
797 if hasattr(sys, "frozen"): #Is frozen by py2exe
739 if '\\library.zip\\' in IPython.__file__.lower():#libraries compressed to zip-file
798 if '\\library.zip\\' in IPython.__file__.lower():#libraries compressed to zip-file
740 root, rest = IPython.__file__.lower().split('library.zip')
799 root, rest = IPython.__file__.lower().split('library.zip')
741 else:
800 else:
742 root=os.path.join(os.path.split(IPython.__file__)[0],"../../")
801 root=os.path.join(os.path.split(IPython.__file__)[0],"../../")
743 root=os.path.abspath(root).rstrip('\\')
802 root=os.path.abspath(root).rstrip('\\')
744 if isdir(os.path.join(root, '_ipython')):
803 if isdir(os.path.join(root, '_ipython')):
745 os.environ["IPYKITROOT"] = root
804 os.environ["IPYKITROOT"] = root
746 return root.decode(sys.getfilesystemencoding())
805 return root.decode(sys.getfilesystemencoding())
747
806
748 if os.name == 'posix':
807 if os.name == 'posix':
749 # Linux, Unix, AIX, OS X
808 # Linux, Unix, AIX, OS X
750 try:
809 try:
751 homedir = env['HOME']
810 homedir = env['HOME']
752 except KeyError:
811 except KeyError:
753 raise HomeDirError('Undefined $HOME, IPython cannot proceed.')
812 raise HomeDirError('Undefined $HOME, IPython cannot proceed.')
754 else:
813 else:
755 return homedir.decode(sys.getfilesystemencoding())
814 return homedir.decode(sys.getfilesystemencoding())
756 elif os.name == 'nt':
815 elif os.name == 'nt':
757 # Now for win9x, XP, Vista, 7?
816 # Now for win9x, XP, Vista, 7?
758 # For some strange reason all of these return 'nt' for os.name.
817 # For some strange reason all of these return 'nt' for os.name.
759 # First look for a network home directory. This will return the UNC
818 # First look for a network home directory. This will return the UNC
760 # path (\\server\\Users\%username%) not the mapped path (Z:\). This
819 # path (\\server\\Users\%username%) not the mapped path (Z:\). This
761 # is needed when running IPython on cluster where all paths have to
820 # is needed when running IPython on cluster where all paths have to
762 # be UNC.
821 # be UNC.
763 try:
822 try:
764 homedir = env['HOMESHARE']
823 homedir = env['HOMESHARE']
765 except KeyError:
824 except KeyError:
766 pass
825 pass
767 else:
826 else:
768 if isdir(homedir):
827 if isdir(homedir):
769 return homedir.decode(sys.getfilesystemencoding())
828 return homedir.decode(sys.getfilesystemencoding())
770
829
771 # Now look for a local home directory
830 # Now look for a local home directory
772 try:
831 try:
773 homedir = os.path.join(env['HOMEDRIVE'],env['HOMEPATH'])
832 homedir = os.path.join(env['HOMEDRIVE'],env['HOMEPATH'])
774 except KeyError:
833 except KeyError:
775 pass
834 pass
776 else:
835 else:
777 if isdir(homedir):
836 if isdir(homedir):
778 return homedir.decode(sys.getfilesystemencoding())
837 return homedir.decode(sys.getfilesystemencoding())
779
838
780 # Now the users profile directory
839 # Now the users profile directory
781 try:
840 try:
782 homedir = os.path.join(env['USERPROFILE'])
841 homedir = os.path.join(env['USERPROFILE'])
783 except KeyError:
842 except KeyError:
784 pass
843 pass
785 else:
844 else:
786 if isdir(homedir):
845 if isdir(homedir):
787 return homedir.decode(sys.getfilesystemencoding())
846 return homedir.decode(sys.getfilesystemencoding())
788
847
789 # Use the registry to get the 'My Documents' folder.
848 # Use the registry to get the 'My Documents' folder.
790 try:
849 try:
791 import _winreg as wreg
850 import _winreg as wreg
792 key = wreg.OpenKey(
851 key = wreg.OpenKey(
793 wreg.HKEY_CURRENT_USER,
852 wreg.HKEY_CURRENT_USER,
794 "Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders"
853 "Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders"
795 )
854 )
796 homedir = wreg.QueryValueEx(key,'Personal')[0]
855 homedir = wreg.QueryValueEx(key,'Personal')[0]
797 key.Close()
856 key.Close()
798 except:
857 except:
799 pass
858 pass
800 else:
859 else:
801 if isdir(homedir):
860 if isdir(homedir):
802 return homedir.decode(sys.getfilesystemencoding())
861 return homedir.decode(sys.getfilesystemencoding())
803
862
804 # If all else fails, raise HomeDirError
863 # If all else fails, raise HomeDirError
805 raise HomeDirError('No valid home directory could be found')
864 raise HomeDirError('No valid home directory could be found')
806 elif os.name == 'dos':
865 elif os.name == 'dos':
807 # Desperate, may do absurd things in classic MacOS. May work under DOS.
866 # Desperate, may do absurd things in classic MacOS. May work under DOS.
808 return 'C:\\'.decode(sys.getfilesystemencoding())
867 return 'C:\\'.decode(sys.getfilesystemencoding())
809 else:
868 else:
810 raise HomeDirError('No valid home directory could be found for your OS')
869 raise HomeDirError('No valid home directory could be found for your OS')
811
870
812
871
813 def get_ipython_dir():
872 def get_ipython_dir():
814 """Get the IPython directory for this platform and user.
873 """Get the IPython directory for this platform and user.
815
874
816 This uses the logic in `get_home_dir` to find the home directory
875 This uses the logic in `get_home_dir` to find the home directory
817 and the adds .ipython to the end of the path.
876 and the adds .ipython to the end of the path.
818 """
877 """
819 ipdir_def = '.ipython'
878 ipdir_def = '.ipython'
820 home_dir = get_home_dir()
879 home_dir = get_home_dir()
821 ipdir = os.environ.get(
880 ipdir = os.environ.get(
822 'IPYTHON_DIR', os.environ.get(
881 'IPYTHON_DIR', os.environ.get(
823 'IPYTHONDIR', os.path.join(home_dir, ipdir_def)
882 'IPYTHONDIR', os.path.join(home_dir, ipdir_def)
824 )
883 )
825 )
884 )
826 return ipdir.decode(sys.getfilesystemencoding())
885 return ipdir.decode(sys.getfilesystemencoding())
827
886
828
887
829 def get_ipython_package_dir():
888 def get_ipython_package_dir():
830 """Get the base directory where IPython itself is installed."""
889 """Get the base directory where IPython itself is installed."""
831 ipdir = os.path.dirname(IPython.__file__)
890 ipdir = os.path.dirname(IPython.__file__)
832 return ipdir.decode(sys.getfilesystemencoding())
891 return ipdir.decode(sys.getfilesystemencoding())
833
892
834
893
835 #****************************************************************************
894 #****************************************************************************
836 # strings and text
895 # strings and text
837
896
838 class LSString(str):
897 class LSString(str):
839 """String derivative with a special access attributes.
898 """String derivative with a special access attributes.
840
899
841 These are normal strings, but with the special attributes:
900 These are normal strings, but with the special attributes:
842
901
843 .l (or .list) : value as list (split on newlines).
902 .l (or .list) : value as list (split on newlines).
844 .n (or .nlstr): original value (the string itself).
903 .n (or .nlstr): original value (the string itself).
845 .s (or .spstr): value as whitespace-separated string.
904 .s (or .spstr): value as whitespace-separated string.
846 .p (or .paths): list of path objects
905 .p (or .paths): list of path objects
847
906
848 Any values which require transformations are computed only once and
907 Any values which require transformations are computed only once and
849 cached.
908 cached.
850
909
851 Such strings are very useful to efficiently interact with the shell, which
910 Such strings are very useful to efficiently interact with the shell, which
852 typically only understands whitespace-separated options for commands."""
911 typically only understands whitespace-separated options for commands."""
853
912
854 def get_list(self):
913 def get_list(self):
855 try:
914 try:
856 return self.__list
915 return self.__list
857 except AttributeError:
916 except AttributeError:
858 self.__list = self.split('\n')
917 self.__list = self.split('\n')
859 return self.__list
918 return self.__list
860
919
861 l = list = property(get_list)
920 l = list = property(get_list)
862
921
863 def get_spstr(self):
922 def get_spstr(self):
864 try:
923 try:
865 return self.__spstr
924 return self.__spstr
866 except AttributeError:
925 except AttributeError:
867 self.__spstr = self.replace('\n',' ')
926 self.__spstr = self.replace('\n',' ')
868 return self.__spstr
927 return self.__spstr
869
928
870 s = spstr = property(get_spstr)
929 s = spstr = property(get_spstr)
871
930
872 def get_nlstr(self):
931 def get_nlstr(self):
873 return self
932 return self
874
933
875 n = nlstr = property(get_nlstr)
934 n = nlstr = property(get_nlstr)
876
935
877 def get_paths(self):
936 def get_paths(self):
878 try:
937 try:
879 return self.__paths
938 return self.__paths
880 except AttributeError:
939 except AttributeError:
881 self.__paths = [path(p) for p in self.split('\n') if os.path.exists(p)]
940 self.__paths = [path(p) for p in self.split('\n') if os.path.exists(p)]
882 return self.__paths
941 return self.__paths
883
942
884 p = paths = property(get_paths)
943 p = paths = property(get_paths)
885
944
886 def print_lsstring(arg):
945 def print_lsstring(arg):
887 """ Prettier (non-repr-like) and more informative printer for LSString """
946 """ Prettier (non-repr-like) and more informative printer for LSString """
888 print "LSString (.p, .n, .l, .s available). Value:"
947 print "LSString (.p, .n, .l, .s available). Value:"
889 print arg
948 print arg
890
949
891 print_lsstring = result_display.when_type(LSString)(print_lsstring)
950 print_lsstring = result_display.when_type(LSString)(print_lsstring)
892
951
893 #----------------------------------------------------------------------------
952 #----------------------------------------------------------------------------
894 class SList(list):
953 class SList(list):
895 """List derivative with a special access attributes.
954 """List derivative with a special access attributes.
896
955
897 These are normal lists, but with the special attributes:
956 These are normal lists, but with the special attributes:
898
957
899 .l (or .list) : value as list (the list itself).
958 .l (or .list) : value as list (the list itself).
900 .n (or .nlstr): value as a string, joined on newlines.
959 .n (or .nlstr): value as a string, joined on newlines.
901 .s (or .spstr): value as a string, joined on spaces.
960 .s (or .spstr): value as a string, joined on spaces.
902 .p (or .paths): list of path objects
961 .p (or .paths): list of path objects
903
962
904 Any values which require transformations are computed only once and
963 Any values which require transformations are computed only once and
905 cached."""
964 cached."""
906
965
907 def get_list(self):
966 def get_list(self):
908 return self
967 return self
909
968
910 l = list = property(get_list)
969 l = list = property(get_list)
911
970
912 def get_spstr(self):
971 def get_spstr(self):
913 try:
972 try:
914 return self.__spstr
973 return self.__spstr
915 except AttributeError:
974 except AttributeError:
916 self.__spstr = ' '.join(self)
975 self.__spstr = ' '.join(self)
917 return self.__spstr
976 return self.__spstr
918
977
919 s = spstr = property(get_spstr)
978 s = spstr = property(get_spstr)
920
979
921 def get_nlstr(self):
980 def get_nlstr(self):
922 try:
981 try:
923 return self.__nlstr
982 return self.__nlstr
924 except AttributeError:
983 except AttributeError:
925 self.__nlstr = '\n'.join(self)
984 self.__nlstr = '\n'.join(self)
926 return self.__nlstr
985 return self.__nlstr
927
986
928 n = nlstr = property(get_nlstr)
987 n = nlstr = property(get_nlstr)
929
988
930 def get_paths(self):
989 def get_paths(self):
931 try:
990 try:
932 return self.__paths
991 return self.__paths
933 except AttributeError:
992 except AttributeError:
934 self.__paths = [path(p) for p in self if os.path.exists(p)]
993 self.__paths = [path(p) for p in self if os.path.exists(p)]
935 return self.__paths
994 return self.__paths
936
995
937 p = paths = property(get_paths)
996 p = paths = property(get_paths)
938
997
939 def grep(self, pattern, prune = False, field = None):
998 def grep(self, pattern, prune = False, field = None):
940 """ Return all strings matching 'pattern' (a regex or callable)
999 """ Return all strings matching 'pattern' (a regex or callable)
941
1000
942 This is case-insensitive. If prune is true, return all items
1001 This is case-insensitive. If prune is true, return all items
943 NOT matching the pattern.
1002 NOT matching the pattern.
944
1003
945 If field is specified, the match must occur in the specified
1004 If field is specified, the match must occur in the specified
946 whitespace-separated field.
1005 whitespace-separated field.
947
1006
948 Examples::
1007 Examples::
949
1008
950 a.grep( lambda x: x.startswith('C') )
1009 a.grep( lambda x: x.startswith('C') )
951 a.grep('Cha.*log', prune=1)
1010 a.grep('Cha.*log', prune=1)
952 a.grep('chm', field=-1)
1011 a.grep('chm', field=-1)
953 """
1012 """
954
1013
955 def match_target(s):
1014 def match_target(s):
956 if field is None:
1015 if field is None:
957 return s
1016 return s
958 parts = s.split()
1017 parts = s.split()
959 try:
1018 try:
960 tgt = parts[field]
1019 tgt = parts[field]
961 return tgt
1020 return tgt
962 except IndexError:
1021 except IndexError:
963 return ""
1022 return ""
964
1023
965 if isinstance(pattern, basestring):
1024 if isinstance(pattern, basestring):
966 pred = lambda x : re.search(pattern, x, re.IGNORECASE)
1025 pred = lambda x : re.search(pattern, x, re.IGNORECASE)
967 else:
1026 else:
968 pred = pattern
1027 pred = pattern
969 if not prune:
1028 if not prune:
970 return SList([el for el in self if pred(match_target(el))])
1029 return SList([el for el in self if pred(match_target(el))])
971 else:
1030 else:
972 return SList([el for el in self if not pred(match_target(el))])
1031 return SList([el for el in self if not pred(match_target(el))])
973 def fields(self, *fields):
1032 def fields(self, *fields):
974 """ Collect whitespace-separated fields from string list
1033 """ Collect whitespace-separated fields from string list
975
1034
976 Allows quick awk-like usage of string lists.
1035 Allows quick awk-like usage of string lists.
977
1036
978 Example data (in var a, created by 'a = !ls -l')::
1037 Example data (in var a, created by 'a = !ls -l')::
979 -rwxrwxrwx 1 ville None 18 Dec 14 2006 ChangeLog
1038 -rwxrwxrwx 1 ville None 18 Dec 14 2006 ChangeLog
980 drwxrwxrwx+ 6 ville None 0 Oct 24 18:05 IPython
1039 drwxrwxrwx+ 6 ville None 0 Oct 24 18:05 IPython
981
1040
982 a.fields(0) is ['-rwxrwxrwx', 'drwxrwxrwx+']
1041 a.fields(0) is ['-rwxrwxrwx', 'drwxrwxrwx+']
983 a.fields(1,0) is ['1 -rwxrwxrwx', '6 drwxrwxrwx+']
1042 a.fields(1,0) is ['1 -rwxrwxrwx', '6 drwxrwxrwx+']
984 (note the joining by space).
1043 (note the joining by space).
985 a.fields(-1) is ['ChangeLog', 'IPython']
1044 a.fields(-1) is ['ChangeLog', 'IPython']
986
1045
987 IndexErrors are ignored.
1046 IndexErrors are ignored.
988
1047
989 Without args, fields() just split()'s the strings.
1048 Without args, fields() just split()'s the strings.
990 """
1049 """
991 if len(fields) == 0:
1050 if len(fields) == 0:
992 return [el.split() for el in self]
1051 return [el.split() for el in self]
993
1052
994 res = SList()
1053 res = SList()
995 for el in [f.split() for f in self]:
1054 for el in [f.split() for f in self]:
996 lineparts = []
1055 lineparts = []
997
1056
998 for fd in fields:
1057 for fd in fields:
999 try:
1058 try:
1000 lineparts.append(el[fd])
1059 lineparts.append(el[fd])
1001 except IndexError:
1060 except IndexError:
1002 pass
1061 pass
1003 if lineparts:
1062 if lineparts:
1004 res.append(" ".join(lineparts))
1063 res.append(" ".join(lineparts))
1005
1064
1006 return res
1065 return res
1007 def sort(self,field= None, nums = False):
1066 def sort(self,field= None, nums = False):
1008 """ sort by specified fields (see fields())
1067 """ sort by specified fields (see fields())
1009
1068
1010 Example::
1069 Example::
1011 a.sort(1, nums = True)
1070 a.sort(1, nums = True)
1012
1071
1013 Sorts a by second field, in numerical order (so that 21 > 3)
1072 Sorts a by second field, in numerical order (so that 21 > 3)
1014
1073
1015 """
1074 """
1016
1075
1017 #decorate, sort, undecorate
1076 #decorate, sort, undecorate
1018 if field is not None:
1077 if field is not None:
1019 dsu = [[SList([line]).fields(field), line] for line in self]
1078 dsu = [[SList([line]).fields(field), line] for line in self]
1020 else:
1079 else:
1021 dsu = [[line, line] for line in self]
1080 dsu = [[line, line] for line in self]
1022 if nums:
1081 if nums:
1023 for i in range(len(dsu)):
1082 for i in range(len(dsu)):
1024 numstr = "".join([ch for ch in dsu[i][0] if ch.isdigit()])
1083 numstr = "".join([ch for ch in dsu[i][0] if ch.isdigit()])
1025 try:
1084 try:
1026 n = int(numstr)
1085 n = int(numstr)
1027 except ValueError:
1086 except ValueError:
1028 n = 0;
1087 n = 0;
1029 dsu[i][0] = n
1088 dsu[i][0] = n
1030
1089
1031
1090
1032 dsu.sort()
1091 dsu.sort()
1033 return SList([t[1] for t in dsu])
1092 return SList([t[1] for t in dsu])
1034
1093
1035 def print_slist(arg):
1094 def print_slist(arg):
1036 """ Prettier (non-repr-like) and more informative printer for SList """
1095 """ Prettier (non-repr-like) and more informative printer for SList """
1037 print "SList (.p, .n, .l, .s, .grep(), .fields(), sort() available):"
1096 print "SList (.p, .n, .l, .s, .grep(), .fields(), sort() available):"
1038 if hasattr(arg, 'hideonce') and arg.hideonce:
1097 if hasattr(arg, 'hideonce') and arg.hideonce:
1039 arg.hideonce = False
1098 arg.hideonce = False
1040 return
1099 return
1041
1100
1042 nlprint(arg)
1101 nlprint(arg)
1043
1102
1044 print_slist = result_display.when_type(SList)(print_slist)
1103 print_slist = result_display.when_type(SList)(print_slist)
1045
1104
1046
1105
1047
1106
1048 #----------------------------------------------------------------------------
1107 #----------------------------------------------------------------------------
1049 def esc_quotes(strng):
1108 def esc_quotes(strng):
1050 """Return the input string with single and double quotes escaped out"""
1109 """Return the input string with single and double quotes escaped out"""
1051
1110
1052 return strng.replace('"','\\"').replace("'","\\'")
1111 return strng.replace('"','\\"').replace("'","\\'")
1053
1112
1054 #----------------------------------------------------------------------------
1113 #----------------------------------------------------------------------------
1055 def make_quoted_expr(s):
1114 def make_quoted_expr(s):
1056 """Return string s in appropriate quotes, using raw string if possible.
1115 """Return string s in appropriate quotes, using raw string if possible.
1057
1116
1058 XXX - example removed because it caused encoding errors in documentation
1117 XXX - example removed because it caused encoding errors in documentation
1059 generation. We need a new example that doesn't contain invalid chars.
1118 generation. We need a new example that doesn't contain invalid chars.
1060
1119
1061 Note the use of raw string and padding at the end to allow trailing
1120 Note the use of raw string and padding at the end to allow trailing
1062 backslash.
1121 backslash.
1063 """
1122 """
1064
1123
1065 tail = ''
1124 tail = ''
1066 tailpadding = ''
1125 tailpadding = ''
1067 raw = ''
1126 raw = ''
1068 if "\\" in s:
1127 if "\\" in s:
1069 raw = 'r'
1128 raw = 'r'
1070 if s.endswith('\\'):
1129 if s.endswith('\\'):
1071 tail = '[:-1]'
1130 tail = '[:-1]'
1072 tailpadding = '_'
1131 tailpadding = '_'
1073 if '"' not in s:
1132 if '"' not in s:
1074 quote = '"'
1133 quote = '"'
1075 elif "'" not in s:
1134 elif "'" not in s:
1076 quote = "'"
1135 quote = "'"
1077 elif '"""' not in s and not s.endswith('"'):
1136 elif '"""' not in s and not s.endswith('"'):
1078 quote = '"""'
1137 quote = '"""'
1079 elif "'''" not in s and not s.endswith("'"):
1138 elif "'''" not in s and not s.endswith("'"):
1080 quote = "'''"
1139 quote = "'''"
1081 else:
1140 else:
1082 # give up, backslash-escaped string will do
1141 # give up, backslash-escaped string will do
1083 return '"%s"' % esc_quotes(s)
1142 return '"%s"' % esc_quotes(s)
1084 res = raw + quote + s + tailpadding + quote + tail
1143 res = raw + quote + s + tailpadding + quote + tail
1085 return res
1144 return res
1086
1145
1087
1146
1088 #----------------------------------------------------------------------------
1147 #----------------------------------------------------------------------------
1089 def raw_input_multi(header='', ps1='==> ', ps2='..> ',terminate_str = '.'):
1148 def raw_input_multi(header='', ps1='==> ', ps2='..> ',terminate_str = '.'):
1090 """Take multiple lines of input.
1149 """Take multiple lines of input.
1091
1150
1092 A list with each line of input as a separate element is returned when a
1151 A list with each line of input as a separate element is returned when a
1093 termination string is entered (defaults to a single '.'). Input can also
1152 termination string is entered (defaults to a single '.'). Input can also
1094 terminate via EOF (^D in Unix, ^Z-RET in Windows).
1153 terminate via EOF (^D in Unix, ^Z-RET in Windows).
1095
1154
1096 Lines of input which end in \\ are joined into single entries (and a
1155 Lines of input which end in \\ are joined into single entries (and a
1097 secondary continuation prompt is issued as long as the user terminates
1156 secondary continuation prompt is issued as long as the user terminates
1098 lines with \\). This allows entering very long strings which are still
1157 lines with \\). This allows entering very long strings which are still
1099 meant to be treated as single entities.
1158 meant to be treated as single entities.
1100 """
1159 """
1101
1160
1102 try:
1161 try:
1103 if header:
1162 if header:
1104 header += '\n'
1163 header += '\n'
1105 lines = [raw_input(header + ps1)]
1164 lines = [raw_input(header + ps1)]
1106 except EOFError:
1165 except EOFError:
1107 return []
1166 return []
1108 terminate = [terminate_str]
1167 terminate = [terminate_str]
1109 try:
1168 try:
1110 while lines[-1:] != terminate:
1169 while lines[-1:] != terminate:
1111 new_line = raw_input(ps1)
1170 new_line = raw_input(ps1)
1112 while new_line.endswith('\\'):
1171 while new_line.endswith('\\'):
1113 new_line = new_line[:-1] + raw_input(ps2)
1172 new_line = new_line[:-1] + raw_input(ps2)
1114 lines.append(new_line)
1173 lines.append(new_line)
1115
1174
1116 return lines[:-1] # don't return the termination command
1175 return lines[:-1] # don't return the termination command
1117 except EOFError:
1176 except EOFError:
1118 print
1177 print
1119 return lines
1178 return lines
1120
1179
1121 #----------------------------------------------------------------------------
1180 #----------------------------------------------------------------------------
1122 def raw_input_ext(prompt='', ps2='... '):
1181 def raw_input_ext(prompt='', ps2='... '):
1123 """Similar to raw_input(), but accepts extended lines if input ends with \\."""
1182 """Similar to raw_input(), but accepts extended lines if input ends with \\."""
1124
1183
1125 line = raw_input(prompt)
1184 line = raw_input(prompt)
1126 while line.endswith('\\'):
1185 while line.endswith('\\'):
1127 line = line[:-1] + raw_input(ps2)
1186 line = line[:-1] + raw_input(ps2)
1128 return line
1187 return line
1129
1188
1130 #----------------------------------------------------------------------------
1189 #----------------------------------------------------------------------------
1131 def ask_yes_no(prompt,default=None):
1190 def ask_yes_no(prompt,default=None):
1132 """Asks a question and returns a boolean (y/n) answer.
1191 """Asks a question and returns a boolean (y/n) answer.
1133
1192
1134 If default is given (one of 'y','n'), it is used if the user input is
1193 If default is given (one of 'y','n'), it is used if the user input is
1135 empty. Otherwise the question is repeated until an answer is given.
1194 empty. Otherwise the question is repeated until an answer is given.
1136
1195
1137 An EOF is treated as the default answer. If there is no default, an
1196 An EOF is treated as the default answer. If there is no default, an
1138 exception is raised to prevent infinite loops.
1197 exception is raised to prevent infinite loops.
1139
1198
1140 Valid answers are: y/yes/n/no (match is not case sensitive)."""
1199 Valid answers are: y/yes/n/no (match is not case sensitive)."""
1141
1200
1142 answers = {'y':True,'n':False,'yes':True,'no':False}
1201 answers = {'y':True,'n':False,'yes':True,'no':False}
1143 ans = None
1202 ans = None
1144 while ans not in answers.keys():
1203 while ans not in answers.keys():
1145 try:
1204 try:
1146 ans = raw_input(prompt+' ').lower()
1205 ans = raw_input(prompt+' ').lower()
1147 if not ans: # response was an empty string
1206 if not ans: # response was an empty string
1148 ans = default
1207 ans = default
1149 except KeyboardInterrupt:
1208 except KeyboardInterrupt:
1150 pass
1209 pass
1151 except EOFError:
1210 except EOFError:
1152 if default in answers.keys():
1211 if default in answers.keys():
1153 ans = default
1212 ans = default
1154 print
1213 print
1155 else:
1214 else:
1156 raise
1215 raise
1157
1216
1158 return answers[ans]
1217 return answers[ans]
1159
1218
1160 #----------------------------------------------------------------------------
1219 #----------------------------------------------------------------------------
1161 class EvalDict:
1220 class EvalDict:
1162 """
1221 """
1163 Emulate a dict which evaluates its contents in the caller's frame.
1222 Emulate a dict which evaluates its contents in the caller's frame.
1164
1223
1165 Usage:
1224 Usage:
1166 >>> number = 19
1225 >>> number = 19
1167
1226
1168 >>> text = "python"
1227 >>> text = "python"
1169
1228
1170 >>> print "%(text.capitalize())s %(number/9.0).1f rules!" % EvalDict()
1229 >>> print "%(text.capitalize())s %(number/9.0).1f rules!" % EvalDict()
1171 Python 2.1 rules!
1230 Python 2.1 rules!
1172 """
1231 """
1173
1232
1174 # This version is due to sismex01@hebmex.com on c.l.py, and is basically a
1233 # This version is due to sismex01@hebmex.com on c.l.py, and is basically a
1175 # modified (shorter) version of:
1234 # modified (shorter) version of:
1176 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66018 by
1235 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66018 by
1177 # Skip Montanaro (skip@pobox.com).
1236 # Skip Montanaro (skip@pobox.com).
1178
1237
1179 def __getitem__(self, name):
1238 def __getitem__(self, name):
1180 frame = sys._getframe(1)
1239 frame = sys._getframe(1)
1181 return eval(name, frame.f_globals, frame.f_locals)
1240 return eval(name, frame.f_globals, frame.f_locals)
1182
1241
1183 EvalString = EvalDict # for backwards compatibility
1242 EvalString = EvalDict # for backwards compatibility
1184 #----------------------------------------------------------------------------
1243 #----------------------------------------------------------------------------
1185 def qw(words,flat=0,sep=None,maxsplit=-1):
1244 def qw(words,flat=0,sep=None,maxsplit=-1):
1186 """Similar to Perl's qw() operator, but with some more options.
1245 """Similar to Perl's qw() operator, but with some more options.
1187
1246
1188 qw(words,flat=0,sep=' ',maxsplit=-1) -> words.split(sep,maxsplit)
1247 qw(words,flat=0,sep=' ',maxsplit=-1) -> words.split(sep,maxsplit)
1189
1248
1190 words can also be a list itself, and with flat=1, the output will be
1249 words can also be a list itself, and with flat=1, the output will be
1191 recursively flattened.
1250 recursively flattened.
1192
1251
1193 Examples:
1252 Examples:
1194
1253
1195 >>> qw('1 2')
1254 >>> qw('1 2')
1196 ['1', '2']
1255 ['1', '2']
1197
1256
1198 >>> qw(['a b','1 2',['m n','p q']])
1257 >>> qw(['a b','1 2',['m n','p q']])
1199 [['a', 'b'], ['1', '2'], [['m', 'n'], ['p', 'q']]]
1258 [['a', 'b'], ['1', '2'], [['m', 'n'], ['p', 'q']]]
1200
1259
1201 >>> qw(['a b','1 2',['m n','p q']],flat=1)
1260 >>> qw(['a b','1 2',['m n','p q']],flat=1)
1202 ['a', 'b', '1', '2', 'm', 'n', 'p', 'q']
1261 ['a', 'b', '1', '2', 'm', 'n', 'p', 'q']
1203 """
1262 """
1204
1263
1205 if type(words) in StringTypes:
1264 if type(words) in StringTypes:
1206 return [word.strip() for word in words.split(sep,maxsplit)
1265 return [word.strip() for word in words.split(sep,maxsplit)
1207 if word and not word.isspace() ]
1266 if word and not word.isspace() ]
1208 if flat:
1267 if flat:
1209 return flatten(map(qw,words,[1]*len(words)))
1268 return flatten(map(qw,words,[1]*len(words)))
1210 return map(qw,words)
1269 return map(qw,words)
1211
1270
1212 #----------------------------------------------------------------------------
1271 #----------------------------------------------------------------------------
1213 def qwflat(words,sep=None,maxsplit=-1):
1272 def qwflat(words,sep=None,maxsplit=-1):
1214 """Calls qw(words) in flat mode. It's just a convenient shorthand."""
1273 """Calls qw(words) in flat mode. It's just a convenient shorthand."""
1215 return qw(words,1,sep,maxsplit)
1274 return qw(words,1,sep,maxsplit)
1216
1275
1217 #----------------------------------------------------------------------------
1276 #----------------------------------------------------------------------------
1218 def qw_lol(indata):
1277 def qw_lol(indata):
1219 """qw_lol('a b') -> [['a','b']],
1278 """qw_lol('a b') -> [['a','b']],
1220 otherwise it's just a call to qw().
1279 otherwise it's just a call to qw().
1221
1280
1222 We need this to make sure the modules_some keys *always* end up as a
1281 We need this to make sure the modules_some keys *always* end up as a
1223 list of lists."""
1282 list of lists."""
1224
1283
1225 if type(indata) in StringTypes:
1284 if type(indata) in StringTypes:
1226 return [qw(indata)]
1285 return [qw(indata)]
1227 else:
1286 else:
1228 return qw(indata)
1287 return qw(indata)
1229
1288
1230 #----------------------------------------------------------------------------
1289 #----------------------------------------------------------------------------
1231 def grep(pat,list,case=1):
1290 def grep(pat,list,case=1):
1232 """Simple minded grep-like function.
1291 """Simple minded grep-like function.
1233 grep(pat,list) returns occurrences of pat in list, None on failure.
1292 grep(pat,list) returns occurrences of pat in list, None on failure.
1234
1293
1235 It only does simple string matching, with no support for regexps. Use the
1294 It only does simple string matching, with no support for regexps. Use the
1236 option case=0 for case-insensitive matching."""
1295 option case=0 for case-insensitive matching."""
1237
1296
1238 # This is pretty crude. At least it should implement copying only references
1297 # This is pretty crude. At least it should implement copying only references
1239 # to the original data in case it's big. Now it copies the data for output.
1298 # to the original data in case it's big. Now it copies the data for output.
1240 out=[]
1299 out=[]
1241 if case:
1300 if case:
1242 for term in list:
1301 for term in list:
1243 if term.find(pat)>-1: out.append(term)
1302 if term.find(pat)>-1: out.append(term)
1244 else:
1303 else:
1245 lpat=pat.lower()
1304 lpat=pat.lower()
1246 for term in list:
1305 for term in list:
1247 if term.lower().find(lpat)>-1: out.append(term)
1306 if term.lower().find(lpat)>-1: out.append(term)
1248
1307
1249 if len(out): return out
1308 if len(out): return out
1250 else: return None
1309 else: return None
1251
1310
1252 #----------------------------------------------------------------------------
1311 #----------------------------------------------------------------------------
1253 def dgrep(pat,*opts):
1312 def dgrep(pat,*opts):
1254 """Return grep() on dir()+dir(__builtins__).
1313 """Return grep() on dir()+dir(__builtins__).
1255
1314
1256 A very common use of grep() when working interactively."""
1315 A very common use of grep() when working interactively."""
1257
1316
1258 return grep(pat,dir(__main__)+dir(__main__.__builtins__),*opts)
1317 return grep(pat,dir(__main__)+dir(__main__.__builtins__),*opts)
1259
1318
1260 #----------------------------------------------------------------------------
1319 #----------------------------------------------------------------------------
1261 def idgrep(pat):
1320 def idgrep(pat):
1262 """Case-insensitive dgrep()"""
1321 """Case-insensitive dgrep()"""
1263
1322
1264 return dgrep(pat,0)
1323 return dgrep(pat,0)
1265
1324
1266 #----------------------------------------------------------------------------
1325 #----------------------------------------------------------------------------
1267 def igrep(pat,list):
1326 def igrep(pat,list):
1268 """Synonym for case-insensitive grep."""
1327 """Synonym for case-insensitive grep."""
1269
1328
1270 return grep(pat,list,case=0)
1329 return grep(pat,list,case=0)
1271
1330
1272 #----------------------------------------------------------------------------
1331 #----------------------------------------------------------------------------
1273 def indent(str,nspaces=4,ntabs=0):
1332 def indent(str,nspaces=4,ntabs=0):
1274 """Indent a string a given number of spaces or tabstops.
1333 """Indent a string a given number of spaces or tabstops.
1275
1334
1276 indent(str,nspaces=4,ntabs=0) -> indent str by ntabs+nspaces.
1335 indent(str,nspaces=4,ntabs=0) -> indent str by ntabs+nspaces.
1277 """
1336 """
1278 if str is None:
1337 if str is None:
1279 return
1338 return
1280 ind = '\t'*ntabs+' '*nspaces
1339 ind = '\t'*ntabs+' '*nspaces
1281 outstr = '%s%s' % (ind,str.replace(os.linesep,os.linesep+ind))
1340 outstr = '%s%s' % (ind,str.replace(os.linesep,os.linesep+ind))
1282 if outstr.endswith(os.linesep+ind):
1341 if outstr.endswith(os.linesep+ind):
1283 return outstr[:-len(ind)]
1342 return outstr[:-len(ind)]
1284 else:
1343 else:
1285 return outstr
1344 return outstr
1286
1345
1287 #-----------------------------------------------------------------------------
1346 #-----------------------------------------------------------------------------
1288 def native_line_ends(filename,backup=1):
1347 def native_line_ends(filename,backup=1):
1289 """Convert (in-place) a file to line-ends native to the current OS.
1348 """Convert (in-place) a file to line-ends native to the current OS.
1290
1349
1291 If the optional backup argument is given as false, no backup of the
1350 If the optional backup argument is given as false, no backup of the
1292 original file is left. """
1351 original file is left. """
1293
1352
1294 backup_suffixes = {'posix':'~','dos':'.bak','nt':'.bak','mac':'.bak'}
1353 backup_suffixes = {'posix':'~','dos':'.bak','nt':'.bak','mac':'.bak'}
1295
1354
1296 bak_filename = filename + backup_suffixes[os.name]
1355 bak_filename = filename + backup_suffixes[os.name]
1297
1356
1298 original = open(filename).read()
1357 original = open(filename).read()
1299 shutil.copy2(filename,bak_filename)
1358 shutil.copy2(filename,bak_filename)
1300 try:
1359 try:
1301 new = open(filename,'wb')
1360 new = open(filename,'wb')
1302 new.write(os.linesep.join(original.splitlines()))
1361 new.write(os.linesep.join(original.splitlines()))
1303 new.write(os.linesep) # ALWAYS put an eol at the end of the file
1362 new.write(os.linesep) # ALWAYS put an eol at the end of the file
1304 new.close()
1363 new.close()
1305 except:
1364 except:
1306 os.rename(bak_filename,filename)
1365 os.rename(bak_filename,filename)
1307 if not backup:
1366 if not backup:
1308 try:
1367 try:
1309 os.remove(bak_filename)
1368 os.remove(bak_filename)
1310 except:
1369 except:
1311 pass
1370 pass
1312
1371
1313 #****************************************************************************
1372 #****************************************************************************
1314 # lists, dicts and structures
1373 # lists, dicts and structures
1315
1374
1316 def belong(candidates,checklist):
1375 def belong(candidates,checklist):
1317 """Check whether a list of items appear in a given list of options.
1376 """Check whether a list of items appear in a given list of options.
1318
1377
1319 Returns a list of 1 and 0, one for each candidate given."""
1378 Returns a list of 1 and 0, one for each candidate given."""
1320
1379
1321 return [x in checklist for x in candidates]
1380 return [x in checklist for x in candidates]
1322
1381
1323 #----------------------------------------------------------------------------
1382 #----------------------------------------------------------------------------
1324 def uniq_stable(elems):
1383 def uniq_stable(elems):
1325 """uniq_stable(elems) -> list
1384 """uniq_stable(elems) -> list
1326
1385
1327 Return from an iterable, a list of all the unique elements in the input,
1386 Return from an iterable, a list of all the unique elements in the input,
1328 but maintaining the order in which they first appear.
1387 but maintaining the order in which they first appear.
1329
1388
1330 A naive solution to this problem which just makes a dictionary with the
1389 A naive solution to this problem which just makes a dictionary with the
1331 elements as keys fails to respect the stability condition, since
1390 elements as keys fails to respect the stability condition, since
1332 dictionaries are unsorted by nature.
1391 dictionaries are unsorted by nature.
1333
1392
1334 Note: All elements in the input must be valid dictionary keys for this
1393 Note: All elements in the input must be valid dictionary keys for this
1335 routine to work, as it internally uses a dictionary for efficiency
1394 routine to work, as it internally uses a dictionary for efficiency
1336 reasons."""
1395 reasons."""
1337
1396
1338 unique = []
1397 unique = []
1339 unique_dict = {}
1398 unique_dict = {}
1340 for nn in elems:
1399 for nn in elems:
1341 if nn not in unique_dict:
1400 if nn not in unique_dict:
1342 unique.append(nn)
1401 unique.append(nn)
1343 unique_dict[nn] = None
1402 unique_dict[nn] = None
1344 return unique
1403 return unique
1345
1404
1346 #----------------------------------------------------------------------------
1405 #----------------------------------------------------------------------------
1347 class NLprinter:
1406 class NLprinter:
1348 """Print an arbitrarily nested list, indicating index numbers.
1407 """Print an arbitrarily nested list, indicating index numbers.
1349
1408
1350 An instance of this class called nlprint is available and callable as a
1409 An instance of this class called nlprint is available and callable as a
1351 function.
1410 function.
1352
1411
1353 nlprint(list,indent=' ',sep=': ') -> prints indenting each level by 'indent'
1412 nlprint(list,indent=' ',sep=': ') -> prints indenting each level by 'indent'
1354 and using 'sep' to separate the index from the value. """
1413 and using 'sep' to separate the index from the value. """
1355
1414
1356 def __init__(self):
1415 def __init__(self):
1357 self.depth = 0
1416 self.depth = 0
1358
1417
1359 def __call__(self,lst,pos='',**kw):
1418 def __call__(self,lst,pos='',**kw):
1360 """Prints the nested list numbering levels."""
1419 """Prints the nested list numbering levels."""
1361 kw.setdefault('indent',' ')
1420 kw.setdefault('indent',' ')
1362 kw.setdefault('sep',': ')
1421 kw.setdefault('sep',': ')
1363 kw.setdefault('start',0)
1422 kw.setdefault('start',0)
1364 kw.setdefault('stop',len(lst))
1423 kw.setdefault('stop',len(lst))
1365 # we need to remove start and stop from kw so they don't propagate
1424 # we need to remove start and stop from kw so they don't propagate
1366 # into a recursive call for a nested list.
1425 # into a recursive call for a nested list.
1367 start = kw['start']; del kw['start']
1426 start = kw['start']; del kw['start']
1368 stop = kw['stop']; del kw['stop']
1427 stop = kw['stop']; del kw['stop']
1369 if self.depth == 0 and 'header' in kw.keys():
1428 if self.depth == 0 and 'header' in kw.keys():
1370 print kw['header']
1429 print kw['header']
1371
1430
1372 for idx in range(start,stop):
1431 for idx in range(start,stop):
1373 elem = lst[idx]
1432 elem = lst[idx]
1374 if type(elem)==type([]):
1433 if type(elem)==type([]):
1375 self.depth += 1
1434 self.depth += 1
1376 self.__call__(elem,itpl('$pos$idx,'),**kw)
1435 self.__call__(elem,itpl('$pos$idx,'),**kw)
1377 self.depth -= 1
1436 self.depth -= 1
1378 else:
1437 else:
1379 printpl(kw['indent']*self.depth+'$pos$idx$kw["sep"]$elem')
1438 printpl(kw['indent']*self.depth+'$pos$idx$kw["sep"]$elem')
1380
1439
1381 nlprint = NLprinter()
1440 nlprint = NLprinter()
1382 #----------------------------------------------------------------------------
1441 #----------------------------------------------------------------------------
1383 def all_belong(candidates,checklist):
1442 def all_belong(candidates,checklist):
1384 """Check whether a list of items ALL appear in a given list of options.
1443 """Check whether a list of items ALL appear in a given list of options.
1385
1444
1386 Returns a single 1 or 0 value."""
1445 Returns a single 1 or 0 value."""
1387
1446
1388 return 1-(0 in [x in checklist for x in candidates])
1447 return 1-(0 in [x in checklist for x in candidates])
1389
1448
1390 #----------------------------------------------------------------------------
1449 #----------------------------------------------------------------------------
1391 def sort_compare(lst1,lst2,inplace = 1):
1450 def sort_compare(lst1,lst2,inplace = 1):
1392 """Sort and compare two lists.
1451 """Sort and compare two lists.
1393
1452
1394 By default it does it in place, thus modifying the lists. Use inplace = 0
1453 By default it does it in place, thus modifying the lists. Use inplace = 0
1395 to avoid that (at the cost of temporary copy creation)."""
1454 to avoid that (at the cost of temporary copy creation)."""
1396 if not inplace:
1455 if not inplace:
1397 lst1 = lst1[:]
1456 lst1 = lst1[:]
1398 lst2 = lst2[:]
1457 lst2 = lst2[:]
1399 lst1.sort(); lst2.sort()
1458 lst1.sort(); lst2.sort()
1400 return lst1 == lst2
1459 return lst1 == lst2
1401
1460
1402 #----------------------------------------------------------------------------
1461 #----------------------------------------------------------------------------
1403 def list2dict(lst):
1462 def list2dict(lst):
1404 """Takes a list of (key,value) pairs and turns it into a dict."""
1463 """Takes a list of (key,value) pairs and turns it into a dict."""
1405
1464
1406 dic = {}
1465 dic = {}
1407 for k,v in lst: dic[k] = v
1466 for k,v in lst: dic[k] = v
1408 return dic
1467 return dic
1409
1468
1410 #----------------------------------------------------------------------------
1469 #----------------------------------------------------------------------------
1411 def list2dict2(lst,default=''):
1470 def list2dict2(lst,default=''):
1412 """Takes a list and turns it into a dict.
1471 """Takes a list and turns it into a dict.
1413 Much slower than list2dict, but more versatile. This version can take
1472 Much slower than list2dict, but more versatile. This version can take
1414 lists with sublists of arbitrary length (including sclars)."""
1473 lists with sublists of arbitrary length (including sclars)."""
1415
1474
1416 dic = {}
1475 dic = {}
1417 for elem in lst:
1476 for elem in lst:
1418 if type(elem) in (types.ListType,types.TupleType):
1477 if type(elem) in (types.ListType,types.TupleType):
1419 size = len(elem)
1478 size = len(elem)
1420 if size == 0:
1479 if size == 0:
1421 pass
1480 pass
1422 elif size == 1:
1481 elif size == 1:
1423 dic[elem] = default
1482 dic[elem] = default
1424 else:
1483 else:
1425 k,v = elem[0], elem[1:]
1484 k,v = elem[0], elem[1:]
1426 if len(v) == 1: v = v[0]
1485 if len(v) == 1: v = v[0]
1427 dic[k] = v
1486 dic[k] = v
1428 else:
1487 else:
1429 dic[elem] = default
1488 dic[elem] = default
1430 return dic
1489 return dic
1431
1490
1432 #----------------------------------------------------------------------------
1491 #----------------------------------------------------------------------------
1433 def flatten(seq):
1492 def flatten(seq):
1434 """Flatten a list of lists (NOT recursive, only works for 2d lists)."""
1493 """Flatten a list of lists (NOT recursive, only works for 2d lists)."""
1435
1494
1436 return [x for subseq in seq for x in subseq]
1495 return [x for subseq in seq for x in subseq]
1437
1496
1438 #----------------------------------------------------------------------------
1497 #----------------------------------------------------------------------------
1439 def get_slice(seq,start=0,stop=None,step=1):
1498 def get_slice(seq,start=0,stop=None,step=1):
1440 """Get a slice of a sequence with variable step. Specify start,stop,step."""
1499 """Get a slice of a sequence with variable step. Specify start,stop,step."""
1441 if stop == None:
1500 if stop == None:
1442 stop = len(seq)
1501 stop = len(seq)
1443 item = lambda i: seq[i]
1502 item = lambda i: seq[i]
1444 return map(item,xrange(start,stop,step))
1503 return map(item,xrange(start,stop,step))
1445
1504
1446 #----------------------------------------------------------------------------
1505 #----------------------------------------------------------------------------
1447 def chop(seq,size):
1506 def chop(seq,size):
1448 """Chop a sequence into chunks of the given size."""
1507 """Chop a sequence into chunks of the given size."""
1449 chunk = lambda i: seq[i:i+size]
1508 chunk = lambda i: seq[i:i+size]
1450 return map(chunk,xrange(0,len(seq),size))
1509 return map(chunk,xrange(0,len(seq),size))
1451
1510
1452 #----------------------------------------------------------------------------
1511 #----------------------------------------------------------------------------
1453 # with is a keyword as of python 2.5, so this function is renamed to withobj
1512 # with is a keyword as of python 2.5, so this function is renamed to withobj
1454 # from its old 'with' name.
1513 # from its old 'with' name.
1455 def with_obj(object, **args):
1514 def with_obj(object, **args):
1456 """Set multiple attributes for an object, similar to Pascal's with.
1515 """Set multiple attributes for an object, similar to Pascal's with.
1457
1516
1458 Example:
1517 Example:
1459 with_obj(jim,
1518 with_obj(jim,
1460 born = 1960,
1519 born = 1960,
1461 haircolour = 'Brown',
1520 haircolour = 'Brown',
1462 eyecolour = 'Green')
1521 eyecolour = 'Green')
1463
1522
1464 Credit: Greg Ewing, in
1523 Credit: Greg Ewing, in
1465 http://mail.python.org/pipermail/python-list/2001-May/040703.html.
1524 http://mail.python.org/pipermail/python-list/2001-May/040703.html.
1466
1525
1467 NOTE: up until IPython 0.7.2, this was called simply 'with', but 'with'
1526 NOTE: up until IPython 0.7.2, this was called simply 'with', but 'with'
1468 has become a keyword for Python 2.5, so we had to rename it."""
1527 has become a keyword for Python 2.5, so we had to rename it."""
1469
1528
1470 object.__dict__.update(args)
1529 object.__dict__.update(args)
1471
1530
1472 #----------------------------------------------------------------------------
1531 #----------------------------------------------------------------------------
1473 def setattr_list(obj,alist,nspace = None):
1532 def setattr_list(obj,alist,nspace = None):
1474 """Set a list of attributes for an object taken from a namespace.
1533 """Set a list of attributes for an object taken from a namespace.
1475
1534
1476 setattr_list(obj,alist,nspace) -> sets in obj all the attributes listed in
1535 setattr_list(obj,alist,nspace) -> sets in obj all the attributes listed in
1477 alist with their values taken from nspace, which must be a dict (something
1536 alist with their values taken from nspace, which must be a dict (something
1478 like locals() will often do) If nspace isn't given, locals() of the
1537 like locals() will often do) If nspace isn't given, locals() of the
1479 *caller* is used, so in most cases you can omit it.
1538 *caller* is used, so in most cases you can omit it.
1480
1539
1481 Note that alist can be given as a string, which will be automatically
1540 Note that alist can be given as a string, which will be automatically
1482 split into a list on whitespace. If given as a list, it must be a list of
1541 split into a list on whitespace. If given as a list, it must be a list of
1483 *strings* (the variable names themselves), not of variables."""
1542 *strings* (the variable names themselves), not of variables."""
1484
1543
1485 # this grabs the local variables from the *previous* call frame -- that is
1544 # this grabs the local variables from the *previous* call frame -- that is
1486 # the locals from the function that called setattr_list().
1545 # the locals from the function that called setattr_list().
1487 # - snipped from weave.inline()
1546 # - snipped from weave.inline()
1488 if nspace is None:
1547 if nspace is None:
1489 call_frame = sys._getframe().f_back
1548 call_frame = sys._getframe().f_back
1490 nspace = call_frame.f_locals
1549 nspace = call_frame.f_locals
1491
1550
1492 if type(alist) in StringTypes:
1551 if type(alist) in StringTypes:
1493 alist = alist.split()
1552 alist = alist.split()
1494 for attr in alist:
1553 for attr in alist:
1495 val = eval(attr,nspace)
1554 val = eval(attr,nspace)
1496 setattr(obj,attr,val)
1555 setattr(obj,attr,val)
1497
1556
1498 #----------------------------------------------------------------------------
1557 #----------------------------------------------------------------------------
1499 def getattr_list(obj,alist,*args):
1558 def getattr_list(obj,alist,*args):
1500 """getattr_list(obj,alist[, default]) -> attribute list.
1559 """getattr_list(obj,alist[, default]) -> attribute list.
1501
1560
1502 Get a list of named attributes for an object. When a default argument is
1561 Get a list of named attributes for an object. When a default argument is
1503 given, it is returned when the attribute doesn't exist; without it, an
1562 given, it is returned when the attribute doesn't exist; without it, an
1504 exception is raised in that case.
1563 exception is raised in that case.
1505
1564
1506 Note that alist can be given as a string, which will be automatically
1565 Note that alist can be given as a string, which will be automatically
1507 split into a list on whitespace. If given as a list, it must be a list of
1566 split into a list on whitespace. If given as a list, it must be a list of
1508 *strings* (the variable names themselves), not of variables."""
1567 *strings* (the variable names themselves), not of variables."""
1509
1568
1510 if type(alist) in StringTypes:
1569 if type(alist) in StringTypes:
1511 alist = alist.split()
1570 alist = alist.split()
1512 if args:
1571 if args:
1513 if len(args)==1:
1572 if len(args)==1:
1514 default = args[0]
1573 default = args[0]
1515 return map(lambda attr: getattr(obj,attr,default),alist)
1574 return map(lambda attr: getattr(obj,attr,default),alist)
1516 else:
1575 else:
1517 raise ValueError,'getattr_list() takes only one optional argument'
1576 raise ValueError,'getattr_list() takes only one optional argument'
1518 else:
1577 else:
1519 return map(lambda attr: getattr(obj,attr),alist)
1578 return map(lambda attr: getattr(obj,attr),alist)
1520
1579
1521 #----------------------------------------------------------------------------
1580 #----------------------------------------------------------------------------
1522 def map_method(method,object_list,*argseq,**kw):
1581 def map_method(method,object_list,*argseq,**kw):
1523 """map_method(method,object_list,*args,**kw) -> list
1582 """map_method(method,object_list,*args,**kw) -> list
1524
1583
1525 Return a list of the results of applying the methods to the items of the
1584 Return a list of the results of applying the methods to the items of the
1526 argument sequence(s). If more than one sequence is given, the method is
1585 argument sequence(s). If more than one sequence is given, the method is
1527 called with an argument list consisting of the corresponding item of each
1586 called with an argument list consisting of the corresponding item of each
1528 sequence. All sequences must be of the same length.
1587 sequence. All sequences must be of the same length.
1529
1588
1530 Keyword arguments are passed verbatim to all objects called.
1589 Keyword arguments are passed verbatim to all objects called.
1531
1590
1532 This is Python code, so it's not nearly as fast as the builtin map()."""
1591 This is Python code, so it's not nearly as fast as the builtin map()."""
1533
1592
1534 out_list = []
1593 out_list = []
1535 idx = 0
1594 idx = 0
1536 for object in object_list:
1595 for object in object_list:
1537 try:
1596 try:
1538 handler = getattr(object, method)
1597 handler = getattr(object, method)
1539 except AttributeError:
1598 except AttributeError:
1540 out_list.append(None)
1599 out_list.append(None)
1541 else:
1600 else:
1542 if argseq:
1601 if argseq:
1543 args = map(lambda lst:lst[idx],argseq)
1602 args = map(lambda lst:lst[idx],argseq)
1544 #print 'ob',object,'hand',handler,'ar',args # dbg
1603 #print 'ob',object,'hand',handler,'ar',args # dbg
1545 out_list.append(handler(args,**kw))
1604 out_list.append(handler(args,**kw))
1546 else:
1605 else:
1547 out_list.append(handler(**kw))
1606 out_list.append(handler(**kw))
1548 idx += 1
1607 idx += 1
1549 return out_list
1608 return out_list
1550
1609
1551 #----------------------------------------------------------------------------
1610 #----------------------------------------------------------------------------
1552 def get_class_members(cls):
1611 def get_class_members(cls):
1553 ret = dir(cls)
1612 ret = dir(cls)
1554 if hasattr(cls,'__bases__'):
1613 if hasattr(cls,'__bases__'):
1555 for base in cls.__bases__:
1614 for base in cls.__bases__:
1556 ret.extend(get_class_members(base))
1615 ret.extend(get_class_members(base))
1557 return ret
1616 return ret
1558
1617
1559 #----------------------------------------------------------------------------
1618 #----------------------------------------------------------------------------
1560 def dir2(obj):
1619 def dir2(obj):
1561 """dir2(obj) -> list of strings
1620 """dir2(obj) -> list of strings
1562
1621
1563 Extended version of the Python builtin dir(), which does a few extra
1622 Extended version of the Python builtin dir(), which does a few extra
1564 checks, and supports common objects with unusual internals that confuse
1623 checks, and supports common objects with unusual internals that confuse
1565 dir(), such as Traits and PyCrust.
1624 dir(), such as Traits and PyCrust.
1566
1625
1567 This version is guaranteed to return only a list of true strings, whereas
1626 This version is guaranteed to return only a list of true strings, whereas
1568 dir() returns anything that objects inject into themselves, even if they
1627 dir() returns anything that objects inject into themselves, even if they
1569 are later not really valid for attribute access (many extension libraries
1628 are later not really valid for attribute access (many extension libraries
1570 have such bugs).
1629 have such bugs).
1571 """
1630 """
1572
1631
1573 # Start building the attribute list via dir(), and then complete it
1632 # Start building the attribute list via dir(), and then complete it
1574 # with a few extra special-purpose calls.
1633 # with a few extra special-purpose calls.
1575 words = dir(obj)
1634 words = dir(obj)
1576
1635
1577 if hasattr(obj,'__class__'):
1636 if hasattr(obj,'__class__'):
1578 words.append('__class__')
1637 words.append('__class__')
1579 words.extend(get_class_members(obj.__class__))
1638 words.extend(get_class_members(obj.__class__))
1580 #if '__base__' in words: 1/0
1639 #if '__base__' in words: 1/0
1581
1640
1582 # Some libraries (such as traits) may introduce duplicates, we want to
1641 # Some libraries (such as traits) may introduce duplicates, we want to
1583 # track and clean this up if it happens
1642 # track and clean this up if it happens
1584 may_have_dupes = False
1643 may_have_dupes = False
1585
1644
1586 # this is the 'dir' function for objects with Enthought's traits
1645 # this is the 'dir' function for objects with Enthought's traits
1587 if hasattr(obj, 'trait_names'):
1646 if hasattr(obj, 'trait_names'):
1588 try:
1647 try:
1589 words.extend(obj.trait_names())
1648 words.extend(obj.trait_names())
1590 may_have_dupes = True
1649 may_have_dupes = True
1591 except TypeError:
1650 except TypeError:
1592 # This will happen if `obj` is a class and not an instance.
1651 # This will happen if `obj` is a class and not an instance.
1593 pass
1652 pass
1594
1653
1595 # Support for PyCrust-style _getAttributeNames magic method.
1654 # Support for PyCrust-style _getAttributeNames magic method.
1596 if hasattr(obj, '_getAttributeNames'):
1655 if hasattr(obj, '_getAttributeNames'):
1597 try:
1656 try:
1598 words.extend(obj._getAttributeNames())
1657 words.extend(obj._getAttributeNames())
1599 may_have_dupes = True
1658 may_have_dupes = True
1600 except TypeError:
1659 except TypeError:
1601 # `obj` is a class and not an instance. Ignore
1660 # `obj` is a class and not an instance. Ignore
1602 # this error.
1661 # this error.
1603 pass
1662 pass
1604
1663
1605 if may_have_dupes:
1664 if may_have_dupes:
1606 # eliminate possible duplicates, as some traits may also
1665 # eliminate possible duplicates, as some traits may also
1607 # appear as normal attributes in the dir() call.
1666 # appear as normal attributes in the dir() call.
1608 words = list(set(words))
1667 words = list(set(words))
1609 words.sort()
1668 words.sort()
1610
1669
1611 # filter out non-string attributes which may be stuffed by dir() calls
1670 # filter out non-string attributes which may be stuffed by dir() calls
1612 # and poor coding in third-party modules
1671 # and poor coding in third-party modules
1613 return [w for w in words if isinstance(w, basestring)]
1672 return [w for w in words if isinstance(w, basestring)]
1614
1673
1615 #----------------------------------------------------------------------------
1674 #----------------------------------------------------------------------------
1616 def import_fail_info(mod_name,fns=None):
1675 def import_fail_info(mod_name,fns=None):
1617 """Inform load failure for a module."""
1676 """Inform load failure for a module."""
1618
1677
1619 if fns == None:
1678 if fns == None:
1620 warn("Loading of %s failed.\n" % (mod_name,))
1679 warn("Loading of %s failed.\n" % (mod_name,))
1621 else:
1680 else:
1622 warn("Loading of %s from %s failed.\n" % (fns,mod_name))
1681 warn("Loading of %s from %s failed.\n" % (fns,mod_name))
1623
1682
1624 #----------------------------------------------------------------------------
1683 #----------------------------------------------------------------------------
1625 # Proposed popitem() extension, written as a method
1684 # Proposed popitem() extension, written as a method
1626
1685
1627
1686
1628 class NotGiven: pass
1687 class NotGiven: pass
1629
1688
1630 def popkey(dct,key,default=NotGiven):
1689 def popkey(dct,key,default=NotGiven):
1631 """Return dct[key] and delete dct[key].
1690 """Return dct[key] and delete dct[key].
1632
1691
1633 If default is given, return it if dct[key] doesn't exist, otherwise raise
1692 If default is given, return it if dct[key] doesn't exist, otherwise raise
1634 KeyError. """
1693 KeyError. """
1635
1694
1636 try:
1695 try:
1637 val = dct[key]
1696 val = dct[key]
1638 except KeyError:
1697 except KeyError:
1639 if default is NotGiven:
1698 if default is NotGiven:
1640 raise
1699 raise
1641 else:
1700 else:
1642 return default
1701 return default
1643 else:
1702 else:
1644 del dct[key]
1703 del dct[key]
1645 return val
1704 return val
1646
1705
1647 def wrap_deprecated(func, suggest = '<nothing>'):
1706 def wrap_deprecated(func, suggest = '<nothing>'):
1648 def newFunc(*args, **kwargs):
1707 def newFunc(*args, **kwargs):
1649 warnings.warn("Call to deprecated function %s, use %s instead" %
1708 warnings.warn("Call to deprecated function %s, use %s instead" %
1650 ( func.__name__, suggest),
1709 ( func.__name__, suggest),
1651 category=DeprecationWarning,
1710 category=DeprecationWarning,
1652 stacklevel = 2)
1711 stacklevel = 2)
1653 return func(*args, **kwargs)
1712 return func(*args, **kwargs)
1654 return newFunc
1713 return newFunc
1655
1714
1656
1715
1657 def _num_cpus_unix():
1716 def _num_cpus_unix():
1658 """Return the number of active CPUs on a Unix system."""
1717 """Return the number of active CPUs on a Unix system."""
1659 return os.sysconf("SC_NPROCESSORS_ONLN")
1718 return os.sysconf("SC_NPROCESSORS_ONLN")
1660
1719
1661
1720
1662 def _num_cpus_darwin():
1721 def _num_cpus_darwin():
1663 """Return the number of active CPUs on a Darwin system."""
1722 """Return the number of active CPUs on a Darwin system."""
1664 p = subprocess.Popen(['sysctl','-n','hw.ncpu'],stdout=subprocess.PIPE)
1723 p = subprocess.Popen(['sysctl','-n','hw.ncpu'],stdout=subprocess.PIPE)
1665 return p.stdout.read()
1724 return p.stdout.read()
1666
1725
1667
1726
1668 def _num_cpus_windows():
1727 def _num_cpus_windows():
1669 """Return the number of active CPUs on a Windows system."""
1728 """Return the number of active CPUs on a Windows system."""
1670 return os.environ.get("NUMBER_OF_PROCESSORS")
1729 return os.environ.get("NUMBER_OF_PROCESSORS")
1671
1730
1672
1731
1673 def num_cpus():
1732 def num_cpus():
1674 """Return the effective number of CPUs in the system as an integer.
1733 """Return the effective number of CPUs in the system as an integer.
1675
1734
1676 This cross-platform function makes an attempt at finding the total number of
1735 This cross-platform function makes an attempt at finding the total number of
1677 available CPUs in the system, as returned by various underlying system and
1736 available CPUs in the system, as returned by various underlying system and
1678 python calls.
1737 python calls.
1679
1738
1680 If it can't find a sensible answer, it returns 1 (though an error *may* make
1739 If it can't find a sensible answer, it returns 1 (though an error *may* make
1681 it return a large positive number that's actually incorrect).
1740 it return a large positive number that's actually incorrect).
1682 """
1741 """
1683
1742
1684 # Many thanks to the Parallel Python project (http://www.parallelpython.com)
1743 # Many thanks to the Parallel Python project (http://www.parallelpython.com)
1685 # for the names of the keys we needed to look up for this function. This
1744 # for the names of the keys we needed to look up for this function. This
1686 # code was inspired by their equivalent function.
1745 # code was inspired by their equivalent function.
1687
1746
1688 ncpufuncs = {'Linux':_num_cpus_unix,
1747 ncpufuncs = {'Linux':_num_cpus_unix,
1689 'Darwin':_num_cpus_darwin,
1748 'Darwin':_num_cpus_darwin,
1690 'Windows':_num_cpus_windows,
1749 'Windows':_num_cpus_windows,
1691 # On Vista, python < 2.5.2 has a bug and returns 'Microsoft'
1750 # On Vista, python < 2.5.2 has a bug and returns 'Microsoft'
1692 # See http://bugs.python.org/issue1082 for details.
1751 # See http://bugs.python.org/issue1082 for details.
1693 'Microsoft':_num_cpus_windows,
1752 'Microsoft':_num_cpus_windows,
1694 }
1753 }
1695
1754
1696 ncpufunc = ncpufuncs.get(platform.system(),
1755 ncpufunc = ncpufuncs.get(platform.system(),
1697 # default to unix version (Solaris, AIX, etc)
1756 # default to unix version (Solaris, AIX, etc)
1698 _num_cpus_unix)
1757 _num_cpus_unix)
1699
1758
1700 try:
1759 try:
1701 ncpus = max(1,int(ncpufunc()))
1760 ncpus = max(1,int(ncpufunc()))
1702 except:
1761 except:
1703 ncpus = 1
1762 ncpus = 1
1704 return ncpus
1763 return ncpus
1705
1764
1706 def extract_vars(*names,**kw):
1765 def extract_vars(*names,**kw):
1707 """Extract a set of variables by name from another frame.
1766 """Extract a set of variables by name from another frame.
1708
1767
1709 :Parameters:
1768 :Parameters:
1710 - `*names`: strings
1769 - `*names`: strings
1711 One or more variable names which will be extracted from the caller's
1770 One or more variable names which will be extracted from the caller's
1712 frame.
1771 frame.
1713
1772
1714 :Keywords:
1773 :Keywords:
1715 - `depth`: integer (0)
1774 - `depth`: integer (0)
1716 How many frames in the stack to walk when looking for your variables.
1775 How many frames in the stack to walk when looking for your variables.
1717
1776
1718
1777
1719 Examples:
1778 Examples:
1720
1779
1721 In [2]: def func(x):
1780 In [2]: def func(x):
1722 ...: y = 1
1781 ...: y = 1
1723 ...: print extract_vars('x','y')
1782 ...: print extract_vars('x','y')
1724 ...:
1783 ...:
1725
1784
1726 In [3]: func('hello')
1785 In [3]: func('hello')
1727 {'y': 1, 'x': 'hello'}
1786 {'y': 1, 'x': 'hello'}
1728 """
1787 """
1729
1788
1730 depth = kw.get('depth',0)
1789 depth = kw.get('depth',0)
1731
1790
1732 callerNS = sys._getframe(depth+1).f_locals
1791 callerNS = sys._getframe(depth+1).f_locals
1733 return dict((k,callerNS[k]) for k in names)
1792 return dict((k,callerNS[k]) for k in names)
1734
1793
1735
1794
1736 def extract_vars_above(*names):
1795 def extract_vars_above(*names):
1737 """Extract a set of variables by name from another frame.
1796 """Extract a set of variables by name from another frame.
1738
1797
1739 Similar to extractVars(), but with a specified depth of 1, so that names
1798 Similar to extractVars(), but with a specified depth of 1, so that names
1740 are exctracted exactly from above the caller.
1799 are exctracted exactly from above the caller.
1741
1800
1742 This is simply a convenience function so that the very common case (for us)
1801 This is simply a convenience function so that the very common case (for us)
1743 of skipping exactly 1 frame doesn't have to construct a special dict for
1802 of skipping exactly 1 frame doesn't have to construct a special dict for
1744 keyword passing."""
1803 keyword passing."""
1745
1804
1746 callerNS = sys._getframe(2).f_locals
1805 callerNS = sys._getframe(2).f_locals
1747 return dict((k,callerNS[k]) for k in names)
1806 return dict((k,callerNS[k]) for k in names)
1748
1807
1749 def expand_path(s):
1808 def expand_path(s):
1750 """Expand $VARS and ~names in a string, like a shell
1809 """Expand $VARS and ~names in a string, like a shell
1751
1810
1752 :Examples:
1811 :Examples:
1753
1812
1754 In [2]: os.environ['FOO']='test'
1813 In [2]: os.environ['FOO']='test'
1755
1814
1756 In [3]: expand_path('variable FOO is $FOO')
1815 In [3]: expand_path('variable FOO is $FOO')
1757 Out[3]: 'variable FOO is test'
1816 Out[3]: 'variable FOO is test'
1758 """
1817 """
1759 # This is a pretty subtle hack. When expand user is given a UNC path
1818 # This is a pretty subtle hack. When expand user is given a UNC path
1760 # on Windows (\\server\share$\%username%), os.path.expandvars, removes
1819 # on Windows (\\server\share$\%username%), os.path.expandvars, removes
1761 # the $ to get (\\server\share\%username%). I think it considered $
1820 # the $ to get (\\server\share\%username%). I think it considered $
1762 # alone an empty var. But, we need the $ to remains there (it indicates
1821 # alone an empty var. But, we need the $ to remains there (it indicates
1763 # a hidden share).
1822 # a hidden share).
1764 if os.name=='nt':
1823 if os.name=='nt':
1765 s = s.replace('$\\', 'IPYTHON_TEMP')
1824 s = s.replace('$\\', 'IPYTHON_TEMP')
1766 s = os.path.expandvars(os.path.expanduser(s))
1825 s = os.path.expandvars(os.path.expanduser(s))
1767 if os.name=='nt':
1826 if os.name=='nt':
1768 s = s.replace('IPYTHON_TEMP', '$\\')
1827 s = s.replace('IPYTHON_TEMP', '$\\')
1769 return s
1828 return s
1770
1829
1771 def list_strings(arg):
1830 def list_strings(arg):
1772 """Always return a list of strings, given a string or list of strings
1831 """Always return a list of strings, given a string or list of strings
1773 as input.
1832 as input.
1774
1833
1775 :Examples:
1834 :Examples:
1776
1835
1777 In [7]: list_strings('A single string')
1836 In [7]: list_strings('A single string')
1778 Out[7]: ['A single string']
1837 Out[7]: ['A single string']
1779
1838
1780 In [8]: list_strings(['A single string in a list'])
1839 In [8]: list_strings(['A single string in a list'])
1781 Out[8]: ['A single string in a list']
1840 Out[8]: ['A single string in a list']
1782
1841
1783 In [9]: list_strings(['A','list','of','strings'])
1842 In [9]: list_strings(['A','list','of','strings'])
1784 Out[9]: ['A', 'list', 'of', 'strings']
1843 Out[9]: ['A', 'list', 'of', 'strings']
1785 """
1844 """
1786
1845
1787 if isinstance(arg,basestring): return [arg]
1846 if isinstance(arg,basestring): return [arg]
1788 else: return arg
1847 else: return arg
1789
1848
1790
1849
1791 #----------------------------------------------------------------------------
1850 #----------------------------------------------------------------------------
1792 def marquee(txt='',width=78,mark='*'):
1851 def marquee(txt='',width=78,mark='*'):
1793 """Return the input string centered in a 'marquee'.
1852 """Return the input string centered in a 'marquee'.
1794
1853
1795 :Examples:
1854 :Examples:
1796
1855
1797 In [16]: marquee('A test',40)
1856 In [16]: marquee('A test',40)
1798 Out[16]: '**************** A test ****************'
1857 Out[16]: '**************** A test ****************'
1799
1858
1800 In [17]: marquee('A test',40,'-')
1859 In [17]: marquee('A test',40,'-')
1801 Out[17]: '---------------- A test ----------------'
1860 Out[17]: '---------------- A test ----------------'
1802
1861
1803 In [18]: marquee('A test',40,' ')
1862 In [18]: marquee('A test',40,' ')
1804 Out[18]: ' A test '
1863 Out[18]: ' A test '
1805
1864
1806 """
1865 """
1807 if not txt:
1866 if not txt:
1808 return (mark*width)[:width]
1867 return (mark*width)[:width]
1809 nmark = (width-len(txt)-2)/len(mark)/2
1868 nmark = (width-len(txt)-2)/len(mark)/2
1810 if nmark < 0: nmark =0
1869 if nmark < 0: nmark =0
1811 marks = mark*nmark
1870 marks = mark*nmark
1812 return '%s %s %s' % (marks,txt,marks)
1871 return '%s %s %s' % (marks,txt,marks)
1813
1872
1814 #*************************** end of file <genutils.py> **********************
1873 #*************************** end of file <genutils.py> **********************
@@ -1,285 +1,323 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 # stdlib
18 # stdlib
19 import os
19 import os
20 import shutil
20 import shutil
21 import sys
21 import sys
22 import tempfile
22 import tempfile
23 import unittest
23
24
25 from cStringIO import StringIO
24 from os.path import join, abspath, split
26 from os.path import join, abspath, split
25
27
26 # third-party
28 # third-party
27 import nose.tools as nt
29 import nose.tools as nt
28
30
29 from nose import with_setup
31 from nose import with_setup
30 from nose.tools import raises
32 from nose.tools import raises
31
33
32 # Our own
34 # Our own
33 import IPython
35 import IPython
34 from IPython.utils import genutils
36 from IPython.utils import genutils
37 from IPython.testing import decorators as dec
35 from IPython.testing.decorators import skipif, skip_if_not_win32
38 from IPython.testing.decorators import skipif, skip_if_not_win32
36
39
37 # Platform-dependent imports
40 # Platform-dependent imports
38 try:
41 try:
39 import _winreg as wreg
42 import _winreg as wreg
40 except ImportError:
43 except ImportError:
41 #Fake _winreg module on none windows platforms
44 #Fake _winreg module on none windows platforms
42 import new
45 import new
43 sys.modules["_winreg"] = new.module("_winreg")
46 sys.modules["_winreg"] = new.module("_winreg")
44 import _winreg as wreg
47 import _winreg as wreg
45 #Add entries that needs to be stubbed by the testing code
48 #Add entries that needs to be stubbed by the testing code
46 (wreg.OpenKey, wreg.QueryValueEx,) = (None, None)
49 (wreg.OpenKey, wreg.QueryValueEx,) = (None, None)
47
50
48 #-----------------------------------------------------------------------------
51 #-----------------------------------------------------------------------------
49 # Globals
52 # Globals
50 #-----------------------------------------------------------------------------
53 #-----------------------------------------------------------------------------
51 env = os.environ
54 env = os.environ
52 TEST_FILE_PATH = split(abspath(__file__))[0]
55 TEST_FILE_PATH = split(abspath(__file__))[0]
53 TMP_TEST_DIR = tempfile.mkdtemp()
56 TMP_TEST_DIR = tempfile.mkdtemp()
54 HOME_TEST_DIR = join(TMP_TEST_DIR, "home_test_dir")
57 HOME_TEST_DIR = join(TMP_TEST_DIR, "home_test_dir")
55 IP_TEST_DIR = join(HOME_TEST_DIR,'_ipython')
58 IP_TEST_DIR = join(HOME_TEST_DIR,'_ipython')
56 #
59 #
57 # Setup/teardown functions/decorators
60 # Setup/teardown functions/decorators
58 #
61 #
59
62
60 def setup():
63 def setup():
61 """Setup testenvironment for the module:
64 """Setup testenvironment for the module:
62
65
63 - Adds dummy home dir tree
66 - Adds dummy home dir tree
64 """
67 """
65 # Do not mask exceptions here. In particular, catching WindowsError is a
68 # Do not mask exceptions here. In particular, catching WindowsError is a
66 # problem because that exception is only defined on Windows...
69 # problem because that exception is only defined on Windows...
67 os.makedirs(IP_TEST_DIR)
70 os.makedirs(IP_TEST_DIR)
68
71
69 def teardown():
72 def teardown():
70 """Teardown testenvironment for the module:
73 """Teardown testenvironment for the module:
71
74
72 - Remove dummy home dir tree
75 - Remove dummy home dir tree
73 """
76 """
74 # Note: we remove the parent test dir, which is the root of all test
77 # Note: we remove the parent test dir, which is the root of all test
75 # subdirs we may have created. Use shutil instead of os.removedirs, so
78 # subdirs we may have created. Use shutil instead of os.removedirs, so
76 # that non-empty directories are all recursively removed.
79 # that non-empty directories are all recursively removed.
77 shutil.rmtree(TMP_TEST_DIR)
80 shutil.rmtree(TMP_TEST_DIR)
78
81
79
82
80 def setup_environment():
83 def setup_environment():
81 """Setup testenvironment for some functions that are tested
84 """Setup testenvironment for some functions that are tested
82 in this module. In particular this functions stores attributes
85 in this module. In particular this functions stores attributes
83 and other things that we need to stub in some test functions.
86 and other things that we need to stub in some test functions.
84 This needs to be done on a function level and not module level because
87 This needs to be done on a function level and not module level because
85 each testfunction needs a pristine environment.
88 each testfunction needs a pristine environment.
86 """
89 """
87 global oldstuff, platformstuff
90 global oldstuff, platformstuff
88 oldstuff = (env.copy(), os.name, genutils.get_home_dir, IPython.__file__,)
91 oldstuff = (env.copy(), os.name, genutils.get_home_dir, IPython.__file__,)
89
92
90 if os.name == 'nt':
93 if os.name == 'nt':
91 platformstuff = (wreg.OpenKey, wreg.QueryValueEx,)
94 platformstuff = (wreg.OpenKey, wreg.QueryValueEx,)
92
95
93 if 'IPYTHONDIR' in env:
96 if 'IPYTHONDIR' in env:
94 del env['IPYTHONDIR']
97 del env['IPYTHONDIR']
95
98
96 def teardown_environment():
99 def teardown_environment():
97 """Restore things that were remebered by the setup_environment function
100 """Restore things that were remebered by the setup_environment function
98 """
101 """
99 (oldenv, os.name, genutils.get_home_dir, IPython.__file__,) = oldstuff
102 (oldenv, os.name, genutils.get_home_dir, IPython.__file__,) = oldstuff
100 for key in env.keys():
103 for key in env.keys():
101 if key not in oldenv:
104 if key not in oldenv:
102 del env[key]
105 del env[key]
103 env.update(oldenv)
106 env.update(oldenv)
104 if hasattr(sys, 'frozen'):
107 if hasattr(sys, 'frozen'):
105 del sys.frozen
108 del sys.frozen
106 if os.name == 'nt':
109 if os.name == 'nt':
107 (wreg.OpenKey, wreg.QueryValueEx,) = platformstuff
110 (wreg.OpenKey, wreg.QueryValueEx,) = platformstuff
108
111
109 # Build decorator that uses the setup_environment/setup_environment
112 # Build decorator that uses the setup_environment/setup_environment
110 with_enivronment = with_setup(setup_environment, teardown_environment)
113 with_environment = with_setup(setup_environment, teardown_environment)
111
114
112
115
113 #
116 #
114 # Tests for get_home_dir
117 # Tests for get_home_dir
115 #
118 #
116
119
117 @skip_if_not_win32
120 @skip_if_not_win32
118 @with_enivronment
121 @with_environment
119 def test_get_home_dir_1():
122 def test_get_home_dir_1():
120 """Testcase for py2exe logic, un-compressed lib
123 """Testcase for py2exe logic, un-compressed lib
121 """
124 """
122 sys.frozen = True
125 sys.frozen = True
123
126
124 #fake filename for IPython.__init__
127 #fake filename for IPython.__init__
125 IPython.__file__ = abspath(join(HOME_TEST_DIR, "Lib/IPython/__init__.py"))
128 IPython.__file__ = abspath(join(HOME_TEST_DIR, "Lib/IPython/__init__.py"))
126
129
127 home_dir = genutils.get_home_dir()
130 home_dir = genutils.get_home_dir()
128 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR))
131 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR))
129
132
130 @skip_if_not_win32
133 @skip_if_not_win32
131 @with_enivronment
134 @with_environment
132 def test_get_home_dir_2():
135 def test_get_home_dir_2():
133 """Testcase for py2exe logic, compressed lib
136 """Testcase for py2exe logic, compressed lib
134 """
137 """
135 sys.frozen = True
138 sys.frozen = True
136 #fake filename for IPython.__init__
139 #fake filename for IPython.__init__
137 IPython.__file__ = abspath(join(HOME_TEST_DIR, "Library.zip/IPython/__init__.py")).lower()
140 IPython.__file__ = abspath(join(HOME_TEST_DIR, "Library.zip/IPython/__init__.py")).lower()
138
141
139 home_dir = genutils.get_home_dir()
142 home_dir = genutils.get_home_dir()
140 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR).lower())
143 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR).lower())
141
144
142 @with_enivronment
145 @with_environment
143 def test_get_home_dir_3():
146 def test_get_home_dir_3():
144 """Testcase $HOME is set, then use its value as home directory."""
147 """Testcase $HOME is set, then use its value as home directory."""
145 env["HOME"] = HOME_TEST_DIR
148 env["HOME"] = HOME_TEST_DIR
146 home_dir = genutils.get_home_dir()
149 home_dir = genutils.get_home_dir()
147 nt.assert_equal(home_dir, env["HOME"])
150 nt.assert_equal(home_dir, env["HOME"])
148
151
149 @with_enivronment
152 @with_environment
150 def test_get_home_dir_4():
153 def test_get_home_dir_4():
151 """Testcase $HOME is not set, os=='poix'.
154 """Testcase $HOME is not set, os=='poix'.
152 This should fail with HomeDirError"""
155 This should fail with HomeDirError"""
153
156
154 os.name = 'posix'
157 os.name = 'posix'
155 if 'HOME' in env: del env['HOME']
158 if 'HOME' in env: del env['HOME']
156 nt.assert_raises(genutils.HomeDirError, genutils.get_home_dir)
159 nt.assert_raises(genutils.HomeDirError, genutils.get_home_dir)
157
160
158 @skip_if_not_win32
161 @skip_if_not_win32
159 @with_enivronment
162 @with_environment
160 def test_get_home_dir_5():
163 def test_get_home_dir_5():
161 """Testcase $HOME is not set, os=='nt'
164 """Testcase $HOME is not set, os=='nt'
162 env['HOMEDRIVE'],env['HOMEPATH'] points to path."""
165 env['HOMEDRIVE'],env['HOMEPATH'] points to path."""
163
166
164 os.name = 'nt'
167 os.name = 'nt'
165 if 'HOME' in env: del env['HOME']
168 if 'HOME' in env: del env['HOME']
166 env['HOMEDRIVE'], env['HOMEPATH'] = os.path.splitdrive(HOME_TEST_DIR)
169 env['HOMEDRIVE'], env['HOMEPATH'] = os.path.splitdrive(HOME_TEST_DIR)
167
170
168 home_dir = genutils.get_home_dir()
171 home_dir = genutils.get_home_dir()
169 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR))
172 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR))
170
173
171 @skip_if_not_win32
174 @skip_if_not_win32
172 @with_enivronment
175 @with_environment
173 def test_get_home_dir_6():
176 def test_get_home_dir_6():
174 """Testcase $HOME is not set, os=='nt'
177 """Testcase $HOME is not set, os=='nt'
175 env['HOMEDRIVE'],env['HOMEPATH'] do not point to path.
178 env['HOMEDRIVE'],env['HOMEPATH'] do not point to path.
176 env['USERPROFILE'] points to path
179 env['USERPROFILE'] points to path
177 """
180 """
178
181
179 os.name = 'nt'
182 os.name = 'nt'
180 if 'HOME' in env: del env['HOME']
183 if 'HOME' in env: del env['HOME']
181 env['HOMEDRIVE'], env['HOMEPATH'] = os.path.abspath(TEST_FILE_PATH), "DOES NOT EXIST"
184 env['HOMEDRIVE'], env['HOMEPATH'] = os.path.abspath(TEST_FILE_PATH), "DOES NOT EXIST"
182 env["USERPROFILE"] = abspath(HOME_TEST_DIR)
185 env["USERPROFILE"] = abspath(HOME_TEST_DIR)
183
186
184 home_dir = genutils.get_home_dir()
187 home_dir = genutils.get_home_dir()
185 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR))
188 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR))
186
189
187 # Should we stub wreg fully so we can run the test on all platforms?
190 # Should we stub wreg fully so we can run the test on all platforms?
188 @skip_if_not_win32
191 @skip_if_not_win32
189 @with_enivronment
192 @with_environment
190 def test_get_home_dir_7():
193 def test_get_home_dir_7():
191 """Testcase $HOME is not set, os=='nt'
194 """Testcase $HOME is not set, os=='nt'
192 env['HOMEDRIVE'],env['HOMEPATH'], env['USERPROFILE'] missing
195 env['HOMEDRIVE'],env['HOMEPATH'], env['USERPROFILE'] missing
193 """
196 """
194 os.name = 'nt'
197 os.name = 'nt'
195 if 'HOME' in env: del env['HOME']
198 if 'HOME' in env: del env['HOME']
196 if 'HOMEDRIVE' in env: del env['HOMEDRIVE']
199 if 'HOMEDRIVE' in env: del env['HOMEDRIVE']
197
200
198 #Stub windows registry functions
201 #Stub windows registry functions
199 def OpenKey(x, y):
202 def OpenKey(x, y):
200 class key:
203 class key:
201 def Close(self):
204 def Close(self):
202 pass
205 pass
203 return key()
206 return key()
204 def QueryValueEx(x, y):
207 def QueryValueEx(x, y):
205 return [abspath(HOME_TEST_DIR)]
208 return [abspath(HOME_TEST_DIR)]
206
209
207 wreg.OpenKey = OpenKey
210 wreg.OpenKey = OpenKey
208 wreg.QueryValueEx = QueryValueEx
211 wreg.QueryValueEx = QueryValueEx
209
212
210 home_dir = genutils.get_home_dir()
213 home_dir = genutils.get_home_dir()
211 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR))
214 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR))
212
215
213 #
216 #
214 # Tests for get_ipython_dir
217 # Tests for get_ipython_dir
215 #
218 #
216
219
217 @with_enivronment
220 @with_environment
218 def test_get_ipython_dir_1():
221 def test_get_ipython_dir_1():
219 """test_get_ipython_dir_1, Testcase to see if we can call get_ipython_dir without Exceptions."""
222 """test_get_ipython_dir_1, Testcase to see if we can call get_ipython_dir without Exceptions."""
220 env['IPYTHONDIR'] = "someplace/.ipython"
223 env['IPYTHONDIR'] = "someplace/.ipython"
221 ipdir = genutils.get_ipython_dir()
224 ipdir = genutils.get_ipython_dir()
222 nt.assert_equal(ipdir, "someplace/.ipython")
225 nt.assert_equal(ipdir, "someplace/.ipython")
223
226
224
227
225 @with_enivronment
228 @with_environment
226 def test_get_ipython_dir_2():
229 def test_get_ipython_dir_2():
227 """test_get_ipython_dir_2, Testcase to see if we can call get_ipython_dir without Exceptions."""
230 """test_get_ipython_dir_2, Testcase to see if we can call get_ipython_dir without Exceptions."""
228 genutils.get_home_dir = lambda : "someplace"
231 genutils.get_home_dir = lambda : "someplace"
229 os.name = "posix"
232 os.name = "posix"
230 ipdir = genutils.get_ipython_dir()
233 ipdir = genutils.get_ipython_dir()
231 nt.assert_equal(ipdir, os.path.join("someplace", ".ipython"))
234 nt.assert_equal(ipdir, os.path.join("someplace", ".ipython"))
232
235
233 #
236 #
234 # Tests for popkey
237 # Tests for popkey
235 #
238 #
236
239
237 def test_popkey_1():
240 def test_popkey_1():
238 """test_popkey_1, Basic usage test of popkey
241 """test_popkey_1, Basic usage test of popkey
239 """
242 """
240 dct = dict(a=1, b=2, c=3)
243 dct = dict(a=1, b=2, c=3)
241 nt.assert_equal(genutils.popkey(dct, "a"), 1)
244 nt.assert_equal(genutils.popkey(dct, "a"), 1)
242 nt.assert_equal(dct, dict(b=2, c=3))
245 nt.assert_equal(dct, dict(b=2, c=3))
243 nt.assert_equal(genutils.popkey(dct, "b"), 2)
246 nt.assert_equal(genutils.popkey(dct, "b"), 2)
244 nt.assert_equal(dct, dict(c=3))
247 nt.assert_equal(dct, dict(c=3))
245 nt.assert_equal(genutils.popkey(dct, "c"), 3)
248 nt.assert_equal(genutils.popkey(dct, "c"), 3)
246 nt.assert_equal(dct, dict())
249 nt.assert_equal(dct, dict())
247
250
248 def test_popkey_2():
251 def test_popkey_2():
249 """test_popkey_2, Test to see that popkey of non occuring keys
252 """test_popkey_2, Test to see that popkey of non occuring keys
250 generates a KeyError exception
253 generates a KeyError exception
251 """
254 """
252 dct = dict(a=1, b=2, c=3)
255 dct = dict(a=1, b=2, c=3)
253 nt.assert_raises(KeyError, genutils.popkey, dct, "d")
256 nt.assert_raises(KeyError, genutils.popkey, dct, "d")
254
257
255 def test_popkey_3():
258 def test_popkey_3():
256 """test_popkey_3, Tests to see that popkey calls returns the correct value
259 """test_popkey_3, Tests to see that popkey calls returns the correct value
257 and that the key/value was removed from the dict.
260 and that the key/value was removed from the dict.
258 """
261 """
259 dct = dict(a=1, b=2, c=3)
262 dct = dict(a=1, b=2, c=3)
260 nt.assert_equal(genutils.popkey(dct, "A", 13), 13)
263 nt.assert_equal(genutils.popkey(dct, "A", 13), 13)
261 nt.assert_equal(dct, dict(a=1, b=2, c=3))
264 nt.assert_equal(dct, dict(a=1, b=2, c=3))
262 nt.assert_equal(genutils.popkey(dct, "B", 14), 14)
265 nt.assert_equal(genutils.popkey(dct, "B", 14), 14)
263 nt.assert_equal(dct, dict(a=1, b=2, c=3))
266 nt.assert_equal(dct, dict(a=1, b=2, c=3))
264 nt.assert_equal(genutils.popkey(dct, "C", 15), 15)
267 nt.assert_equal(genutils.popkey(dct, "C", 15), 15)
265 nt.assert_equal(dct, dict(a=1, b=2, c=3))
268 nt.assert_equal(dct, dict(a=1, b=2, c=3))
266 nt.assert_equal(genutils.popkey(dct, "a"), 1)
269 nt.assert_equal(genutils.popkey(dct, "a"), 1)
267 nt.assert_equal(dct, dict(b=2, c=3))
270 nt.assert_equal(dct, dict(b=2, c=3))
268 nt.assert_equal(genutils.popkey(dct, "b"), 2)
271 nt.assert_equal(genutils.popkey(dct, "b"), 2)
269 nt.assert_equal(dct, dict(c=3))
272 nt.assert_equal(dct, dict(c=3))
270 nt.assert_equal(genutils.popkey(dct, "c"), 3)
273 nt.assert_equal(genutils.popkey(dct, "c"), 3)
271 nt.assert_equal(dct, dict())
274 nt.assert_equal(dct, dict())
272
275
273
276
274 def test_filefind():
277 def test_filefind():
275 """Various tests for filefind"""
278 """Various tests for filefind"""
276 f = tempfile.NamedTemporaryFile()
279 f = tempfile.NamedTemporaryFile()
277 print 'fname:',f.name
280 print 'fname:',f.name
278 alt_dirs = genutils.get_ipython_dir()
281 alt_dirs = genutils.get_ipython_dir()
279 t = genutils.filefind(f.name,alt_dirs)
282 t = genutils.filefind(f.name,alt_dirs)
280 print 'found:',t
283 print 'found:',t
281
284
282
285
283 def test_get_ipython_package_dir():
286 def test_get_ipython_package_dir():
284 ipdir = genutils.get_ipython_package_dir()
287 ipdir = genutils.get_ipython_package_dir()
285 nt.assert_true(os.path.isdir(ipdir))
288 nt.assert_true(os.path.isdir(ipdir))
289
290
291 def test_tee_simple():
292 "Very simple check with stdout only"
293 chan = StringIO()
294 text = 'Hello'
295 tee = genutils.Tee(chan, channel='stdout')
296 print >> chan, text,
297 nt.assert_equal(chan.getvalue(), text)
298
299
300 class TeeTestCase(dec.ParametricTestCase):
301
302 def tchan(self, channel, check='close'):
303 trap = StringIO()
304 chan = StringIO()
305 text = 'Hello'
306
307 std_ori = getattr(sys, channel)
308 setattr(sys, channel, trap)
309
310 tee = genutils.Tee(chan, channel=channel)
311 print >> chan, text,
312 setattr(sys, channel, std_ori)
313 trap_val = trap.getvalue()
314 nt.assert_equals(chan.getvalue(), text)
315 if check=='close':
316 tee.close()
317 else:
318 del tee
319
320 def test(self):
321 for chan in ['stdout', 'stderr']:
322 for check in ['close', 'del']:
323 yield self.tchan(chan, check)
General Comments 0
You need to be logged in to leave comments. Login now