blob: 5063a30d2290c00fedfcd4da7cd0ae9180f04f5f [file] [log] [blame]
Benjamin Peterson7e213252010-03-30 17:58:13 +00001import re
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00002import sys
Barry Warsaw00decd72006-07-27 23:43:15 +00003import types
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00004import unittest
5import inspect
R. David Murraydf1cf302010-06-17 01:36:52 +00006import linecache
Barry Warsaw00decd72006-07-27 23:43:15 +00007import datetime
Victor Stinnerc8a77d32017-05-09 11:53:16 +02008import textwrap
Benjamin Peterson7e213252010-03-30 17:58:13 +00009from UserList import UserList
10from UserDict import UserDict
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000011
Victor Stinnerc8a77d32017-05-09 11:53:16 +020012from test.support import run_unittest, check_py3k_warnings, have_unicode
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000013
Florent Xicluna07627882010-03-21 01:14:24 +000014with check_py3k_warnings(
15 ("tuple parameter unpacking has been removed", SyntaxWarning),
16 quiet=True):
17 from test import inspect_fodder as mod
18 from test import inspect_fodder2 as mod2
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000019
R. David Murray996ba022009-05-13 17:14:11 +000020# C module for test_findsource_binary
Serhiy Storchakad6bfa942015-05-31 08:01:00 +030021try:
22 import unicodedata
23except ImportError:
24 unicodedata = None
R. David Murray996ba022009-05-13 17:14:11 +000025
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000026# Functions tested in this suite:
27# ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode,
Facundo Batista759bfc62008-02-18 03:43:43 +000028# isbuiltin, isroutine, isgenerator, isgeneratorfunction, getmembers,
29# getdoc, getfile, getmodule, getsourcefile, getcomments, getsource,
30# getclasstree, getargspec, getargvalues, formatargspec, formatargvalues,
31# currentframe, stack, trace, isdatadescriptor
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000032
Nick Coghlana2053472008-12-14 10:54:50 +000033# NOTE: There are some additional tests relating to interaction with
34# zipimport in the test_zipimport_support test module.
35
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000036modfile = mod.__file__
Georg Brandlb2afe852006-06-09 20:43:48 +000037if modfile.endswith(('c', 'o')):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000038 modfile = modfile[:-1]
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000039
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000040import __builtin__
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000041
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000042try:
Florent Xicluna07627882010-03-21 01:14:24 +000043 1 // 0
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000044except:
45 tb = sys.exc_traceback
46
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000047git = mod.StupidGit()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000048
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000049class IsTestBase(unittest.TestCase):
50 predicates = set([inspect.isbuiltin, inspect.isclass, inspect.iscode,
51 inspect.isframe, inspect.isfunction, inspect.ismethod,
Facundo Batista759bfc62008-02-18 03:43:43 +000052 inspect.ismodule, inspect.istraceback,
53 inspect.isgenerator, inspect.isgeneratorfunction])
Tim Peters5a9fb3c2005-01-07 16:01:32 +000054
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000055 def istest(self, predicate, exp):
56 obj = eval(exp)
Benjamin Peterson5c8da862009-06-30 22:57:08 +000057 self.assertTrue(predicate(obj), '%s(%s)' % (predicate.__name__, exp))
Tim Peters5a9fb3c2005-01-07 16:01:32 +000058
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000059 for other in self.predicates - set([predicate]):
Facundo Batista759bfc62008-02-18 03:43:43 +000060 if predicate == inspect.isgeneratorfunction and\
61 other == inspect.isfunction:
62 continue
Benjamin Peterson5c8da862009-06-30 22:57:08 +000063 self.assertFalse(other(obj), 'not %s(%s)' % (other.__name__, exp))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000064
Facundo Batista759bfc62008-02-18 03:43:43 +000065def generator_function_example(self):
66 for i in xrange(2):
67 yield i
68
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000069class TestPredicates(IsTestBase):
Christian Heimes728bee82008-03-03 20:30:29 +000070 def test_sixteen(self):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000071 count = len(filter(lambda x:x.startswith('is'), dir(inspect)))
Facundo Batista759bfc62008-02-18 03:43:43 +000072 # This test is here for remember you to update Doc/library/inspect.rst
Georg Brandl26bc1772008-03-03 20:39:00 +000073 # which claims there are 16 such functions
Christian Heimes728bee82008-03-03 20:30:29 +000074 expected = 16
Neal Norwitzdf80af72006-07-28 04:22:34 +000075 err_msg = "There are %d (not %d) is* functions" % (count, expected)
76 self.assertEqual(count, expected, err_msg)
Tim Peters5a9fb3c2005-01-07 16:01:32 +000077
Facundo Batista759bfc62008-02-18 03:43:43 +000078
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000079 def test_excluding_predicates(self):
80 self.istest(inspect.isbuiltin, 'sys.exit')
81 self.istest(inspect.isbuiltin, '[].append')
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000082 self.istest(inspect.iscode, 'mod.spam.func_code')
83 self.istest(inspect.isframe, 'tb.tb_frame')
84 self.istest(inspect.isfunction, 'mod.spam')
85 self.istest(inspect.ismethod, 'mod.StupidGit.abuse')
86 self.istest(inspect.ismethod, 'git.argue')
87 self.istest(inspect.ismodule, 'mod')
88 self.istest(inspect.istraceback, 'tb')
89 self.istest(inspect.isdatadescriptor, '__builtin__.file.closed')
90 self.istest(inspect.isdatadescriptor, '__builtin__.file.softspace')
Facundo Batista759bfc62008-02-18 03:43:43 +000091 self.istest(inspect.isgenerator, '(x for x in xrange(2))')
92 self.istest(inspect.isgeneratorfunction, 'generator_function_example')
Barry Warsaw00decd72006-07-27 23:43:15 +000093 if hasattr(types, 'GetSetDescriptorType'):
94 self.istest(inspect.isgetsetdescriptor,
95 'type(tb.tb_frame).f_locals')
96 else:
Benjamin Peterson5c8da862009-06-30 22:57:08 +000097 self.assertFalse(inspect.isgetsetdescriptor(type(tb.tb_frame).f_locals))
Barry Warsaw00decd72006-07-27 23:43:15 +000098 if hasattr(types, 'MemberDescriptorType'):
99 self.istest(inspect.ismemberdescriptor, 'datetime.timedelta.days')
100 else:
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000101 self.assertFalse(inspect.ismemberdescriptor(datetime.timedelta.days))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000102
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000103 def test_isroutine(self):
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000104 self.assertTrue(inspect.isroutine(mod.spam))
105 self.assertTrue(inspect.isroutine([].count))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000106
Benjamin Peterson5e5fbb62009-01-17 22:27:54 +0000107 def test_isclass(self):
108 self.istest(inspect.isclass, 'mod.StupidGit')
109 self.assertTrue(inspect.isclass(list))
110
111 class newstyle(object): pass
112 self.assertTrue(inspect.isclass(newstyle))
113
114 class CustomGetattr(object):
115 def __getattr__(self, attr):
116 return None
117 self.assertFalse(inspect.isclass(CustomGetattr()))
118
Amaury Forgeot d'Arcb54447f2009-01-13 23:39:22 +0000119 def test_get_slot_members(self):
120 class C(object):
121 __slots__ = ("a", "b")
122
123 x = C()
124 x.a = 42
125 members = dict(inspect.getmembers(x))
Ezio Melottiaa980582010-01-23 23:04:36 +0000126 self.assertIn('a', members)
127 self.assertNotIn('b', members)
Amaury Forgeot d'Arcb54447f2009-01-13 23:39:22 +0000128
Benjamin Petersonc63457b2009-10-15 03:06:55 +0000129 def test_isabstract(self):
130 from abc import ABCMeta, abstractmethod
131
132 class AbstractClassExample(object):
133 __metaclass__ = ABCMeta
134
135 @abstractmethod
136 def foo(self):
137 pass
138
139 class ClassExample(AbstractClassExample):
140 def foo(self):
141 pass
142
143 a = ClassExample()
144
145 # Test general behaviour.
146 self.assertTrue(inspect.isabstract(AbstractClassExample))
147 self.assertFalse(inspect.isabstract(ClassExample))
148 self.assertFalse(inspect.isabstract(a))
149 self.assertFalse(inspect.isabstract(int))
150 self.assertFalse(inspect.isabstract(5))
151
Amaury Forgeot d'Arcb54447f2009-01-13 23:39:22 +0000152
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000153class TestInterpreterStack(IsTestBase):
154 def __init__(self, *args, **kwargs):
155 unittest.TestCase.__init__(self, *args, **kwargs)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000156
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000157 git.abuse(7, 8, 9)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000158
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000159 def test_abuse_done(self):
160 self.istest(inspect.istraceback, 'git.ex[2]')
161 self.istest(inspect.isframe, 'mod.fr')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000162
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000163 def test_stack(self):
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000164 self.assertTrue(len(mod.st) >= 5)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000165 self.assertEqual(mod.st[0][1:],
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000166 (modfile, 16, 'eggs', [' st = inspect.stack()\n'], 0))
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000167 self.assertEqual(mod.st[1][1:],
168 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
169 self.assertEqual(mod.st[2][1:],
170 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
171 self.assertEqual(mod.st[3][1:],
172 (modfile, 39, 'abuse', [' self.argue(a, b, c)\n'], 0))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000173
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000174 def test_trace(self):
175 self.assertEqual(len(git.tr), 3)
176 self.assertEqual(git.tr[0][1:], (modfile, 43, 'argue',
177 [' spam(a, b, c)\n'], 0))
178 self.assertEqual(git.tr[1][1:], (modfile, 9, 'spam',
179 [' eggs(b + d, c + f)\n'], 0))
180 self.assertEqual(git.tr[2][1:], (modfile, 18, 'eggs',
Mark Dickinsonc68e9f02010-02-03 16:50:14 +0000181 [' q = y // 0\n'], 0))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000182
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000183 def test_frame(self):
184 args, varargs, varkw, locals = inspect.getargvalues(mod.fr)
185 self.assertEqual(args, ['x', 'y'])
186 self.assertEqual(varargs, None)
187 self.assertEqual(varkw, None)
188 self.assertEqual(locals, {'x': 11, 'p': 11, 'y': 14})
189 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
190 '(x=11, y=14)')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000191
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000192 def test_previous_frame(self):
193 args, varargs, varkw, locals = inspect.getargvalues(mod.fr.f_back)
194 self.assertEqual(args, ['a', 'b', 'c', 'd', ['e', ['f']]])
195 self.assertEqual(varargs, 'g')
196 self.assertEqual(varkw, 'h')
197 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
198 '(a=7, b=8, c=9, d=3, (e=4, (f=5,)), *g=(), **h={})')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000199
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000200class GetSourceBase(unittest.TestCase):
201 # Subclasses must override.
202 fodderFile = None
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000203
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000204 def __init__(self, *args, **kwargs):
205 unittest.TestCase.__init__(self, *args, **kwargs)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000206
Philip Jenvey6a111022009-05-28 05:58:44 +0000207 with open(inspect.getsourcefile(self.fodderFile)) as fp:
208 self.source = fp.read()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000209
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000210 def sourcerange(self, top, bottom):
211 lines = self.source.split("\n")
Tal Einat491740f2018-08-26 11:44:53 +0300212 return "\n".join(lines[top-1:bottom]) + ("\n" if bottom else "")
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000213
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000214 def assertSourceEqual(self, obj, top, bottom):
215 self.assertEqual(inspect.getsource(obj),
216 self.sourcerange(top, bottom))
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000217
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000218class TestRetrievingSourceCode(GetSourceBase):
219 fodderFile = mod
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000220
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000221 def test_getclasses(self):
222 classes = inspect.getmembers(mod, inspect.isclass)
223 self.assertEqual(classes,
224 [('FesteringGob', mod.FesteringGob),
225 ('MalodorousPervert', mod.MalodorousPervert),
226 ('ParrotDroppings', mod.ParrotDroppings),
Serhiy Storchaka6db9e882013-09-05 17:28:10 +0300227 ('StupidGit', mod.StupidGit),
228 ('Tit', mod.MalodorousPervert),
229 ])
230 tree = inspect.getclasstree([cls[1] for cls in classes])
231 self.assertEqual(tree,
232 [(mod.ParrotDroppings, ()),
233 [(mod.FesteringGob, (mod.MalodorousPervert,
234 mod.ParrotDroppings))
235 ],
236 (mod.StupidGit, ()),
237 [(mod.MalodorousPervert, (mod.StupidGit,)),
238 [(mod.FesteringGob, (mod.MalodorousPervert,
239 mod.ParrotDroppings))
240 ]
241 ]
242 ])
243 tree = inspect.getclasstree([cls[1] for cls in classes], True)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000244 self.assertEqual(tree,
245 [(mod.ParrotDroppings, ()),
246 (mod.StupidGit, ()),
247 [(mod.MalodorousPervert, (mod.StupidGit,)),
248 [(mod.FesteringGob, (mod.MalodorousPervert,
249 mod.ParrotDroppings))
250 ]
251 ]
252 ])
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000253
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000254 def test_getfunctions(self):
255 functions = inspect.getmembers(mod, inspect.isfunction)
256 self.assertEqual(functions, [('eggs', mod.eggs),
257 ('spam', mod.spam)])
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000258
R. David Murrayf28fd242010-02-23 00:24:49 +0000259 @unittest.skipIf(sys.flags.optimize >= 2,
260 "Docstrings are omitted with -O2 and above")
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000261 def test_getdoc(self):
262 self.assertEqual(inspect.getdoc(mod), 'A module docstring.')
263 self.assertEqual(inspect.getdoc(mod.StupidGit),
264 'A longer,\n\nindented\n\ndocstring.')
265 self.assertEqual(inspect.getdoc(git.abuse),
266 'Another\n\ndocstring\n\ncontaining\n\ntabs')
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000267
Georg Brandl7be19aa2008-06-07 15:59:10 +0000268 def test_cleandoc(self):
269 self.assertEqual(inspect.cleandoc('An\n indented\n docstring.'),
270 'An\nindented\ndocstring.')
271
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000272 def test_getcomments(self):
273 self.assertEqual(inspect.getcomments(mod), '# line 1\n')
274 self.assertEqual(inspect.getcomments(mod.StupidGit), '# line 20\n')
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000275
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000276 def test_getmodule(self):
Nick Coghlanc495c662006-09-07 10:50:34 +0000277 # Check actual module
278 self.assertEqual(inspect.getmodule(mod), mod)
279 # Check class (uses __module__ attribute)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000280 self.assertEqual(inspect.getmodule(mod.StupidGit), mod)
Nick Coghlanc495c662006-09-07 10:50:34 +0000281 # Check a method (no __module__ attribute, falls back to filename)
282 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
283 # Do it again (check the caching isn't broken)
284 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
285 # Check a builtin
286 self.assertEqual(inspect.getmodule(str), sys.modules["__builtin__"])
287 # Check filename override
288 self.assertEqual(inspect.getmodule(None, modfile), mod)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000289
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000290 def test_getsource(self):
291 self.assertSourceEqual(git.abuse, 29, 39)
292 self.assertSourceEqual(mod.StupidGit, 21, 46)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000293
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000294 def test_getsourcefile(self):
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000295 self.assertEqual(inspect.getsourcefile(mod.spam), modfile)
296 self.assertEqual(inspect.getsourcefile(git.abuse), modfile)
R. David Murraydf1cf302010-06-17 01:36:52 +0000297 fn = "_non_existing_filename_used_for_sourcefile_test.py"
298 co = compile("None", fn, "exec")
299 self.assertEqual(inspect.getsourcefile(co), None)
300 linecache.cache[co.co_filename] = (1, None, "None", co.co_filename)
301 self.assertEqual(inspect.getsourcefile(co), fn)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000302
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000303 def test_getfile(self):
304 self.assertEqual(inspect.getfile(mod.StupidGit), mod.__file__)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000305
Phillip J. Eby5d86bdb2006-07-10 19:03:29 +0000306 def test_getmodule_recursion(self):
Christian Heimesc756d002007-11-27 21:34:01 +0000307 from types import ModuleType
Phillip J. Eby5d86bdb2006-07-10 19:03:29 +0000308 name = '__inspect_dummy'
Christian Heimesc756d002007-11-27 21:34:01 +0000309 m = sys.modules[name] = ModuleType(name)
Tim Peters722b8832006-07-10 21:11:49 +0000310 m.__file__ = "<string>" # hopefully not a real filename...
Phillip J. Eby5d86bdb2006-07-10 19:03:29 +0000311 m.__loader__ = "dummy" # pretend the filename is understood by a loader
312 exec "def x(): pass" in m.__dict__
313 self.assertEqual(inspect.getsourcefile(m.x.func_code), '<string>')
314 del sys.modules[name]
Phillip J. Eby1a2959c2006-07-20 15:54:16 +0000315 inspect.getmodule(compile('a=10','','single'))
Phillip J. Eby5d86bdb2006-07-10 19:03:29 +0000316
Benjamin Peterson0eb4ac42011-06-11 15:53:11 -0500317 def test_proceed_with_fake_filename(self):
318 '''doctest monkeypatches linecache to enable inspection'''
319 fn, source = '<test>', 'def x(): pass\n'
320 getlines = linecache.getlines
321 def monkey(filename, module_globals=None):
322 if filename == fn:
323 return source.splitlines(True)
324 else:
325 return getlines(filename, module_globals)
326 linecache.getlines = monkey
327 try:
328 ns = {}
329 exec compile(source, fn, 'single') in ns
330 inspect.getsource(ns["x"])
331 finally:
332 linecache.getlines = getlines
333
Tal Einat491740f2018-08-26 11:44:53 +0300334class TestGettingSourceOfToplevelFrames(GetSourceBase):
335 fodderFile = mod
336
337 def test_range_toplevel_frame(self):
338 self.maxDiff = None
339 self.assertSourceEqual(mod.currentframe, 1, None)
340
341 def test_range_traceback_toplevel_frame(self):
342 self.assertSourceEqual(mod.tb, 1, None)
343
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000344class TestDecorators(GetSourceBase):
345 fodderFile = mod2
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000346
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000347 def test_wrapped_decorator(self):
348 self.assertSourceEqual(mod2.wrapped, 14, 17)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000349
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000350 def test_replacing_decorator(self):
351 self.assertSourceEqual(mod2.gone, 9, 10)
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000352
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000353class TestOneliners(GetSourceBase):
354 fodderFile = mod2
355 def test_oneline_lambda(self):
356 # Test inspect.getsource with a one-line lambda function.
357 self.assertSourceEqual(mod2.oll, 25, 25)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000358
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000359 def test_threeline_lambda(self):
360 # Test inspect.getsource with a three-line lambda function,
361 # where the second and third lines are _not_ indented.
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000362 self.assertSourceEqual(mod2.tll, 28, 30)
363
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000364 def test_twoline_indented_lambda(self):
365 # Test inspect.getsource with a two-line lambda function,
366 # where the second line _is_ indented.
367 self.assertSourceEqual(mod2.tlli, 33, 34)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000368
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000369 def test_onelinefunc(self):
370 # Test inspect.getsource with a regular one-line function.
371 self.assertSourceEqual(mod2.onelinefunc, 37, 37)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000372
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000373 def test_manyargs(self):
374 # Test inspect.getsource with a regular function where
375 # the arguments are on two lines and _not_ indented and
376 # the body on the second line with the last arguments.
377 self.assertSourceEqual(mod2.manyargs, 40, 41)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000378
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000379 def test_twolinefunc(self):
380 # Test inspect.getsource with a regular function where
381 # the body is on two lines, following the argument list and
382 # continued on the next line by a \\.
383 self.assertSourceEqual(mod2.twolinefunc, 44, 45)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000384
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000385 def test_lambda_in_list(self):
386 # Test inspect.getsource with a one-line lambda function
387 # defined in a list, indented.
388 self.assertSourceEqual(mod2.a[1], 49, 49)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000389
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000390 def test_anonymous(self):
391 # Test inspect.getsource with a lambda function defined
392 # as argument to another function.
393 self.assertSourceEqual(mod2.anonymous, 55, 55)
394
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000395class TestBuggyCases(GetSourceBase):
396 fodderFile = mod2
397
398 def test_with_comment(self):
399 self.assertSourceEqual(mod2.with_comment, 58, 59)
400
401 def test_multiline_sig(self):
402 self.assertSourceEqual(mod2.multiline_sig[0], 63, 64)
403
Armin Rigodd5c0232005-09-25 11:45:45 +0000404 def test_nested_class(self):
405 self.assertSourceEqual(mod2.func69().func71, 71, 72)
406
407 def test_one_liner_followed_by_non_name(self):
408 self.assertSourceEqual(mod2.func77, 77, 77)
409
410 def test_one_liner_dedent_non_name(self):
411 self.assertSourceEqual(mod2.cls82.func83, 83, 83)
412
413 def test_with_comment_instead_of_docstring(self):
414 self.assertSourceEqual(mod2.func88, 88, 90)
415
Georg Brandl2463f8f2006-08-14 21:34:08 +0000416 def test_method_in_dynamic_class(self):
417 self.assertSourceEqual(mod2.method_in_dynamic_class, 95, 97)
418
R. David Murray87855542009-05-14 16:12:57 +0000419 @unittest.skipIf(
420 not hasattr(unicodedata, '__file__') or
421 unicodedata.__file__[-4:] in (".pyc", ".pyo"),
422 "unicodedata is not an external binary module")
R. David Murray996ba022009-05-13 17:14:11 +0000423 def test_findsource_binary(self):
R. David Murray87855542009-05-14 16:12:57 +0000424 self.assertRaises(IOError, inspect.getsource, unicodedata)
425 self.assertRaises(IOError, inspect.findsource, unicodedata)
R. David Murray996ba022009-05-13 17:14:11 +0000426
R. David Murraydf1cf302010-06-17 01:36:52 +0000427 def test_findsource_code_in_linecache(self):
428 lines = ["x=1"]
429 co = compile(lines[0], "_dynamically_created_file", "exec")
430 self.assertRaises(IOError, inspect.findsource, co)
431 self.assertRaises(IOError, inspect.getsource, co)
432 linecache.cache[co.co_filename] = (1, None, lines, co.co_filename)
Ezio Melotti2623a372010-11-21 13:34:58 +0000433 self.assertEqual(inspect.findsource(co), (lines,0))
434 self.assertEqual(inspect.getsource(co), lines[0])
R. David Murraydf1cf302010-06-17 01:36:52 +0000435
Ezio Melottie66e7de2013-03-30 05:10:28 +0200436 def test_findsource_without_filename(self):
437 for fname in ['', '<string>']:
438 co = compile('x=1', fname, "exec")
439 self.assertRaises(IOError, inspect.findsource, co)
440 self.assertRaises(IOError, inspect.getsource, co)
441
Antoine Pitroub8572a12011-12-21 10:16:14 +0100442
443class _BrokenDataDescriptor(object):
444 """
445 A broken data descriptor. See bug #1785.
446 """
447 def __get__(*args):
448 raise AssertionError("should not __get__ data descriptors")
449
450 def __set__(*args):
451 raise RuntimeError
452
453 def __getattr__(*args):
454 raise AssertionError("should not __getattr__ data descriptors")
455
456
457class _BrokenMethodDescriptor(object):
458 """
459 A broken method descriptor. See bug #1785.
460 """
461 def __get__(*args):
462 raise AssertionError("should not __get__ method descriptors")
463
464 def __getattr__(*args):
465 raise AssertionError("should not __getattr__ method descriptors")
466
467
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000468# Helper for testing classify_class_attrs.
Tim Peters13b49d32001-09-23 02:00:29 +0000469def attrs_wo_objs(cls):
470 return [t[:3] for t in inspect.classify_class_attrs(cls)]
471
Antoine Pitroub8572a12011-12-21 10:16:14 +0100472
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000473class TestClassesAndFunctions(unittest.TestCase):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000474 def test_classic_mro(self):
475 # Test classic-class method resolution order.
476 class A: pass
477 class B(A): pass
478 class C(A): pass
479 class D(B, C): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000480
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000481 expected = (D, B, A, C)
482 got = inspect.getmro(D)
483 self.assertEqual(expected, got)
Tim Peters13b49d32001-09-23 02:00:29 +0000484
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000485 def test_newstyle_mro(self):
486 # The same w/ new-class MRO.
487 class A(object): pass
488 class B(A): pass
489 class C(A): pass
490 class D(B, C): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000491
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000492 expected = (D, B, C, A, object)
493 got = inspect.getmro(D)
494 self.assertEqual(expected, got)
Tim Peters13b49d32001-09-23 02:00:29 +0000495
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000496 def assertArgSpecEquals(self, routine, args_e, varargs_e = None,
497 varkw_e = None, defaults_e = None,
498 formatted = None):
499 args, varargs, varkw, defaults = inspect.getargspec(routine)
500 self.assertEqual(args, args_e)
501 self.assertEqual(varargs, varargs_e)
502 self.assertEqual(varkw, varkw_e)
503 self.assertEqual(defaults, defaults_e)
504 if formatted is not None:
505 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults),
506 formatted)
Tim Peters13b49d32001-09-23 02:00:29 +0000507
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000508 def test_getargspec(self):
509 self.assertArgSpecEquals(mod.eggs, ['x', 'y'], formatted = '(x, y)')
Tim Peters13b49d32001-09-23 02:00:29 +0000510
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000511 self.assertArgSpecEquals(mod.spam,
512 ['a', 'b', 'c', 'd', ['e', ['f']]],
513 'g', 'h', (3, (4, (5,))),
514 '(a, b, c, d=3, (e, (f,))=(4, (5,)), *g, **h)')
Tim Peters13b49d32001-09-23 02:00:29 +0000515
Victor Stinnerc8a77d32017-05-09 11:53:16 +0200516 with check_py3k_warnings(("tuple parameter unpacking has been removed",
517 SyntaxWarning),
518 quiet=True):
519 exec(textwrap.dedent('''
520 def spam_deref(a, b, c, d=3, (e, (f,))=(4, (5,)), *g, **h):
521 def eggs():
522 return a + b + c + d + e + f + g + h
523 return eggs
524 '''))
Serhiy Storchaka3b230042017-02-01 22:53:03 +0200525 self.assertArgSpecEquals(spam_deref,
526 ['a', 'b', 'c', 'd', ['e', ['f']]],
527 'g', 'h', (3, (4, (5,))),
528 '(a, b, c, d=3, (e, (f,))=(4, (5,)), *g, **h)')
529
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000530 def test_getargspec_method(self):
531 class A(object):
532 def m(self):
533 pass
534 self.assertArgSpecEquals(A.m, ['self'])
Tim Peters13b49d32001-09-23 02:00:29 +0000535
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000536 def test_getargspec_sublistofone(self):
Florent Xicluna07627882010-03-21 01:14:24 +0000537 with check_py3k_warnings(
538 ("tuple parameter unpacking has been removed", SyntaxWarning),
539 ("parenthesized argument names are invalid", SyntaxWarning)):
540 exec 'def sublistOfOne((foo,)): return 1'
541 self.assertArgSpecEquals(sublistOfOne, [['foo']])
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000542
Serhiy Storchaka3b230042017-02-01 22:53:03 +0200543 exec 'def sublistOfOne((foo,)): return (lambda: foo)'
544 self.assertArgSpecEquals(sublistOfOne, [['foo']])
545
Florent Xicluna07627882010-03-21 01:14:24 +0000546 exec 'def fakeSublistOfOne((foo)): return 1'
547 self.assertArgSpecEquals(fakeSublistOfOne, ['foo'])
Neal Norwitz33b730e2006-03-27 08:58:23 +0000548
Serhiy Storchaka3b230042017-02-01 22:53:03 +0200549 exec 'def sublistOfOne((foo)): return (lambda: foo)'
550 self.assertArgSpecEquals(sublistOfOne, ['foo'])
551
Jean-Paul Calderoneb60ee462010-04-10 19:59:28 +0000552
553 def _classify_test(self, newstyle):
554 """Helper for testing that classify_class_attrs finds a bunch of
555 different kinds of attributes on a given class.
556 """
557 if newstyle:
558 base = object
559 else:
560 class base:
561 pass
562
563 class A(base):
564 def s(): pass
565 s = staticmethod(s)
566
567 def c(cls): pass
568 c = classmethod(c)
569
570 def getp(self): pass
571 p = property(getp)
572
573 def m(self): pass
574
575 def m1(self): pass
576
577 datablob = '1'
578
Antoine Pitroub8572a12011-12-21 10:16:14 +0100579 dd = _BrokenDataDescriptor()
580 md = _BrokenMethodDescriptor()
581
Jean-Paul Calderoneb60ee462010-04-10 19:59:28 +0000582 attrs = attrs_wo_objs(A)
583 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
584 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
585 self.assertIn(('p', 'property', A), attrs, 'missing property')
586 self.assertIn(('m', 'method', A), attrs, 'missing plain method')
587 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
588 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitroub8572a12011-12-21 10:16:14 +0100589 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
590 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Jean-Paul Calderoneb60ee462010-04-10 19:59:28 +0000591
592 class B(A):
593 def m(self): pass
594
595 attrs = attrs_wo_objs(B)
596 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
597 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
598 self.assertIn(('p', 'property', A), attrs, 'missing property')
599 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
600 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
601 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitroub8572a12011-12-21 10:16:14 +0100602 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
603 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Jean-Paul Calderoneb60ee462010-04-10 19:59:28 +0000604
605
606 class C(A):
607 def m(self): pass
608 def c(self): pass
609
610 attrs = attrs_wo_objs(C)
611 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
612 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
613 self.assertIn(('p', 'property', A), attrs, 'missing property')
614 self.assertIn(('m', 'method', C), attrs, 'missing plain method')
615 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
616 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitroub8572a12011-12-21 10:16:14 +0100617 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
618 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Jean-Paul Calderoneb60ee462010-04-10 19:59:28 +0000619
620 class D(B, C):
621 def m1(self): pass
622
623 attrs = attrs_wo_objs(D)
624 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
625 if newstyle:
626 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
627 else:
628 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
629 self.assertIn(('p', 'property', A), attrs, 'missing property')
630 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
631 self.assertIn(('m1', 'method', D), attrs, 'missing plain method')
632 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitroub8572a12011-12-21 10:16:14 +0100633 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
634 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Jean-Paul Calderoneb60ee462010-04-10 19:59:28 +0000635
636
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000637 def test_classify_oldstyle(self):
Jean-Paul Calderoneb60ee462010-04-10 19:59:28 +0000638 """classify_class_attrs finds static methods, class methods,
639 properties, normal methods, and data attributes on an old-style
640 class.
641 """
642 self._classify_test(False)
Tim Peters13b49d32001-09-23 02:00:29 +0000643
644
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000645 def test_classify_newstyle(self):
Jean-Paul Calderoneb60ee462010-04-10 19:59:28 +0000646 """Just like test_classify_oldstyle, but for a new-style class.
647 """
648 self._classify_test(True)
Tim Peters13b49d32001-09-23 02:00:29 +0000649
Antoine Pitroub8572a12011-12-21 10:16:14 +0100650 def test_classify_builtin_types(self):
651 # Simple sanity check that all built-in types can have their
652 # attributes classified.
653 for name in dir(__builtin__):
654 builtin = getattr(__builtin__, name)
655 if isinstance(builtin, type):
656 inspect.classify_class_attrs(builtin)
657
Antoine Pitroue09bc1e2012-01-18 17:39:01 +0100658 def test_getmembers_method(self):
Antoine Pitroub8572a12011-12-21 10:16:14 +0100659 # Old-style classes
Antoine Pitroue09bc1e2012-01-18 17:39:01 +0100660 class B:
661 def f(self):
662 pass
Antoine Pitroub8572a12011-12-21 10:16:14 +0100663
Antoine Pitroue09bc1e2012-01-18 17:39:01 +0100664 self.assertIn(('f', B.f), inspect.getmembers(B))
665 # contrary to spec, ismethod() is also True for unbound methods
666 # (see #1785)
667 self.assertIn(('f', B.f), inspect.getmembers(B, inspect.ismethod))
668 b = B()
669 self.assertIn(('f', b.f), inspect.getmembers(b))
670 self.assertIn(('f', b.f), inspect.getmembers(b, inspect.ismethod))
Antoine Pitroub8572a12011-12-21 10:16:14 +0100671
672 # New-style classes
Antoine Pitroue09bc1e2012-01-18 17:39:01 +0100673 class B(object):
674 def f(self):
Antoine Pitroub8572a12011-12-21 10:16:14 +0100675 pass
Antoine Pitroub8572a12011-12-21 10:16:14 +0100676
Antoine Pitroue09bc1e2012-01-18 17:39:01 +0100677 self.assertIn(('f', B.f), inspect.getmembers(B))
678 self.assertIn(('f', B.f), inspect.getmembers(B, inspect.ismethod))
679 b = B()
680 self.assertIn(('f', b.f), inspect.getmembers(b))
681 self.assertIn(('f', b.f), inspect.getmembers(b, inspect.ismethod))
Tim Peters13b49d32001-09-23 02:00:29 +0000682
Jeremy Hyltonc4bf5ed2003-06-27 18:43:12 +0000683
Benjamin Peterson7e213252010-03-30 17:58:13 +0000684class TestGetcallargsFunctions(unittest.TestCase):
685
686 # tuple parameters are named '.1', '.2', etc.
687 is_tuplename = re.compile(r'^\.\d+$').match
688
689 def assertEqualCallArgs(self, func, call_params_string, locs=None):
690 locs = dict(locs or {}, func=func)
691 r1 = eval('func(%s)' % call_params_string, None, locs)
692 r2 = eval('inspect.getcallargs(func, %s)' % call_params_string, None,
693 locs)
694 self.assertEqual(r1, r2)
695
696 def assertEqualException(self, func, call_param_string, locs=None):
697 locs = dict(locs or {}, func=func)
698 try:
699 eval('func(%s)' % call_param_string, None, locs)
700 except Exception, ex1:
701 pass
702 else:
703 self.fail('Exception not raised')
704 try:
705 eval('inspect.getcallargs(func, %s)' % call_param_string, None,
706 locs)
707 except Exception, ex2:
708 pass
709 else:
710 self.fail('Exception not raised')
711 self.assertIs(type(ex1), type(ex2))
712 self.assertEqual(str(ex1), str(ex2))
713
714 def makeCallable(self, signature):
715 """Create a function that returns its locals(), excluding the
716 autogenerated '.1', '.2', etc. tuple param names (if any)."""
Ezio Melottifcc500e2010-03-31 08:33:50 +0000717 with check_py3k_warnings(
718 ("tuple parameter unpacking has been removed", SyntaxWarning),
719 quiet=True):
720 code = ("lambda %s: dict(i for i in locals().items() "
721 "if not is_tuplename(i[0]))")
722 return eval(code % signature, {'is_tuplename' : self.is_tuplename})
Benjamin Peterson7e213252010-03-30 17:58:13 +0000723
724 def test_plain(self):
725 f = self.makeCallable('a, b=1')
726 self.assertEqualCallArgs(f, '2')
727 self.assertEqualCallArgs(f, '2, 3')
728 self.assertEqualCallArgs(f, 'a=2')
729 self.assertEqualCallArgs(f, 'b=3, a=2')
730 self.assertEqualCallArgs(f, '2, b=3')
731 # expand *iterable / **mapping
732 self.assertEqualCallArgs(f, '*(2,)')
733 self.assertEqualCallArgs(f, '*[2]')
734 self.assertEqualCallArgs(f, '*(2, 3)')
735 self.assertEqualCallArgs(f, '*[2, 3]')
736 self.assertEqualCallArgs(f, '**{"a":2}')
737 self.assertEqualCallArgs(f, 'b=3, **{"a":2}')
738 self.assertEqualCallArgs(f, '2, **{"b":3}')
739 self.assertEqualCallArgs(f, '**{"b":3, "a":2}')
740 # expand UserList / UserDict
741 self.assertEqualCallArgs(f, '*UserList([2])')
742 self.assertEqualCallArgs(f, '*UserList([2, 3])')
743 self.assertEqualCallArgs(f, '**UserDict(a=2)')
744 self.assertEqualCallArgs(f, '2, **UserDict(b=3)')
745 self.assertEqualCallArgs(f, 'b=2, **UserDict(a=3)')
746 # unicode keyword args
747 self.assertEqualCallArgs(f, '**{u"a":2}')
748 self.assertEqualCallArgs(f, 'b=3, **{u"a":2}')
749 self.assertEqualCallArgs(f, '2, **{u"b":3}')
750 self.assertEqualCallArgs(f, '**{u"b":3, u"a":2}')
751
752 def test_varargs(self):
753 f = self.makeCallable('a, b=1, *c')
754 self.assertEqualCallArgs(f, '2')
755 self.assertEqualCallArgs(f, '2, 3')
756 self.assertEqualCallArgs(f, '2, 3, 4')
757 self.assertEqualCallArgs(f, '*(2,3,4)')
758 self.assertEqualCallArgs(f, '2, *[3,4]')
759 self.assertEqualCallArgs(f, '2, 3, *UserList([4])')
760
761 def test_varkw(self):
762 f = self.makeCallable('a, b=1, **c')
763 self.assertEqualCallArgs(f, 'a=2')
764 self.assertEqualCallArgs(f, '2, b=3, c=4')
765 self.assertEqualCallArgs(f, 'b=3, a=2, c=4')
766 self.assertEqualCallArgs(f, 'c=4, **{"a":2, "b":3}')
767 self.assertEqualCallArgs(f, '2, c=4, **{"b":3}')
768 self.assertEqualCallArgs(f, 'b=2, **{"a":3, "c":4}')
769 self.assertEqualCallArgs(f, '**UserDict(a=2, b=3, c=4)')
770 self.assertEqualCallArgs(f, '2, c=4, **UserDict(b=3)')
771 self.assertEqualCallArgs(f, 'b=2, **UserDict(a=3, c=4)')
772 # unicode keyword args
773 self.assertEqualCallArgs(f, 'c=4, **{u"a":2, u"b":3}')
774 self.assertEqualCallArgs(f, '2, c=4, **{u"b":3}')
775 self.assertEqualCallArgs(f, 'b=2, **{u"a":3, u"c":4}')
776
Benjamin Peterson77d46602011-03-28 17:32:31 -0500777 def test_varkw_only(self):
778 # issue11256:
779 f = self.makeCallable('**c')
780 self.assertEqualCallArgs(f, '')
781 self.assertEqualCallArgs(f, 'a=1')
782 self.assertEqualCallArgs(f, 'a=1, b=2')
783 self.assertEqualCallArgs(f, 'c=3, **{"a": 1, "b": 2}')
784 self.assertEqualCallArgs(f, '**UserDict(a=1, b=2)')
785 self.assertEqualCallArgs(f, 'c=3, **UserDict(a=1, b=2)')
786
Benjamin Peterson7e213252010-03-30 17:58:13 +0000787 def test_tupleargs(self):
788 f = self.makeCallable('(b,c), (d,(e,f))=(0,[1,2])')
789 self.assertEqualCallArgs(f, '(2,3)')
790 self.assertEqualCallArgs(f, '[2,3]')
791 self.assertEqualCallArgs(f, 'UserList([2,3])')
792 self.assertEqualCallArgs(f, '(2,3), (4,(5,6))')
793 self.assertEqualCallArgs(f, '(2,3), (4,[5,6])')
794 self.assertEqualCallArgs(f, '(2,3), [4,UserList([5,6])]')
795
796 def test_multiple_features(self):
797 f = self.makeCallable('a, b=2, (c,(d,e))=(3,[4,5]), *f, **g')
798 self.assertEqualCallArgs(f, '2, 3, (4,[5,6]), 7')
799 self.assertEqualCallArgs(f, '2, 3, *[(4,[5,6]), 7], x=8')
800 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
801 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9')
802 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9')
803 self.assertEqualCallArgs(f, 'x=8, *UserList([2, 3, (4,[5,6])]), '
804 '**{"y":9, "z":10}')
805 self.assertEqualCallArgs(f, '2, x=8, *UserList([3, (4,[5,6])]), '
806 '**UserDict(y=9, z=10)')
807
808 def test_errors(self):
809 f0 = self.makeCallable('')
810 f1 = self.makeCallable('a, b')
811 f2 = self.makeCallable('a, b=1')
812 # f0 takes no arguments
813 self.assertEqualException(f0, '1')
814 self.assertEqualException(f0, 'x=1')
815 self.assertEqualException(f0, '1,x=1')
816 # f1 takes exactly 2 arguments
817 self.assertEqualException(f1, '')
818 self.assertEqualException(f1, '1')
819 self.assertEqualException(f1, 'a=2')
820 self.assertEqualException(f1, 'b=3')
821 # f2 takes at least 1 argument
822 self.assertEqualException(f2, '')
823 self.assertEqualException(f2, 'b=3')
824 for f in f1, f2:
825 # f1/f2 takes exactly/at most 2 arguments
826 self.assertEqualException(f, '2, 3, 4')
827 self.assertEqualException(f, '1, 2, 3, a=1')
828 self.assertEqualException(f, '2, 3, 4, c=5')
829 self.assertEqualException(f, '2, 3, 4, a=1, c=5')
830 # f got an unexpected keyword argument
831 self.assertEqualException(f, 'c=2')
832 self.assertEqualException(f, '2, c=3')
833 self.assertEqualException(f, '2, 3, c=4')
834 self.assertEqualException(f, '2, c=4, b=3')
Serhiy Storchakad6bfa942015-05-31 08:01:00 +0300835 if have_unicode:
836 self.assertEqualException(f, '**{u"\u03c0\u03b9": 4}')
Benjamin Peterson7e213252010-03-30 17:58:13 +0000837 # f got multiple values for keyword argument
838 self.assertEqualException(f, '1, a=2')
839 self.assertEqualException(f, '1, **{"a":2}')
840 self.assertEqualException(f, '1, 2, b=3')
841 # XXX: Python inconsistency
842 # - for functions and bound methods: unexpected keyword 'c'
843 # - for unbound methods: multiple values for keyword 'a'
844 #self.assertEqualException(f, '1, c=3, a=2')
845 f = self.makeCallable('(a,b)=(0,1)')
846 self.assertEqualException(f, '1')
847 self.assertEqualException(f, '[1]')
848 self.assertEqualException(f, '(1,2,3)')
Benjamin Peterson77d46602011-03-28 17:32:31 -0500849 # issue11256:
850 f3 = self.makeCallable('**c')
851 self.assertEqualException(f3, '1, 2')
852 self.assertEqualException(f3, '1, 2, a=1, b=2')
Benjamin Peterson7e213252010-03-30 17:58:13 +0000853
Serhiy Storchaka3b230042017-02-01 22:53:03 +0200854
855class TestGetcallargsFunctionsCellVars(TestGetcallargsFunctions):
856
857 def makeCallable(self, signature):
858 """Create a function that returns its locals(), excluding the
859 autogenerated '.1', '.2', etc. tuple param names (if any)."""
860 with check_py3k_warnings(
861 ("tuple parameter unpacking has been removed", SyntaxWarning),
862 quiet=True):
863 code = """lambda %s: (
864 (lambda: a+b+c+d+d+e+f+g+h), # make parameters cell vars
865 dict(i for i in locals().items()
866 if not is_tuplename(i[0]))
867 )[1]"""
868 return eval(code % signature, {'is_tuplename' : self.is_tuplename})
869
870
Benjamin Peterson7e213252010-03-30 17:58:13 +0000871class TestGetcallargsMethods(TestGetcallargsFunctions):
872
873 def setUp(self):
874 class Foo(object):
875 pass
876 self.cls = Foo
877 self.inst = Foo()
878
879 def makeCallable(self, signature):
880 assert 'self' not in signature
881 mk = super(TestGetcallargsMethods, self).makeCallable
882 self.cls.method = mk('self, ' + signature)
883 return self.inst.method
884
885class TestGetcallargsUnboundMethods(TestGetcallargsMethods):
886
887 def makeCallable(self, signature):
888 super(TestGetcallargsUnboundMethods, self).makeCallable(signature)
889 return self.cls.method
890
891 def assertEqualCallArgs(self, func, call_params_string, locs=None):
892 return super(TestGetcallargsUnboundMethods, self).assertEqualCallArgs(
893 *self._getAssertEqualParams(func, call_params_string, locs))
894
895 def assertEqualException(self, func, call_params_string, locs=None):
896 return super(TestGetcallargsUnboundMethods, self).assertEqualException(
897 *self._getAssertEqualParams(func, call_params_string, locs))
898
899 def _getAssertEqualParams(self, func, call_params_string, locs=None):
900 assert 'inst' not in call_params_string
901 locs = dict(locs or {}, inst=self.inst)
902 return (func, 'inst,' + call_params_string, locs)
903
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000904def test_main():
Benjamin Peterson7e213252010-03-30 17:58:13 +0000905 run_unittest(
906 TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBuggyCases,
907 TestInterpreterStack, TestClassesAndFunctions, TestPredicates,
Serhiy Storchaka3b230042017-02-01 22:53:03 +0200908 TestGetcallargsFunctions, TestGetcallargsFunctionsCellVars,
Tal Einat491740f2018-08-26 11:44:53 +0300909 TestGetcallargsMethods, TestGetcallargsUnboundMethods,
910 TestGettingSourceOfToplevelFrames)
Martin v. Löwis893ffa42003-10-31 15:35:53 +0000911
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000912if __name__ == "__main__":
913 test_main()