Merged release21-maint changes.
[python/dscho.git] / Lib / test / test_inspect.py
blob130fa8ef7350b5c243e2a34e0d66d5ddb87b1c09
1 source = '''# line 1
2 'A module docstring.'
4 import sys, inspect
5 # line 5
7 # line 7
8 def spam(a, b, c, d=3, (e, (f,))=(4, (5,)), *g, **h):
9 eggs(b + d, c + f)
11 # line 11
12 def eggs(x, y):
13 "A docstring."
14 global fr, st
15 fr = inspect.currentframe()
16 st = inspect.stack()
17 p = x
18 q = y / 0
20 # line 20
21 class StupidGit:
22 """A longer,
24 indented
26 docstring."""
27 # line 27
29 def abuse(self, a, b, c):
30 """Another
32 \tdocstring
34 containing
36 \ttabs
38 """
39 self.argue(a, b, c)
40 # line 40
41 def argue(self, a, b, c):
42 try:
43 spam(a, b, c)
44 except:
45 self.ex = sys.exc_info()
46 self.tr = inspect.trace()
48 # line 48
49 class MalodorousPervert(StupidGit):
50 pass
52 class ParrotDroppings:
53 pass
55 class FesteringGob(MalodorousPervert, ParrotDroppings):
56 pass
57 '''
59 # Functions tested in this suite:
60 # ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode,
61 # isbuiltin, isroutine, getmembers, getdoc, getfile, getmodule,
62 # getsourcefile, getcomments, getsource, getclasstree, getargspec,
63 # getargvalues, formatargspec, formatargvalues, currentframe, stack, trace
65 from test_support import TestFailed, TESTFN
66 import sys, imp, os, string
68 def test(assertion, message, *args):
69 if not assertion:
70 raise TestFailed, message % args
72 import inspect
74 file = open(TESTFN, 'w')
75 file.write(source)
76 file.close()
78 # Note that load_source creates file TESTFN+'c' or TESTFN+'o'.
79 mod = imp.load_source('testmod', TESTFN)
80 files_to_clean_up = [TESTFN, TESTFN + 'c', TESTFN + 'o']
82 def istest(func, exp):
83 obj = eval(exp)
84 test(func(obj), '%s(%s)' % (func.__name__, exp))
85 for other in [inspect.isbuiltin, inspect.isclass, inspect.iscode,
86 inspect.isframe, inspect.isfunction, inspect.ismethod,
87 inspect.ismodule, inspect.istraceback]:
88 if other is not func:
89 test(not other(obj), 'not %s(%s)' % (other.__name__, exp))
91 git = mod.StupidGit()
92 try:
93 1/0
94 except:
95 tb = sys.exc_traceback
97 istest(inspect.isbuiltin, 'sys.exit')
98 istest(inspect.isbuiltin, '[].append')
99 istest(inspect.isclass, 'mod.StupidGit')
100 istest(inspect.iscode, 'mod.spam.func_code')
101 istest(inspect.isframe, 'tb.tb_frame')
102 istest(inspect.isfunction, 'mod.spam')
103 istest(inspect.ismethod, 'mod.StupidGit.abuse')
104 istest(inspect.ismethod, 'git.argue')
105 istest(inspect.ismodule, 'mod')
106 istest(inspect.istraceback, 'tb')
107 test(inspect.isroutine(mod.spam), 'isroutine(mod.spam)')
108 test(inspect.isroutine([].count), 'isroutine([].count)')
110 classes = inspect.getmembers(mod, inspect.isclass)
111 test(classes ==
112 [('FesteringGob', mod.FesteringGob),
113 ('MalodorousPervert', mod.MalodorousPervert),
114 ('ParrotDroppings', mod.ParrotDroppings),
115 ('StupidGit', mod.StupidGit)], 'class list')
116 tree = inspect.getclasstree(map(lambda x: x[1], classes), 1)
117 test(tree ==
118 [(mod.ParrotDroppings, ()),
119 (mod.StupidGit, ()),
120 [(mod.MalodorousPervert, (mod.StupidGit,)),
121 [(mod.FesteringGob, (mod.MalodorousPervert, mod.ParrotDroppings))
124 ], 'class tree')
126 functions = inspect.getmembers(mod, inspect.isfunction)
127 test(functions == [('eggs', mod.eggs), ('spam', mod.spam)], 'function list')
129 test(inspect.getdoc(mod) == 'A module docstring.', 'getdoc(mod)')
130 test(inspect.getcomments(mod) == '# line 1\n', 'getcomments(mod)')
131 test(inspect.getmodule(mod.StupidGit) == mod, 'getmodule(mod.StupidGit)')
132 test(inspect.getfile(mod.StupidGit) == TESTFN, 'getfile(mod.StupidGit)')
133 test(inspect.getsourcefile(mod.spam) == TESTFN, 'getsourcefile(mod.spam)')
134 test(inspect.getsourcefile(git.abuse) == TESTFN, 'getsourcefile(git.abuse)')
136 def sourcerange(top, bottom):
137 lines = string.split(source, '\n')
138 return string.join(lines[top-1:bottom], '\n') + '\n'
140 test(inspect.getsource(git.abuse) == sourcerange(29, 39),
141 'getsource(git.abuse)')
142 test(inspect.getsource(mod.StupidGit) == sourcerange(21, 46),
143 'getsource(mod.StupidGit)')
144 test(inspect.getdoc(mod.StupidGit) ==
145 'A longer,\n\nindented\n\ndocstring.', 'getdoc(mod.StupidGit)')
146 test(inspect.getdoc(git.abuse) ==
147 'Another\n\ndocstring\n\ncontaining\n\ntabs\n\n', 'getdoc(git.abuse)')
148 test(inspect.getcomments(mod.StupidGit) == '# line 20\n',
149 'getcomments(mod.StupidGit)')
151 args, varargs, varkw, defaults = inspect.getargspec(mod.eggs)
152 test(args == ['x', 'y'], 'mod.eggs args')
153 test(varargs == None, 'mod.eggs varargs')
154 test(varkw == None, 'mod.eggs varkw')
155 test(defaults == None, 'mod.eggs defaults')
156 test(inspect.formatargspec(args, varargs, varkw, defaults) ==
157 '(x, y)', 'mod.eggs formatted argspec')
158 args, varargs, varkw, defaults = inspect.getargspec(mod.spam)
159 test(args == ['a', 'b', 'c', 'd', ['e', ['f']]], 'mod.spam args')
160 test(varargs == 'g', 'mod.spam varargs')
161 test(varkw == 'h', 'mod.spam varkw')
162 test(defaults == (3, (4, (5,))), 'mod.spam defaults')
163 test(inspect.formatargspec(args, varargs, varkw, defaults) ==
164 '(a, b, c, d=3, (e, (f,))=(4, (5,)), *g, **h)',
165 'mod.spam formatted argspec')
167 git.abuse(7, 8, 9)
169 istest(inspect.istraceback, 'git.ex[2]')
170 istest(inspect.isframe, 'mod.fr')
172 test(len(git.tr) == 3, 'trace() length')
173 test(git.tr[0][1:] == (TESTFN, 46, 'argue',
174 [' self.tr = inspect.trace()\n'], 0),
175 'trace() row 2')
176 test(git.tr[1][1:] == (TESTFN, 9, 'spam', [' eggs(b + d, c + f)\n'], 0),
177 'trace() row 2')
178 test(git.tr[2][1:] == (TESTFN, 18, 'eggs', [' q = y / 0\n'], 0),
179 'trace() row 3')
181 test(len(mod.st) >= 5, 'stack() length')
182 test(mod.st[0][1:] ==
183 (TESTFN, 16, 'eggs', [' st = inspect.stack()\n'], 0),
184 'stack() row 1')
185 test(mod.st[1][1:] ==
186 (TESTFN, 9, 'spam', [' eggs(b + d, c + f)\n'], 0),
187 'stack() row 2')
188 test(mod.st[2][1:] ==
189 (TESTFN, 43, 'argue', [' spam(a, b, c)\n'], 0),
190 'stack() row 3')
191 test(mod.st[3][1:] ==
192 (TESTFN, 39, 'abuse', [' self.argue(a, b, c)\n'], 0),
193 'stack() row 4')
195 args, varargs, varkw, locals = inspect.getargvalues(mod.fr)
196 test(args == ['x', 'y'], 'mod.fr args')
197 test(varargs == None, 'mod.fr varargs')
198 test(varkw == None, 'mod.fr varkw')
199 test(locals == {'x': 11, 'p': 11, 'y': 14}, 'mod.fr locals')
200 test(inspect.formatargvalues(args, varargs, varkw, locals) ==
201 '(x=11, y=14)', 'mod.fr formatted argvalues')
203 args, varargs, varkw, locals = inspect.getargvalues(mod.fr.f_back)
204 test(args == ['a', 'b', 'c', 'd', ['e', ['f']]], 'mod.fr.f_back args')
205 test(varargs == 'g', 'mod.fr.f_back varargs')
206 test(varkw == 'h', 'mod.fr.f_back varkw')
207 test(inspect.formatargvalues(args, varargs, varkw, locals) ==
208 '(a=7, b=8, c=9, d=3, (e=4, (f=5,)), *g=(), **h={})',
209 'mod.fr.f_back formatted argvalues')
211 for fname in files_to_clean_up:
212 try:
213 os.unlink(fname)
214 except:
215 pass