blob: 389dae761c56c9744f60cd7d63cf1cfd9384f0d1 [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
Florent Xicluna07627882010-03-21 01:14:24 +00007from test.test_support import run_unittest, check_py3k_warnings
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00008
Florent Xicluna07627882010-03-21 01:14:24 +00009with check_py3k_warnings(
10 ("tuple parameter unpacking has been removed", SyntaxWarning),
11 quiet=True):
12 from test import inspect_fodder as mod
13 from test import inspect_fodder2 as mod2
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000014
R. David Murray996ba022009-05-13 17:14:11 +000015# C module for test_findsource_binary
R. David Murray87855542009-05-14 16:12:57 +000016import unicodedata
R. David Murray996ba022009-05-13 17:14:11 +000017
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000018# Functions tested in this suite:
19# ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode,
Facundo Batista759bfc62008-02-18 03:43:43 +000020# isbuiltin, isroutine, isgenerator, isgeneratorfunction, getmembers,
21# getdoc, getfile, getmodule, getsourcefile, getcomments, getsource,
22# getclasstree, getargspec, getargvalues, formatargspec, formatargvalues,
23# currentframe, stack, trace, isdatadescriptor
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000024
Nick Coghlana2053472008-12-14 10:54:50 +000025# NOTE: There are some additional tests relating to interaction with
26# zipimport in the test_zipimport_support test module.
27
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000028modfile = mod.__file__
Georg Brandlb2afe852006-06-09 20:43:48 +000029if modfile.endswith(('c', 'o')):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000030 modfile = modfile[:-1]
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000031
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000032import __builtin__
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000033
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000034try:
Florent Xicluna07627882010-03-21 01:14:24 +000035 1 // 0
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000036except:
37 tb = sys.exc_traceback
38
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000039git = mod.StupidGit()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000040
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000041class IsTestBase(unittest.TestCase):
42 predicates = set([inspect.isbuiltin, inspect.isclass, inspect.iscode,
43 inspect.isframe, inspect.isfunction, inspect.ismethod,
Facundo Batista759bfc62008-02-18 03:43:43 +000044 inspect.ismodule, inspect.istraceback,
45 inspect.isgenerator, inspect.isgeneratorfunction])
Tim Peters5a9fb3c2005-01-07 16:01:32 +000046
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000047 def istest(self, predicate, exp):
48 obj = eval(exp)
Benjamin Peterson5c8da862009-06-30 22:57:08 +000049 self.assertTrue(predicate(obj), '%s(%s)' % (predicate.__name__, exp))
Tim Peters5a9fb3c2005-01-07 16:01:32 +000050
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000051 for other in self.predicates - set([predicate]):
Facundo Batista759bfc62008-02-18 03:43:43 +000052 if predicate == inspect.isgeneratorfunction and\
53 other == inspect.isfunction:
54 continue
Benjamin Peterson5c8da862009-06-30 22:57:08 +000055 self.assertFalse(other(obj), 'not %s(%s)' % (other.__name__, exp))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000056
Facundo Batista759bfc62008-02-18 03:43:43 +000057def generator_function_example(self):
58 for i in xrange(2):
59 yield i
60
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000061class TestPredicates(IsTestBase):
Christian Heimes728bee82008-03-03 20:30:29 +000062 def test_sixteen(self):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000063 count = len(filter(lambda x:x.startswith('is'), dir(inspect)))
Facundo Batista759bfc62008-02-18 03:43:43 +000064 # This test is here for remember you to update Doc/library/inspect.rst
Georg Brandl26bc1772008-03-03 20:39:00 +000065 # which claims there are 16 such functions
Christian Heimes728bee82008-03-03 20:30:29 +000066 expected = 16
Neal Norwitzdf80af72006-07-28 04:22:34 +000067 err_msg = "There are %d (not %d) is* functions" % (count, expected)
68 self.assertEqual(count, expected, err_msg)
Tim Peters5a9fb3c2005-01-07 16:01:32 +000069
Facundo Batista759bfc62008-02-18 03:43:43 +000070
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000071 def test_excluding_predicates(self):
72 self.istest(inspect.isbuiltin, 'sys.exit')
73 self.istest(inspect.isbuiltin, '[].append')
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000074 self.istest(inspect.iscode, 'mod.spam.func_code')
75 self.istest(inspect.isframe, 'tb.tb_frame')
76 self.istest(inspect.isfunction, 'mod.spam')
77 self.istest(inspect.ismethod, 'mod.StupidGit.abuse')
78 self.istest(inspect.ismethod, 'git.argue')
79 self.istest(inspect.ismodule, 'mod')
80 self.istest(inspect.istraceback, 'tb')
81 self.istest(inspect.isdatadescriptor, '__builtin__.file.closed')
82 self.istest(inspect.isdatadescriptor, '__builtin__.file.softspace')
Facundo Batista759bfc62008-02-18 03:43:43 +000083 self.istest(inspect.isgenerator, '(x for x in xrange(2))')
84 self.istest(inspect.isgeneratorfunction, 'generator_function_example')
Barry Warsaw00decd72006-07-27 23:43:15 +000085 if hasattr(types, 'GetSetDescriptorType'):
86 self.istest(inspect.isgetsetdescriptor,
87 'type(tb.tb_frame).f_locals')
88 else:
Benjamin Peterson5c8da862009-06-30 22:57:08 +000089 self.assertFalse(inspect.isgetsetdescriptor(type(tb.tb_frame).f_locals))
Barry Warsaw00decd72006-07-27 23:43:15 +000090 if hasattr(types, 'MemberDescriptorType'):
91 self.istest(inspect.ismemberdescriptor, 'datetime.timedelta.days')
92 else:
Benjamin Peterson5c8da862009-06-30 22:57:08 +000093 self.assertFalse(inspect.ismemberdescriptor(datetime.timedelta.days))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000094
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000095 def test_isroutine(self):
Benjamin Peterson5c8da862009-06-30 22:57:08 +000096 self.assertTrue(inspect.isroutine(mod.spam))
97 self.assertTrue(inspect.isroutine([].count))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000098
Benjamin Peterson5e5fbb62009-01-17 22:27:54 +000099 def test_isclass(self):
100 self.istest(inspect.isclass, 'mod.StupidGit')
101 self.assertTrue(inspect.isclass(list))
102
103 class newstyle(object): pass
104 self.assertTrue(inspect.isclass(newstyle))
105
106 class CustomGetattr(object):
107 def __getattr__(self, attr):
108 return None
109 self.assertFalse(inspect.isclass(CustomGetattr()))
110
Amaury Forgeot d'Arcb54447f2009-01-13 23:39:22 +0000111 def test_get_slot_members(self):
112 class C(object):
113 __slots__ = ("a", "b")
114
115 x = C()
116 x.a = 42
117 members = dict(inspect.getmembers(x))
Ezio Melottiaa980582010-01-23 23:04:36 +0000118 self.assertIn('a', members)
119 self.assertNotIn('b', members)
Amaury Forgeot d'Arcb54447f2009-01-13 23:39:22 +0000120
Benjamin Petersonc63457b2009-10-15 03:06:55 +0000121 def test_isabstract(self):
122 from abc import ABCMeta, abstractmethod
123
124 class AbstractClassExample(object):
125 __metaclass__ = ABCMeta
126
127 @abstractmethod
128 def foo(self):
129 pass
130
131 class ClassExample(AbstractClassExample):
132 def foo(self):
133 pass
134
135 a = ClassExample()
136
137 # Test general behaviour.
138 self.assertTrue(inspect.isabstract(AbstractClassExample))
139 self.assertFalse(inspect.isabstract(ClassExample))
140 self.assertFalse(inspect.isabstract(a))
141 self.assertFalse(inspect.isabstract(int))
142 self.assertFalse(inspect.isabstract(5))
143
Amaury Forgeot d'Arcb54447f2009-01-13 23:39:22 +0000144
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000145class TestInterpreterStack(IsTestBase):
146 def __init__(self, *args, **kwargs):
147 unittest.TestCase.__init__(self, *args, **kwargs)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000148
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000149 git.abuse(7, 8, 9)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000150
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000151 def test_abuse_done(self):
152 self.istest(inspect.istraceback, 'git.ex[2]')
153 self.istest(inspect.isframe, 'mod.fr')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000154
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000155 def test_stack(self):
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000156 self.assertTrue(len(mod.st) >= 5)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000157 self.assertEqual(mod.st[0][1:],
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000158 (modfile, 16, 'eggs', [' st = inspect.stack()\n'], 0))
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000159 self.assertEqual(mod.st[1][1:],
160 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
161 self.assertEqual(mod.st[2][1:],
162 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
163 self.assertEqual(mod.st[3][1:],
164 (modfile, 39, 'abuse', [' self.argue(a, b, c)\n'], 0))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000165
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000166 def test_trace(self):
167 self.assertEqual(len(git.tr), 3)
168 self.assertEqual(git.tr[0][1:], (modfile, 43, 'argue',
169 [' spam(a, b, c)\n'], 0))
170 self.assertEqual(git.tr[1][1:], (modfile, 9, 'spam',
171 [' eggs(b + d, c + f)\n'], 0))
172 self.assertEqual(git.tr[2][1:], (modfile, 18, 'eggs',
Mark Dickinsonc68e9f02010-02-03 16:50:14 +0000173 [' q = y // 0\n'], 0))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000174
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000175 def test_frame(self):
176 args, varargs, varkw, locals = inspect.getargvalues(mod.fr)
177 self.assertEqual(args, ['x', 'y'])
178 self.assertEqual(varargs, None)
179 self.assertEqual(varkw, None)
180 self.assertEqual(locals, {'x': 11, 'p': 11, 'y': 14})
181 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
182 '(x=11, y=14)')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000183
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000184 def test_previous_frame(self):
185 args, varargs, varkw, locals = inspect.getargvalues(mod.fr.f_back)
186 self.assertEqual(args, ['a', 'b', 'c', 'd', ['e', ['f']]])
187 self.assertEqual(varargs, 'g')
188 self.assertEqual(varkw, 'h')
189 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
190 '(a=7, b=8, c=9, d=3, (e=4, (f=5,)), *g=(), **h={})')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000191
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000192class GetSourceBase(unittest.TestCase):
193 # Subclasses must override.
194 fodderFile = None
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000195
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000196 def __init__(self, *args, **kwargs):
197 unittest.TestCase.__init__(self, *args, **kwargs)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000198
Philip Jenvey6a111022009-05-28 05:58:44 +0000199 with open(inspect.getsourcefile(self.fodderFile)) as fp:
200 self.source = fp.read()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000201
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000202 def sourcerange(self, top, bottom):
203 lines = self.source.split("\n")
204 return "\n".join(lines[top-1:bottom]) + "\n"
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000205
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000206 def assertSourceEqual(self, obj, top, bottom):
207 self.assertEqual(inspect.getsource(obj),
208 self.sourcerange(top, bottom))
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000209
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000210class TestRetrievingSourceCode(GetSourceBase):
211 fodderFile = mod
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000212
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000213 def test_getclasses(self):
214 classes = inspect.getmembers(mod, inspect.isclass)
215 self.assertEqual(classes,
216 [('FesteringGob', mod.FesteringGob),
217 ('MalodorousPervert', mod.MalodorousPervert),
218 ('ParrotDroppings', mod.ParrotDroppings),
219 ('StupidGit', mod.StupidGit)])
220 tree = inspect.getclasstree([cls[1] for cls in classes], 1)
221 self.assertEqual(tree,
222 [(mod.ParrotDroppings, ()),
223 (mod.StupidGit, ()),
224 [(mod.MalodorousPervert, (mod.StupidGit,)),
225 [(mod.FesteringGob, (mod.MalodorousPervert,
226 mod.ParrotDroppings))
227 ]
228 ]
229 ])
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000230
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000231 def test_getfunctions(self):
232 functions = inspect.getmembers(mod, inspect.isfunction)
233 self.assertEqual(functions, [('eggs', mod.eggs),
234 ('spam', mod.spam)])
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000235
R. David Murrayf28fd242010-02-23 00:24:49 +0000236 @unittest.skipIf(sys.flags.optimize >= 2,
237 "Docstrings are omitted with -O2 and above")
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000238 def test_getdoc(self):
239 self.assertEqual(inspect.getdoc(mod), 'A module docstring.')
240 self.assertEqual(inspect.getdoc(mod.StupidGit),
241 'A longer,\n\nindented\n\ndocstring.')
242 self.assertEqual(inspect.getdoc(git.abuse),
243 'Another\n\ndocstring\n\ncontaining\n\ntabs')
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000244
Georg Brandl7be19aa2008-06-07 15:59:10 +0000245 def test_cleandoc(self):
246 self.assertEqual(inspect.cleandoc('An\n indented\n docstring.'),
247 'An\nindented\ndocstring.')
248
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000249 def test_getcomments(self):
250 self.assertEqual(inspect.getcomments(mod), '# line 1\n')
251 self.assertEqual(inspect.getcomments(mod.StupidGit), '# line 20\n')
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000252
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000253 def test_getmodule(self):
Nick Coghlanc495c662006-09-07 10:50:34 +0000254 # Check actual module
255 self.assertEqual(inspect.getmodule(mod), mod)
256 # Check class (uses __module__ attribute)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000257 self.assertEqual(inspect.getmodule(mod.StupidGit), mod)
Nick Coghlanc495c662006-09-07 10:50:34 +0000258 # Check a method (no __module__ attribute, falls back to filename)
259 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
260 # Do it again (check the caching isn't broken)
261 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
262 # Check a builtin
263 self.assertEqual(inspect.getmodule(str), sys.modules["__builtin__"])
264 # Check filename override
265 self.assertEqual(inspect.getmodule(None, modfile), mod)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000266
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000267 def test_getsource(self):
268 self.assertSourceEqual(git.abuse, 29, 39)
269 self.assertSourceEqual(mod.StupidGit, 21, 46)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000270
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000271 def test_getsourcefile(self):
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000272 self.assertEqual(inspect.getsourcefile(mod.spam), modfile)
273 self.assertEqual(inspect.getsourcefile(git.abuse), modfile)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000274
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000275 def test_getfile(self):
276 self.assertEqual(inspect.getfile(mod.StupidGit), mod.__file__)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000277
Phillip J. Eby5d86bdb2006-07-10 19:03:29 +0000278 def test_getmodule_recursion(self):
Christian Heimesc756d002007-11-27 21:34:01 +0000279 from types import ModuleType
Phillip J. Eby5d86bdb2006-07-10 19:03:29 +0000280 name = '__inspect_dummy'
Christian Heimesc756d002007-11-27 21:34:01 +0000281 m = sys.modules[name] = ModuleType(name)
Tim Peters722b8832006-07-10 21:11:49 +0000282 m.__file__ = "<string>" # hopefully not a real filename...
Phillip J. Eby5d86bdb2006-07-10 19:03:29 +0000283 m.__loader__ = "dummy" # pretend the filename is understood by a loader
284 exec "def x(): pass" in m.__dict__
285 self.assertEqual(inspect.getsourcefile(m.x.func_code), '<string>')
286 del sys.modules[name]
Phillip J. Eby1a2959c2006-07-20 15:54:16 +0000287 inspect.getmodule(compile('a=10','','single'))
Phillip J. Eby5d86bdb2006-07-10 19:03:29 +0000288
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000289class TestDecorators(GetSourceBase):
290 fodderFile = mod2
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000291
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000292 def test_wrapped_decorator(self):
293 self.assertSourceEqual(mod2.wrapped, 14, 17)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000294
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000295 def test_replacing_decorator(self):
296 self.assertSourceEqual(mod2.gone, 9, 10)
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000297
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000298class TestOneliners(GetSourceBase):
299 fodderFile = mod2
300 def test_oneline_lambda(self):
301 # Test inspect.getsource with a one-line lambda function.
302 self.assertSourceEqual(mod2.oll, 25, 25)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000303
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000304 def test_threeline_lambda(self):
305 # Test inspect.getsource with a three-line lambda function,
306 # where the second and third lines are _not_ indented.
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000307 self.assertSourceEqual(mod2.tll, 28, 30)
308
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000309 def test_twoline_indented_lambda(self):
310 # Test inspect.getsource with a two-line lambda function,
311 # where the second line _is_ indented.
312 self.assertSourceEqual(mod2.tlli, 33, 34)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000313
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000314 def test_onelinefunc(self):
315 # Test inspect.getsource with a regular one-line function.
316 self.assertSourceEqual(mod2.onelinefunc, 37, 37)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000317
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000318 def test_manyargs(self):
319 # Test inspect.getsource with a regular function where
320 # the arguments are on two lines and _not_ indented and
321 # the body on the second line with the last arguments.
322 self.assertSourceEqual(mod2.manyargs, 40, 41)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000323
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000324 def test_twolinefunc(self):
325 # Test inspect.getsource with a regular function where
326 # the body is on two lines, following the argument list and
327 # continued on the next line by a \\.
328 self.assertSourceEqual(mod2.twolinefunc, 44, 45)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000329
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000330 def test_lambda_in_list(self):
331 # Test inspect.getsource with a one-line lambda function
332 # defined in a list, indented.
333 self.assertSourceEqual(mod2.a[1], 49, 49)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000334
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000335 def test_anonymous(self):
336 # Test inspect.getsource with a lambda function defined
337 # as argument to another function.
338 self.assertSourceEqual(mod2.anonymous, 55, 55)
339
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000340class TestBuggyCases(GetSourceBase):
341 fodderFile = mod2
342
343 def test_with_comment(self):
344 self.assertSourceEqual(mod2.with_comment, 58, 59)
345
346 def test_multiline_sig(self):
347 self.assertSourceEqual(mod2.multiline_sig[0], 63, 64)
348
Armin Rigodd5c0232005-09-25 11:45:45 +0000349 def test_nested_class(self):
350 self.assertSourceEqual(mod2.func69().func71, 71, 72)
351
352 def test_one_liner_followed_by_non_name(self):
353 self.assertSourceEqual(mod2.func77, 77, 77)
354
355 def test_one_liner_dedent_non_name(self):
356 self.assertSourceEqual(mod2.cls82.func83, 83, 83)
357
358 def test_with_comment_instead_of_docstring(self):
359 self.assertSourceEqual(mod2.func88, 88, 90)
360
Georg Brandl2463f8f2006-08-14 21:34:08 +0000361 def test_method_in_dynamic_class(self):
362 self.assertSourceEqual(mod2.method_in_dynamic_class, 95, 97)
363
R. David Murray87855542009-05-14 16:12:57 +0000364 @unittest.skipIf(
365 not hasattr(unicodedata, '__file__') or
366 unicodedata.__file__[-4:] in (".pyc", ".pyo"),
367 "unicodedata is not an external binary module")
R. David Murray996ba022009-05-13 17:14:11 +0000368 def test_findsource_binary(self):
R. David Murray87855542009-05-14 16:12:57 +0000369 self.assertRaises(IOError, inspect.getsource, unicodedata)
370 self.assertRaises(IOError, inspect.findsource, unicodedata)
R. David Murray996ba022009-05-13 17:14:11 +0000371
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000372# Helper for testing classify_class_attrs.
Tim Peters13b49d32001-09-23 02:00:29 +0000373def attrs_wo_objs(cls):
374 return [t[:3] for t in inspect.classify_class_attrs(cls)]
375
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000376class TestClassesAndFunctions(unittest.TestCase):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000377 def test_classic_mro(self):
378 # Test classic-class method resolution order.
379 class A: pass
380 class B(A): pass
381 class C(A): pass
382 class D(B, C): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000383
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000384 expected = (D, B, A, C)
385 got = inspect.getmro(D)
386 self.assertEqual(expected, got)
Tim Peters13b49d32001-09-23 02:00:29 +0000387
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000388 def test_newstyle_mro(self):
389 # The same w/ new-class MRO.
390 class A(object): pass
391 class B(A): pass
392 class C(A): pass
393 class D(B, C): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000394
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000395 expected = (D, B, C, A, object)
396 got = inspect.getmro(D)
397 self.assertEqual(expected, got)
Tim Peters13b49d32001-09-23 02:00:29 +0000398
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000399 def assertArgSpecEquals(self, routine, args_e, varargs_e = None,
400 varkw_e = None, defaults_e = None,
401 formatted = None):
402 args, varargs, varkw, defaults = inspect.getargspec(routine)
403 self.assertEqual(args, args_e)
404 self.assertEqual(varargs, varargs_e)
405 self.assertEqual(varkw, varkw_e)
406 self.assertEqual(defaults, defaults_e)
407 if formatted is not None:
408 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults),
409 formatted)
Tim Peters13b49d32001-09-23 02:00:29 +0000410
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000411 def test_getargspec(self):
412 self.assertArgSpecEquals(mod.eggs, ['x', 'y'], formatted = '(x, y)')
Tim Peters13b49d32001-09-23 02:00:29 +0000413
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000414 self.assertArgSpecEquals(mod.spam,
415 ['a', 'b', 'c', 'd', ['e', ['f']]],
416 'g', 'h', (3, (4, (5,))),
417 '(a, b, c, d=3, (e, (f,))=(4, (5,)), *g, **h)')
Tim Peters13b49d32001-09-23 02:00:29 +0000418
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000419 def test_getargspec_method(self):
420 class A(object):
421 def m(self):
422 pass
423 self.assertArgSpecEquals(A.m, ['self'])
Tim Peters13b49d32001-09-23 02:00:29 +0000424
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000425 def test_getargspec_sublistofone(self):
Florent Xicluna07627882010-03-21 01:14:24 +0000426 with check_py3k_warnings(
427 ("tuple parameter unpacking has been removed", SyntaxWarning),
428 ("parenthesized argument names are invalid", SyntaxWarning)):
429 exec 'def sublistOfOne((foo,)): return 1'
430 self.assertArgSpecEquals(sublistOfOne, [['foo']])
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000431
Florent Xicluna07627882010-03-21 01:14:24 +0000432 exec 'def fakeSublistOfOne((foo)): return 1'
433 self.assertArgSpecEquals(fakeSublistOfOne, ['foo'])
Neal Norwitz33b730e2006-03-27 08:58:23 +0000434
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000435 def test_classify_oldstyle(self):
436 class A:
437 def s(): pass
438 s = staticmethod(s)
439
440 def c(cls): pass
441 c = classmethod(c)
442
443 def getp(self): pass
444 p = property(getp)
445
446 def m(self): pass
447
448 def m1(self): pass
449
450 datablob = '1'
451
452 attrs = attrs_wo_objs(A)
Ezio Melottiaa980582010-01-23 23:04:36 +0000453 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
454 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
455 self.assertIn(('p', 'property', A), attrs, 'missing property')
456 self.assertIn(('m', 'method', A), attrs, 'missing plain method')
457 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
458 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000459
460 class B(A):
461 def m(self): pass
462
463 attrs = attrs_wo_objs(B)
Ezio Melottiaa980582010-01-23 23:04:36 +0000464 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
465 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
466 self.assertIn(('p', 'property', A), attrs, 'missing property')
467 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
468 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
469 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Tim Peters13b49d32001-09-23 02:00:29 +0000470
471
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000472 class C(A):
473 def m(self): pass
474 def c(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000475
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000476 attrs = attrs_wo_objs(C)
Ezio Melottiaa980582010-01-23 23:04:36 +0000477 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
478 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
479 self.assertIn(('p', 'property', A), attrs, 'missing property')
480 self.assertIn(('m', 'method', C), attrs, 'missing plain method')
481 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
482 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Tim Peters13b49d32001-09-23 02:00:29 +0000483
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000484 class D(B, C):
485 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000486
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000487 attrs = attrs_wo_objs(D)
Ezio Melottiaa980582010-01-23 23:04:36 +0000488 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
489 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
490 self.assertIn(('p', 'property', A), attrs, 'missing property')
491 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
492 self.assertIn(('m1', 'method', D), attrs, 'missing plain method')
493 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Tim Peters13b49d32001-09-23 02:00:29 +0000494
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000495 # Repeat all that, but w/ new-style classes.
496 def test_classify_newstyle(self):
497 class A(object):
Tim Peters13b49d32001-09-23 02:00:29 +0000498
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000499 def s(): pass
500 s = staticmethod(s)
Tim Peters13b49d32001-09-23 02:00:29 +0000501
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000502 def c(cls): pass
503 c = classmethod(c)
Tim Peters13b49d32001-09-23 02:00:29 +0000504
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000505 def getp(self): pass
506 p = property(getp)
Tim Peters13b49d32001-09-23 02:00:29 +0000507
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000508 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000509
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000510 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000511
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000512 datablob = '1'
Tim Peters13b49d32001-09-23 02:00:29 +0000513
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000514 attrs = attrs_wo_objs(A)
Ezio Melottiaa980582010-01-23 23:04:36 +0000515 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
516 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
517 self.assertIn(('p', 'property', A), attrs, 'missing property')
518 self.assertIn(('m', 'method', A), attrs, 'missing plain method')
519 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
520 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Tim Peters13b49d32001-09-23 02:00:29 +0000521
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000522 class B(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000523
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000524 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000525
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000526 attrs = attrs_wo_objs(B)
Ezio Melottiaa980582010-01-23 23:04:36 +0000527 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
528 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
529 self.assertIn(('p', 'property', A), attrs, 'missing property')
530 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
531 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
532 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Tim Peters13b49d32001-09-23 02:00:29 +0000533
534
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000535 class C(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000536
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000537 def m(self): pass
538 def c(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000539
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000540 attrs = attrs_wo_objs(C)
Ezio Melottiaa980582010-01-23 23:04:36 +0000541 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
542 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
543 self.assertIn(('p', 'property', A), attrs, 'missing property')
544 self.assertIn(('m', 'method', C), attrs, 'missing plain method')
545 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
546 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Tim Peters13b49d32001-09-23 02:00:29 +0000547
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000548 class D(B, C):
Tim Peters13b49d32001-09-23 02:00:29 +0000549
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000550 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000551
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000552 attrs = attrs_wo_objs(D)
Ezio Melottiaa980582010-01-23 23:04:36 +0000553 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
554 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
555 self.assertIn(('p', 'property', A), attrs, 'missing property')
556 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
557 self.assertIn(('m1', 'method', D), attrs, 'missing plain method')
558 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Jeremy Hyltonc4bf5ed2003-06-27 18:43:12 +0000559
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000560def test_main():
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000561 run_unittest(TestDecorators, TestRetrievingSourceCode, TestOneliners,
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000562 TestBuggyCases,
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000563 TestInterpreterStack, TestClassesAndFunctions, TestPredicates)
Martin v. Löwis893ffa42003-10-31 15:35:53 +0000564
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000565if __name__ == "__main__":
566 test_main()