blob: 7d09c6fa0202f87cc9559d2b1debc7015cc83597 [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")
212 return "\n".join(lines[top-1:bottom]) + "\n"
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
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000334class TestDecorators(GetSourceBase):
335 fodderFile = mod2
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000336
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000337 def test_wrapped_decorator(self):
338 self.assertSourceEqual(mod2.wrapped, 14, 17)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000339
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000340 def test_replacing_decorator(self):
341 self.assertSourceEqual(mod2.gone, 9, 10)
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000342
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000343class TestOneliners(GetSourceBase):
344 fodderFile = mod2
345 def test_oneline_lambda(self):
346 # Test inspect.getsource with a one-line lambda function.
347 self.assertSourceEqual(mod2.oll, 25, 25)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000348
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000349 def test_threeline_lambda(self):
350 # Test inspect.getsource with a three-line lambda function,
351 # where the second and third lines are _not_ indented.
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000352 self.assertSourceEqual(mod2.tll, 28, 30)
353
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000354 def test_twoline_indented_lambda(self):
355 # Test inspect.getsource with a two-line lambda function,
356 # where the second line _is_ indented.
357 self.assertSourceEqual(mod2.tlli, 33, 34)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000358
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000359 def test_onelinefunc(self):
360 # Test inspect.getsource with a regular one-line function.
361 self.assertSourceEqual(mod2.onelinefunc, 37, 37)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000362
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000363 def test_manyargs(self):
364 # Test inspect.getsource with a regular function where
365 # the arguments are on two lines and _not_ indented and
366 # the body on the second line with the last arguments.
367 self.assertSourceEqual(mod2.manyargs, 40, 41)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000368
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000369 def test_twolinefunc(self):
370 # Test inspect.getsource with a regular function where
371 # the body is on two lines, following the argument list and
372 # continued on the next line by a \\.
373 self.assertSourceEqual(mod2.twolinefunc, 44, 45)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000374
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000375 def test_lambda_in_list(self):
376 # Test inspect.getsource with a one-line lambda function
377 # defined in a list, indented.
378 self.assertSourceEqual(mod2.a[1], 49, 49)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000379
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000380 def test_anonymous(self):
381 # Test inspect.getsource with a lambda function defined
382 # as argument to another function.
383 self.assertSourceEqual(mod2.anonymous, 55, 55)
384
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000385class TestBuggyCases(GetSourceBase):
386 fodderFile = mod2
387
388 def test_with_comment(self):
389 self.assertSourceEqual(mod2.with_comment, 58, 59)
390
391 def test_multiline_sig(self):
392 self.assertSourceEqual(mod2.multiline_sig[0], 63, 64)
393
Armin Rigodd5c0232005-09-25 11:45:45 +0000394 def test_nested_class(self):
395 self.assertSourceEqual(mod2.func69().func71, 71, 72)
396
397 def test_one_liner_followed_by_non_name(self):
398 self.assertSourceEqual(mod2.func77, 77, 77)
399
400 def test_one_liner_dedent_non_name(self):
401 self.assertSourceEqual(mod2.cls82.func83, 83, 83)
402
403 def test_with_comment_instead_of_docstring(self):
404 self.assertSourceEqual(mod2.func88, 88, 90)
405
Georg Brandl2463f8f2006-08-14 21:34:08 +0000406 def test_method_in_dynamic_class(self):
407 self.assertSourceEqual(mod2.method_in_dynamic_class, 95, 97)
408
R. David Murray87855542009-05-14 16:12:57 +0000409 @unittest.skipIf(
410 not hasattr(unicodedata, '__file__') or
411 unicodedata.__file__[-4:] in (".pyc", ".pyo"),
412 "unicodedata is not an external binary module")
R. David Murray996ba022009-05-13 17:14:11 +0000413 def test_findsource_binary(self):
R. David Murray87855542009-05-14 16:12:57 +0000414 self.assertRaises(IOError, inspect.getsource, unicodedata)
415 self.assertRaises(IOError, inspect.findsource, unicodedata)
R. David Murray996ba022009-05-13 17:14:11 +0000416
R. David Murraydf1cf302010-06-17 01:36:52 +0000417 def test_findsource_code_in_linecache(self):
418 lines = ["x=1"]
419 co = compile(lines[0], "_dynamically_created_file", "exec")
420 self.assertRaises(IOError, inspect.findsource, co)
421 self.assertRaises(IOError, inspect.getsource, co)
422 linecache.cache[co.co_filename] = (1, None, lines, co.co_filename)
Ezio Melotti2623a372010-11-21 13:34:58 +0000423 self.assertEqual(inspect.findsource(co), (lines,0))
424 self.assertEqual(inspect.getsource(co), lines[0])
R. David Murraydf1cf302010-06-17 01:36:52 +0000425
Ezio Melottie66e7de2013-03-30 05:10:28 +0200426 def test_findsource_without_filename(self):
427 for fname in ['', '<string>']:
428 co = compile('x=1', fname, "exec")
429 self.assertRaises(IOError, inspect.findsource, co)
430 self.assertRaises(IOError, inspect.getsource, co)
431
Antoine Pitroub8572a12011-12-21 10:16:14 +0100432
433class _BrokenDataDescriptor(object):
434 """
435 A broken data descriptor. See bug #1785.
436 """
437 def __get__(*args):
438 raise AssertionError("should not __get__ data descriptors")
439
440 def __set__(*args):
441 raise RuntimeError
442
443 def __getattr__(*args):
444 raise AssertionError("should not __getattr__ data descriptors")
445
446
447class _BrokenMethodDescriptor(object):
448 """
449 A broken method descriptor. See bug #1785.
450 """
451 def __get__(*args):
452 raise AssertionError("should not __get__ method descriptors")
453
454 def __getattr__(*args):
455 raise AssertionError("should not __getattr__ method descriptors")
456
457
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000458# Helper for testing classify_class_attrs.
Tim Peters13b49d32001-09-23 02:00:29 +0000459def attrs_wo_objs(cls):
460 return [t[:3] for t in inspect.classify_class_attrs(cls)]
461
Antoine Pitroub8572a12011-12-21 10:16:14 +0100462
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000463class TestClassesAndFunctions(unittest.TestCase):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000464 def test_classic_mro(self):
465 # Test classic-class method resolution order.
466 class A: pass
467 class B(A): pass
468 class C(A): pass
469 class D(B, C): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000470
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000471 expected = (D, B, A, C)
472 got = inspect.getmro(D)
473 self.assertEqual(expected, got)
Tim Peters13b49d32001-09-23 02:00:29 +0000474
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000475 def test_newstyle_mro(self):
476 # The same w/ new-class MRO.
477 class A(object): pass
478 class B(A): pass
479 class C(A): pass
480 class D(B, C): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000481
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000482 expected = (D, B, C, A, object)
483 got = inspect.getmro(D)
484 self.assertEqual(expected, got)
Tim Peters13b49d32001-09-23 02:00:29 +0000485
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000486 def assertArgSpecEquals(self, routine, args_e, varargs_e = None,
487 varkw_e = None, defaults_e = None,
488 formatted = None):
489 args, varargs, varkw, defaults = inspect.getargspec(routine)
490 self.assertEqual(args, args_e)
491 self.assertEqual(varargs, varargs_e)
492 self.assertEqual(varkw, varkw_e)
493 self.assertEqual(defaults, defaults_e)
494 if formatted is not None:
495 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults),
496 formatted)
Tim Peters13b49d32001-09-23 02:00:29 +0000497
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000498 def test_getargspec(self):
499 self.assertArgSpecEquals(mod.eggs, ['x', 'y'], formatted = '(x, y)')
Tim Peters13b49d32001-09-23 02:00:29 +0000500
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000501 self.assertArgSpecEquals(mod.spam,
502 ['a', 'b', 'c', 'd', ['e', ['f']]],
503 'g', 'h', (3, (4, (5,))),
504 '(a, b, c, d=3, (e, (f,))=(4, (5,)), *g, **h)')
Tim Peters13b49d32001-09-23 02:00:29 +0000505
Victor Stinnerc8a77d32017-05-09 11:53:16 +0200506 with check_py3k_warnings(("tuple parameter unpacking has been removed",
507 SyntaxWarning),
508 quiet=True):
509 exec(textwrap.dedent('''
510 def spam_deref(a, b, c, d=3, (e, (f,))=(4, (5,)), *g, **h):
511 def eggs():
512 return a + b + c + d + e + f + g + h
513 return eggs
514 '''))
Serhiy Storchaka3b230042017-02-01 22:53:03 +0200515 self.assertArgSpecEquals(spam_deref,
516 ['a', 'b', 'c', 'd', ['e', ['f']]],
517 'g', 'h', (3, (4, (5,))),
518 '(a, b, c, d=3, (e, (f,))=(4, (5,)), *g, **h)')
519
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000520 def test_getargspec_method(self):
521 class A(object):
522 def m(self):
523 pass
524 self.assertArgSpecEquals(A.m, ['self'])
Tim Peters13b49d32001-09-23 02:00:29 +0000525
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000526 def test_getargspec_sublistofone(self):
Florent Xicluna07627882010-03-21 01:14:24 +0000527 with check_py3k_warnings(
528 ("tuple parameter unpacking has been removed", SyntaxWarning),
529 ("parenthesized argument names are invalid", SyntaxWarning)):
530 exec 'def sublistOfOne((foo,)): return 1'
531 self.assertArgSpecEquals(sublistOfOne, [['foo']])
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000532
Serhiy Storchaka3b230042017-02-01 22:53:03 +0200533 exec 'def sublistOfOne((foo,)): return (lambda: foo)'
534 self.assertArgSpecEquals(sublistOfOne, [['foo']])
535
Florent Xicluna07627882010-03-21 01:14:24 +0000536 exec 'def fakeSublistOfOne((foo)): return 1'
537 self.assertArgSpecEquals(fakeSublistOfOne, ['foo'])
Neal Norwitz33b730e2006-03-27 08:58:23 +0000538
Serhiy Storchaka3b230042017-02-01 22:53:03 +0200539 exec 'def sublistOfOne((foo)): return (lambda: foo)'
540 self.assertArgSpecEquals(sublistOfOne, ['foo'])
541
Jean-Paul Calderoneb60ee462010-04-10 19:59:28 +0000542
543 def _classify_test(self, newstyle):
544 """Helper for testing that classify_class_attrs finds a bunch of
545 different kinds of attributes on a given class.
546 """
547 if newstyle:
548 base = object
549 else:
550 class base:
551 pass
552
553 class A(base):
554 def s(): pass
555 s = staticmethod(s)
556
557 def c(cls): pass
558 c = classmethod(c)
559
560 def getp(self): pass
561 p = property(getp)
562
563 def m(self): pass
564
565 def m1(self): pass
566
567 datablob = '1'
568
Antoine Pitroub8572a12011-12-21 10:16:14 +0100569 dd = _BrokenDataDescriptor()
570 md = _BrokenMethodDescriptor()
571
Jean-Paul Calderoneb60ee462010-04-10 19:59:28 +0000572 attrs = attrs_wo_objs(A)
573 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
574 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
575 self.assertIn(('p', 'property', A), attrs, 'missing property')
576 self.assertIn(('m', 'method', A), attrs, 'missing plain method')
577 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
578 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitroub8572a12011-12-21 10:16:14 +0100579 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
580 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Jean-Paul Calderoneb60ee462010-04-10 19:59:28 +0000581
582 class B(A):
583 def m(self): pass
584
585 attrs = attrs_wo_objs(B)
586 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
587 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
588 self.assertIn(('p', 'property', A), attrs, 'missing property')
589 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
590 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
591 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitroub8572a12011-12-21 10:16:14 +0100592 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
593 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Jean-Paul Calderoneb60ee462010-04-10 19:59:28 +0000594
595
596 class C(A):
597 def m(self): pass
598 def c(self): pass
599
600 attrs = attrs_wo_objs(C)
601 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
602 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
603 self.assertIn(('p', 'property', A), attrs, 'missing property')
604 self.assertIn(('m', 'method', C), attrs, 'missing plain method')
605 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
606 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitroub8572a12011-12-21 10:16:14 +0100607 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
608 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Jean-Paul Calderoneb60ee462010-04-10 19:59:28 +0000609
610 class D(B, C):
611 def m1(self): pass
612
613 attrs = attrs_wo_objs(D)
614 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
615 if newstyle:
616 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
617 else:
618 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
619 self.assertIn(('p', 'property', A), attrs, 'missing property')
620 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
621 self.assertIn(('m1', 'method', D), attrs, 'missing plain method')
622 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitroub8572a12011-12-21 10:16:14 +0100623 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
624 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Jean-Paul Calderoneb60ee462010-04-10 19:59:28 +0000625
626
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000627 def test_classify_oldstyle(self):
Jean-Paul Calderoneb60ee462010-04-10 19:59:28 +0000628 """classify_class_attrs finds static methods, class methods,
629 properties, normal methods, and data attributes on an old-style
630 class.
631 """
632 self._classify_test(False)
Tim Peters13b49d32001-09-23 02:00:29 +0000633
634
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000635 def test_classify_newstyle(self):
Jean-Paul Calderoneb60ee462010-04-10 19:59:28 +0000636 """Just like test_classify_oldstyle, but for a new-style class.
637 """
638 self._classify_test(True)
Tim Peters13b49d32001-09-23 02:00:29 +0000639
Antoine Pitroub8572a12011-12-21 10:16:14 +0100640 def test_classify_builtin_types(self):
641 # Simple sanity check that all built-in types can have their
642 # attributes classified.
643 for name in dir(__builtin__):
644 builtin = getattr(__builtin__, name)
645 if isinstance(builtin, type):
646 inspect.classify_class_attrs(builtin)
647
Antoine Pitroue09bc1e2012-01-18 17:39:01 +0100648 def test_getmembers_method(self):
Antoine Pitroub8572a12011-12-21 10:16:14 +0100649 # Old-style classes
Antoine Pitroue09bc1e2012-01-18 17:39:01 +0100650 class B:
651 def f(self):
652 pass
Antoine Pitroub8572a12011-12-21 10:16:14 +0100653
Antoine Pitroue09bc1e2012-01-18 17:39:01 +0100654 self.assertIn(('f', B.f), inspect.getmembers(B))
655 # contrary to spec, ismethod() is also True for unbound methods
656 # (see #1785)
657 self.assertIn(('f', B.f), inspect.getmembers(B, inspect.ismethod))
658 b = B()
659 self.assertIn(('f', b.f), inspect.getmembers(b))
660 self.assertIn(('f', b.f), inspect.getmembers(b, inspect.ismethod))
Antoine Pitroub8572a12011-12-21 10:16:14 +0100661
662 # New-style classes
Antoine Pitroue09bc1e2012-01-18 17:39:01 +0100663 class B(object):
664 def f(self):
Antoine Pitroub8572a12011-12-21 10:16:14 +0100665 pass
Antoine Pitroub8572a12011-12-21 10:16:14 +0100666
Antoine Pitroue09bc1e2012-01-18 17:39:01 +0100667 self.assertIn(('f', B.f), inspect.getmembers(B))
668 self.assertIn(('f', B.f), inspect.getmembers(B, inspect.ismethod))
669 b = B()
670 self.assertIn(('f', b.f), inspect.getmembers(b))
671 self.assertIn(('f', b.f), inspect.getmembers(b, inspect.ismethod))
Tim Peters13b49d32001-09-23 02:00:29 +0000672
Jeremy Hyltonc4bf5ed2003-06-27 18:43:12 +0000673
Benjamin Peterson7e213252010-03-30 17:58:13 +0000674class TestGetcallargsFunctions(unittest.TestCase):
675
676 # tuple parameters are named '.1', '.2', etc.
677 is_tuplename = re.compile(r'^\.\d+$').match
678
679 def assertEqualCallArgs(self, func, call_params_string, locs=None):
680 locs = dict(locs or {}, func=func)
681 r1 = eval('func(%s)' % call_params_string, None, locs)
682 r2 = eval('inspect.getcallargs(func, %s)' % call_params_string, None,
683 locs)
684 self.assertEqual(r1, r2)
685
686 def assertEqualException(self, func, call_param_string, locs=None):
687 locs = dict(locs or {}, func=func)
688 try:
689 eval('func(%s)' % call_param_string, None, locs)
690 except Exception, ex1:
691 pass
692 else:
693 self.fail('Exception not raised')
694 try:
695 eval('inspect.getcallargs(func, %s)' % call_param_string, None,
696 locs)
697 except Exception, ex2:
698 pass
699 else:
700 self.fail('Exception not raised')
701 self.assertIs(type(ex1), type(ex2))
702 self.assertEqual(str(ex1), str(ex2))
703
704 def makeCallable(self, signature):
705 """Create a function that returns its locals(), excluding the
706 autogenerated '.1', '.2', etc. tuple param names (if any)."""
Ezio Melottifcc500e2010-03-31 08:33:50 +0000707 with check_py3k_warnings(
708 ("tuple parameter unpacking has been removed", SyntaxWarning),
709 quiet=True):
710 code = ("lambda %s: dict(i for i in locals().items() "
711 "if not is_tuplename(i[0]))")
712 return eval(code % signature, {'is_tuplename' : self.is_tuplename})
Benjamin Peterson7e213252010-03-30 17:58:13 +0000713
714 def test_plain(self):
715 f = self.makeCallable('a, b=1')
716 self.assertEqualCallArgs(f, '2')
717 self.assertEqualCallArgs(f, '2, 3')
718 self.assertEqualCallArgs(f, 'a=2')
719 self.assertEqualCallArgs(f, 'b=3, a=2')
720 self.assertEqualCallArgs(f, '2, b=3')
721 # expand *iterable / **mapping
722 self.assertEqualCallArgs(f, '*(2,)')
723 self.assertEqualCallArgs(f, '*[2]')
724 self.assertEqualCallArgs(f, '*(2, 3)')
725 self.assertEqualCallArgs(f, '*[2, 3]')
726 self.assertEqualCallArgs(f, '**{"a":2}')
727 self.assertEqualCallArgs(f, 'b=3, **{"a":2}')
728 self.assertEqualCallArgs(f, '2, **{"b":3}')
729 self.assertEqualCallArgs(f, '**{"b":3, "a":2}')
730 # expand UserList / UserDict
731 self.assertEqualCallArgs(f, '*UserList([2])')
732 self.assertEqualCallArgs(f, '*UserList([2, 3])')
733 self.assertEqualCallArgs(f, '**UserDict(a=2)')
734 self.assertEqualCallArgs(f, '2, **UserDict(b=3)')
735 self.assertEqualCallArgs(f, 'b=2, **UserDict(a=3)')
736 # unicode keyword args
737 self.assertEqualCallArgs(f, '**{u"a":2}')
738 self.assertEqualCallArgs(f, 'b=3, **{u"a":2}')
739 self.assertEqualCallArgs(f, '2, **{u"b":3}')
740 self.assertEqualCallArgs(f, '**{u"b":3, u"a":2}')
741
742 def test_varargs(self):
743 f = self.makeCallable('a, b=1, *c')
744 self.assertEqualCallArgs(f, '2')
745 self.assertEqualCallArgs(f, '2, 3')
746 self.assertEqualCallArgs(f, '2, 3, 4')
747 self.assertEqualCallArgs(f, '*(2,3,4)')
748 self.assertEqualCallArgs(f, '2, *[3,4]')
749 self.assertEqualCallArgs(f, '2, 3, *UserList([4])')
750
751 def test_varkw(self):
752 f = self.makeCallable('a, b=1, **c')
753 self.assertEqualCallArgs(f, 'a=2')
754 self.assertEqualCallArgs(f, '2, b=3, c=4')
755 self.assertEqualCallArgs(f, 'b=3, a=2, c=4')
756 self.assertEqualCallArgs(f, 'c=4, **{"a":2, "b":3}')
757 self.assertEqualCallArgs(f, '2, c=4, **{"b":3}')
758 self.assertEqualCallArgs(f, 'b=2, **{"a":3, "c":4}')
759 self.assertEqualCallArgs(f, '**UserDict(a=2, b=3, c=4)')
760 self.assertEqualCallArgs(f, '2, c=4, **UserDict(b=3)')
761 self.assertEqualCallArgs(f, 'b=2, **UserDict(a=3, c=4)')
762 # unicode keyword args
763 self.assertEqualCallArgs(f, 'c=4, **{u"a":2, u"b":3}')
764 self.assertEqualCallArgs(f, '2, c=4, **{u"b":3}')
765 self.assertEqualCallArgs(f, 'b=2, **{u"a":3, u"c":4}')
766
Benjamin Peterson77d46602011-03-28 17:32:31 -0500767 def test_varkw_only(self):
768 # issue11256:
769 f = self.makeCallable('**c')
770 self.assertEqualCallArgs(f, '')
771 self.assertEqualCallArgs(f, 'a=1')
772 self.assertEqualCallArgs(f, 'a=1, b=2')
773 self.assertEqualCallArgs(f, 'c=3, **{"a": 1, "b": 2}')
774 self.assertEqualCallArgs(f, '**UserDict(a=1, b=2)')
775 self.assertEqualCallArgs(f, 'c=3, **UserDict(a=1, b=2)')
776
Benjamin Peterson7e213252010-03-30 17:58:13 +0000777 def test_tupleargs(self):
778 f = self.makeCallable('(b,c), (d,(e,f))=(0,[1,2])')
779 self.assertEqualCallArgs(f, '(2,3)')
780 self.assertEqualCallArgs(f, '[2,3]')
781 self.assertEqualCallArgs(f, 'UserList([2,3])')
782 self.assertEqualCallArgs(f, '(2,3), (4,(5,6))')
783 self.assertEqualCallArgs(f, '(2,3), (4,[5,6])')
784 self.assertEqualCallArgs(f, '(2,3), [4,UserList([5,6])]')
785
786 def test_multiple_features(self):
787 f = self.makeCallable('a, b=2, (c,(d,e))=(3,[4,5]), *f, **g')
788 self.assertEqualCallArgs(f, '2, 3, (4,[5,6]), 7')
789 self.assertEqualCallArgs(f, '2, 3, *[(4,[5,6]), 7], x=8')
790 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
791 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9')
792 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9')
793 self.assertEqualCallArgs(f, 'x=8, *UserList([2, 3, (4,[5,6])]), '
794 '**{"y":9, "z":10}')
795 self.assertEqualCallArgs(f, '2, x=8, *UserList([3, (4,[5,6])]), '
796 '**UserDict(y=9, z=10)')
797
798 def test_errors(self):
799 f0 = self.makeCallable('')
800 f1 = self.makeCallable('a, b')
801 f2 = self.makeCallable('a, b=1')
802 # f0 takes no arguments
803 self.assertEqualException(f0, '1')
804 self.assertEqualException(f0, 'x=1')
805 self.assertEqualException(f0, '1,x=1')
806 # f1 takes exactly 2 arguments
807 self.assertEqualException(f1, '')
808 self.assertEqualException(f1, '1')
809 self.assertEqualException(f1, 'a=2')
810 self.assertEqualException(f1, 'b=3')
811 # f2 takes at least 1 argument
812 self.assertEqualException(f2, '')
813 self.assertEqualException(f2, 'b=3')
814 for f in f1, f2:
815 # f1/f2 takes exactly/at most 2 arguments
816 self.assertEqualException(f, '2, 3, 4')
817 self.assertEqualException(f, '1, 2, 3, a=1')
818 self.assertEqualException(f, '2, 3, 4, c=5')
819 self.assertEqualException(f, '2, 3, 4, a=1, c=5')
820 # f got an unexpected keyword argument
821 self.assertEqualException(f, 'c=2')
822 self.assertEqualException(f, '2, c=3')
823 self.assertEqualException(f, '2, 3, c=4')
824 self.assertEqualException(f, '2, c=4, b=3')
Serhiy Storchakad6bfa942015-05-31 08:01:00 +0300825 if have_unicode:
826 self.assertEqualException(f, '**{u"\u03c0\u03b9": 4}')
Benjamin Peterson7e213252010-03-30 17:58:13 +0000827 # f got multiple values for keyword argument
828 self.assertEqualException(f, '1, a=2')
829 self.assertEqualException(f, '1, **{"a":2}')
830 self.assertEqualException(f, '1, 2, b=3')
831 # XXX: Python inconsistency
832 # - for functions and bound methods: unexpected keyword 'c'
833 # - for unbound methods: multiple values for keyword 'a'
834 #self.assertEqualException(f, '1, c=3, a=2')
835 f = self.makeCallable('(a,b)=(0,1)')
836 self.assertEqualException(f, '1')
837 self.assertEqualException(f, '[1]')
838 self.assertEqualException(f, '(1,2,3)')
Benjamin Peterson77d46602011-03-28 17:32:31 -0500839 # issue11256:
840 f3 = self.makeCallable('**c')
841 self.assertEqualException(f3, '1, 2')
842 self.assertEqualException(f3, '1, 2, a=1, b=2')
Benjamin Peterson7e213252010-03-30 17:58:13 +0000843
Serhiy Storchaka3b230042017-02-01 22:53:03 +0200844
845class TestGetcallargsFunctionsCellVars(TestGetcallargsFunctions):
846
847 def makeCallable(self, signature):
848 """Create a function that returns its locals(), excluding the
849 autogenerated '.1', '.2', etc. tuple param names (if any)."""
850 with check_py3k_warnings(
851 ("tuple parameter unpacking has been removed", SyntaxWarning),
852 quiet=True):
853 code = """lambda %s: (
854 (lambda: a+b+c+d+d+e+f+g+h), # make parameters cell vars
855 dict(i for i in locals().items()
856 if not is_tuplename(i[0]))
857 )[1]"""
858 return eval(code % signature, {'is_tuplename' : self.is_tuplename})
859
860
Benjamin Peterson7e213252010-03-30 17:58:13 +0000861class TestGetcallargsMethods(TestGetcallargsFunctions):
862
863 def setUp(self):
864 class Foo(object):
865 pass
866 self.cls = Foo
867 self.inst = Foo()
868
869 def makeCallable(self, signature):
870 assert 'self' not in signature
871 mk = super(TestGetcallargsMethods, self).makeCallable
872 self.cls.method = mk('self, ' + signature)
873 return self.inst.method
874
875class TestGetcallargsUnboundMethods(TestGetcallargsMethods):
876
877 def makeCallable(self, signature):
878 super(TestGetcallargsUnboundMethods, self).makeCallable(signature)
879 return self.cls.method
880
881 def assertEqualCallArgs(self, func, call_params_string, locs=None):
882 return super(TestGetcallargsUnboundMethods, self).assertEqualCallArgs(
883 *self._getAssertEqualParams(func, call_params_string, locs))
884
885 def assertEqualException(self, func, call_params_string, locs=None):
886 return super(TestGetcallargsUnboundMethods, self).assertEqualException(
887 *self._getAssertEqualParams(func, call_params_string, locs))
888
889 def _getAssertEqualParams(self, func, call_params_string, locs=None):
890 assert 'inst' not in call_params_string
891 locs = dict(locs or {}, inst=self.inst)
892 return (func, 'inst,' + call_params_string, locs)
893
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000894def test_main():
Benjamin Peterson7e213252010-03-30 17:58:13 +0000895 run_unittest(
896 TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBuggyCases,
897 TestInterpreterStack, TestClassesAndFunctions, TestPredicates,
Serhiy Storchaka3b230042017-02-01 22:53:03 +0200898 TestGetcallargsFunctions, TestGetcallargsFunctionsCellVars,
899 TestGetcallargsMethods, TestGetcallargsUnboundMethods)
Martin v. Löwis893ffa42003-10-31 15:35:53 +0000900
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000901if __name__ == "__main__":
902 test_main()