8 def spam(a, b, c, d=3, (e, (f,))=(4, (5,)), *g, **h):
15 fr = inspect.currentframe()
29 def abuse(self, a, b, c):
41 def argue(self, a, b, c):
45 self.ex = sys.exc_info()
46 self.tr = inspect.trace()
49 class MalodorousPervert(StupidGit):
52 class ParrotDroppings:
55 class FesteringGob(MalodorousPervert, ParrotDroppings):
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
66 from test
.test_support
import TestFailed
, TESTFN
67 import sys
, imp
, os
, string
69 def test(assertion
, message
, *args
):
71 raise TestFailed
, message
% args
75 file = open(TESTFN
, 'w')
79 # Note that load_source creates file TESTFN+'c' or TESTFN+'o'.
80 mod
= imp
.load_source('testmod', TESTFN
)
81 files_to_clean_up
= [TESTFN
, TESTFN
+ 'c', TESTFN
+ 'o']
83 def istest(func
, 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
]:
90 test(not other(obj
), 'not %s(%s)' % (other
.__name
__, exp
))
96 tb
= sys
.exc_traceback
98 istest(inspect
.isbuiltin
, 'sys.exit')
99 istest(inspect
.isbuiltin
, '[].append')
100 istest(inspect
.isclass
, 'mod.StupidGit')
101 istest(inspect
.iscode
, 'mod.spam.func_code')
102 istest(inspect
.isframe
, 'tb.tb_frame')
103 istest(inspect
.isfunction
, 'mod.spam')
104 istest(inspect
.ismethod
, 'mod.StupidGit.abuse')
105 istest(inspect
.ismethod
, 'git.argue')
106 istest(inspect
.ismodule
, 'mod')
107 istest(inspect
.istraceback
, 'tb')
109 istest(inspect
.isdatadescriptor
, '__builtin__.file.closed')
110 istest(inspect
.isdatadescriptor
, '__builtin__.file.softspace')
111 test(inspect
.isroutine(mod
.spam
), 'isroutine(mod.spam)')
112 test(inspect
.isroutine([].count
), 'isroutine([].count)')
114 classes
= inspect
.getmembers(mod
, inspect
.isclass
)
116 [('FesteringGob', mod
.FesteringGob
),
117 ('MalodorousPervert', mod
.MalodorousPervert
),
118 ('ParrotDroppings', mod
.ParrotDroppings
),
119 ('StupidGit', mod
.StupidGit
)], 'class list')
120 tree
= inspect
.getclasstree(map(lambda x
: x
[1], classes
), 1)
122 [(mod
.ParrotDroppings
, ()),
124 [(mod
.MalodorousPervert
, (mod
.StupidGit
,)),
125 [(mod
.FesteringGob
, (mod
.MalodorousPervert
, mod
.ParrotDroppings
))
130 functions
= inspect
.getmembers(mod
, inspect
.isfunction
)
131 test(functions
== [('eggs', mod
.eggs
), ('spam', mod
.spam
)], 'function list')
133 test(inspect
.getdoc(mod
) == 'A module docstring.', 'getdoc(mod)')
134 test(inspect
.getcomments(mod
) == '# line 1\n', 'getcomments(mod)')
135 test(inspect
.getmodule(mod
.StupidGit
) == mod
, 'getmodule(mod.StupidGit)')
136 test(inspect
.getfile(mod
.StupidGit
) == TESTFN
, 'getfile(mod.StupidGit)')
137 test(inspect
.getsourcefile(mod
.spam
) == TESTFN
, 'getsourcefile(mod.spam)')
138 test(inspect
.getsourcefile(git
.abuse
) == TESTFN
, 'getsourcefile(git.abuse)')
140 def sourcerange(top
, bottom
):
141 lines
= string
.split(source
, '\n')
142 return string
.join(lines
[top
-1:bottom
], '\n') + '\n'
144 test(inspect
.getsource(git
.abuse
) == sourcerange(29, 39),
145 'getsource(git.abuse)')
146 test(inspect
.getsource(mod
.StupidGit
) == sourcerange(21, 46),
147 'getsource(mod.StupidGit)')
148 test(inspect
.getdoc(mod
.StupidGit
) ==
149 'A longer,\n\nindented\n\ndocstring.', 'getdoc(mod.StupidGit)')
150 test(inspect
.getdoc(git
.abuse
) ==
151 'Another\n\ndocstring\n\ncontaining\n\ntabs', 'getdoc(git.abuse)')
152 test(inspect
.getcomments(mod
.StupidGit
) == '# line 20\n',
153 'getcomments(mod.StupidGit)')
157 istest(inspect
.istraceback
, 'git.ex[2]')
158 istest(inspect
.isframe
, 'mod.fr')
160 test(len(git
.tr
) == 3, 'trace() length')
161 test(git
.tr
[0][1:] == (TESTFN
, 46, 'argue',
162 [' self.tr = inspect.trace()\n'], 0),
164 test(git
.tr
[1][1:] == (TESTFN
, 9, 'spam', [' eggs(b + d, c + f)\n'], 0),
166 test(git
.tr
[2][1:] == (TESTFN
, 18, 'eggs', [' q = y / 0\n'], 0),
169 test(len(mod
.st
) >= 5, 'stack() length')
170 test(mod
.st
[0][1:] ==
171 (TESTFN
, 16, 'eggs', [' st = inspect.stack()\n'], 0),
173 test(mod
.st
[1][1:] ==
174 (TESTFN
, 9, 'spam', [' eggs(b + d, c + f)\n'], 0),
176 test(mod
.st
[2][1:] ==
177 (TESTFN
, 43, 'argue', [' spam(a, b, c)\n'], 0),
179 test(mod
.st
[3][1:] ==
180 (TESTFN
, 39, 'abuse', [' self.argue(a, b, c)\n'], 0),
183 args
, varargs
, varkw
, locals = inspect
.getargvalues(mod
.fr
)
184 test(args
== ['x', 'y'], 'mod.fr args')
185 test(varargs
== None, 'mod.fr varargs')
186 test(varkw
== None, 'mod.fr varkw')
187 test(locals == {'x': 11, 'p': 11, 'y': 14}, 'mod.fr locals')
188 test(inspect
.formatargvalues(args
, varargs
, varkw
, locals) ==
189 '(x=11, y=14)', 'mod.fr formatted argvalues')
191 args
, varargs
, varkw
, locals = inspect
.getargvalues(mod
.fr
.f_back
)
192 test(args
== ['a', 'b', 'c', 'd', ['e', ['f']]], 'mod.fr.f_back args')
193 test(varargs
== 'g', 'mod.fr.f_back varargs')
194 test(varkw
== 'h', 'mod.fr.f_back varkw')
195 test(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')
199 for fname
in files_to_clean_up
:
205 # Test classic-class method resolution order.
211 expected
= (D
, B
, A
, C
)
212 got
= inspect
.getmro(D
)
213 test(expected
== got
, "expected %r mro, got %r", expected
, got
)
215 # The same w/ new-class MRO.
216 class A(object): pass
221 expected
= (D
, B
, C
, A
, object)
222 got
= inspect
.getmro(D
)
223 test(expected
== got
, "expected %r mro, got %r", expected
, got
)
225 # Test classify_class_attrs.
226 def attrs_wo_objs(cls
):
227 return [t
[:3] for t
in inspect
.classify_class_attrs(cls
)]
245 attrs
= attrs_wo_objs(A
)
246 test(('s', 'static method', A
) in attrs
, 'missing static method')
247 test(('c', 'class method', A
) in attrs
, 'missing class method')
248 test(('p', 'property', A
) in attrs
, 'missing property')
249 test(('m', 'method', A
) in attrs
, 'missing plain method')
250 test(('m1', 'method', A
) in attrs
, 'missing plain method')
251 test(('datablob', 'data', A
) in attrs
, 'missing data')
256 attrs
= attrs_wo_objs(B
)
257 test(('s', 'static method', A
) in attrs
, 'missing static method')
258 test(('c', 'class method', A
) in attrs
, 'missing class method')
259 test(('p', 'property', A
) in attrs
, 'missing property')
260 test(('m', 'method', B
) in attrs
, 'missing plain method')
261 test(('m1', 'method', A
) in attrs
, 'missing plain method')
262 test(('datablob', 'data', A
) in attrs
, 'missing data')
269 attrs
= attrs_wo_objs(C
)
270 test(('s', 'static method', A
) in attrs
, 'missing static method')
271 test(('c', 'method', C
) in attrs
, 'missing plain method')
272 test(('p', 'property', A
) in attrs
, 'missing property')
273 test(('m', 'method', C
) in attrs
, 'missing plain method')
274 test(('m1', 'method', A
) in attrs
, 'missing plain method')
275 test(('datablob', 'data', A
) in attrs
, 'missing data')
280 attrs
= attrs_wo_objs(D
)
281 test(('s', 'static method', A
) in attrs
, 'missing static method')
282 test(('c', 'class method', A
) in attrs
, 'missing class method')
283 test(('p', 'property', A
) in attrs
, 'missing property')
284 test(('m', 'method', B
) in attrs
, 'missing plain method')
285 test(('m1', 'method', D
) in attrs
, 'missing plain method')
286 test(('datablob', 'data', A
) in attrs
, 'missing data')
288 # Repeat all that, but w/ new-style classes.
307 attrs
= attrs_wo_objs(A
)
308 test(('s', 'static method', A
) in attrs
, 'missing static method')
309 test(('c', 'class method', A
) in attrs
, 'missing class method')
310 test(('p', 'property', A
) in attrs
, 'missing property')
311 test(('m', 'method', A
) in attrs
, 'missing plain method')
312 test(('m1', 'method', A
) in attrs
, 'missing plain method')
313 test(('datablob', 'data', A
) in attrs
, 'missing data')
319 attrs
= attrs_wo_objs(B
)
320 test(('s', 'static method', A
) in attrs
, 'missing static method')
321 test(('c', 'class method', A
) in attrs
, 'missing class method')
322 test(('p', 'property', A
) in attrs
, 'missing property')
323 test(('m', 'method', B
) in attrs
, 'missing plain method')
324 test(('m1', 'method', A
) in attrs
, 'missing plain method')
325 test(('datablob', 'data', A
) in attrs
, 'missing data')
333 attrs
= attrs_wo_objs(C
)
334 test(('s', 'static method', A
) in attrs
, 'missing static method')
335 test(('c', 'method', C
) in attrs
, 'missing plain method')
336 test(('p', 'property', A
) in attrs
, 'missing property')
337 test(('m', 'method', C
) in attrs
, 'missing plain method')
338 test(('m1', 'method', A
) in attrs
, 'missing plain method')
339 test(('datablob', 'data', A
) in attrs
, 'missing data')
345 attrs
= attrs_wo_objs(D
)
346 test(('s', 'static method', A
) in attrs
, 'missing static method')
347 test(('c', 'method', C
) in attrs
, 'missing plain method')
348 test(('p', 'property', A
) in attrs
, 'missing property')
349 test(('m', 'method', B
) in attrs
, 'missing plain method')
350 test(('m1', 'method', D
) in attrs
, 'missing plain method')
351 test(('datablob', 'data', A
) in attrs
, 'missing data')
353 args
, varargs
, varkw
, defaults
= inspect
.getargspec(mod
.eggs
)
354 test(args
== ['x', 'y'], 'mod.eggs args')
355 test(varargs
== None, 'mod.eggs varargs')
356 test(varkw
== None, 'mod.eggs varkw')
357 test(defaults
== None, 'mod.eggs defaults')
358 test(inspect
.formatargspec(args
, varargs
, varkw
, defaults
) ==
359 '(x, y)', 'mod.eggs formatted argspec')
360 args
, varargs
, varkw
, defaults
= inspect
.getargspec(mod
.spam
)
361 test(args
== ['a', 'b', 'c', 'd', ['e', ['f']]], 'mod.spam args')
362 test(varargs
== 'g', 'mod.spam varargs')
363 test(varkw
== 'h', 'mod.spam varkw')
364 test(defaults
== (3, (4, (5,))), 'mod.spam defaults')
365 test(inspect
.formatargspec(args
, varargs
, varkw
, defaults
) ==
366 '(a, b, c, d=3, (e, (f,))=(4, (5,)), *g, **h)',
367 'mod.spam formatted argspec')
368 args
, varargs
, varkw
, defaults
= inspect
.getargspec(A
.m
)
369 test(args
== ['self'], 'A.m args')
370 test(varargs
is None, 'A.m varargs')
371 test(varkw
is None, 'A.m varkw')
372 test(defaults
is None, 'A.m defaults')