blob: 9dba30db530c9fa62d7fc10b0bf0f56f02b3ba8d [file] [log] [blame]
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001import sys
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002import types
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00003import unittest
4import inspect
Thomas Wouters0e3f5912006-08-11 14:57:12 +00005import datetime
Guido van Rossum813b0e52007-05-21 18:11:34 +00006import collections
Christian Heimesa3538eb2007-11-06 11:44:48 +00007from os.path import normcase
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00008
Benjamin Petersonee8712c2008-05-20 21:35:26 +00009from test.support import TESTFN, run_unittest
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000010
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000011from test import inspect_fodder as mod
12from test import inspect_fodder2 as mod2
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000013
R. David Murray74b89242009-05-13 17:33:03 +000014# C module for test_findsource_binary
R. David Murrayb5655772009-05-14 16:17:50 +000015import unicodedata
R. David Murray74b89242009-05-13 17:33:03 +000016
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000017# Functions tested in this suite:
18# ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode,
Christian Heimes7131fd92008-02-19 14:21:46 +000019# isbuiltin, isroutine, isgenerator, isgeneratorfunction, getmembers,
20# getdoc, getfile, getmodule, getsourcefile, getcomments, getsource,
21# getclasstree, getargspec, getargvalues, formatargspec, formatargvalues,
22# currentframe, stack, trace, isdatadescriptor
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000023
Nick Coghlanf088e5e2008-12-14 11:50:48 +000024# NOTE: There are some additional tests relating to interaction with
25# zipimport in the test_zipimport_support test module.
26
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000027modfile = mod.__file__
Thomas Wouters0e3f5912006-08-11 14:57:12 +000028if modfile.endswith(('c', 'o')):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000029 modfile = modfile[:-1]
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000030
Christian Heimesa3538eb2007-11-06 11:44:48 +000031# Normalize file names: on Windows, the case of file names of compiled
32# modules depends on the path used to start the python executable.
33modfile = normcase(modfile)
34
35def revise(filename, *args):
36 return (normcase(filename),) + args
37
Georg Brandl1a3284e2007-12-02 09:40:06 +000038import builtins
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000039
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000040try:
41 1/0
42except:
Guido van Rossume7ba4952007-06-06 23:52:48 +000043 tb = sys.exc_info()[2]
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000044
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000045git = mod.StupidGit()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000046
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000047class IsTestBase(unittest.TestCase):
48 predicates = set([inspect.isbuiltin, inspect.isclass, inspect.iscode,
49 inspect.isframe, inspect.isfunction, inspect.ismethod,
Christian Heimes7131fd92008-02-19 14:21:46 +000050 inspect.ismodule, inspect.istraceback,
51 inspect.isgenerator, inspect.isgeneratorfunction])
Tim Peters5a9fb3c2005-01-07 16:01:32 +000052
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000053 def istest(self, predicate, exp):
54 obj = eval(exp)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000055 self.assertTrue(predicate(obj), '%s(%s)' % (predicate.__name__, exp))
Tim Peters5a9fb3c2005-01-07 16:01:32 +000056
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000057 for other in self.predicates - set([predicate]):
Christian Heimes7131fd92008-02-19 14:21:46 +000058 if predicate == inspect.isgeneratorfunction and\
59 other == inspect.isfunction:
60 continue
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000061 self.assertFalse(other(obj), 'not %s(%s)' % (other.__name__, exp))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000062
Christian Heimes7131fd92008-02-19 14:21:46 +000063def generator_function_example(self):
64 for i in range(2):
65 yield i
66
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000067class TestPredicates(IsTestBase):
Christian Heimes227c8002008-03-03 20:34:40 +000068 def test_sixteen(self):
Guido van Rossumc1f779c2007-07-03 08:25:58 +000069 count = len([x for x in dir(inspect) if x.startswith('is')])
Christian Heimes7131fd92008-02-19 14:21:46 +000070 # This test is here for remember you to update Doc/library/inspect.rst
Christian Heimes78644762008-03-04 23:39:23 +000071 # which claims there are 16 such functions
Christian Heimes227c8002008-03-03 20:34:40 +000072 expected = 16
Thomas Wouters0e3f5912006-08-11 14:57:12 +000073 err_msg = "There are %d (not %d) is* functions" % (count, expected)
74 self.assertEqual(count, expected, err_msg)
Tim Peters5a9fb3c2005-01-07 16:01:32 +000075
Christian Heimes7131fd92008-02-19 14:21:46 +000076
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000077 def test_excluding_predicates(self):
78 self.istest(inspect.isbuiltin, 'sys.exit')
79 self.istest(inspect.isbuiltin, '[].append')
Neal Norwitz221085d2007-02-25 20:55:47 +000080 self.istest(inspect.iscode, 'mod.spam.__code__')
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000081 self.istest(inspect.isframe, 'tb.tb_frame')
82 self.istest(inspect.isfunction, 'mod.spam')
Christian Heimes4a22b5d2007-11-25 09:39:14 +000083 self.istest(inspect.isfunction, 'mod.StupidGit.abuse')
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000084 self.istest(inspect.ismethod, 'git.argue')
85 self.istest(inspect.ismodule, 'mod')
86 self.istest(inspect.istraceback, 'tb')
Guido van Rossum813b0e52007-05-21 18:11:34 +000087 self.istest(inspect.isdatadescriptor, 'collections.defaultdict.default_factory')
Christian Heimes7131fd92008-02-19 14:21:46 +000088 self.istest(inspect.isgenerator, '(x for x in range(2))')
89 self.istest(inspect.isgeneratorfunction, 'generator_function_example')
Thomas Wouters0e3f5912006-08-11 14:57:12 +000090 if hasattr(types, 'GetSetDescriptorType'):
91 self.istest(inspect.isgetsetdescriptor,
92 'type(tb.tb_frame).f_locals')
93 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000094 self.assertFalse(inspect.isgetsetdescriptor(type(tb.tb_frame).f_locals))
Thomas Wouters0e3f5912006-08-11 14:57:12 +000095 if hasattr(types, 'MemberDescriptorType'):
96 self.istest(inspect.ismemberdescriptor, 'datetime.timedelta.days')
97 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000098 self.assertFalse(inspect.ismemberdescriptor(datetime.timedelta.days))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000099
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000100 def test_isroutine(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000101 self.assertTrue(inspect.isroutine(mod.spam))
102 self.assertTrue(inspect.isroutine([].count))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000103
Benjamin Petersonc4656002009-01-17 22:41:18 +0000104 def test_isclass(self):
105 self.istest(inspect.isclass, 'mod.StupidGit')
106 self.assertTrue(inspect.isclass(list))
107
108 class CustomGetattr(object):
109 def __getattr__(self, attr):
110 return None
111 self.assertFalse(inspect.isclass(CustomGetattr()))
112
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000113 def test_get_slot_members(self):
114 class C(object):
115 __slots__ = ("a", "b")
116
117 x = C()
118 x.a = 42
119 members = dict(inspect.getmembers(x))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000120 self.assertTrue('a' in members)
121 self.assertTrue('b' not in members)
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000122
Benjamin Petersona0dfa822009-11-13 02:25:08 +0000123 def test_isabstract(self):
124 from abc import ABCMeta, abstractmethod
125
126 class AbstractClassExample(metaclass=ABCMeta):
127
128 @abstractmethod
129 def foo(self):
130 pass
131
132 class ClassExample(AbstractClassExample):
133 def foo(self):
134 pass
135
136 a = ClassExample()
137
138 # Test general behaviour.
139 self.assertTrue(inspect.isabstract(AbstractClassExample))
140 self.assertFalse(inspect.isabstract(ClassExample))
141 self.assertFalse(inspect.isabstract(a))
142 self.assertFalse(inspect.isabstract(int))
143 self.assertFalse(inspect.isabstract(5))
144
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000145
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000146class TestInterpreterStack(IsTestBase):
147 def __init__(self, *args, **kwargs):
148 unittest.TestCase.__init__(self, *args, **kwargs)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000149
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000150 git.abuse(7, 8, 9)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000151
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000152 def test_abuse_done(self):
153 self.istest(inspect.istraceback, 'git.ex[2]')
154 self.istest(inspect.isframe, 'mod.fr')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000155
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000156 def test_stack(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000157 self.assertTrue(len(mod.st) >= 5)
Christian Heimesa3538eb2007-11-06 11:44:48 +0000158 self.assertEqual(revise(*mod.st[0][1:]),
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000159 (modfile, 16, 'eggs', [' st = inspect.stack()\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000160 self.assertEqual(revise(*mod.st[1][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000161 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000162 self.assertEqual(revise(*mod.st[2][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000163 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000164 self.assertEqual(revise(*mod.st[3][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000165 (modfile, 39, 'abuse', [' self.argue(a, b, c)\n'], 0))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000166
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000167 def test_trace(self):
168 self.assertEqual(len(git.tr), 3)
Christian Heimesa3538eb2007-11-06 11:44:48 +0000169 self.assertEqual(revise(*git.tr[0][1:]),
170 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
171 self.assertEqual(revise(*git.tr[1][1:]),
172 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
173 self.assertEqual(revise(*git.tr[2][1:]),
174 (modfile, 18, 'eggs', [' q = y / 0\n'], 0))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000175
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000176 def test_frame(self):
177 args, varargs, varkw, locals = inspect.getargvalues(mod.fr)
178 self.assertEqual(args, ['x', 'y'])
179 self.assertEqual(varargs, None)
180 self.assertEqual(varkw, None)
181 self.assertEqual(locals, {'x': 11, 'p': 11, 'y': 14})
182 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
183 '(x=11, y=14)')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000184
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000185 def test_previous_frame(self):
186 args, varargs, varkw, locals = inspect.getargvalues(mod.fr.f_back)
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000187 self.assertEqual(args, ['a', 'b', 'c', 'd', 'e', 'f'])
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000188 self.assertEqual(varargs, 'g')
189 self.assertEqual(varkw, 'h')
190 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000191 '(a=7, b=8, c=9, d=3, e=4, f=5, *g=(), **h={})')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000192
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000193class GetSourceBase(unittest.TestCase):
194 # Subclasses must override.
195 fodderFile = None
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000196
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000197 def __init__(self, *args, **kwargs):
198 unittest.TestCase.__init__(self, *args, **kwargs)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000199
Philip Jenveya27c5bd2009-05-28 06:09:08 +0000200 with open(inspect.getsourcefile(self.fodderFile)) as fp:
201 self.source = fp.read()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000202
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000203 def sourcerange(self, top, bottom):
204 lines = self.source.split("\n")
205 return "\n".join(lines[top-1:bottom]) + "\n"
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000206
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000207 def assertSourceEqual(self, obj, top, bottom):
208 self.assertEqual(inspect.getsource(obj),
209 self.sourcerange(top, bottom))
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000210
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000211class TestRetrievingSourceCode(GetSourceBase):
212 fodderFile = mod
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000213
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000214 def test_getclasses(self):
215 classes = inspect.getmembers(mod, inspect.isclass)
216 self.assertEqual(classes,
217 [('FesteringGob', mod.FesteringGob),
218 ('MalodorousPervert', mod.MalodorousPervert),
219 ('ParrotDroppings', mod.ParrotDroppings),
220 ('StupidGit', mod.StupidGit)])
221 tree = inspect.getclasstree([cls[1] for cls in classes], 1)
222 self.assertEqual(tree,
Thomas Wouters725af872006-04-15 09:13:19 +0000223 [(object, ()),
224 [(mod.ParrotDroppings, (object,)),
225 (mod.StupidGit, (object,)),
226 [(mod.MalodorousPervert, (mod.StupidGit,)),
227 [(mod.FesteringGob, (mod.MalodorousPervert,
228 mod.ParrotDroppings))
229 ]
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000230 ]
231 ]
232 ])
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000233
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000234 def test_getfunctions(self):
235 functions = inspect.getmembers(mod, inspect.isfunction)
236 self.assertEqual(functions, [('eggs', mod.eggs),
237 ('spam', mod.spam)])
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000238
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000239 def test_getdoc(self):
240 self.assertEqual(inspect.getdoc(mod), 'A module docstring.')
241 self.assertEqual(inspect.getdoc(mod.StupidGit),
242 'A longer,\n\nindented\n\ndocstring.')
243 self.assertEqual(inspect.getdoc(git.abuse),
244 'Another\n\ndocstring\n\ncontaining\n\ntabs')
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000245
Georg Brandl0c77a822008-06-10 16:37:50 +0000246 def test_cleandoc(self):
247 self.assertEqual(inspect.cleandoc('An\n indented\n docstring.'),
248 'An\nindented\ndocstring.')
249
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000250 def test_getcomments(self):
251 self.assertEqual(inspect.getcomments(mod), '# line 1\n')
252 self.assertEqual(inspect.getcomments(mod.StupidGit), '# line 20\n')
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000253
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000254 def test_getmodule(self):
Thomas Wouters89f507f2006-12-13 04:49:30 +0000255 # Check actual module
256 self.assertEqual(inspect.getmodule(mod), mod)
257 # Check class (uses __module__ attribute)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000258 self.assertEqual(inspect.getmodule(mod.StupidGit), mod)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000259 # Check a method (no __module__ attribute, falls back to filename)
260 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
261 # Do it again (check the caching isn't broken)
262 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
263 # Check a builtin
Georg Brandl1a3284e2007-12-02 09:40:06 +0000264 self.assertEqual(inspect.getmodule(str), sys.modules["builtins"])
Thomas Wouters89f507f2006-12-13 04:49:30 +0000265 # Check filename override
266 self.assertEqual(inspect.getmodule(None, modfile), mod)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000267
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000268 def test_getsource(self):
269 self.assertSourceEqual(git.abuse, 29, 39)
270 self.assertSourceEqual(mod.StupidGit, 21, 46)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000271
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000272 def test_getsourcefile(self):
Christian Heimesa3538eb2007-11-06 11:44:48 +0000273 self.assertEqual(normcase(inspect.getsourcefile(mod.spam)), modfile)
274 self.assertEqual(normcase(inspect.getsourcefile(git.abuse)), modfile)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000275
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000276 def test_getfile(self):
277 self.assertEqual(inspect.getfile(mod.StupidGit), mod.__file__)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000278
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000279 def test_getmodule_recursion(self):
Christian Heimes45f9af32007-11-27 21:50:00 +0000280 from types import ModuleType
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000281 name = '__inspect_dummy'
Christian Heimes45f9af32007-11-27 21:50:00 +0000282 m = sys.modules[name] = ModuleType(name)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000283 m.__file__ = "<string>" # hopefully not a real filename...
284 m.__loader__ = "dummy" # pretend the filename is understood by a loader
Georg Brandl7cae87c2006-09-06 06:51:57 +0000285 exec("def x(): pass", m.__dict__)
Neal Norwitz221085d2007-02-25 20:55:47 +0000286 self.assertEqual(inspect.getsourcefile(m.x.__code__), '<string>')
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000287 del sys.modules[name]
288 inspect.getmodule(compile('a=10','','single'))
289
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000290class TestDecorators(GetSourceBase):
291 fodderFile = mod2
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000292
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000293 def test_wrapped_decorator(self):
Christian Heimes09aaa882008-02-23 15:01:06 +0000294 self.assertSourceEqual(mod2.wrapped, 14, 17)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000295
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000296 def test_replacing_decorator(self):
297 self.assertSourceEqual(mod2.gone, 9, 10)
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000298
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000299class TestOneliners(GetSourceBase):
300 fodderFile = mod2
301 def test_oneline_lambda(self):
302 # Test inspect.getsource with a one-line lambda function.
303 self.assertSourceEqual(mod2.oll, 25, 25)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000304
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000305 def test_threeline_lambda(self):
306 # Test inspect.getsource with a three-line lambda function,
307 # where the second and third lines are _not_ indented.
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000308 self.assertSourceEqual(mod2.tll, 28, 30)
309
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000310 def test_twoline_indented_lambda(self):
311 # Test inspect.getsource with a two-line lambda function,
312 # where the second line _is_ indented.
313 self.assertSourceEqual(mod2.tlli, 33, 34)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000314
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000315 def test_onelinefunc(self):
316 # Test inspect.getsource with a regular one-line function.
317 self.assertSourceEqual(mod2.onelinefunc, 37, 37)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000318
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000319 def test_manyargs(self):
320 # Test inspect.getsource with a regular function where
321 # the arguments are on two lines and _not_ indented and
322 # the body on the second line with the last arguments.
323 self.assertSourceEqual(mod2.manyargs, 40, 41)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000324
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000325 def test_twolinefunc(self):
326 # Test inspect.getsource with a regular function where
327 # the body is on two lines, following the argument list and
328 # continued on the next line by a \\.
329 self.assertSourceEqual(mod2.twolinefunc, 44, 45)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000330
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000331 def test_lambda_in_list(self):
332 # Test inspect.getsource with a one-line lambda function
333 # defined in a list, indented.
334 self.assertSourceEqual(mod2.a[1], 49, 49)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000335
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000336 def test_anonymous(self):
337 # Test inspect.getsource with a lambda function defined
338 # as argument to another function.
339 self.assertSourceEqual(mod2.anonymous, 55, 55)
340
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000341class TestBuggyCases(GetSourceBase):
342 fodderFile = mod2
343
344 def test_with_comment(self):
345 self.assertSourceEqual(mod2.with_comment, 58, 59)
346
347 def test_multiline_sig(self):
348 self.assertSourceEqual(mod2.multiline_sig[0], 63, 64)
349
Armin Rigodd5c0232005-09-25 11:45:45 +0000350 def test_nested_class(self):
351 self.assertSourceEqual(mod2.func69().func71, 71, 72)
352
353 def test_one_liner_followed_by_non_name(self):
354 self.assertSourceEqual(mod2.func77, 77, 77)
355
356 def test_one_liner_dedent_non_name(self):
357 self.assertSourceEqual(mod2.cls82.func83, 83, 83)
358
359 def test_with_comment_instead_of_docstring(self):
360 self.assertSourceEqual(mod2.func88, 88, 90)
361
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000362 def test_method_in_dynamic_class(self):
363 self.assertSourceEqual(mod2.method_in_dynamic_class, 95, 97)
364
R. David Murrayb5655772009-05-14 16:17:50 +0000365 @unittest.skipIf(
366 not hasattr(unicodedata, '__file__') or
367 unicodedata.__file__[-4:] in (".pyc", ".pyo"),
368 "unicodedata is not an external binary module")
R. David Murray74b89242009-05-13 17:33:03 +0000369 def test_findsource_binary(self):
R. David Murrayb5655772009-05-14 16:17:50 +0000370 self.assertRaises(IOError, inspect.getsource, unicodedata)
371 self.assertRaises(IOError, inspect.findsource, unicodedata)
R. David Murray74b89242009-05-13 17:33:03 +0000372
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000373# Helper for testing classify_class_attrs.
Tim Peters13b49d32001-09-23 02:00:29 +0000374def attrs_wo_objs(cls):
375 return [t[:3] for t in inspect.classify_class_attrs(cls)]
376
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000377class TestClassesAndFunctions(unittest.TestCase):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000378 def test_newstyle_mro(self):
379 # The same w/ new-class MRO.
380 class A(object): pass
381 class B(A): pass
382 class C(A): pass
383 class D(B, C): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000384
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000385 expected = (D, B, C, A, object)
386 got = inspect.getmro(D)
387 self.assertEqual(expected, got)
Tim Peters13b49d32001-09-23 02:00:29 +0000388
Christian Heimes3795b532007-11-08 13:48:53 +0000389 def assertArgSpecEquals(self, routine, args_e, varargs_e=None,
390 varkw_e=None, defaults_e=None, formatted=None):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000391 args, varargs, varkw, defaults = inspect.getargspec(routine)
392 self.assertEqual(args, args_e)
393 self.assertEqual(varargs, varargs_e)
394 self.assertEqual(varkw, varkw_e)
395 self.assertEqual(defaults, defaults_e)
396 if formatted is not None:
397 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults),
398 formatted)
Tim Peters13b49d32001-09-23 02:00:29 +0000399
Christian Heimes3795b532007-11-08 13:48:53 +0000400 def assertFullArgSpecEquals(self, routine, args_e, varargs_e=None,
401 varkw_e=None, defaults_e=None,
402 kwonlyargs_e=[], kwonlydefaults_e=None,
403 ann_e={}, formatted=None):
404 args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \
405 inspect.getfullargspec(routine)
406 self.assertEqual(args, args_e)
407 self.assertEqual(varargs, varargs_e)
408 self.assertEqual(varkw, varkw_e)
409 self.assertEqual(defaults, defaults_e)
410 self.assertEqual(kwonlyargs, kwonlyargs_e)
411 self.assertEqual(kwonlydefaults, kwonlydefaults_e)
412 self.assertEqual(ann, ann_e)
413 if formatted is not None:
414 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults,
415 kwonlyargs, kwonlydefaults, ann),
416 formatted)
417
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000418 def test_getargspec(self):
Christian Heimes3795b532007-11-08 13:48:53 +0000419 self.assertArgSpecEquals(mod.eggs, ['x', 'y'], formatted='(x, y)')
Tim Peters13b49d32001-09-23 02:00:29 +0000420
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000421 self.assertArgSpecEquals(mod.spam,
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000422 ['a', 'b', 'c', 'd', 'e', 'f'],
423 'g', 'h', (3, 4, 5),
424 '(a, b, c, d=3, e=4, f=5, *g, **h)')
Tim Peters13b49d32001-09-23 02:00:29 +0000425
Christian Heimes3795b532007-11-08 13:48:53 +0000426 self.assertRaises(ValueError, self.assertArgSpecEquals,
427 mod2.keyworded, [])
428
429 self.assertRaises(ValueError, self.assertArgSpecEquals,
430 mod2.annotated, [])
Benjamin Peterson9953a8d2009-01-17 04:15:01 +0000431 self.assertRaises(ValueError, self.assertArgSpecEquals,
432 mod2.keyword_only_arg, [])
433
Christian Heimes3795b532007-11-08 13:48:53 +0000434
435 def test_getfullargspec(self):
436 self.assertFullArgSpecEquals(mod2.keyworded, [], varargs_e='arg1',
437 kwonlyargs_e=['arg2'],
438 kwonlydefaults_e={'arg2':1},
439 formatted='(*arg1, arg2=1)')
440
441 self.assertFullArgSpecEquals(mod2.annotated, ['arg1'],
Christian Heimesc9543e42007-11-28 08:28:28 +0000442 ann_e={'arg1' : list},
Christian Heimes3795b532007-11-08 13:48:53 +0000443 formatted='(arg1: list)')
Benjamin Peterson9953a8d2009-01-17 04:15:01 +0000444 self.assertFullArgSpecEquals(mod2.keyword_only_arg, [],
445 kwonlyargs_e=['arg'],
446 formatted='(*, arg)')
447
Christian Heimes3795b532007-11-08 13:48:53 +0000448
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000449 def test_getargspec_method(self):
450 class A(object):
451 def m(self):
452 pass
453 self.assertArgSpecEquals(A.m, ['self'])
Tim Peters13b49d32001-09-23 02:00:29 +0000454
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000455 def test_classify_newstyle(self):
456 class A(object):
Tim Peters13b49d32001-09-23 02:00:29 +0000457
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000458 def s(): pass
459 s = staticmethod(s)
Tim Peters13b49d32001-09-23 02:00:29 +0000460
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000461 def c(cls): pass
462 c = classmethod(c)
Tim Peters13b49d32001-09-23 02:00:29 +0000463
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000464 def getp(self): pass
465 p = property(getp)
Tim Peters13b49d32001-09-23 02:00:29 +0000466
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000467 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000468
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000469 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000470
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000471 datablob = '1'
Tim Peters13b49d32001-09-23 02:00:29 +0000472
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000473 attrs = attrs_wo_objs(A)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000474 self.assertTrue(('s', 'static method', A) in attrs, 'missing static method')
475 self.assertTrue(('c', 'class method', A) in attrs, 'missing class method')
476 self.assertTrue(('p', 'property', A) in attrs, 'missing property')
477 self.assertTrue(('m', 'method', A) in attrs,
Christian Heimes4a22b5d2007-11-25 09:39:14 +0000478 'missing plain method: %r' % attrs)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000479 self.assertTrue(('m1', 'method', A) in attrs, 'missing plain method')
480 self.assertTrue(('datablob', 'data', A) in attrs, 'missing data')
Tim Peters13b49d32001-09-23 02:00:29 +0000481
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000482 class B(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000483
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000484 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000485
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000486 attrs = attrs_wo_objs(B)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000487 self.assertTrue(('s', 'static method', A) in attrs, 'missing static method')
488 self.assertTrue(('c', 'class method', A) in attrs, 'missing class method')
489 self.assertTrue(('p', 'property', A) in attrs, 'missing property')
490 self.assertTrue(('m', 'method', B) in attrs, 'missing plain method')
491 self.assertTrue(('m1', 'method', A) in attrs, 'missing plain method')
492 self.assertTrue(('datablob', 'data', A) in attrs, 'missing data')
Tim Peters13b49d32001-09-23 02:00:29 +0000493
494
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000495 class C(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000496
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000497 def m(self): pass
498 def c(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000499
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000500 attrs = attrs_wo_objs(C)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000501 self.assertTrue(('s', 'static method', A) in attrs, 'missing static method')
502 self.assertTrue(('c', 'method', C) in attrs, 'missing plain method')
503 self.assertTrue(('p', 'property', A) in attrs, 'missing property')
504 self.assertTrue(('m', 'method', C) in attrs, 'missing plain method')
505 self.assertTrue(('m1', 'method', A) in attrs, 'missing plain method')
506 self.assertTrue(('datablob', 'data', A) in attrs, 'missing data')
Tim Peters13b49d32001-09-23 02:00:29 +0000507
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000508 class D(B, C):
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 attrs = attrs_wo_objs(D)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000513 self.assertTrue(('s', 'static method', A) in attrs, 'missing static method')
514 self.assertTrue(('c', 'method', C) in attrs, 'missing plain method')
515 self.assertTrue(('p', 'property', A) in attrs, 'missing property')
516 self.assertTrue(('m', 'method', B) in attrs, 'missing plain method')
517 self.assertTrue(('m1', 'method', D) in attrs, 'missing plain method')
518 self.assertTrue(('datablob', 'data', A) in attrs, 'missing data')
Jeremy Hyltonc4bf5ed2003-06-27 18:43:12 +0000519
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000520def test_main():
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000521 run_unittest(TestDecorators, TestRetrievingSourceCode, TestOneliners,
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000522 TestBuggyCases,
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000523 TestInterpreterStack, TestClassesAndFunctions, TestPredicates)
Martin v. Löwis893ffa42003-10-31 15:35:53 +0000524
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000525if __name__ == "__main__":
526 test_main()