0001 source = '''# line 1 0002 'A module docstring.' 0003 0004 import sys, inspect 0005 # line 5 0006 0007 # line 7 0008 def spam(a, b, c, d=3, (e, (f,))=(4, (5,)), *g, **h): 0009 eggs(b + d, c + f) 0010 0011 # line 11 0012 def eggs(x, y): 0013 "A docstring." 0014 global fr, st 0015 fr = inspect.currentframe() 0016 st = inspect.stack() 0017 p = x 0018 q = y / 0 0019 0020 # line 20 0021 class StupidGit: 0022 """A longer, 0023 0024 indented 0025 0026 docstring.""" 0027 # line 27 0028 0029 def abuse(self, a, b, c): 0030 """Another 0031 0032 \tdocstring 0033 0034 containing 0035 0036 \ttabs 0037 \t 0038 """ 0039 self.argue(a, b, c) 0040 # line 40 0041 def argue(self, a, b, c): 0042 try: 0043 spam(a, b, c) 0044 except: 0045 self.ex = sys.exc_info() 0046 self.tr = inspect.trace() 0047 0048 # line 48 0049 class MalodorousPervert(StupidGit): 0050 pass 0051 0052 class ParrotDroppings: 0053 pass 0054 0055 class FesteringGob(MalodorousPervert, ParrotDroppings): 0056 pass 0057 ''' 0058 0059 # Functions tested in this suite: 0060 # ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode, 0061 # isbuiltin, isroutine, getmembers, getdoc, getfile, getmodule, 0062 # getsourcefile, getcomments, getsource, getclasstree, getargspec, 0063 # getargvalues, formatargspec, formatargvalues, currentframe, stack, trace 0064 # isdatadescriptor 0065 0066 from test.test_support import TestFailed, TESTFN 0067 import sys, imp, os, string 0068 0069 def test(assertion, message, *args): 0070 if not assertion: 0071 raise TestFailed, message % args 0072 0073 import inspect 0074 0075 file = open(TESTFN, 'w') 0076 file.write(source) 0077 file.close() 0078 0079 # Note that load_source creates file TESTFN+'c' or TESTFN+'o'. 0080 mod = imp.load_source('testmod', TESTFN) 0081 files_to_clean_up = [TESTFN, TESTFN + 'c', TESTFN + 'o'] 0082 0083 def istest(func, exp): 0084 obj = eval(exp) 0085 test(func(obj), '%s(%s)' % (func.__name__, exp)) 0086 for other in [inspect.isbuiltin, inspect.isclass, inspect.iscode, 0087 inspect.isframe, inspect.isfunction, inspect.ismethod, 0088 inspect.ismodule, inspect.istraceback]: 0089 if other is not func: 0090 test(not other(obj), 'not %s(%s)' % (other.__name__, exp)) 0091 0092 git = mod.StupidGit() 0093 try: 0094 1/0 0095 except: 0096 tb = sys.exc_traceback 0097 0098 istest(inspect.isbuiltin, 'sys.exit') 0099 istest(inspect.isbuiltin, '[].append') 0100 istest(inspect.isclass, 'mod.StupidGit') 0101 istest(inspect.iscode, 'mod.spam.func_code') 0102 istest(inspect.isframe, 'tb.tb_frame') 0103 istest(inspect.isfunction, 'mod.spam') 0104 istest(inspect.ismethod, 'mod.StupidGit.abuse') 0105 istest(inspect.ismethod, 'git.argue') 0106 istest(inspect.ismodule, 'mod') 0107 istest(inspect.istraceback, 'tb') 0108 import __builtin__ 0109 istest(inspect.isdatadescriptor, '__builtin__.file.closed') 0110 istest(inspect.isdatadescriptor, '__builtin__.file.softspace') 0111 test(inspect.isroutine(mod.spam), 'isroutine(mod.spam)') 0112 test(inspect.isroutine([].count), 'isroutine([].count)') 0113 0114 classes = inspect.getmembers(mod, inspect.isclass) 0115 test(classes == 0116 [('FesteringGob', mod.FesteringGob), 0117 ('MalodorousPervert', mod.MalodorousPervert), 0118 ('ParrotDroppings', mod.ParrotDroppings), 0119 ('StupidGit', mod.StupidGit)], 'class list') 0120 tree = inspect.getclasstree(map(lambda x: x[1], classes), 1) 0121 test(tree == 0122 [(mod.ParrotDroppings, ()), 0123 (mod.StupidGit, ()), 0124 [(mod.MalodorousPervert, (mod.StupidGit,)), 0125 [(mod.FesteringGob, (mod.MalodorousPervert, mod.ParrotDroppings)) 0126 ] 0127 ] 0128 ], 'class tree') 0129 0130 functions = inspect.getmembers(mod, inspect.isfunction) 0131 test(functions == [('eggs', mod.eggs), ('spam', mod.spam)], 'function list') 0132 0133 test(inspect.getdoc(mod) == 'A module docstring.', 'getdoc(mod)') 0134 test(inspect.getcomments(mod) == '# line 1\n', 'getcomments(mod)') 0135 test(inspect.getmodule(mod.StupidGit) == mod, 'getmodule(mod.StupidGit)') 0136 test(inspect.getfile(mod.StupidGit) == TESTFN, 'getfile(mod.StupidGit)') 0137 test(inspect.getsourcefile(mod.spam) == TESTFN, 'getsourcefile(mod.spam)') 0138 test(inspect.getsourcefile(git.abuse) == TESTFN, 'getsourcefile(git.abuse)') 0139 0140 def sourcerange(top, bottom): 0141 lines = string.split(source, '\n') 0142 return string.join(lines[top-1:bottom], '\n') + '\n' 0143 0144 test(inspect.getsource(git.abuse) == sourcerange(29, 39), 0145 'getsource(git.abuse)') 0146 test(inspect.getsource(mod.StupidGit) == sourcerange(21, 46), 0147 'getsource(mod.StupidGit)') 0148 test(inspect.getdoc(mod.StupidGit) == 0149 'A longer,\n\nindented\n\ndocstring.', 'getdoc(mod.StupidGit)') 0150 test(inspect.getdoc(git.abuse) == 0151 'Another\n\ndocstring\n\ncontaining\n\ntabs', 'getdoc(git.abuse)') 0152 test(inspect.getcomments(mod.StupidGit) == '# line 20\n', 0153 'getcomments(mod.StupidGit)') 0154 0155 git.abuse(7, 8, 9) 0156 0157 istest(inspect.istraceback, 'git.ex[2]') 0158 istest(inspect.isframe, 'mod.fr') 0159 0160 test(len(git.tr) == 3, 'trace() length') 0161 test(git.tr[0][1:] == (TESTFN, 43, 'argue', 0162 [' spam(a, b, c)\n'], 0), 0163 'trace() row 2') 0164 test(git.tr[1][1:] == (TESTFN, 9, 'spam', [' eggs(b + d, c + f)\n'], 0), 0165 'trace() row 2') 0166 test(git.tr[2][1:] == (TESTFN, 18, 'eggs', [' q = y / 0\n'], 0), 0167 'trace() row 3') 0168 0169 test(len(mod.st) >= 5, 'stack() length') 0170 test(mod.st[0][1:] == 0171 (TESTFN, 16, 'eggs', [' st = inspect.stack()\n'], 0), 0172 'stack() row 1') 0173 test(mod.st[1][1:] == 0174 (TESTFN, 9, 'spam', [' eggs(b + d, c + f)\n'], 0), 0175 'stack() row 2') 0176 test(mod.st[2][1:] == 0177 (TESTFN, 43, 'argue', [' spam(a, b, c)\n'], 0), 0178 'stack() row 3') 0179 test(mod.st[3][1:] == 0180 (TESTFN, 39, 'abuse', [' self.argue(a, b, c)\n'], 0), 0181 'stack() row 4') 0182 0183 args, varargs, varkw, locals = inspect.getargvalues(mod.fr) 0184 test(args == ['x', 'y'], 'mod.fr args') 0185 test(varargs == None, 'mod.fr varargs') 0186 test(varkw == None, 'mod.fr varkw') 0187 test(locals == {'x': 11, 'p': 11, 'y': 14}, 'mod.fr locals') 0188 test(inspect.formatargvalues(args, varargs, varkw, locals) == 0189 '(x=11, y=14)', 'mod.fr formatted argvalues') 0190 0191 args, varargs, varkw, locals = inspect.getargvalues(mod.fr.f_back) 0192 test(args == ['a', 'b', 'c', 'd', ['e', ['f']]], 'mod.fr.f_back args') 0193 test(varargs == 'g', 'mod.fr.f_back varargs') 0194 test(varkw == 'h', 'mod.fr.f_back varkw') 0195 test(inspect.formatargvalues(args, varargs, varkw, locals) == 0196 '(a=7, b=8, c=9, d=3, (e=4, (f=5,)), *g=(), **h={})', 0197 'mod.fr.f_back formatted argvalues') 0198 0199 for fname in files_to_clean_up: 0200 try: 0201 os.unlink(fname) 0202 except: 0203 pass 0204 0205 # Test for decorators as well. 0206 0207 source = r""" 0208 def wrap(foo=None): 0209 def wrapper(func): 0210 return func 0211 return wrapper 0212 0213 def replace(func): 0214 def insteadfunc(): 0215 print 'hello' 0216 return insteadfunc 0217 0218 # two decorators, one with argument 0219 @wrap() 0220 @wrap(wrap) 0221 def wrapped(): 0222 pass 0223 0224 @replace 0225 def gone(): 0226 pass""" 0227 0228 file = open(TESTFN + "2", "w") 0229 file.write(source) 0230 file.close() 0231 files_to_clean_up = [TESTFN + "2", TESTFN + '2c', TESTFN + '2o'] 0232 0233 mod2 = imp.load_source("testmod3", TESTFN + "2") 0234 0235 test(inspect.getsource(mod2.wrapped) == sourcerange(13, 16), 0236 "inspect.getsource(mod.wrapped)") 0237 test(inspect.getsource(mod2.gone) == sourcerange(8, 9), 0238 "inspect.getsource(mod.gone)") 0239 0240 for fname in files_to_clean_up: 0241 try: 0242 os.unlink(fname) 0243 except: 0244 pass 0245 0246 # Test classic-class method resolution order. 0247 class A: pass 0248 class B(A): pass 0249 class C(A): pass 0250 class D(B, C): pass 0251 0252 expected = (D, B, A, C) 0253 got = inspect.getmro(D) 0254 test(expected == got, "expected %r mro, got %r", expected, got) 0255 0256 # The same w/ new-class MRO. 0257 class A(object): pass 0258 class B(A): pass 0259 class C(A): pass 0260 class D(B, C): pass 0261 0262 expected = (D, B, C, A, object) 0263 got = inspect.getmro(D) 0264 test(expected == got, "expected %r mro, got %r", expected, got) 0265 0266 # Test classify_class_attrs. 0267 def attrs_wo_objs(cls): 0268 return [t[:3] for t in inspect.classify_class_attrs(cls)] 0269 0270 class A: 0271 def s(): pass 0272 s = staticmethod(s) 0273 0274 def c(cls): pass 0275 c = classmethod(c) 0276 0277 def getp(self): pass 0278 p = property(getp) 0279 0280 def m(self): pass 0281 0282 def m1(self): pass 0283 0284 datablob = '1' 0285 0286 attrs = attrs_wo_objs(A) 0287 test(('s', 'static method', A) in attrs, 'missing static method') 0288 test(('c', 'class method', A) in attrs, 'missing class method') 0289 test(('p', 'property', A) in attrs, 'missing property') 0290 test(('m', 'method', A) in attrs, 'missing plain method') 0291 test(('m1', 'method', A) in attrs, 'missing plain method') 0292 test(('datablob', 'data', A) in attrs, 'missing data') 0293 0294 class B(A): 0295 def m(self): pass 0296 0297 attrs = attrs_wo_objs(B) 0298 test(('s', 'static method', A) in attrs, 'missing static method') 0299 test(('c', 'class method', A) in attrs, 'missing class method') 0300 test(('p', 'property', A) in attrs, 'missing property') 0301 test(('m', 'method', B) in attrs, 'missing plain method') 0302 test(('m1', 'method', A) in attrs, 'missing plain method') 0303 test(('datablob', 'data', A) in attrs, 'missing data') 0304 0305 0306 class C(A): 0307 def m(self): pass 0308 def c(self): pass 0309 0310 attrs = attrs_wo_objs(C) 0311 test(('s', 'static method', A) in attrs, 'missing static method') 0312 test(('c', 'method', C) in attrs, 'missing plain method') 0313 test(('p', 'property', A) in attrs, 'missing property') 0314 test(('m', 'method', C) in attrs, 'missing plain method') 0315 test(('m1', 'method', A) in attrs, 'missing plain method') 0316 test(('datablob', 'data', A) in attrs, 'missing data') 0317 0318 class D(B, C): 0319 def m1(self): pass 0320 0321 attrs = attrs_wo_objs(D) 0322 test(('s', 'static method', A) in attrs, 'missing static method') 0323 test(('c', 'class method', A) in attrs, 'missing class method') 0324 test(('p', 'property', A) in attrs, 'missing property') 0325 test(('m', 'method', B) in attrs, 'missing plain method') 0326 test(('m1', 'method', D) in attrs, 'missing plain method') 0327 test(('datablob', 'data', A) in attrs, 'missing data') 0328 0329 # Repeat all that, but w/ new-style classes. 0330 0331 class A(object): 0332 0333 def s(): pass 0334 s = staticmethod(s) 0335 0336 def c(cls): pass 0337 c = classmethod(c) 0338 0339 def getp(self): pass 0340 p = property(getp) 0341 0342 def m(self): pass 0343 0344 def m1(self): pass 0345 0346 datablob = '1' 0347 0348 attrs = attrs_wo_objs(A) 0349 test(('s', 'static method', A) in attrs, 'missing static method') 0350 test(('c', 'class method', A) in attrs, 'missing class method') 0351 test(('p', 'property', A) in attrs, 'missing property') 0352 test(('m', 'method', A) in attrs, 'missing plain method') 0353 test(('m1', 'method', A) in attrs, 'missing plain method') 0354 test(('datablob', 'data', A) in attrs, 'missing data') 0355 0356 class B(A): 0357 0358 def m(self): pass 0359 0360 attrs = attrs_wo_objs(B) 0361 test(('s', 'static method', A) in attrs, 'missing static method') 0362 test(('c', 'class method', A) in attrs, 'missing class method') 0363 test(('p', 'property', A) in attrs, 'missing property') 0364 test(('m', 'method', B) in attrs, 'missing plain method') 0365 test(('m1', 'method', A) in attrs, 'missing plain method') 0366 test(('datablob', 'data', A) in attrs, 'missing data') 0367 0368 0369 class C(A): 0370 0371 def m(self): pass 0372 def c(self): pass 0373 0374 attrs = attrs_wo_objs(C) 0375 test(('s', 'static method', A) in attrs, 'missing static method') 0376 test(('c', 'method', C) in attrs, 'missing plain method') 0377 test(('p', 'property', A) in attrs, 'missing property') 0378 test(('m', 'method', C) in attrs, 'missing plain method') 0379 test(('m1', 'method', A) in attrs, 'missing plain method') 0380 test(('datablob', 'data', A) in attrs, 'missing data') 0381 0382 class D(B, C): 0383 0384 def m1(self): pass 0385 0386 attrs = attrs_wo_objs(D) 0387 test(('s', 'static method', A) in attrs, 'missing static method') 0388 test(('c', 'method', C) in attrs, 'missing plain method') 0389 test(('p', 'property', A) in attrs, 'missing property') 0390 test(('m', 'method', B) in attrs, 'missing plain method') 0391 test(('m1', 'method', D) in attrs, 'missing plain method') 0392 test(('datablob', 'data', A) in attrs, 'missing data') 0393 0394 args, varargs, varkw, defaults = inspect.getargspec(mod.eggs) 0395 test(args == ['x', 'y'], 'mod.eggs args') 0396 test(varargs == None, 'mod.eggs varargs') 0397 test(varkw == None, 'mod.eggs varkw') 0398 test(defaults == None, 'mod.eggs defaults') 0399 test(inspect.formatargspec(args, varargs, varkw, defaults) == 0400 '(x, y)', 'mod.eggs formatted argspec') 0401 args, varargs, varkw, defaults = inspect.getargspec(mod.spam) 0402 test(args == ['a', 'b', 'c', 'd', ['e', ['f']]], 'mod.spam args') 0403 test(varargs == 'g', 'mod.spam varargs') 0404 test(varkw == 'h', 'mod.spam varkw') 0405 test(defaults == (3, (4, (5,))), 'mod.spam defaults') 0406 test(inspect.formatargspec(args, varargs, varkw, defaults) == 0407 '(a, b, c, d=3, (e, (f,))=(4, (5,)), *g, **h)', 0408 'mod.spam formatted argspec') 0409 args, varargs, varkw, defaults = inspect.getargspec(A.m) 0410 test(args == ['self'], 'A.m args') 0411 test(varargs is None, 'A.m varargs') 0412 test(varkw is None, 'A.m varkw') 0413 test(defaults is None, 'A.m defaults') 0414 0415 # Doc/lib/libinspect.tex claims there are 11 such functions 0416 count = len(filter(lambda x:x.startswith('is'), dir(inspect))) 0417 test(count == 11, "There are %d (not 11) is* functions", count) 0418 0419 def sublistOfOne((foo)): return 1 0420 0421 args, varargs, varkw, defaults = inspect.getargspec(sublistOfOne) 0422 test(args == [['foo']], 'sublistOfOne args') 0423 test(varargs is None, 'sublistOfOne varargs') 0424 test(varkw is None, 'sublistOfOne varkw') 0425 test(defaults is None, 'sublistOfOn defaults') 0426
Generated by PyXR 0.9.4