@@ -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 |