blob: e4c4ee8039bbd89de7e7c1ed43e3930a21d44c35 [file] [log] [blame]
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001import sys
Barry Warsaw00decd72006-07-27 23:43:15 +00002import types
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00003import unittest
4import inspect
Barry Warsaw00decd72006-07-27 23:43:15 +00005import datetime
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00006
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00007from test.test_support import TESTFN, run_unittest
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00008
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00009from test import inspect_fodder as mod
10from test import inspect_fodder2 as mod2
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000011
R. David Murray996ba022009-05-13 17:14:11 +000012# C module for test_findsource_binary
R. David Murray87855542009-05-14 16:12:57 +000013import unicodedata
R. David Murray996ba022009-05-13 17:14:11 +000014
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000015# Functions tested in this suite:
16# ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode,
Facundo Batista759bfc62008-02-18 03:43:43 +000017# isbuiltin, isroutine, isgenerator, isgeneratorfunction, getmembers,
18# getdoc, getfile, getmodule, getsourcefile, getcomments, getsource,
19# getclasstree, getargspec, getargvalues, formatargspec, formatargvalues,
20# currentframe, stack, trace, isdatadescriptor
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000021
Nick Coghlana2053472008-12-14 10:54:50 +000022# NOTE: There are some additional tests relating to interaction with
23# zipimport in the test_zipimport_support test module.
24
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000025modfile = mod.__file__
Georg Brandlb2afe852006-06-09 20:43:48 +000026if modfile.endswith(('c', 'o')):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000027 modfile = modfile[:-1]
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000028
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000029import __builtin__
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000030
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000031try:
32 1/0
33except:
34 tb = sys.exc_traceback
35
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000036git = mod.StupidGit()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000037
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000038class IsTestBase(unittest.TestCase):
39 predicates = set([inspect.isbuiltin, inspect.isclass, inspect.iscode,
40 inspect.isframe, inspect.isfunction, inspect.ismethod,
Facundo Batista759bfc62008-02-18 03:43:43 +000041 inspect.ismodule, inspect.istraceback,
42 inspect.isgenerator, inspect.isgeneratorfunction])
Tim Peters5a9fb3c2005-01-07 16:01:32 +000043
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000044 def istest(self, predicate, exp):
45 obj = eval(exp)
Benjamin Peterson5c8da862009-06-30 22:57:08 +000046 self.assertTrue(predicate(obj), '%s(%s)' % (predicate.__name__, exp))
Tim Peters5a9fb3c2005-01-07 16:01:32 +000047
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000048 for other in self.predicates - set([predicate]):
Facundo Batista759bfc62008-02-18 03:43:43 +000049 if predicate == inspect.isgeneratorfunction and\
50 other == inspect.isfunction:
51 continue
Benjamin Peterson5c8da862009-06-30 22:57:08 +000052 self.assertFalse(other(obj), 'not %s(%s)' % (other.__name__, exp))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000053
Facundo Batista759bfc62008-02-18 03:43:43 +000054def generator_function_example(self):
55 for i in xrange(2):
56 yield i
57
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000058class TestPredicates(IsTestBase):
Christian Heimes728bee82008-03-03 20:30:29 +000059 def test_sixteen(self):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000060 count = len(filter(lambda x:x.startswith('is'), dir(inspect)))
Facundo Batista759bfc62008-02-18 03:43:43 +000061 # This test is here for remember you to update Doc/library/inspect.rst
Georg Brandl26bc1772008-03-03 20:39:00 +000062 # which claims there are 16 such functions
Christian Heimes728bee82008-03-03 20:30:29 +000063 expected = 16
Neal Norwitzdf80af72006-07-28 04:22:34 +000064 err_msg = "There are %d (not %d) is* functions" % (count, expected)
65 self.assertEqual(count, expected, err_msg)
Tim Peters5a9fb3c2005-01-07 16:01:32 +000066
Facundo Batista759bfc62008-02-18 03:43:43 +000067
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000068 def test_excluding_predicates(self):
69 self.istest(inspect.isbuiltin, 'sys.exit')
70 self.istest(inspect.isbuiltin, '[].append')
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000071 self.istest(inspect.iscode, 'mod.spam.func_code')
72 self.istest(inspect.isframe, 'tb.tb_frame')
73 self.istest(inspect.isfunction, 'mod.spam')
74 self.istest(inspect.ismethod, 'mod.StupidGit.abuse')
75 self.istest(inspect.ismethod, 'git.argue')
76 self.istest(inspect.ismodule, 'mod')
77 self.istest(inspect.istraceback, 'tb')
78 self.istest(inspect.isdatadescriptor, '__builtin__.file.closed')
79 self.istest(inspect.isdatadescriptor, '__builtin__.file.softspace')
Facundo Batista759bfc62008-02-18 03:43:43 +000080 self.istest(inspect.isgenerator, '(x for x in xrange(2))')
81 self.istest(inspect.isgeneratorfunction, 'generator_function_example')
Barry Warsaw00decd72006-07-27 23:43:15 +000082 if hasattr(types, 'GetSetDescriptorType'):
83 self.istest(inspect.isgetsetdescriptor,
84 'type(tb.tb_frame).f_locals')
85 else:
Benjamin Peterson5c8da862009-06-30 22:57:08 +000086 self.assertFalse(inspect.isgetsetdescriptor(type(tb.tb_frame).f_locals))
Barry Warsaw00decd72006-07-27 23:43:15 +000087 if hasattr(types, 'MemberDescriptorType'):
88 self.istest(inspect.ismemberdescriptor, 'datetime.timedelta.days')
89 else:
Benjamin Peterson5c8da862009-06-30 22:57:08 +000090 self.assertFalse(inspect.ismemberdescriptor(datetime.timedelta.days))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000091
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000092 def test_isroutine(self):
Benjamin Peterson5c8da862009-06-30 22:57:08 +000093 self.assertTrue(inspect.isroutine(mod.spam))
94 self.assertTrue(inspect.isroutine([].count))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000095
Benjamin Peterson5e5fbb62009-01-17 22:27:54 +000096 def test_isclass(self):
97 self.istest(inspect.isclass, 'mod.StupidGit')
98 self.assertTrue(inspect.isclass(list))
99
100 class newstyle(object): pass
101 self.assertTrue(inspect.isclass(newstyle))
102
103 class CustomGetattr(object):
104 def __getattr__(self, attr):
105 return None
106 self.assertFalse(inspect.isclass(CustomGetattr()))
107
Amaury Forgeot d'Arcb54447f2009-01-13 23:39:22 +0000108 def test_get_slot_members(self):
109 class C(object):
110 __slots__ = ("a", "b")
111
112 x = C()
113 x.a = 42
114 members = dict(inspect.getmembers(x))
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000115 self.assertTrue('a' in members)
116 self.assertTrue('b' not in members)
Amaury Forgeot d'Arcb54447f2009-01-13 23:39:22 +0000117
118
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000119class TestInterpreterStack(IsTestBase):
120 def __init__(self, *args, **kwargs):
121 unittest.TestCase.__init__(self, *args, **kwargs)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000122
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000123 git.abuse(7, 8, 9)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000124
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000125 def test_abuse_done(self):
126 self.istest(inspect.istraceback, 'git.ex[2]')
127 self.istest(inspect.isframe, 'mod.fr')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000128
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000129 def test_stack(self):
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000130 self.assertTrue(len(mod.st) >= 5)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000131 self.assertEqual(mod.st[0][1:],
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000132 (modfile, 16, 'eggs', [' st = inspect.stack()\n'], 0))
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000133 self.assertEqual(mod.st[1][1:],
134 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
135 self.assertEqual(mod.st[2][1:],
136 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
137 self.assertEqual(mod.st[3][1:],
138 (modfile, 39, 'abuse', [' self.argue(a, b, c)\n'], 0))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000139
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000140 def test_trace(self):
141 self.assertEqual(len(git.tr), 3)
142 self.assertEqual(git.tr[0][1:], (modfile, 43, 'argue',
143 [' spam(a, b, c)\n'], 0))
144 self.assertEqual(git.tr[1][1:], (modfile, 9, 'spam',
145 [' eggs(b + d, c + f)\n'], 0))
146 self.assertEqual(git.tr[2][1:], (modfile, 18, 'eggs',
147 [' q = y / 0\n'], 0))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000148
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000149 def test_frame(self):
150 args, varargs, varkw, locals = inspect.getargvalues(mod.fr)
151 self.assertEqual(args, ['x', 'y'])
152 self.assertEqual(varargs, None)
153 self.assertEqual(varkw, None)
154 self.assertEqual(locals, {'x': 11, 'p': 11, 'y': 14})
155 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
156 '(x=11, y=14)')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000157
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000158 def test_previous_frame(self):
159 args, varargs, varkw, locals = inspect.getargvalues(mod.fr.f_back)
160 self.assertEqual(args, ['a', 'b', 'c', 'd', ['e', ['f']]])
161 self.assertEqual(varargs, 'g')
162 self.assertEqual(varkw, 'h')
163 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
164 '(a=7, b=8, c=9, d=3, (e=4, (f=5,)), *g=(), **h={})')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000165
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000166class GetSourceBase(unittest.TestCase):
167 # Subclasses must override.
168 fodderFile = None
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000169
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000170 def __init__(self, *args, **kwargs):
171 unittest.TestCase.__init__(self, *args, **kwargs)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000172
Philip Jenvey6a111022009-05-28 05:58:44 +0000173 with open(inspect.getsourcefile(self.fodderFile)) as fp:
174 self.source = fp.read()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000175
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000176 def sourcerange(self, top, bottom):
177 lines = self.source.split("\n")
178 return "\n".join(lines[top-1:bottom]) + "\n"
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000179
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000180 def assertSourceEqual(self, obj, top, bottom):
181 self.assertEqual(inspect.getsource(obj),
182 self.sourcerange(top, bottom))
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000183
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000184class TestRetrievingSourceCode(GetSourceBase):
185 fodderFile = mod
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000186
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000187 def test_getclasses(self):
188 classes = inspect.getmembers(mod, inspect.isclass)
189 self.assertEqual(classes,
190 [('FesteringGob', mod.FesteringGob),
191 ('MalodorousPervert', mod.MalodorousPervert),
192 ('ParrotDroppings', mod.ParrotDroppings),
193 ('StupidGit', mod.StupidGit)])
194 tree = inspect.getclasstree([cls[1] for cls in classes], 1)
195 self.assertEqual(tree,
196 [(mod.ParrotDroppings, ()),
197 (mod.StupidGit, ()),
198 [(mod.MalodorousPervert, (mod.StupidGit,)),
199 [(mod.FesteringGob, (mod.MalodorousPervert,
200 mod.ParrotDroppings))
201 ]
202 ]
203 ])
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000204
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000205 def test_getfunctions(self):
206 functions = inspect.getmembers(mod, inspect.isfunction)
207 self.assertEqual(functions, [('eggs', mod.eggs),
208 ('spam', mod.spam)])
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000209
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000210 def test_getdoc(self):
211 self.assertEqual(inspect.getdoc(mod), 'A module docstring.')
212 self.assertEqual(inspect.getdoc(mod.StupidGit),
213 'A longer,\n\nindented\n\ndocstring.')
214 self.assertEqual(inspect.getdoc(git.abuse),
215 'Another\n\ndocstring\n\ncontaining\n\ntabs')
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000216
Georg Brandl7be19aa2008-06-07 15:59:10 +0000217 def test_cleandoc(self):
218 self.assertEqual(inspect.cleandoc('An\n indented\n docstring.'),
219 'An\nindented\ndocstring.')
220
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000221 def test_getcomments(self):
222 self.assertEqual(inspect.getcomments(mod), '# line 1\n')
223 self.assertEqual(inspect.getcomments(mod.StupidGit), '# line 20\n')
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000224
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000225 def test_getmodule(self):
Nick Coghlanc495c662006-09-07 10:50:34 +0000226 # Check actual module
227 self.assertEqual(inspect.getmodule(mod), mod)
228 # Check class (uses __module__ attribute)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000229 self.assertEqual(inspect.getmodule(mod.StupidGit), mod)
Nick Coghlanc495c662006-09-07 10:50:34 +0000230 # Check a method (no __module__ attribute, falls back to filename)
231 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
232 # Do it again (check the caching isn't broken)
233 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
234 # Check a builtin
235 self.assertEqual(inspect.getmodule(str), sys.modules["__builtin__"])
236 # Check filename override
237 self.assertEqual(inspect.getmodule(None, modfile), mod)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000238
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000239 def test_getsource(self):
240 self.assertSourceEqual(git.abuse, 29, 39)
241 self.assertSourceEqual(mod.StupidGit, 21, 46)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000242
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000243 def test_getsourcefile(self):
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000244 self.assertEqual(inspect.getsourcefile(mod.spam), modfile)
245 self.assertEqual(inspect.getsourcefile(git.abuse), modfile)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000246
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000247 def test_getfile(self):
248 self.assertEqual(inspect.getfile(mod.StupidGit), mod.__file__)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000249
Phillip J. Eby5d86bdb2006-07-10 19:03:29 +0000250 def test_getmodule_recursion(self):
Christian Heimesc756d002007-11-27 21:34:01 +0000251 from types import ModuleType
Phillip J. Eby5d86bdb2006-07-10 19:03:29 +0000252 name = '__inspect_dummy'
Christian Heimesc756d002007-11-27 21:34:01 +0000253 m = sys.modules[name] = ModuleType(name)
Tim Peters722b8832006-07-10 21:11:49 +0000254 m.__file__ = "<string>" # hopefully not a real filename...
Phillip J. Eby5d86bdb2006-07-10 19:03:29 +0000255 m.__loader__ = "dummy" # pretend the filename is understood by a loader
256 exec "def x(): pass" in m.__dict__
257 self.assertEqual(inspect.getsourcefile(m.x.func_code), '<string>')
258 del sys.modules[name]
Phillip J. Eby1a2959c2006-07-20 15:54:16 +0000259 inspect.getmodule(compile('a=10','','single'))
Phillip J. Eby5d86bdb2006-07-10 19:03:29 +0000260
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000261class TestDecorators(GetSourceBase):
262 fodderFile = mod2
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000263
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000264 def test_wrapped_decorator(self):
265 self.assertSourceEqual(mod2.wrapped, 14, 17)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000266
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000267 def test_replacing_decorator(self):
268 self.assertSourceEqual(mod2.gone, 9, 10)
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000269
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000270class TestOneliners(GetSourceBase):
271 fodderFile = mod2
272 def test_oneline_lambda(self):
273 # Test inspect.getsource with a one-line lambda function.
274 self.assertSourceEqual(mod2.oll, 25, 25)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000275
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000276 def test_threeline_lambda(self):
277 # Test inspect.getsource with a three-line lambda function,
278 # where the second and third lines are _not_ indented.
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000279 self.assertSourceEqual(mod2.tll, 28, 30)
280
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000281 def test_twoline_indented_lambda(self):
282 # Test inspect.getsource with a two-line lambda function,
283 # where the second line _is_ indented.
284 self.assertSourceEqual(mod2.tlli, 33, 34)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000285
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000286 def test_onelinefunc(self):
287 # Test inspect.getsource with a regular one-line function.
288 self.assertSourceEqual(mod2.onelinefunc, 37, 37)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000289
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000290 def test_manyargs(self):
291 # Test inspect.getsource with a regular function where
292 # the arguments are on two lines and _not_ indented and
293 # the body on the second line with the last arguments.
294 self.assertSourceEqual(mod2.manyargs, 40, 41)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000295
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000296 def test_twolinefunc(self):
297 # Test inspect.getsource with a regular function where
298 # the body is on two lines, following the argument list and
299 # continued on the next line by a \\.
300 self.assertSourceEqual(mod2.twolinefunc, 44, 45)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000301
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000302 def test_lambda_in_list(self):
303 # Test inspect.getsource with a one-line lambda function
304 # defined in a list, indented.
305 self.assertSourceEqual(mod2.a[1], 49, 49)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000306
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000307 def test_anonymous(self):
308 # Test inspect.getsource with a lambda function defined
309 # as argument to another function.
310 self.assertSourceEqual(mod2.anonymous, 55, 55)
311
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000312class TestBuggyCases(GetSourceBase):
313 fodderFile = mod2
314
315 def test_with_comment(self):
316 self.assertSourceEqual(mod2.with_comment, 58, 59)
317
318 def test_multiline_sig(self):
319 self.assertSourceEqual(mod2.multiline_sig[0], 63, 64)
320
Armin Rigodd5c0232005-09-25 11:45:45 +0000321 def test_nested_class(self):
322 self.assertSourceEqual(mod2.func69().func71, 71, 72)
323
324 def test_one_liner_followed_by_non_name(self):
325 self.assertSourceEqual(mod2.func77, 77, 77)
326
327 def test_one_liner_dedent_non_name(self):
328 self.assertSourceEqual(mod2.cls82.func83, 83, 83)
329
330 def test_with_comment_instead_of_docstring(self):
331 self.assertSourceEqual(mod2.func88, 88, 90)
332
Georg Brandl2463f8f2006-08-14 21:34:08 +0000333 def test_method_in_dynamic_class(self):
334 self.assertSourceEqual(mod2.method_in_dynamic_class, 95, 97)
335
R. David Murray87855542009-05-14 16:12:57 +0000336 @unittest.skipIf(
337 not hasattr(unicodedata, '__file__') or
338 unicodedata.__file__[-4:] in (".pyc", ".pyo"),
339 "unicodedata is not an external binary module")
R. David Murray996ba022009-05-13 17:14:11 +0000340 def test_findsource_binary(self):
R. David Murray87855542009-05-14 16:12:57 +0000341 self.assertRaises(IOError, inspect.getsource, unicodedata)
342 self.assertRaises(IOError, inspect.findsource, unicodedata)
R. David Murray996ba022009-05-13 17:14:11 +0000343
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000344# Helper for testing classify_class_attrs.
Tim Peters13b49d32001-09-23 02:00:29 +0000345def attrs_wo_objs(cls):
346 return [t[:3] for t in inspect.classify_class_attrs(cls)]
347
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000348class TestClassesAndFunctions(unittest.TestCase):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000349 def test_classic_mro(self):
350 # Test classic-class method resolution order.
351 class A: pass
352 class B(A): pass
353 class C(A): pass
354 class D(B, C): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000355
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000356 expected = (D, B, A, C)
357 got = inspect.getmro(D)
358 self.assertEqual(expected, got)
Tim Peters13b49d32001-09-23 02:00:29 +0000359
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000360 def test_newstyle_mro(self):
361 # The same w/ new-class MRO.
362 class A(object): pass
363 class B(A): pass
364 class C(A): pass
365 class D(B, C): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000366
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000367 expected = (D, B, C, A, object)
368 got = inspect.getmro(D)
369 self.assertEqual(expected, got)
Tim Peters13b49d32001-09-23 02:00:29 +0000370
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000371 def assertArgSpecEquals(self, routine, args_e, varargs_e = None,
372 varkw_e = None, defaults_e = None,
373 formatted = None):
374 args, varargs, varkw, defaults = inspect.getargspec(routine)
375 self.assertEqual(args, args_e)
376 self.assertEqual(varargs, varargs_e)
377 self.assertEqual(varkw, varkw_e)
378 self.assertEqual(defaults, defaults_e)
379 if formatted is not None:
380 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults),
381 formatted)
Tim Peters13b49d32001-09-23 02:00:29 +0000382
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000383 def test_getargspec(self):
384 self.assertArgSpecEquals(mod.eggs, ['x', 'y'], formatted = '(x, y)')
Tim Peters13b49d32001-09-23 02:00:29 +0000385
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000386 self.assertArgSpecEquals(mod.spam,
387 ['a', 'b', 'c', 'd', ['e', ['f']]],
388 'g', 'h', (3, (4, (5,))),
389 '(a, b, c, d=3, (e, (f,))=(4, (5,)), *g, **h)')
Tim Peters13b49d32001-09-23 02:00:29 +0000390
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000391 def test_getargspec_method(self):
392 class A(object):
393 def m(self):
394 pass
395 self.assertArgSpecEquals(A.m, ['self'])
Tim Peters13b49d32001-09-23 02:00:29 +0000396
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000397 def test_getargspec_sublistofone(self):
Neal Norwitz33b730e2006-03-27 08:58:23 +0000398 def sublistOfOne((foo,)): return 1
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000399 self.assertArgSpecEquals(sublistOfOne, [['foo']])
400
Neal Norwitz33b730e2006-03-27 08:58:23 +0000401 def fakeSublistOfOne((foo)): return 1
402 self.assertArgSpecEquals(fakeSublistOfOne, ['foo'])
403
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000404 def test_classify_oldstyle(self):
405 class A:
406 def s(): pass
407 s = staticmethod(s)
408
409 def c(cls): pass
410 c = classmethod(c)
411
412 def getp(self): pass
413 p = property(getp)
414
415 def m(self): pass
416
417 def m1(self): pass
418
419 datablob = '1'
420
421 attrs = attrs_wo_objs(A)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000422 self.assertTrue(('s', 'static method', A) in attrs, 'missing static method')
423 self.assertTrue(('c', 'class method', A) in attrs, 'missing class method')
424 self.assertTrue(('p', 'property', A) in attrs, 'missing property')
425 self.assertTrue(('m', 'method', A) in attrs, 'missing plain method')
426 self.assertTrue(('m1', 'method', A) in attrs, 'missing plain method')
427 self.assertTrue(('datablob', 'data', A) in attrs, 'missing data')
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000428
429 class B(A):
430 def m(self): pass
431
432 attrs = attrs_wo_objs(B)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000433 self.assertTrue(('s', 'static method', A) in attrs, 'missing static method')
434 self.assertTrue(('c', 'class method', A) in attrs, 'missing class method')
435 self.assertTrue(('p', 'property', A) in attrs, 'missing property')
436 self.assertTrue(('m', 'method', B) in attrs, 'missing plain method')
437 self.assertTrue(('m1', 'method', A) in attrs, 'missing plain method')
438 self.assertTrue(('datablob', 'data', A) in attrs, 'missing data')
Tim Peters13b49d32001-09-23 02:00:29 +0000439
440
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000441 class C(A):
442 def m(self): pass
443 def c(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000444
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000445 attrs = attrs_wo_objs(C)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000446 self.assertTrue(('s', 'static method', A) in attrs, 'missing static method')
447 self.assertTrue(('c', 'method', C) in attrs, 'missing plain method')
448 self.assertTrue(('p', 'property', A) in attrs, 'missing property')
449 self.assertTrue(('m', 'method', C) in attrs, 'missing plain method')
450 self.assertTrue(('m1', 'method', A) in attrs, 'missing plain method')
451 self.assertTrue(('datablob', 'data', A) in attrs, 'missing data')
Tim Peters13b49d32001-09-23 02:00:29 +0000452
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000453 class D(B, C):
454 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000455
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000456 attrs = attrs_wo_objs(D)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000457 self.assertTrue(('s', 'static method', A) in attrs, 'missing static method')
458 self.assertTrue(('c', 'class method', A) in attrs, 'missing class method')
459 self.assertTrue(('p', 'property', A) in attrs, 'missing property')
460 self.assertTrue(('m', 'method', B) in attrs, 'missing plain method')
461 self.assertTrue(('m1', 'method', D) in attrs, 'missing plain method')
462 self.assertTrue(('datablob', 'data', A) in attrs, 'missing data')
Tim Peters13b49d32001-09-23 02:00:29 +0000463
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000464 # Repeat all that, but w/ new-style classes.
465 def test_classify_newstyle(self):
466 class A(object):
Tim Peters13b49d32001-09-23 02:00:29 +0000467
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000468 def s(): pass
469 s = staticmethod(s)
Tim Peters13b49d32001-09-23 02:00:29 +0000470
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000471 def c(cls): pass
472 c = classmethod(c)
Tim Peters13b49d32001-09-23 02:00:29 +0000473
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000474 def getp(self): pass
475 p = property(getp)
Tim Peters13b49d32001-09-23 02:00:29 +0000476
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000477 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000478
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000479 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000480
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000481 datablob = '1'
Tim Peters13b49d32001-09-23 02:00:29 +0000482
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000483 attrs = attrs_wo_objs(A)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000484 self.assertTrue(('s', 'static method', A) in attrs, 'missing static method')
485 self.assertTrue(('c', 'class method', A) in attrs, 'missing class method')
486 self.assertTrue(('p', 'property', A) in attrs, 'missing property')
487 self.assertTrue(('m', 'method', A) in attrs, 'missing plain method')
488 self.assertTrue(('m1', 'method', A) in attrs, 'missing plain method')
489 self.assertTrue(('datablob', 'data', A) in attrs, 'missing data')
Tim Peters13b49d32001-09-23 02:00:29 +0000490
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000491 class B(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000492
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000493 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000494
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000495 attrs = attrs_wo_objs(B)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000496 self.assertTrue(('s', 'static method', A) in attrs, 'missing static method')
497 self.assertTrue(('c', 'class method', A) in attrs, 'missing class method')
498 self.assertTrue(('p', 'property', A) in attrs, 'missing property')
499 self.assertTrue(('m', 'method', B) in attrs, 'missing plain method')
500 self.assertTrue(('m1', 'method', A) in attrs, 'missing plain method')
501 self.assertTrue(('datablob', 'data', A) in attrs, 'missing data')
Tim Peters13b49d32001-09-23 02:00:29 +0000502
503
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000504 class C(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000505
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000506 def m(self): pass
507 def c(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000508
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000509 attrs = attrs_wo_objs(C)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000510 self.assertTrue(('s', 'static method', A) in attrs, 'missing static method')
511 self.assertTrue(('c', 'method', C) in attrs, 'missing plain method')
512 self.assertTrue(('p', 'property', A) in attrs, 'missing property')
513 self.assertTrue(('m', 'method', C) in attrs, 'missing plain method')
514 self.assertTrue(('m1', 'method', A) in attrs, 'missing plain method')
515 self.assertTrue(('datablob', 'data', A) in attrs, 'missing data')
Tim Peters13b49d32001-09-23 02:00:29 +0000516
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000517 class D(B, C):
Tim Peters13b49d32001-09-23 02:00:29 +0000518
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000519 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000520
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000521 attrs = attrs_wo_objs(D)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000522 self.assertTrue(('s', 'static method', A) in attrs, 'missing static method')
523 self.assertTrue(('c', 'method', C) in attrs, 'missing plain method')
524 self.assertTrue(('p', 'property', A) in attrs, 'missing property')
525 self.assertTrue(('m', 'method', B) in attrs, 'missing plain method')
526 self.assertTrue(('m1', 'method', D) in attrs, 'missing plain method')
527 self.assertTrue(('datablob', 'data', A) in attrs, 'missing data')
Jeremy Hyltonc4bf5ed2003-06-27 18:43:12 +0000528
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000529def test_main():
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000530 run_unittest(TestDecorators, TestRetrievingSourceCode, TestOneliners,
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000531 TestBuggyCases,
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000532 TestInterpreterStack, TestClassesAndFunctions, TestPredicates)
Martin v. Löwis893ffa42003-10-31 15:35:53 +0000533
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000534if __name__ == "__main__":
535 test_main()