PyXR

c:\python24\lib \ test \ test_inspect.py



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
SourceForge.net Logo