blob: b89f807544b3213505e41eae25b1f92d4299bec5 [file] [log] [blame]
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001import re
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00002import sys
Thomas Wouters0e3f5912006-08-11 14:57:12 +00003import types
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00004import unittest
5import inspect
Thomas Wouters0e3f5912006-08-11 14:57:12 +00006import datetime
Guido van Rossum813b0e52007-05-21 18:11:34 +00007import collections
Christian Heimesa3538eb2007-11-06 11:44:48 +00008from os.path import normcase
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00009
Georg Brandl1b37e872010-03-14 10:45:50 +000010from test.support import run_unittest
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000011
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000012from test import inspect_fodder as mod
13from test import inspect_fodder2 as mod2
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000014
R. David Murray74b89242009-05-13 17:33:03 +000015# C module for test_findsource_binary
R. David Murrayb5655772009-05-14 16:17:50 +000016import unicodedata
R. David Murray74b89242009-05-13 17:33:03 +000017
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000018# Functions tested in this suite:
19# ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode,
Christian Heimes7131fd92008-02-19 14:21:46 +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 Coghlanf088e5e2008-12-14 11:50:48 +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__
Thomas Wouters0e3f5912006-08-11 14:57:12 +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
Christian Heimesa3538eb2007-11-06 11:44:48 +000032# Normalize file names: on Windows, the case of file names of compiled
33# modules depends on the path used to start the python executable.
34modfile = normcase(modfile)
35
36def revise(filename, *args):
37 return (normcase(filename),) + args
38
Georg Brandl1a3284e2007-12-02 09:40:06 +000039import builtins
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000040
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000041try:
42 1/0
43except:
Guido van Rossume7ba4952007-06-06 23:52:48 +000044 tb = sys.exc_info()[2]
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000045
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000046git = mod.StupidGit()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000047
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000048class IsTestBase(unittest.TestCase):
49 predicates = set([inspect.isbuiltin, inspect.isclass, inspect.iscode,
50 inspect.isframe, inspect.isfunction, inspect.ismethod,
Christian Heimes7131fd92008-02-19 14:21:46 +000051 inspect.ismodule, inspect.istraceback,
52 inspect.isgenerator, inspect.isgeneratorfunction])
Tim Peters5a9fb3c2005-01-07 16:01:32 +000053
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000054 def istest(self, predicate, exp):
55 obj = eval(exp)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000056 self.assertTrue(predicate(obj), '%s(%s)' % (predicate.__name__, exp))
Tim Peters5a9fb3c2005-01-07 16:01:32 +000057
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000058 for other in self.predicates - set([predicate]):
Christian Heimes7131fd92008-02-19 14:21:46 +000059 if predicate == inspect.isgeneratorfunction and\
60 other == inspect.isfunction:
61 continue
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000062 self.assertFalse(other(obj), 'not %s(%s)' % (other.__name__, exp))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000063
Christian Heimes7131fd92008-02-19 14:21:46 +000064def generator_function_example(self):
65 for i in range(2):
66 yield i
67
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000068class TestPredicates(IsTestBase):
Christian Heimes227c8002008-03-03 20:34:40 +000069 def test_sixteen(self):
Guido van Rossumc1f779c2007-07-03 08:25:58 +000070 count = len([x for x in dir(inspect) if x.startswith('is')])
Christian Heimes7131fd92008-02-19 14:21:46 +000071 # This test is here for remember you to update Doc/library/inspect.rst
Christian Heimes78644762008-03-04 23:39:23 +000072 # which claims there are 16 such functions
Christian Heimes227c8002008-03-03 20:34:40 +000073 expected = 16
Thomas Wouters0e3f5912006-08-11 14:57:12 +000074 err_msg = "There are %d (not %d) is* functions" % (count, expected)
75 self.assertEqual(count, expected, err_msg)
Tim Peters5a9fb3c2005-01-07 16:01:32 +000076
Christian Heimes7131fd92008-02-19 14:21:46 +000077
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000078 def test_excluding_predicates(self):
79 self.istest(inspect.isbuiltin, 'sys.exit')
80 self.istest(inspect.isbuiltin, '[].append')
Neal Norwitz221085d2007-02-25 20:55:47 +000081 self.istest(inspect.iscode, 'mod.spam.__code__')
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000082 self.istest(inspect.isframe, 'tb.tb_frame')
83 self.istest(inspect.isfunction, 'mod.spam')
Christian Heimes4a22b5d2007-11-25 09:39:14 +000084 self.istest(inspect.isfunction, 'mod.StupidGit.abuse')
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000085 self.istest(inspect.ismethod, 'git.argue')
86 self.istest(inspect.ismodule, 'mod')
87 self.istest(inspect.istraceback, 'tb')
Guido van Rossum813b0e52007-05-21 18:11:34 +000088 self.istest(inspect.isdatadescriptor, 'collections.defaultdict.default_factory')
Christian Heimes7131fd92008-02-19 14:21:46 +000089 self.istest(inspect.isgenerator, '(x for x in range(2))')
90 self.istest(inspect.isgeneratorfunction, 'generator_function_example')
Thomas Wouters0e3f5912006-08-11 14:57:12 +000091 if hasattr(types, 'GetSetDescriptorType'):
92 self.istest(inspect.isgetsetdescriptor,
93 'type(tb.tb_frame).f_locals')
94 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000095 self.assertFalse(inspect.isgetsetdescriptor(type(tb.tb_frame).f_locals))
Thomas Wouters0e3f5912006-08-11 14:57:12 +000096 if hasattr(types, 'MemberDescriptorType'):
97 self.istest(inspect.ismemberdescriptor, 'datetime.timedelta.days')
98 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000099 self.assertFalse(inspect.ismemberdescriptor(datetime.timedelta.days))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000100
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000101 def test_isroutine(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000102 self.assertTrue(inspect.isroutine(mod.spam))
103 self.assertTrue(inspect.isroutine([].count))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000104
Benjamin Petersonc4656002009-01-17 22:41:18 +0000105 def test_isclass(self):
106 self.istest(inspect.isclass, 'mod.StupidGit')
107 self.assertTrue(inspect.isclass(list))
108
109 class CustomGetattr(object):
110 def __getattr__(self, attr):
111 return None
112 self.assertFalse(inspect.isclass(CustomGetattr()))
113
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000114 def test_get_slot_members(self):
115 class C(object):
116 __slots__ = ("a", "b")
117
118 x = C()
119 x.a = 42
120 members = dict(inspect.getmembers(x))
Benjamin Peterson577473f2010-01-19 00:09:57 +0000121 self.assertIn('a', members)
122 self.assertNotIn('b', members)
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000123
Benjamin Petersona0dfa822009-11-13 02:25:08 +0000124 def test_isabstract(self):
125 from abc import ABCMeta, abstractmethod
126
127 class AbstractClassExample(metaclass=ABCMeta):
128
129 @abstractmethod
130 def foo(self):
131 pass
132
133 class ClassExample(AbstractClassExample):
134 def foo(self):
135 pass
136
137 a = ClassExample()
138
139 # Test general behaviour.
140 self.assertTrue(inspect.isabstract(AbstractClassExample))
141 self.assertFalse(inspect.isabstract(ClassExample))
142 self.assertFalse(inspect.isabstract(a))
143 self.assertFalse(inspect.isabstract(int))
144 self.assertFalse(inspect.isabstract(5))
145
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000146
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000147class TestInterpreterStack(IsTestBase):
148 def __init__(self, *args, **kwargs):
149 unittest.TestCase.__init__(self, *args, **kwargs)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000150
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000151 git.abuse(7, 8, 9)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000152
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000153 def test_abuse_done(self):
154 self.istest(inspect.istraceback, 'git.ex[2]')
155 self.istest(inspect.isframe, 'mod.fr')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000156
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000157 def test_stack(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000158 self.assertTrue(len(mod.st) >= 5)
Christian Heimesa3538eb2007-11-06 11:44:48 +0000159 self.assertEqual(revise(*mod.st[0][1:]),
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000160 (modfile, 16, 'eggs', [' st = inspect.stack()\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000161 self.assertEqual(revise(*mod.st[1][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000162 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000163 self.assertEqual(revise(*mod.st[2][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000164 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000165 self.assertEqual(revise(*mod.st[3][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000166 (modfile, 39, 'abuse', [' self.argue(a, b, c)\n'], 0))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000167
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000168 def test_trace(self):
169 self.assertEqual(len(git.tr), 3)
Florent Xiclunac8575922010-03-24 17:37:49 +0000170 self.assertEqual(revise(*git.tr[0][1:]),
171 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
172 self.assertEqual(revise(*git.tr[1][1:]),
173 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
174 self.assertEqual(revise(*git.tr[2][1:]),
175 (modfile, 18, 'eggs', [' q = y / 0\n'], 0))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000176
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000177 def test_frame(self):
178 args, varargs, varkw, locals = inspect.getargvalues(mod.fr)
179 self.assertEqual(args, ['x', 'y'])
180 self.assertEqual(varargs, None)
181 self.assertEqual(varkw, None)
182 self.assertEqual(locals, {'x': 11, 'p': 11, 'y': 14})
183 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
184 '(x=11, y=14)')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000185
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000186 def test_previous_frame(self):
187 args, varargs, varkw, locals = inspect.getargvalues(mod.fr.f_back)
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000188 self.assertEqual(args, ['a', 'b', 'c', 'd', 'e', 'f'])
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000189 self.assertEqual(varargs, 'g')
190 self.assertEqual(varkw, 'h')
191 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000192 '(a=7, b=8, c=9, d=3, e=4, f=5, *g=(), **h={})')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000193
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000194class GetSourceBase(unittest.TestCase):
195 # Subclasses must override.
196 fodderFile = None
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000197
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000198 def __init__(self, *args, **kwargs):
199 unittest.TestCase.__init__(self, *args, **kwargs)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000200
Philip Jenveya27c5bd2009-05-28 06:09:08 +0000201 with open(inspect.getsourcefile(self.fodderFile)) as fp:
202 self.source = fp.read()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000203
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000204 def sourcerange(self, top, bottom):
205 lines = self.source.split("\n")
206 return "\n".join(lines[top-1:bottom]) + "\n"
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000207
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000208 def assertSourceEqual(self, obj, top, bottom):
209 self.assertEqual(inspect.getsource(obj),
210 self.sourcerange(top, bottom))
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000211
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000212class TestRetrievingSourceCode(GetSourceBase):
213 fodderFile = mod
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000214
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000215 def test_getclasses(self):
216 classes = inspect.getmembers(mod, inspect.isclass)
217 self.assertEqual(classes,
218 [('FesteringGob', mod.FesteringGob),
219 ('MalodorousPervert', mod.MalodorousPervert),
220 ('ParrotDroppings', mod.ParrotDroppings),
221 ('StupidGit', mod.StupidGit)])
222 tree = inspect.getclasstree([cls[1] for cls in classes], 1)
223 self.assertEqual(tree,
Thomas Wouters725af872006-04-15 09:13:19 +0000224 [(object, ()),
225 [(mod.ParrotDroppings, (object,)),
226 (mod.StupidGit, (object,)),
227 [(mod.MalodorousPervert, (mod.StupidGit,)),
228 [(mod.FesteringGob, (mod.MalodorousPervert,
229 mod.ParrotDroppings))
230 ]
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000231 ]
232 ]
233 ])
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000234
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000235 def test_getfunctions(self):
236 functions = inspect.getmembers(mod, inspect.isfunction)
237 self.assertEqual(functions, [('eggs', mod.eggs),
238 ('spam', mod.spam)])
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000239
R. David Murray378c0cf2010-02-24 01:46:21 +0000240 @unittest.skipIf(sys.flags.optimize >= 2,
241 "Docstrings are omitted with -O2 and above")
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000242 def test_getdoc(self):
243 self.assertEqual(inspect.getdoc(mod), 'A module docstring.')
244 self.assertEqual(inspect.getdoc(mod.StupidGit),
245 'A longer,\n\nindented\n\ndocstring.')
246 self.assertEqual(inspect.getdoc(git.abuse),
247 'Another\n\ndocstring\n\ncontaining\n\ntabs')
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000248
Georg Brandl0c77a822008-06-10 16:37:50 +0000249 def test_cleandoc(self):
250 self.assertEqual(inspect.cleandoc('An\n indented\n docstring.'),
251 'An\nindented\ndocstring.')
252
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000253 def test_getcomments(self):
254 self.assertEqual(inspect.getcomments(mod), '# line 1\n')
255 self.assertEqual(inspect.getcomments(mod.StupidGit), '# line 20\n')
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000256
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000257 def test_getmodule(self):
Thomas Wouters89f507f2006-12-13 04:49:30 +0000258 # Check actual module
259 self.assertEqual(inspect.getmodule(mod), mod)
260 # Check class (uses __module__ attribute)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000261 self.assertEqual(inspect.getmodule(mod.StupidGit), mod)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000262 # Check a method (no __module__ attribute, falls back to filename)
263 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
264 # Do it again (check the caching isn't broken)
265 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
266 # Check a builtin
Georg Brandl1a3284e2007-12-02 09:40:06 +0000267 self.assertEqual(inspect.getmodule(str), sys.modules["builtins"])
Thomas Wouters89f507f2006-12-13 04:49:30 +0000268 # Check filename override
269 self.assertEqual(inspect.getmodule(None, modfile), mod)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000270
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000271 def test_getsource(self):
272 self.assertSourceEqual(git.abuse, 29, 39)
273 self.assertSourceEqual(mod.StupidGit, 21, 46)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000274
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000275 def test_getsourcefile(self):
Christian Heimesa3538eb2007-11-06 11:44:48 +0000276 self.assertEqual(normcase(inspect.getsourcefile(mod.spam)), modfile)
277 self.assertEqual(normcase(inspect.getsourcefile(git.abuse)), modfile)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000278
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000279 def test_getfile(self):
280 self.assertEqual(inspect.getfile(mod.StupidGit), mod.__file__)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000281
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000282 def test_getmodule_recursion(self):
Christian Heimes45f9af32007-11-27 21:50:00 +0000283 from types import ModuleType
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000284 name = '__inspect_dummy'
Christian Heimes45f9af32007-11-27 21:50:00 +0000285 m = sys.modules[name] = ModuleType(name)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000286 m.__file__ = "<string>" # hopefully not a real filename...
287 m.__loader__ = "dummy" # pretend the filename is understood by a loader
Georg Brandl7cae87c2006-09-06 06:51:57 +0000288 exec("def x(): pass", m.__dict__)
Neal Norwitz221085d2007-02-25 20:55:47 +0000289 self.assertEqual(inspect.getsourcefile(m.x.__code__), '<string>')
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000290 del sys.modules[name]
291 inspect.getmodule(compile('a=10','','single'))
292
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000293class TestDecorators(GetSourceBase):
294 fodderFile = mod2
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000295
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000296 def test_wrapped_decorator(self):
Christian Heimes09aaa882008-02-23 15:01:06 +0000297 self.assertSourceEqual(mod2.wrapped, 14, 17)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000298
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000299 def test_replacing_decorator(self):
300 self.assertSourceEqual(mod2.gone, 9, 10)
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000301
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000302class TestOneliners(GetSourceBase):
303 fodderFile = mod2
304 def test_oneline_lambda(self):
305 # Test inspect.getsource with a one-line lambda function.
306 self.assertSourceEqual(mod2.oll, 25, 25)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000307
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000308 def test_threeline_lambda(self):
309 # Test inspect.getsource with a three-line lambda function,
310 # where the second and third lines are _not_ indented.
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000311 self.assertSourceEqual(mod2.tll, 28, 30)
312
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000313 def test_twoline_indented_lambda(self):
314 # Test inspect.getsource with a two-line lambda function,
315 # where the second line _is_ indented.
316 self.assertSourceEqual(mod2.tlli, 33, 34)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000317
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000318 def test_onelinefunc(self):
319 # Test inspect.getsource with a regular one-line function.
320 self.assertSourceEqual(mod2.onelinefunc, 37, 37)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000321
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000322 def test_manyargs(self):
323 # Test inspect.getsource with a regular function where
324 # the arguments are on two lines and _not_ indented and
325 # the body on the second line with the last arguments.
326 self.assertSourceEqual(mod2.manyargs, 40, 41)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000327
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000328 def test_twolinefunc(self):
329 # Test inspect.getsource with a regular function where
330 # the body is on two lines, following the argument list and
331 # continued on the next line by a \\.
332 self.assertSourceEqual(mod2.twolinefunc, 44, 45)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000333
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000334 def test_lambda_in_list(self):
335 # Test inspect.getsource with a one-line lambda function
336 # defined in a list, indented.
337 self.assertSourceEqual(mod2.a[1], 49, 49)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000338
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000339 def test_anonymous(self):
340 # Test inspect.getsource with a lambda function defined
341 # as argument to another function.
342 self.assertSourceEqual(mod2.anonymous, 55, 55)
343
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000344class TestBuggyCases(GetSourceBase):
345 fodderFile = mod2
346
347 def test_with_comment(self):
348 self.assertSourceEqual(mod2.with_comment, 58, 59)
349
350 def test_multiline_sig(self):
351 self.assertSourceEqual(mod2.multiline_sig[0], 63, 64)
352
Armin Rigodd5c0232005-09-25 11:45:45 +0000353 def test_nested_class(self):
354 self.assertSourceEqual(mod2.func69().func71, 71, 72)
355
356 def test_one_liner_followed_by_non_name(self):
357 self.assertSourceEqual(mod2.func77, 77, 77)
358
359 def test_one_liner_dedent_non_name(self):
360 self.assertSourceEqual(mod2.cls82.func83, 83, 83)
361
362 def test_with_comment_instead_of_docstring(self):
363 self.assertSourceEqual(mod2.func88, 88, 90)
364
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000365 def test_method_in_dynamic_class(self):
366 self.assertSourceEqual(mod2.method_in_dynamic_class, 95, 97)
367
R. David Murrayb5655772009-05-14 16:17:50 +0000368 @unittest.skipIf(
369 not hasattr(unicodedata, '__file__') or
370 unicodedata.__file__[-4:] in (".pyc", ".pyo"),
371 "unicodedata is not an external binary module")
R. David Murray74b89242009-05-13 17:33:03 +0000372 def test_findsource_binary(self):
R. David Murrayb5655772009-05-14 16:17:50 +0000373 self.assertRaises(IOError, inspect.getsource, unicodedata)
374 self.assertRaises(IOError, inspect.findsource, unicodedata)
R. David Murray74b89242009-05-13 17:33:03 +0000375
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000376# Helper for testing classify_class_attrs.
Tim Peters13b49d32001-09-23 02:00:29 +0000377def attrs_wo_objs(cls):
378 return [t[:3] for t in inspect.classify_class_attrs(cls)]
379
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000380class TestClassesAndFunctions(unittest.TestCase):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000381 def test_newstyle_mro(self):
382 # The same w/ new-class MRO.
383 class A(object): pass
384 class B(A): pass
385 class C(A): pass
386 class D(B, C): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000387
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000388 expected = (D, B, C, A, object)
389 got = inspect.getmro(D)
390 self.assertEqual(expected, got)
Tim Peters13b49d32001-09-23 02:00:29 +0000391
Christian Heimes3795b532007-11-08 13:48:53 +0000392 def assertArgSpecEquals(self, routine, args_e, varargs_e=None,
393 varkw_e=None, defaults_e=None, formatted=None):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000394 args, varargs, varkw, defaults = inspect.getargspec(routine)
395 self.assertEqual(args, args_e)
396 self.assertEqual(varargs, varargs_e)
397 self.assertEqual(varkw, varkw_e)
398 self.assertEqual(defaults, defaults_e)
399 if formatted is not None:
400 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults),
401 formatted)
Tim Peters13b49d32001-09-23 02:00:29 +0000402
Christian Heimes3795b532007-11-08 13:48:53 +0000403 def assertFullArgSpecEquals(self, routine, args_e, varargs_e=None,
404 varkw_e=None, defaults_e=None,
405 kwonlyargs_e=[], kwonlydefaults_e=None,
406 ann_e={}, formatted=None):
407 args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \
408 inspect.getfullargspec(routine)
409 self.assertEqual(args, args_e)
410 self.assertEqual(varargs, varargs_e)
411 self.assertEqual(varkw, varkw_e)
412 self.assertEqual(defaults, defaults_e)
413 self.assertEqual(kwonlyargs, kwonlyargs_e)
414 self.assertEqual(kwonlydefaults, kwonlydefaults_e)
415 self.assertEqual(ann, ann_e)
416 if formatted is not None:
417 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults,
418 kwonlyargs, kwonlydefaults, ann),
419 formatted)
420
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000421 def test_getargspec(self):
Christian Heimes3795b532007-11-08 13:48:53 +0000422 self.assertArgSpecEquals(mod.eggs, ['x', 'y'], formatted='(x, y)')
Tim Peters13b49d32001-09-23 02:00:29 +0000423
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000424 self.assertArgSpecEquals(mod.spam,
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000425 ['a', 'b', 'c', 'd', 'e', 'f'],
426 'g', 'h', (3, 4, 5),
427 '(a, b, c, d=3, e=4, f=5, *g, **h)')
Tim Peters13b49d32001-09-23 02:00:29 +0000428
Christian Heimes3795b532007-11-08 13:48:53 +0000429 self.assertRaises(ValueError, self.assertArgSpecEquals,
430 mod2.keyworded, [])
431
432 self.assertRaises(ValueError, self.assertArgSpecEquals,
433 mod2.annotated, [])
Benjamin Peterson9953a8d2009-01-17 04:15:01 +0000434 self.assertRaises(ValueError, self.assertArgSpecEquals,
435 mod2.keyword_only_arg, [])
436
Christian Heimes3795b532007-11-08 13:48:53 +0000437
438 def test_getfullargspec(self):
439 self.assertFullArgSpecEquals(mod2.keyworded, [], varargs_e='arg1',
440 kwonlyargs_e=['arg2'],
441 kwonlydefaults_e={'arg2':1},
442 formatted='(*arg1, arg2=1)')
443
444 self.assertFullArgSpecEquals(mod2.annotated, ['arg1'],
Christian Heimesc9543e42007-11-28 08:28:28 +0000445 ann_e={'arg1' : list},
Christian Heimes3795b532007-11-08 13:48:53 +0000446 formatted='(arg1: list)')
Benjamin Peterson9953a8d2009-01-17 04:15:01 +0000447 self.assertFullArgSpecEquals(mod2.keyword_only_arg, [],
448 kwonlyargs_e=['arg'],
449 formatted='(*, arg)')
450
Christian Heimes3795b532007-11-08 13:48:53 +0000451
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000452 def test_getargspec_method(self):
453 class A(object):
454 def m(self):
455 pass
456 self.assertArgSpecEquals(A.m, ['self'])
Tim Peters13b49d32001-09-23 02:00:29 +0000457
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000458 def test_classify_newstyle(self):
459 class A(object):
Tim Peters13b49d32001-09-23 02:00:29 +0000460
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000461 def s(): pass
462 s = staticmethod(s)
Tim Peters13b49d32001-09-23 02:00:29 +0000463
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000464 def c(cls): pass
465 c = classmethod(c)
Tim Peters13b49d32001-09-23 02:00:29 +0000466
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000467 def getp(self): pass
468 p = property(getp)
Tim Peters13b49d32001-09-23 02:00:29 +0000469
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000470 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000471
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000472 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000473
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000474 datablob = '1'
Tim Peters13b49d32001-09-23 02:00:29 +0000475
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000476 attrs = attrs_wo_objs(A)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000477 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
478 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
479 self.assertIn(('p', 'property', A), attrs, 'missing property')
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000480 self.assertIn(('m', 'method', A), attrs,
481 'missing plain method: %r' % attrs)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000482 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
483 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Tim Peters13b49d32001-09-23 02:00:29 +0000484
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000485 class B(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000486
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000487 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000488
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000489 attrs = attrs_wo_objs(B)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000490 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
491 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
492 self.assertIn(('p', 'property', A), attrs, 'missing property')
493 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
494 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
495 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Tim Peters13b49d32001-09-23 02:00:29 +0000496
497
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000498 class C(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000499
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000500 def m(self): pass
501 def c(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000502
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000503 attrs = attrs_wo_objs(C)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000504 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
505 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
506 self.assertIn(('p', 'property', A), attrs, 'missing property')
507 self.assertIn(('m', 'method', C), attrs, 'missing plain method')
508 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
509 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Tim Peters13b49d32001-09-23 02:00:29 +0000510
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000511 class D(B, C):
Tim Peters13b49d32001-09-23 02:00:29 +0000512
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000513 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000514
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000515 attrs = attrs_wo_objs(D)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000516 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
517 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
518 self.assertIn(('p', 'property', A), attrs, 'missing property')
519 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
520 self.assertIn(('m1', 'method', D), attrs, 'missing plain method')
521 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Jeremy Hyltonc4bf5ed2003-06-27 18:43:12 +0000522
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000523class TestGetcallargsFunctions(unittest.TestCase):
524
525 def assertEqualCallArgs(self, func, call_params_string, locs=None):
526 locs = dict(locs or {}, func=func)
527 r1 = eval('func(%s)' % call_params_string, None, locs)
528 r2 = eval('inspect.getcallargs(func, %s)' % call_params_string, None,
529 locs)
530 self.assertEqual(r1, r2)
531
532 def assertEqualException(self, func, call_param_string, locs=None):
533 locs = dict(locs or {}, func=func)
534 try:
535 eval('func(%s)' % call_param_string, None, locs)
536 except Exception as e:
537 ex1 = e
538 else:
539 self.fail('Exception not raised')
540 try:
541 eval('inspect.getcallargs(func, %s)' % call_param_string, None,
542 locs)
543 except Exception as e:
544 ex2 = e
545 else:
546 self.fail('Exception not raised')
547 self.assertIs(type(ex1), type(ex2))
548 self.assertEqual(str(ex1), str(ex2))
549 del ex1, ex2
550
551 def makeCallable(self, signature):
552 """Create a function that returns its locals()"""
553 code = "lambda %s: locals()"
554 return eval(code % signature)
555
556 def test_plain(self):
557 f = self.makeCallable('a, b=1')
558 self.assertEqualCallArgs(f, '2')
559 self.assertEqualCallArgs(f, '2, 3')
560 self.assertEqualCallArgs(f, 'a=2')
561 self.assertEqualCallArgs(f, 'b=3, a=2')
562 self.assertEqualCallArgs(f, '2, b=3')
563 # expand *iterable / **mapping
564 self.assertEqualCallArgs(f, '*(2,)')
565 self.assertEqualCallArgs(f, '*[2]')
566 self.assertEqualCallArgs(f, '*(2, 3)')
567 self.assertEqualCallArgs(f, '*[2, 3]')
568 self.assertEqualCallArgs(f, '**{"a":2}')
569 self.assertEqualCallArgs(f, 'b=3, **{"a":2}')
570 self.assertEqualCallArgs(f, '2, **{"b":3}')
571 self.assertEqualCallArgs(f, '**{"b":3, "a":2}')
572 # expand UserList / UserDict
573 self.assertEqualCallArgs(f, '*collections.UserList([2])')
574 self.assertEqualCallArgs(f, '*collections.UserList([2, 3])')
575 self.assertEqualCallArgs(f, '**collections.UserDict(a=2)')
576 self.assertEqualCallArgs(f, '2, **collections.UserDict(b=3)')
577 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3)')
578
579 def test_varargs(self):
580 f = self.makeCallable('a, b=1, *c')
581 self.assertEqualCallArgs(f, '2')
582 self.assertEqualCallArgs(f, '2, 3')
583 self.assertEqualCallArgs(f, '2, 3, 4')
584 self.assertEqualCallArgs(f, '*(2,3,4)')
585 self.assertEqualCallArgs(f, '2, *[3,4]')
586 self.assertEqualCallArgs(f, '2, 3, *collections.UserList([4])')
587
588 def test_varkw(self):
589 f = self.makeCallable('a, b=1, **c')
590 self.assertEqualCallArgs(f, 'a=2')
591 self.assertEqualCallArgs(f, '2, b=3, c=4')
592 self.assertEqualCallArgs(f, 'b=3, a=2, c=4')
593 self.assertEqualCallArgs(f, 'c=4, **{"a":2, "b":3}')
594 self.assertEqualCallArgs(f, '2, c=4, **{"b":3}')
595 self.assertEqualCallArgs(f, 'b=2, **{"a":3, "c":4}')
596 self.assertEqualCallArgs(f, '**collections.UserDict(a=2, b=3, c=4)')
597 self.assertEqualCallArgs(f, '2, c=4, **collections.UserDict(b=3)')
598 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3, c=4)')
599
600 def test_keyword_only(self):
601 f = self.makeCallable('a=3, *, c, d=2')
602 self.assertEqualCallArgs(f, 'c=3')
603 self.assertEqualCallArgs(f, 'c=3, a=3')
604 self.assertEqualCallArgs(f, 'a=2, c=4')
605 self.assertEqualCallArgs(f, '4, c=4')
606 self.assertEqualException(f, '')
607 self.assertEqualException(f, '3')
608 self.assertEqualException(f, 'a=3')
609 self.assertEqualException(f, 'd=4')
610
611 def test_multiple_features(self):
612 f = self.makeCallable('a, b=2, *f, **g')
613 self.assertEqualCallArgs(f, '2, 3, 7')
614 self.assertEqualCallArgs(f, '2, 3, x=8')
615 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
616 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9')
617 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9')
618 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
619 '[2, 3, (4,[5,6])]), **{"y":9, "z":10}')
620 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
621 '(4,[5,6])]), **collections.UserDict('
622 'y=9, z=10)')
623
624 def test_errors(self):
625 f0 = self.makeCallable('')
626 f1 = self.makeCallable('a, b')
627 f2 = self.makeCallable('a, b=1')
628 # f0 takes no arguments
629 self.assertEqualException(f0, '1')
630 self.assertEqualException(f0, 'x=1')
631 self.assertEqualException(f0, '1,x=1')
632 # f1 takes exactly 2 arguments
633 self.assertEqualException(f1, '')
634 self.assertEqualException(f1, '1')
635 self.assertEqualException(f1, 'a=2')
636 self.assertEqualException(f1, 'b=3')
637 # f2 takes at least 1 argument
638 self.assertEqualException(f2, '')
639 self.assertEqualException(f2, 'b=3')
640 for f in f1, f2:
641 # f1/f2 takes exactly/at most 2 arguments
642 self.assertEqualException(f, '2, 3, 4')
643 self.assertEqualException(f, '1, 2, 3, a=1')
644 self.assertEqualException(f, '2, 3, 4, c=5')
645 self.assertEqualException(f, '2, 3, 4, a=1, c=5')
646 # f got an unexpected keyword argument
647 self.assertEqualException(f, 'c=2')
648 self.assertEqualException(f, '2, c=3')
649 self.assertEqualException(f, '2, 3, c=4')
650 self.assertEqualException(f, '2, c=4, b=3')
651 self.assertEqualException(f, '**{u"\u03c0\u03b9": 4}')
652 # f got multiple values for keyword argument
653 self.assertEqualException(f, '1, a=2')
654 self.assertEqualException(f, '1, **{"a":2}')
655 self.assertEqualException(f, '1, 2, b=3')
656 # XXX: Python inconsistency
657 # - for functions and bound methods: unexpected keyword 'c'
658 # - for unbound methods: multiple values for keyword 'a'
659 #self.assertEqualException(f, '1, c=3, a=2')
660
661class TestGetcallargsMethods(TestGetcallargsFunctions):
662
663 def setUp(self):
664 class Foo(object):
665 pass
666 self.cls = Foo
667 self.inst = Foo()
668
669 def makeCallable(self, signature):
670 assert 'self' not in signature
671 mk = super(TestGetcallargsMethods, self).makeCallable
672 self.cls.method = mk('self, ' + signature)
673 return self.inst.method
674
675class TestGetcallargsUnboundMethods(TestGetcallargsMethods):
676
677 def makeCallable(self, signature):
678 super(TestGetcallargsUnboundMethods, self).makeCallable(signature)
679 return self.cls.method
680
681 def assertEqualCallArgs(self, func, call_params_string, locs=None):
682 return super(TestGetcallargsUnboundMethods, self).assertEqualCallArgs(
683 *self._getAssertEqualParams(func, call_params_string, locs))
684
685 def assertEqualException(self, func, call_params_string, locs=None):
686 return super(TestGetcallargsUnboundMethods, self).assertEqualException(
687 *self._getAssertEqualParams(func, call_params_string, locs))
688
689 def _getAssertEqualParams(self, func, call_params_string, locs=None):
690 assert 'inst' not in call_params_string
691 locs = dict(locs or {}, inst=self.inst)
692 return (func, 'inst,' + call_params_string, locs)
693
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000694def test_main():
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000695 run_unittest(
696 TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBuggyCases,
697 TestInterpreterStack, TestClassesAndFunctions, TestPredicates,
698 TestGetcallargsFunctions, TestGetcallargsMethods,
699 TestGetcallargsUnboundMethods)
Martin v. Löwis893ffa42003-10-31 15:35:53 +0000700
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000701if __name__ == "__main__":
702 test_main()