blob: 9da66942870281dc2b35d37d6b70d0e83c17b563 [file] [log] [blame]
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001source = '''# line 1
2'A module docstring.'
3
4import sys, inspect
5# line 5
6
7# line 7
8def spam(a, b, c, d=3, (e, (f,))=(4, (5,)), *g, **h):
9 eggs(b + d, c + f)
10
11# line 11
12def 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
19
20# line 20
21class StupidGit:
22 """A longer,
23
24 indented
25
26 docstring."""
27# line 27
28
29 def abuse(self, a, b, c):
30 """Another
31
32\tdocstring
33
34 containing
35
36\ttabs
37\t
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()
47
48# line 48
49class MalodorousPervert(StupidGit):
50 pass
51
52class ParrotDroppings:
53 pass
54
55class FesteringGob(MalodorousPervert, ParrotDroppings):
56 pass
57'''
58
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
Martin v. Löwise59e2ba2003-05-03 09:09:02 +000064# isdatadescriptor
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000065
Barry Warsaw04f357c2002-07-23 19:04:11 +000066from test.test_support import TestFailed, TESTFN
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000067import sys, imp, os, string
68
69def test(assertion, message, *args):
70 if not assertion:
71 raise TestFailed, message % args
72
73import inspect
74
75file = open(TESTFN, 'w')
76file.write(source)
77file.close()
78
Tim Peters243bff42001-03-04 00:30:25 +000079# Note that load_source creates file TESTFN+'c' or TESTFN+'o'.
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000080mod = imp.load_source('testmod', TESTFN)
Tim Peters243bff42001-03-04 00:30:25 +000081files_to_clean_up = [TESTFN, TESTFN + 'c', TESTFN + 'o']
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000082
83def istest(func, exp):
84 obj = eval(exp)
85 test(func(obj), '%s(%s)' % (func.__name__, exp))
86 for other in [inspect.isbuiltin, inspect.isclass, inspect.iscode,
87 inspect.isframe, inspect.isfunction, inspect.ismethod,
88 inspect.ismodule, inspect.istraceback]:
89 if other is not func:
90 test(not other(obj), 'not %s(%s)' % (other.__name__, exp))
91
92git = mod.StupidGit()
93try:
94 1/0
95except:
96 tb = sys.exc_traceback
97
98istest(inspect.isbuiltin, 'sys.exit')
99istest(inspect.isbuiltin, '[].append')
100istest(inspect.isclass, 'mod.StupidGit')
101istest(inspect.iscode, 'mod.spam.func_code')
102istest(inspect.isframe, 'tb.tb_frame')
103istest(inspect.isfunction, 'mod.spam')
104istest(inspect.ismethod, 'mod.StupidGit.abuse')
105istest(inspect.ismethod, 'git.argue')
106istest(inspect.ismodule, 'mod')
107istest(inspect.istraceback, 'tb')
Martin v. Löwis4d28d962003-05-03 09:58:26 +0000108import __builtin__
109istest(inspect.isdatadescriptor, '__builtin__.file.closed')
110istest(inspect.isdatadescriptor, '__builtin__.file.softspace')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000111test(inspect.isroutine(mod.spam), 'isroutine(mod.spam)')
112test(inspect.isroutine([].count), 'isroutine([].count)')
113
114classes = inspect.getmembers(mod, inspect.isclass)
115test(classes ==
116 [('FesteringGob', mod.FesteringGob),
117 ('MalodorousPervert', mod.MalodorousPervert),
118 ('ParrotDroppings', mod.ParrotDroppings),
119 ('StupidGit', mod.StupidGit)], 'class list')
120tree = inspect.getclasstree(map(lambda x: x[1], classes), 1)
121test(tree ==
122 [(mod.ParrotDroppings, ()),
123 (mod.StupidGit, ()),
124 [(mod.MalodorousPervert, (mod.StupidGit,)),
125 [(mod.FesteringGob, (mod.MalodorousPervert, mod.ParrotDroppings))
126 ]
127 ]
128 ], 'class tree')
129
130functions = inspect.getmembers(mod, inspect.isfunction)
131test(functions == [('eggs', mod.eggs), ('spam', mod.spam)], 'function list')
132
133test(inspect.getdoc(mod) == 'A module docstring.', 'getdoc(mod)')
134test(inspect.getcomments(mod) == '# line 1\n', 'getcomments(mod)')
135test(inspect.getmodule(mod.StupidGit) == mod, 'getmodule(mod.StupidGit)')
136test(inspect.getfile(mod.StupidGit) == TESTFN, 'getfile(mod.StupidGit)')
137test(inspect.getsourcefile(mod.spam) == TESTFN, 'getsourcefile(mod.spam)')
138test(inspect.getsourcefile(git.abuse) == TESTFN, 'getsourcefile(git.abuse)')
139
140def sourcerange(top, bottom):
141 lines = string.split(source, '\n')
142 return string.join(lines[top-1:bottom], '\n') + '\n'
143
144test(inspect.getsource(git.abuse) == sourcerange(29, 39),
145 'getsource(git.abuse)')
146test(inspect.getsource(mod.StupidGit) == sourcerange(21, 46),
147 'getsource(mod.StupidGit)')
148test(inspect.getdoc(mod.StupidGit) ==
149 'A longer,\n\nindented\n\ndocstring.', 'getdoc(mod.StupidGit)')
150test(inspect.getdoc(git.abuse) ==
Ka-Ping Yeea59ef7b2002-11-30 03:53:15 +0000151 'Another\n\ndocstring\n\ncontaining\n\ntabs', 'getdoc(git.abuse)')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000152test(inspect.getcomments(mod.StupidGit) == '# line 20\n',
153 'getcomments(mod.StupidGit)')
154
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000155git.abuse(7, 8, 9)
156
157istest(inspect.istraceback, 'git.ex[2]')
158istest(inspect.isframe, 'mod.fr')
159
Ka-Ping Yeef170d7f2001-03-23 05:14:10 +0000160test(len(git.tr) == 3, 'trace() length')
161test(git.tr[0][1:] == (TESTFN, 46, 'argue',
162 [' self.tr = inspect.trace()\n'], 0),
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000163 'trace() row 2')
Ka-Ping Yeef170d7f2001-03-23 05:14:10 +0000164test(git.tr[1][1:] == (TESTFN, 9, 'spam', [' eggs(b + d, c + f)\n'], 0),
165 'trace() row 2')
166test(git.tr[2][1:] == (TESTFN, 18, 'eggs', [' q = y / 0\n'], 0),
167 'trace() row 3')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000168
169test(len(mod.st) >= 5, 'stack() length')
170test(mod.st[0][1:] ==
Ka-Ping Yee90543442001-03-02 05:48:10 +0000171 (TESTFN, 16, 'eggs', [' st = inspect.stack()\n'], 0),
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000172 'stack() row 1')
173test(mod.st[1][1:] ==
Ka-Ping Yee90543442001-03-02 05:48:10 +0000174 (TESTFN, 9, 'spam', [' eggs(b + d, c + f)\n'], 0),
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000175 'stack() row 2')
176test(mod.st[2][1:] ==
Ka-Ping Yee90543442001-03-02 05:48:10 +0000177 (TESTFN, 43, 'argue', [' spam(a, b, c)\n'], 0),
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000178 'stack() row 3')
179test(mod.st[3][1:] ==
Ka-Ping Yee90543442001-03-02 05:48:10 +0000180 (TESTFN, 39, 'abuse', [' self.argue(a, b, c)\n'], 0),
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000181 'stack() row 4')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000182
183args, varargs, varkw, locals = inspect.getargvalues(mod.fr)
184test(args == ['x', 'y'], 'mod.fr args')
185test(varargs == None, 'mod.fr varargs')
186test(varkw == None, 'mod.fr varkw')
187test(locals == {'x': 11, 'p': 11, 'y': 14}, 'mod.fr locals')
188test(inspect.formatargvalues(args, varargs, varkw, locals) ==
189 '(x=11, y=14)', 'mod.fr formatted argvalues')
190
191args, varargs, varkw, locals = inspect.getargvalues(mod.fr.f_back)
192test(args == ['a', 'b', 'c', 'd', ['e', ['f']]], 'mod.fr.f_back args')
193test(varargs == 'g', 'mod.fr.f_back varargs')
194test(varkw == 'h', 'mod.fr.f_back varkw')
195test(inspect.formatargvalues(args, varargs, varkw, locals) ==
196 '(a=7, b=8, c=9, d=3, (e=4, (f=5,)), *g=(), **h={})',
197 'mod.fr.f_back formatted argvalues')
198
Tim Peters243bff42001-03-04 00:30:25 +0000199for fname in files_to_clean_up:
200 try:
201 os.unlink(fname)
202 except:
203 pass
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000204
205# Test classic-class method resolution order.
206class A: pass
207class B(A): pass
208class C(A): pass
209class D(B, C): pass
210
211expected = (D, B, A, C)
212got = inspect.getmro(D)
213test(expected == got, "expected %r mro, got %r", expected, got)
214
215# The same w/ new-class MRO.
216class A(object): pass
217class B(A): pass
218class C(A): pass
219class D(B, C): pass
220
221expected = (D, B, C, A, object)
222got = inspect.getmro(D)
223test(expected == got, "expected %r mro, got %r", expected, got)
Tim Peters13b49d32001-09-23 02:00:29 +0000224
225# Test classify_class_attrs.
226def attrs_wo_objs(cls):
227 return [t[:3] for t in inspect.classify_class_attrs(cls)]
228
229class A:
230 def s(): pass
231 s = staticmethod(s)
232
233 def c(cls): pass
234 c = classmethod(c)
235
236 def getp(self): pass
237 p = property(getp)
238
239 def m(self): pass
240
241 def m1(self): pass
242
243 datablob = '1'
244
245attrs = attrs_wo_objs(A)
246test(('s', 'static method', A) in attrs, 'missing static method')
247test(('c', 'class method', A) in attrs, 'missing class method')
248test(('p', 'property', A) in attrs, 'missing property')
249test(('m', 'method', A) in attrs, 'missing plain method')
250test(('m1', 'method', A) in attrs, 'missing plain method')
251test(('datablob', 'data', A) in attrs, 'missing data')
252
253class B(A):
254 def m(self): pass
255
256attrs = attrs_wo_objs(B)
257test(('s', 'static method', A) in attrs, 'missing static method')
258test(('c', 'class method', A) in attrs, 'missing class method')
259test(('p', 'property', A) in attrs, 'missing property')
260test(('m', 'method', B) in attrs, 'missing plain method')
261test(('m1', 'method', A) in attrs, 'missing plain method')
262test(('datablob', 'data', A) in attrs, 'missing data')
263
264
265class C(A):
266 def m(self): pass
267 def c(self): pass
268
269attrs = attrs_wo_objs(C)
270test(('s', 'static method', A) in attrs, 'missing static method')
271test(('c', 'method', C) in attrs, 'missing plain method')
272test(('p', 'property', A) in attrs, 'missing property')
273test(('m', 'method', C) in attrs, 'missing plain method')
274test(('m1', 'method', A) in attrs, 'missing plain method')
275test(('datablob', 'data', A) in attrs, 'missing data')
276
277class D(B, C):
278 def m1(self): pass
279
280attrs = attrs_wo_objs(D)
281test(('s', 'static method', A) in attrs, 'missing static method')
282test(('c', 'class method', A) in attrs, 'missing class method')
283test(('p', 'property', A) in attrs, 'missing property')
284test(('m', 'method', B) in attrs, 'missing plain method')
285test(('m1', 'method', D) in attrs, 'missing plain method')
286test(('datablob', 'data', A) in attrs, 'missing data')
287
Tim Peters60066292001-10-15 22:53:29 +0000288# Repeat all that, but w/ new-style classes.
Tim Peters13b49d32001-09-23 02:00:29 +0000289
290class A(object):
Tim Peters13b49d32001-09-23 02:00:29 +0000291
292 def s(): pass
293 s = staticmethod(s)
294
295 def c(cls): pass
296 c = classmethod(c)
297
298 def getp(self): pass
299 p = property(getp)
300
301 def m(self): pass
302
303 def m1(self): pass
304
305 datablob = '1'
306
307attrs = attrs_wo_objs(A)
308test(('s', 'static method', A) in attrs, 'missing static method')
309test(('c', 'class method', A) in attrs, 'missing class method')
310test(('p', 'property', A) in attrs, 'missing property')
311test(('m', 'method', A) in attrs, 'missing plain method')
312test(('m1', 'method', A) in attrs, 'missing plain method')
313test(('datablob', 'data', A) in attrs, 'missing data')
314
315class B(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000316
317 def m(self): pass
318
319attrs = attrs_wo_objs(B)
320test(('s', 'static method', A) in attrs, 'missing static method')
321test(('c', 'class method', A) in attrs, 'missing class method')
322test(('p', 'property', A) in attrs, 'missing property')
323test(('m', 'method', B) in attrs, 'missing plain method')
324test(('m1', 'method', A) in attrs, 'missing plain method')
325test(('datablob', 'data', A) in attrs, 'missing data')
326
327
328class C(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000329
330 def m(self): pass
331 def c(self): pass
332
333attrs = attrs_wo_objs(C)
334test(('s', 'static method', A) in attrs, 'missing static method')
335test(('c', 'method', C) in attrs, 'missing plain method')
336test(('p', 'property', A) in attrs, 'missing property')
337test(('m', 'method', C) in attrs, 'missing plain method')
338test(('m1', 'method', A) in attrs, 'missing plain method')
339test(('datablob', 'data', A) in attrs, 'missing data')
340
341class D(B, C):
Tim Peters13b49d32001-09-23 02:00:29 +0000342
343 def m1(self): pass
344
345attrs = attrs_wo_objs(D)
346test(('s', 'static method', A) in attrs, 'missing static method')
347test(('c', 'method', C) in attrs, 'missing plain method')
348test(('p', 'property', A) in attrs, 'missing property')
349test(('m', 'method', B) in attrs, 'missing plain method')
350test(('m1', 'method', D) in attrs, 'missing plain method')
351test(('datablob', 'data', A) in attrs, 'missing data')
Jeremy Hyltonc4bf5ed2003-06-27 18:43:12 +0000352
353args, varargs, varkw, defaults = inspect.getargspec(mod.eggs)
354test(args == ['x', 'y'], 'mod.eggs args')
355test(varargs == None, 'mod.eggs varargs')
356test(varkw == None, 'mod.eggs varkw')
357test(defaults == None, 'mod.eggs defaults')
358test(inspect.formatargspec(args, varargs, varkw, defaults) ==
359 '(x, y)', 'mod.eggs formatted argspec')
360args, varargs, varkw, defaults = inspect.getargspec(mod.spam)
361test(args == ['a', 'b', 'c', 'd', ['e', ['f']]], 'mod.spam args')
362test(varargs == 'g', 'mod.spam varargs')
363test(varkw == 'h', 'mod.spam varkw')
364test(defaults == (3, (4, (5,))), 'mod.spam defaults')
365test(inspect.formatargspec(args, varargs, varkw, defaults) ==
366 '(a, b, c, d=3, (e, (f,))=(4, (5,)), *g, **h)',
367 'mod.spam formatted argspec')
368args, varargs, varkw, defaults = inspect.getargspec(A.m)
369test(args == ['self'], 'A.m args')
370test(varargs is None, 'A.m varargs')
371test(varkw is None, 'A.m varkw')
372test(defaults is None, 'A.m defaults')