##// END OF EJS Templates
Work to address the review comments on Fernando's branch....
Brian Granger -
r2498:3eae1372
parent child
Show More
@@ -0,0 +1,167
1 # encoding: utf-8
2 """
3 Older utilities that are not being used.
4
5 WARNING: IF YOU NEED TO USE ONE OF THESE FUNCTIONS, PLEASE FIRST MOVE IT
6 TO ANOTHER APPROPRIATE MODULE IN IPython.utils.
7 """
8
9 #-----------------------------------------------------------------------------
10 # Copyright (C) 2008-2009 The IPython Development Team
11 #
12 # Distributed under the terms of the BSD License. The full license is in
13 # the file COPYING, distributed as part of this software.
14 #-----------------------------------------------------------------------------
15
16 #-----------------------------------------------------------------------------
17 # Imports
18 #-----------------------------------------------------------------------------
19
20 import sys
21 import warnings
22
23 from IPython.utils.warn import warn
24
25 #-----------------------------------------------------------------------------
26 # Code
27 #-----------------------------------------------------------------------------
28
29
30 def mutex_opts(dict,ex_op):
31 """Check for presence of mutually exclusive keys in a dict.
32
33 Call: mutex_opts(dict,[[op1a,op1b],[op2a,op2b]...]"""
34 for op1,op2 in ex_op:
35 if op1 in dict and op2 in dict:
36 raise ValueError,'\n*** ERROR in Arguments *** '\
37 'Options '+op1+' and '+op2+' are mutually exclusive.'
38
39
40 class EvalDict:
41 """
42 Emulate a dict which evaluates its contents in the caller's frame.
43
44 Usage:
45 >>> number = 19
46
47 >>> text = "python"
48
49 >>> print "%(text.capitalize())s %(number/9.0).1f rules!" % EvalDict()
50 Python 2.1 rules!
51 """
52
53 # This version is due to sismex01@hebmex.com on c.l.py, and is basically a
54 # modified (shorter) version of:
55 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66018 by
56 # Skip Montanaro (skip@pobox.com).
57
58 def __getitem__(self, name):
59 frame = sys._getframe(1)
60 return eval(name, frame.f_globals, frame.f_locals)
61
62 EvalString = EvalDict # for backwards compatibility
63
64
65 def all_belong(candidates,checklist):
66 """Check whether a list of items ALL appear in a given list of options.
67
68 Returns a single 1 or 0 value."""
69
70 return 1-(0 in [x in checklist for x in candidates])
71
72
73 def belong(candidates,checklist):
74 """Check whether a list of items appear in a given list of options.
75
76 Returns a list of 1 and 0, one for each candidate given."""
77
78 return [x in checklist for x in candidates]
79
80
81 def with_obj(object, **args):
82 """Set multiple attributes for an object, similar to Pascal's with.
83
84 Example:
85 with_obj(jim,
86 born = 1960,
87 haircolour = 'Brown',
88 eyecolour = 'Green')
89
90 Credit: Greg Ewing, in
91 http://mail.python.org/pipermail/python-list/2001-May/040703.html.
92
93 NOTE: up until IPython 0.7.2, this was called simply 'with', but 'with'
94 has become a keyword for Python 2.5, so we had to rename it."""
95
96 object.__dict__.update(args)
97
98
99 def map_method(method,object_list,*argseq,**kw):
100 """map_method(method,object_list,*args,**kw) -> list
101
102 Return a list of the results of applying the methods to the items of the
103 argument sequence(s). If more than one sequence is given, the method is
104 called with an argument list consisting of the corresponding item of each
105 sequence. All sequences must be of the same length.
106
107 Keyword arguments are passed verbatim to all objects called.
108
109 This is Python code, so it's not nearly as fast as the builtin map()."""
110
111 out_list = []
112 idx = 0
113 for object in object_list:
114 try:
115 handler = getattr(object, method)
116 except AttributeError:
117 out_list.append(None)
118 else:
119 if argseq:
120 args = map(lambda lst:lst[idx],argseq)
121 #print 'ob',object,'hand',handler,'ar',args # dbg
122 out_list.append(handler(args,**kw))
123 else:
124 out_list.append(handler(**kw))
125 idx += 1
126 return out_list
127
128
129 def import_fail_info(mod_name,fns=None):
130 """Inform load failure for a module."""
131
132 if fns == None:
133 warn("Loading of %s failed.\n" % (mod_name,))
134 else:
135 warn("Loading of %s from %s failed.\n" % (fns,mod_name))
136
137
138 class NotGiven: pass
139
140 def popkey(dct,key,default=NotGiven):
141 """Return dct[key] and delete dct[key].
142
143 If default is given, return it if dct[key] doesn't exist, otherwise raise
144 KeyError. """
145
146 try:
147 val = dct[key]
148 except KeyError:
149 if default is NotGiven:
150 raise
151 else:
152 return default
153 else:
154 del dct[key]
155 return val
156
157
158 def wrap_deprecated(func, suggest = '<nothing>'):
159 def newFunc(*args, **kwargs):
160 warnings.warn("Call to deprecated function %s, use %s instead" %
161 ( func.__name__, suggest),
162 category=DeprecationWarning,
163 stacklevel = 2)
164 return func(*args, **kwargs)
165 return newFunc
166
167
@@ -0,0 +1,31
1 # encoding: utf-8
2 """
3 See if we have curses.
4 """
5
6 #-----------------------------------------------------------------------------
7 # Copyright (C) 2008-2009 The IPython Development Team
8 #
9 # Distributed under the terms of the BSD License. The full license is in
10 # the file COPYING, distributed as part of this software.
11 #-----------------------------------------------------------------------------
12
13 #-----------------------------------------------------------------------------
14 # Imports
15 #-----------------------------------------------------------------------------
16
17 #-----------------------------------------------------------------------------
18 # Code
19 #-----------------------------------------------------------------------------
20
21 # Curses and termios are Unix-only modules
22 try:
23 import curses
24 # We need termios as well, so if its import happens to raise, we bail on
25 # using curses altogether.
26 import termios
27 except ImportError:
28 use_curses = False
29 else:
30 # Curses on Solaris may not be complete, so we can't use it there
31 use_curses = hasattr(curses,'initscr') No newline at end of file
@@ -0,0 +1,106
1 # encoding: utf-8
2 """Utilities for working with data structures like lists, dicts and tuples.
3 """
4
5 #-----------------------------------------------------------------------------
6 # Copyright (C) 2008-2009 The IPython Development Team
7 #
8 # Distributed under the terms of the BSD License. The full license is in
9 # the file COPYING, distributed as part of this software.
10 #-----------------------------------------------------------------------------
11
12 #-----------------------------------------------------------------------------
13 # Imports
14 #-----------------------------------------------------------------------------
15
16 import types
17
18 #-----------------------------------------------------------------------------
19 # Code
20 #-----------------------------------------------------------------------------
21
22 def uniq_stable(elems):
23 """uniq_stable(elems) -> list
24
25 Return from an iterable, a list of all the unique elements in the input,
26 but maintaining the order in which they first appear.
27
28 A naive solution to this problem which just makes a dictionary with the
29 elements as keys fails to respect the stability condition, since
30 dictionaries are unsorted by nature.
31
32 Note: All elements in the input must be valid dictionary keys for this
33 routine to work, as it internally uses a dictionary for efficiency
34 reasons."""
35
36 unique = []
37 unique_dict = {}
38 for nn in elems:
39 if nn not in unique_dict:
40 unique.append(nn)
41 unique_dict[nn] = None
42 return unique
43
44
45 def sort_compare(lst1, lst2, inplace=1):
46 """Sort and compare two lists.
47
48 By default it does it in place, thus modifying the lists. Use inplace = 0
49 to avoid that (at the cost of temporary copy creation)."""
50 if not inplace:
51 lst1 = lst1[:]
52 lst2 = lst2[:]
53 lst1.sort(); lst2.sort()
54 return lst1 == lst2
55
56
57 def list2dict(lst):
58 """Takes a list of (key,value) pairs and turns it into a dict."""
59
60 dic = {}
61 for k,v in lst: dic[k] = v
62 return dic
63
64
65 def list2dict2(lst, default=''):
66 """Takes a list and turns it into a dict.
67 Much slower than list2dict, but more versatile. This version can take
68 lists with sublists of arbitrary length (including sclars)."""
69
70 dic = {}
71 for elem in lst:
72 if type(elem) in (types.ListType,types.TupleType):
73 size = len(elem)
74 if size == 0:
75 pass
76 elif size == 1:
77 dic[elem] = default
78 else:
79 k,v = elem[0], elem[1:]
80 if len(v) == 1: v = v[0]
81 dic[k] = v
82 else:
83 dic[elem] = default
84 return dic
85
86
87 def flatten(seq):
88 """Flatten a list of lists (NOT recursive, only works for 2d lists)."""
89
90 return [x for subseq in seq for x in subseq]
91
92
93 def get_slice(seq, start=0, stop=None, step=1):
94 """Get a slice of a sequence with variable step. Specify start,stop,step."""
95 if stop == None:
96 stop = len(seq)
97 item = lambda i: seq[i]
98 return map(item,xrange(start,stop,step))
99
100
101 def chop(seq, size):
102 """Chop a sequence into chunks of the given size."""
103 chunk = lambda i: seq[i:i+size]
104 return map(chunk,xrange(0,len(seq),size))
105
106
@@ -0,0 +1,46
1 # encoding: utf-8
2 """Decorators that don't go anywhere else.
3
4 This module contains misc. decorators that don't really go with another module
5 in :mod:`IPython.utils`. Beore putting something here please see if it should
6 go into another topical module in :mod:`IPython.utils`.
7 """
8
9 #-----------------------------------------------------------------------------
10 # Copyright (C) 2008-2009 The IPython Development Team
11 #
12 # Distributed under the terms of the BSD License. The full license is in
13 # the file COPYING, distributed as part of this software.
14 #-----------------------------------------------------------------------------
15
16 #-----------------------------------------------------------------------------
17 # Imports
18 #-----------------------------------------------------------------------------
19
20 #-----------------------------------------------------------------------------
21 # Code
22 #-----------------------------------------------------------------------------
23
24 def flag_calls(func):
25 """Wrap a function to detect and flag when it gets called.
26
27 This is a decorator which takes a function and wraps it in a function with
28 a 'called' attribute. wrapper.called is initialized to False.
29
30 The wrapper.called attribute is set to False right before each call to the
31 wrapped function, so if the call fails it remains False. After the call
32 completes, wrapper.called is set to True and the output is returned.
33
34 Testing for truth in wrapper.called allows you to determine if a call to
35 func() was attempted and succeeded."""
36
37 def wrapper(*args,**kw):
38 wrapper.called = False
39 out = func(*args,**kw)
40 wrapper.called = True
41 return out
42
43 wrapper.called = False
44 wrapper.__doc__ = func.__doc__
45 return wrapper
46
@@ -0,0 +1,82
1 # encoding: utf-8
2 """A fancy version of Python's builtin :func:`dir` function.
3 """
4
5 #-----------------------------------------------------------------------------
6 # Copyright (C) 2008-2009 The IPython Development Team
7 #
8 # Distributed under the terms of the BSD License. The full license is in
9 # the file COPYING, distributed as part of this software.
10 #-----------------------------------------------------------------------------
11
12 #-----------------------------------------------------------------------------
13 # Imports
14 #-----------------------------------------------------------------------------
15
16 #-----------------------------------------------------------------------------
17 # Code
18 #-----------------------------------------------------------------------------
19
20 def get_class_members(cls):
21 ret = dir(cls)
22 if hasattr(cls,'__bases__'):
23 for base in cls.__bases__:
24 ret.extend(get_class_members(base))
25 return ret
26
27
28 def dir2(obj):
29 """dir2(obj) -> list of strings
30
31 Extended version of the Python builtin dir(), which does a few extra
32 checks, and supports common objects with unusual internals that confuse
33 dir(), such as Traits and PyCrust.
34
35 This version is guaranteed to return only a list of true strings, whereas
36 dir() returns anything that objects inject into themselves, even if they
37 are later not really valid for attribute access (many extension libraries
38 have such bugs).
39 """
40
41 # Start building the attribute list via dir(), and then complete it
42 # with a few extra special-purpose calls.
43 words = dir(obj)
44
45 if hasattr(obj,'__class__'):
46 words.append('__class__')
47 words.extend(get_class_members(obj.__class__))
48 #if '__base__' in words: 1/0
49
50 # Some libraries (such as traits) may introduce duplicates, we want to
51 # track and clean this up if it happens
52 may_have_dupes = False
53
54 # this is the 'dir' function for objects with Enthought's traits
55 if hasattr(obj, 'trait_names'):
56 try:
57 words.extend(obj.trait_names())
58 may_have_dupes = True
59 except TypeError:
60 # This will happen if `obj` is a class and not an instance.
61 pass
62
63 # Support for PyCrust-style _getAttributeNames magic method.
64 if hasattr(obj, '_getAttributeNames'):
65 try:
66 words.extend(obj._getAttributeNames())
67 may_have_dupes = True
68 except TypeError:
69 # `obj` is a class and not an instance. Ignore
70 # this error.
71 pass
72
73 if may_have_dupes:
74 # eliminate possible duplicates, as some traits may also
75 # appear as normal attributes in the dir() call.
76 words = list(set(words))
77 words.sort()
78
79 # filter out non-string attributes which may be stuffed by dir() calls
80 # and poor coding in third-party modules
81 return [w for w in words if isinstance(w, basestring)]
82
@@ -0,0 +1,75
1 # encoding: utf-8
2 """
3 A utility for handling the reloading of doctest.
4 """
5
6 #-----------------------------------------------------------------------------
7 # Copyright (C) 2008-2009 The IPython Development Team
8 #
9 # Distributed under the terms of the BSD License. The full license is in
10 # the file COPYING, distributed as part of this software.
11 #-----------------------------------------------------------------------------
12
13 #-----------------------------------------------------------------------------
14 # Imports
15 #-----------------------------------------------------------------------------
16
17 import sys
18
19 #-----------------------------------------------------------------------------
20 # Code
21 #-----------------------------------------------------------------------------
22
23 def dhook_wrap(func,*a,**k):
24 """Wrap a function call in a sys.displayhook controller.
25
26 Returns a wrapper around func which calls func, with all its arguments and
27 keywords unmodified, using the default sys.displayhook. Since IPython
28 modifies sys.displayhook, it breaks the behavior of certain systems that
29 rely on the default behavior, notably doctest.
30 """
31
32 def f(*a,**k):
33
34 dhook_s = sys.displayhook
35 sys.displayhook = sys.__displayhook__
36 try:
37 out = func(*a,**k)
38 finally:
39 sys.displayhook = dhook_s
40
41 return out
42
43 f.__doc__ = func.__doc__
44 return f
45
46
47 def doctest_reload():
48 """Properly reload doctest to reuse it interactively.
49
50 This routine:
51
52 - imports doctest but does NOT reload it (see below).
53
54 - resets its global 'master' attribute to None, so that multiple uses of
55 the module interactively don't produce cumulative reports.
56
57 - Monkeypatches its core test runner method to protect it from IPython's
58 modified displayhook. Doctest expects the default displayhook behavior
59 deep down, so our modification breaks it completely. For this reason, a
60 hard monkeypatch seems like a reasonable solution rather than asking
61 users to manually use a different doctest runner when under IPython.
62
63 Notes
64 -----
65
66 This function *used to* reload doctest, but this has been disabled because
67 reloading doctest unconditionally can cause massive breakage of other
68 doctest-dependent modules already in memory, such as those for IPython's
69 own testing system. The name wasn't changed to avoid breaking people's
70 code, but the reload call isn't actually made anymore."""
71
72 import doctest
73 doctest.master = None
74 doctest.DocTestRunner.run = dhook_wrap(doctest.DocTestRunner.run)
75
@@ -0,0 +1,85
1 # encoding: utf-8
2 """
3 Utilities for working with stack frames.
4 """
5
6 #-----------------------------------------------------------------------------
7 # Copyright (C) 2008-2009 The IPython Development Team
8 #
9 # Distributed under the terms of the BSD License. The full license is in
10 # the file COPYING, distributed as part of this software.
11 #-----------------------------------------------------------------------------
12
13 #-----------------------------------------------------------------------------
14 # Imports
15 #-----------------------------------------------------------------------------
16
17 import sys
18
19 #-----------------------------------------------------------------------------
20 # Code
21 #-----------------------------------------------------------------------------
22
23 def extract_vars(*names,**kw):
24 """Extract a set of variables by name from another frame.
25
26 :Parameters:
27 - `*names`: strings
28 One or more variable names which will be extracted from the caller's
29 frame.
30
31 :Keywords:
32 - `depth`: integer (0)
33 How many frames in the stack to walk when looking for your variables.
34
35
36 Examples:
37
38 In [2]: def func(x):
39 ...: y = 1
40 ...: print extract_vars('x','y')
41 ...:
42
43 In [3]: func('hello')
44 {'y': 1, 'x': 'hello'}
45 """
46
47 depth = kw.get('depth',0)
48
49 callerNS = sys._getframe(depth+1).f_locals
50 return dict((k,callerNS[k]) for k in names)
51
52
53 def extract_vars_above(*names):
54 """Extract a set of variables by name from another frame.
55
56 Similar to extractVars(), but with a specified depth of 1, so that names
57 are exctracted exactly from above the caller.
58
59 This is simply a convenience function so that the very common case (for us)
60 of skipping exactly 1 frame doesn't have to construct a special dict for
61 keyword passing."""
62
63 callerNS = sys._getframe(2).f_locals
64 return dict((k,callerNS[k]) for k in names)
65
66
67 def debugx(expr,pre_msg=''):
68 """Print the value of an expression from the caller's frame.
69
70 Takes an expression, evaluates it in the caller's frame and prints both
71 the given expression and the resulting value (as well as a debug mark
72 indicating the name of the calling function. The input must be of a form
73 suitable for eval().
74
75 An optional message can be passed, which will be prepended to the printed
76 expr->value pair."""
77
78 cf = sys._getframe(1)
79 print '[DBG:%s] %s%s -> %r' % (cf.f_code.co_name,pre_msg,expr,
80 eval(expr,cf.f_globals,cf.f_locals))
81
82
83 # deactivate it by uncommenting the following line, which makes it a no-op
84 #def debugx(expr,pre_msg=''): pass
85
@@ -0,0 +1,292
1 # encoding: utf-8
2 """
3 IO related utilities.
4 """
5
6 #-----------------------------------------------------------------------------
7 # Copyright (C) 2008-2009 The IPython Development Team
8 #
9 # Distributed under the terms of the BSD License. The full license is in
10 # the file COPYING, distributed as part of this software.
11 #-----------------------------------------------------------------------------
12
13 #-----------------------------------------------------------------------------
14 # Imports
15 #-----------------------------------------------------------------------------
16
17 import sys
18 import tempfile
19
20 from IPython.external.Itpl import itpl, printpl
21
22 #-----------------------------------------------------------------------------
23 # Code
24 #-----------------------------------------------------------------------------
25
26
27 class IOStream:
28
29 def __init__(self,stream,fallback):
30 if not hasattr(stream,'write') or not hasattr(stream,'flush'):
31 stream = fallback
32 self.stream = stream
33 self._swrite = stream.write
34 self.flush = stream.flush
35
36 def write(self,data):
37 try:
38 self._swrite(data)
39 except:
40 try:
41 # print handles some unicode issues which may trip a plain
42 # write() call. Attempt to emulate write() by using a
43 # trailing comma
44 print >> self.stream, data,
45 except:
46 # if we get here, something is seriously broken.
47 print >> sys.stderr, \
48 'ERROR - failed to write data to stream:', self.stream
49
50 def writeln(self, data):
51 self.write(data)
52 self.write('\n')
53
54 def close(self):
55 pass
56
57
58 class IOTerm:
59 """ Term holds the file or file-like objects for handling I/O operations.
60
61 These are normally just sys.stdin, sys.stdout and sys.stderr but for
62 Windows they can can replaced to allow editing the strings before they are
63 displayed."""
64
65 # In the future, having IPython channel all its I/O operations through
66 # this class will make it easier to embed it into other environments which
67 # are not a normal terminal (such as a GUI-based shell)
68 def __init__(self,cin=None,cout=None,cerr=None):
69 self.cin = IOStream(cin,sys.stdin)
70 self.cout = IOStream(cout,sys.stdout)
71 self.cerr = IOStream(cerr,sys.stderr)
72
73
74 # Global variable to be used for all I/O
75 Term = IOTerm()
76
77
78 import IPython.utils.rlineimpl as readline
79 # Remake Term to use the readline i/o facilities
80 if sys.platform == 'win32' and readline.have_readline:
81
82 Term = IOTerm(cout=readline._outputfile,cerr=readline._outputfile)
83
84
85 class Tee(object):
86 """A class to duplicate an output stream to stdout/err.
87
88 This works in a manner very similar to the Unix 'tee' command.
89
90 When the object is closed or deleted, it closes the original file given to
91 it for duplication.
92 """
93 # Inspired by:
94 # http://mail.python.org/pipermail/python-list/2007-May/442737.html
95
96 def __init__(self, file_or_name, mode=None, channel='stdout'):
97 """Construct a new Tee object.
98
99 Parameters
100 ----------
101 file_or_name : filename or open filehandle (writable)
102 File that will be duplicated
103
104 mode : optional, valid mode for open().
105 If a filename was give, open with this mode.
106
107 channel : str, one of ['stdout', 'stderr']
108 """
109 if channel not in ['stdout', 'stderr']:
110 raise ValueError('Invalid channel spec %s' % channel)
111
112 if hasattr(file, 'write') and hasattr(file, 'seek'):
113 self.file = file_or_name
114 else:
115 self.file = open(file_or_name, mode)
116 self.channel = channel
117 self.ostream = getattr(sys, channel)
118 setattr(sys, channel, self)
119 self._closed = False
120
121 def close(self):
122 """Close the file and restore the channel."""
123 self.flush()
124 setattr(sys, self.channel, self.ostream)
125 self.file.close()
126 self._closed = True
127
128 def write(self, data):
129 """Write data to both channels."""
130 self.file.write(data)
131 self.ostream.write(data)
132 self.ostream.flush()
133
134 def flush(self):
135 """Flush both channels."""
136 self.file.flush()
137 self.ostream.flush()
138
139 def __del__(self):
140 if not self._closed:
141 self.close()
142
143
144 def file_read(filename):
145 """Read a file and close it. Returns the file source."""
146 fobj = open(filename,'r');
147 source = fobj.read();
148 fobj.close()
149 return source
150
151
152 def file_readlines(filename):
153 """Read a file and close it. Returns the file source using readlines()."""
154 fobj = open(filename,'r');
155 lines = fobj.readlines();
156 fobj.close()
157 return lines
158
159
160 def raw_input_multi(header='', ps1='==> ', ps2='..> ',terminate_str = '.'):
161 """Take multiple lines of input.
162
163 A list with each line of input as a separate element is returned when a
164 termination string is entered (defaults to a single '.'). Input can also
165 terminate via EOF (^D in Unix, ^Z-RET in Windows).
166
167 Lines of input which end in \\ are joined into single entries (and a
168 secondary continuation prompt is issued as long as the user terminates
169 lines with \\). This allows entering very long strings which are still
170 meant to be treated as single entities.
171 """
172
173 try:
174 if header:
175 header += '\n'
176