blob: 3d9c3b119e9fc53d1d3152636d49fb73d45ed711 [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
Benjamin Peterson7e213252010-03-30 17:58:13 +00008from UserList import UserList
9from UserDict import UserDict
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000010
Serhiy Storchakad6bfa942015-05-31 08:01:00 +030011from test.test_support import run_unittest, check_py3k_warnings, have_unicode
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000012
Florent Xicluna07627882010-03-21 01:14:24 +000013with check_py3k_warnings(
14 ("tuple parameter unpacking has been removed", SyntaxWarning),
15 quiet=True):
16 from test import inspect_fodder as mod
17 from test import inspect_fodder2 as mod2
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000018
R. David Murray996ba022009-05-13 17:14:11 +000019# C module for test_findsource_binary
Serhiy Storchakad6bfa942015-05-31 08:01:00 +030020try:
21 import unicodedata
22except ImportError:
23 unicodedata = None
R. David Murray996ba022009-05-13 17:14:11 +000024
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000025# Functions tested in this suite:
26# ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode,
Facundo Batista759bfc62008-02-18 03:43:43 +000027# isbuiltin, isroutine, isgenerator, isgeneratorfunction, getmembers,
28# getdoc, getfile, getmodule, getsourcefile, getcomments, getsource,
29# getclasstree, getargspec, getargvalues, formatargspec, formatargvalues,
30# currentframe, stack, trace, isdatadescriptor
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000031
Nick Coghlana2053472008-12-14 10:54:50 +000032# NOTE: There are some additional tests relating to interaction with
33# zipimport in the test_zipimport_support test module.
34
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000035modfile = mod.__file__
Georg Brandlb2afe852006-06-09 20:43:48 +000036if modfile.endswith(('c', 'o')):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000037 modfile = modfile[:-1]
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000038
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000039import __builtin__
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000040
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000041try:
Florent Xicluna07627882010-03-21 01:14:24 +000042 1 // 0
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000043except:
44 tb = sys.exc_traceback
45
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,
Facundo Batista759bfc62008-02-18 03:43:43 +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 Peterson5c8da862009-06-30 22:57:08 +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]):
Facundo Batista759bfc62008-02-18 03:43:43 +000059 if predicate == inspect.isgeneratorfunction and\
60 other == inspect.isfunction:
61 continue
Benjamin Peterson5c8da862009-06-30 22:57:08 +000062 self.assertFalse(other(obj), 'not %s(%s)' % (other.__name__, exp))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000063
Facundo Batista759bfc62008-02-18 03:43:43 +000064def generator_function_example(self):
65 for i in xrange(2):
66 yield i
67
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000068class TestPredicates(IsTestBase):
Christian Heimes728bee82008-03-03 20:30:29 +000069 def test_sixteen(self):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000070 count = len(filter(lambda x:x.startswith('is'), dir(inspect)))
Facundo Batista759bfc62008-02-18 03:43:43 +000071 # This test is here for remember you to update Doc/library/inspect.rst
Georg Brandl26bc1772008-03-03 20:39:00 +000072 # which claims there are 16 such functions
Christian Heimes728bee82008-03-03 20:30:29 +000073 expected = 16
Neal Norwitzdf80af72006-07-28 04:22:34 +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
Facundo Batista759bfc62008-02-18 03:43:43 +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')
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000081 self.istest(inspect.iscode, 'mod.spam.func_code')
82 self.istest(inspect.isframe, 'tb.tb_frame')
83 self.istest(inspect.isfunction, 'mod.spam')
84 self.istest(inspect.ismethod, 'mod.StupidGit.abuse')
85 self.istest(inspect.ismethod, 'git.argue')
86 self.istest(inspect.ismodule, 'mod')
87 self.istest(inspect.istraceback, 'tb')
88 self.istest(inspect.isdatadescriptor, '__builtin__.file.closed')
89 self.istest(inspect.isdatadescriptor, '__builtin__.file.softspace')
Facundo Batista759bfc62008-02-18 03:43:43 +000090 self.istest(inspect.isgenerator, '(x for x in xrange(2))')
91 self.istest(inspect.isgeneratorfunction, 'generator_function_example')
Barry Warsaw00decd72006-07-27 23:43:15 +000092 if hasattr(types, 'GetSetDescriptorType'):
93 self.istest(inspect.isgetsetdescriptor,
94 'type(tb.tb_frame).f_locals')
95 else:
Benjamin Peterson5c8da862009-06-30 22:57:08 +000096 self.assertFalse(inspect.isgetsetdescriptor(type(tb.tb_frame).f_locals))
Barry Warsaw00decd72006-07-27 23:43:15 +000097 if hasattr(types, 'MemberDescriptorType'):
98 self.istest(inspect.ismemberdescriptor, 'datetime.timedelta.days')
99 else:
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000100 self.assertFalse(inspect.ismemberdescriptor(datetime.timedelta.days))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000101
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000102 def test_isroutine(self):
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000103 self.assertTrue(inspect.isroutine(mod.spam))
104 self.assertTrue(inspect.isroutine([].count))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000105
Benjamin Peterson5e5fbb62009-01-17 22:27:54 +0000106 def test_isclass(self):
107 self.istest(inspect.isclass, 'mod.StupidGit')
108 self.assertTrue(inspect.isclass(list))
109
110 class newstyle(object): pass
111 self.assertTrue(inspect.isclass(newstyle))
112
113 class CustomGetattr(object):
114 def __getattr__(self, attr):
115 return None
116 self.assertFalse(inspect.isclass(CustomGetattr()))
117
Amaury Forgeot d'Arcb54447f2009-01-13 23:39:22 +0000118 def test_get_slot_members(self):
119 class C(object):
120 __slots__ = ("a", "b")
121
122 x = C()
123 x.a = 42
124 members = dict(inspect.getmembers(x))
Ezio Melottiaa980582010-01-23 23:04:36 +0000125 self.assertIn('a', members)
126 self.assertNotIn('b', members)
Amaury Forgeot d'Arcb54447f2009-01-13 23:39:22 +0000127
Benjamin Petersonc63457b2009-10-15 03:06:55 +0000128 def test_isabstract(self):
129 from abc import ABCMeta, abstractmethod
130
131 class AbstractClassExample(object):
132 __metaclass__ = ABCMeta
133
134 @abstractmethod
135 def foo(self):
136 pass
137
138 class ClassExample(AbstractClassExample):
139 def foo(self):
140 pass
141
142 a = ClassExample()
143
144 # Test general behaviour.
145 self.assertTrue(inspect.isabstract(AbstractClassExample))
146 self.assertFalse(inspect.isabstract(ClassExample))
147 self.assertFalse(inspect.isabstract(a))
148 self.assertFalse(inspect.isabstract(int))
149 self.assertFalse(inspect.isabstract(5))
150
Amaury Forgeot d'Arcb54447f2009-01-13 23:39:22 +0000151
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000152class TestInterpreterStack(IsTestBase):
153 def __init__(self, *args, **kwargs):
154 unittest.TestCase.__init__(self, *args, **kwargs)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000155
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000156 git.abuse(7, 8, 9)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000157
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000158 def test_abuse_done(self):
159 self.istest(inspect.istraceback, 'git.ex[2]')
160 self.istest(inspect.isframe, 'mod.fr')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000161
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000162 def test_stack(self):
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000163 self.assertTrue(len(mod.st) >= 5)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000164 self.assertEqual(mod.st[0][1:],
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000165 (modfile, 16, 'eggs', [' st = inspect.stack()\n'], 0))
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000166 self.assertEqual(mod.st[1][1:],
167 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
168 self.assertEqual(mod.st[2][1:],
169 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
170 self.assertEqual(mod.st[3][1:],
171 (modfile, 39, 'abuse', [' self.argue(a, b, c)\n'], 0))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000172
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000173 def test_trace(self):
174 self.assertEqual(len(git.tr), 3)
175 self.assertEqual(git.tr[0][1:], (modfile, 43, 'argue',
176 [' spam(a, b, c)\n'], 0))
177 self.assertEqual(git.tr[1][1:], (modfile, 9, 'spam',
178 [' eggs(b + d, c + f)\n'], 0))
179 self.assertEqual(git.tr[2][1:], (modfile, 18, 'eggs',
Mark Dickinsonc68e9f02010-02-03 16:50:14 +0000180 [' q = y // 0\n'], 0))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000181
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000182 def test_frame(self):
183 args, varargs, varkw, locals = inspect.getargvalues(mod.fr)
184 self.assertEqual(args, ['x', 'y'])
185 self.assertEqual(varargs, None)
186 self.assertEqual(varkw, None)
187 self.assertEqual(locals, {'x': 11, 'p': 11, 'y': 14})
188 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
189 '(x=11, y=14)')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000190
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000191 def test_previous_frame(self):
192 args, varargs, varkw, locals = inspect.getargvalues(mod.fr.f_back)
193 self.assertEqual(args, ['a', 'b', 'c', 'd', ['e', ['f']]])
194 self.assertEqual(varargs, 'g')
195 self.assertEqual(varkw, 'h')
196 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
197 '(a=7, b=8, c=9, d=3, (e=4, (f=5,)), *g=(), **h={})')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000198
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000199class GetSourceBase(unittest.TestCase):
200 # Subclasses must override.
201 fodderFile = None
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000202
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000203 def __init__(self, *args, **kwargs):
204 unittest.TestCase.__init__(self, *args, **kwargs)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000205
Philip Jenvey6a111022009-05-28 05:58:44 +0000206 with open(inspect.getsourcefile(self.fodderFile)) as fp:
207 self.source = fp.read()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000208
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000209 def sourcerange(self, top, bottom):
210 lines = self.source.split("\n")
211 return "\n".join(lines[top-1:bottom]) + "\n"
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000212
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000213 def assertSourceEqual(self, obj, top, bottom):
214 self.assertEqual(inspect.getsource(obj),
215 self.sourcerange(top, bottom))
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000216
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000217class TestRetrievingSourceCode(GetSourceBase):
218 fodderFile = mod
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000219
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000220 def test_getclasses(self):
221 classes = inspect.getmembers(mod, inspect.isclass)
222 self.assertEqual(classes,
223 [('FesteringGob', mod.FesteringGob),
224 ('MalodorousPervert', mod.MalodorousPervert),
225 ('ParrotDroppings', mod.ParrotDroppings),
Serhiy Storchaka6db9e882013-09-05 17:28:10 +0300226 ('StupidGit', mod.StupidGit),
227 ('Tit', mod.MalodorousPervert),
228 ])
229 tree = inspect.getclasstree([cls[1] for cls in classes])
230 self.assertEqual(tree,
231 [(mod.ParrotDroppings, ()),
232 [(mod.FesteringGob, (mod.MalodorousPervert,
233 mod.ParrotDroppings))
234 ],
235 (mod.StupidGit, ()),
236 [(mod.MalodorousPervert, (mod.StupidGit,)),
237 [(mod.FesteringGob, (mod.MalodorousPervert,
238 mod.ParrotDroppings))
239 ]
240 ]
241 ])
242 tree = inspect.getclasstree([cls[1] for cls in classes], True)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000243 self.assertEqual(tree,
244 [(mod.ParrotDroppings, ()),
245 (mod.StupidGit, ()),
246 [(mod.MalodorousPervert, (mod.StupidGit,)),
247 [(mod.FesteringGob, (mod.MalodorousPervert,
248 mod.ParrotDroppings))
249 ]
250 ]
251 ])
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000252
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000253 def test_getfunctions(self):
254 functions = inspect.getmembers(mod, inspect.isfunction)
255 self.assertEqual(functions, [('eggs', mod.eggs),
256 ('spam', mod.spam)])
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000257
R. David Murrayf28fd242010-02-23 00:24:49 +0000258 @unittest.skipIf(sys.flags.optimize >= 2,
259 "Docstrings are omitted with -O2 and above")
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000260 def test_getdoc(self):
261 self.assertEqual(inspect.getdoc(mod), 'A module docstring.')
262 self.assertEqual(inspect.getdoc(mod.StupidGit),
263 'A longer,\n\nindented\n\ndocstring.')
264 self.assertEqual(inspect.getdoc(git.abuse),
265 'Another\n\ndocstring\n\ncontaining\n\ntabs')
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000266
Georg Brandl7be19aa2008-06-07 15:59:10 +0000267 def test_cleandoc(self):
268 self.assertEqual(inspect.cleandoc('An\n indented\n docstring.'),
269 'An\nindented\ndocstring.')
270
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000271 def test_getcomments(self):
272 self.assertEqual(inspect.getcomments(mod), '# line 1\n')
273 self.assertEqual(inspect.getcomments(mod.StupidGit), '# line 20\n')
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000274
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000275 def test_getmodule(self):
Nick Coghlanc495c662006-09-07 10:50:34 +0000276 # Check actual module
277 self.assertEqual(inspect.getmodule(mod), mod)
278 # Check class (uses __module__ attribute)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000279 self.assertEqual(inspect.getmodule(mod.StupidGit), mod)
Nick Coghlanc495c662006-09-07 10:50:34 +0000280 # Check a method (no __module__ attribute, falls back to filename)
281 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
282 # Do it again (check the caching isn't broken)
283 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
284 # Check a builtin
285 self.assertEqual(inspect.getmodule(str), sys.modules["__builtin__"])
286 # Check filename override
287 self.assertEqual(inspect.getmodule(None, modfile), mod)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000288
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000289 def test_getsource(self):
290 self.assertSourceEqual(git.abuse, 29, 39)
291 self.assertSourceEqual(mod.StupidGit, 21, 46)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000292
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000293 def test_getsourcefile(self):
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000294 self.assertEqual(inspect.getsourcefile(mod.spam), modfile)
295 self.assertEqual(inspect.getsourcefile(git.abuse), modfile)
R. David Murraydf1cf302010-06-17 01:36:52 +0000296 fn = "_non_existing_filename_used_for_sourcefile_test.py"
297 co = compile("None", fn, "exec")
298 self.assertEqual(inspect.getsourcefile(co), None)
299 linecache.cache[co.co_filename] = (1, None, "None", co.co_filename)
300 self.assertEqual(inspect.getsourcefile(co), fn)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000301
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000302 def test_getfile(self):
303 self.assertEqual(inspect.getfile(mod.StupidGit), mod.__file__)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000304
Phillip J. Eby5d86bdb2006-07-10 19:03:29 +0000305 def test_getmodule_recursion(self):
Christian Heimesc756d002007-11-27 21:34:01 +0000306 from types import ModuleType
Phillip J. Eby5d86bdb2006-07-10 19:03:29 +0000307 name = '__inspect_dummy'
Christian Heimesc756d002007-11-27 21:34:01 +0000308 m = sys.modules[name] = ModuleType(name)
Tim Peters722b8832006-07-10 21:11:49 +0000309 m.__file__ = "<string>" # hopefully not a real filename...
Phillip J. Eby5d86bdb2006-07-10 19:03:29 +0000310 m.__loader__ = "dummy" # pretend the filename is understood by a loader
311 exec "def x(): pass" in m.__dict__
312 self.assertEqual(inspect.getsourcefile(m.x.func_code), '<string>')
313 del sys.modules[name]
Phillip J. Eby1a2959c2006-07-20 15:54:16 +0000314 inspect.getmodule(compile('a=10','','single'))
Phillip J. Eby5d86bdb2006-07-10 19:03:29 +0000315
Benjamin Peterson0eb4ac42011-06-11 15:53:11 -0500316 def test_proceed_with_fake_filename(self):
317 '''doctest monkeypatches linecache to enable inspection'''
318 fn, source = '<test>', 'def x(): pass\n'
319 getlines = linecache.getlines
320 def monkey(filename, module_globals=None):
321 if filename == fn:
322 return source.splitlines(True)
323 else:
324 return getlines(filename, module_globals)
325 linecache.getlines = monkey
326 try:
327 ns = {}
328 exec compile(source, fn, 'single') in ns
329 inspect.getsource(ns["x"])
330 finally:
331 linecache.getlines = getlines
332
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000333class TestDecorators(GetSourceBase):
334 fodderFile = mod2
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000335
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000336 def test_wrapped_decorator(self):
337 self.assertSourceEqual(mod2.wrapped, 14, 17)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000338
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000339 def test_replacing_decorator(self):
340 self.assertSourceEqual(mod2.gone, 9, 10)
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000341
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000342class TestOneliners(GetSourceBase):
343 fodderFile = mod2
344 def test_oneline_lambda(self):
345 # Test inspect.getsource with a one-line lambda function.
346 self.assertSourceEqual(mod2.oll, 25, 25)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000347
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000348 def test_threeline_lambda(self):
349 # Test inspect.getsource with a three-line lambda function,
350 # where the second and third lines are _not_ indented.
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000351 self.assertSourceEqual(mod2.tll, 28, 30)
352
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000353 def test_twoline_indented_lambda(self):
354 # Test inspect.getsource with a two-line lambda function,
355 # where the second line _is_ indented.
356 self.assertSourceEqual(mod2.tlli, 33, 34)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000357
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000358 def test_onelinefunc(self):
359 # Test inspect.getsource with a regular one-line function.
360 self.assertSourceEqual(mod2.onelinefunc, 37, 37)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000361
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000362 def test_manyargs(self):
363 # Test inspect.getsource with a regular function where
364 # the arguments are on two lines and _not_ indented and
365 # the body on the second line with the last arguments.
366 self.assertSourceEqual(mod2.manyargs, 40, 41)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000367
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000368 def test_twolinefunc(self):
369 # Test inspect.getsource with a regular function where
370 # the body is on two lines, following the argument list and
371 # continued on the next line by a \\.
372 self.assertSourceEqual(mod2.twolinefunc, 44, 45)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000373
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000374 def test_lambda_in_list(self):
375 # Test inspect.getsource with a one-line lambda function
376 # defined in a list, indented.
377 self.assertSourceEqual(mod2.a[1], 49, 49)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000378
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000379 def test_anonymous(self):
380 # Test inspect.getsource with a lambda function defined
381 # as argument to another function.
382 self.assertSourceEqual(mod2.anonymous, 55, 55)
383
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000384class TestBuggyCases(GetSourceBase):
385 fodderFile = mod2
386
387 def test_with_comment(self):
388 self.assertSourceEqual(mod2.with_comment, 58, 59)
389
390 def test_multiline_sig(self):
391 self.assertSourceEqual(mod2.multiline_sig[0], 63, 64)
392
Armin Rigodd5c0232005-09-25 11:45:45 +0000393 def test_nested_class(self):
394 self.assertSourceEqual(mod2.func69().func71, 71, 72)
395
396 def test_one_liner_followed_by_non_name(self):
397 self.assertSourceEqual(mod2.func77, 77, 77)
398
399 def test_one_liner_dedent_non_name(self):
400 self.assertSourceEqual(mod2.cls82.func83, 83, 83)
401
402 def test_with_comment_instead_of_docstring(self):
403 self.assertSourceEqual(mod2.func88, 88, 90)
404
Georg Brandl2463f8f2006-08-14 21:34:08 +0000405 def test_method_in_dynamic_class(self):
406 self.assertSourceEqual(mod2.method_in_dynamic_class, 95, 97)
407
R. David Murray87855542009-05-14 16:12:57 +0000408 @unittest.skipIf(
409 not hasattr(unicodedata, '__file__') or
410 unicodedata.__file__[-4:] in (".pyc", ".pyo"),
411 "unicodedata is not an external binary module")
R. David Murray996ba022009-05-13 17:14:11 +0000412 def test_findsource_binary(self):
R. David Murray87855542009-05-14 16:12:57 +0000413 self.assertRaises(IOError, inspect.getsource, unicodedata)
414 self.assertRaises(IOError, inspect.findsource, unicodedata)
R. David Murray996ba022009-05-13 17:14:11 +0000415
R. David Murraydf1cf302010-06-17 01:36:52 +0000416 def test_findsource_code_in_linecache(self):
417 lines = ["x=1"]
418 co = compile(lines[0], "_dynamically_created_file", "exec")
419 self.assertRaises(IOError, inspect.findsource, co)
420 self.assertRaises(IOError, inspect.getsource, co)
421 linecache.cache[co.co_filename] = (1, None, lines, co.co_filename)
Ezio Melotti2623a372010-11-21 13:34:58 +0000422 self.assertEqual(inspect.findsource(co), (lines,0))
423 self.assertEqual(inspect.getsource(co), lines[0])
R. David Murraydf1cf302010-06-17 01:36:52 +0000424
Ezio Melottie66e7de2013-03-30 05:10:28 +0200425 def test_findsource_without_filename(self):
426 for fname in ['', '<string>']:
427 co = compile('x=1', fname, "exec")
428 self.assertRaises(IOError, inspect.findsource, co)
429 self.assertRaises(IOError, inspect.getsource, co)
430
Antoine Pitroub8572a12011-12-21 10:16:14 +0100431
432class _BrokenDataDescriptor(object):
433 """
434 A broken data descriptor. See bug #1785.
435 """
436 def __get__(*args):
437 raise AssertionError("should not __get__ data descriptors")
438
439 def __set__(*args):
440 raise RuntimeError
441
442 def __getattr__(*args):
443 raise AssertionError("should not __getattr__ data descriptors")
444
445
446class _BrokenMethodDescriptor(object):
447 """
448 A broken method descriptor. See bug #1785.
449 """
450 def __get__(*args):
451 raise AssertionError("should not __get__ method descriptors")
452
453 def __getattr__(*args):
454 raise AssertionError("should not __getattr__ method descriptors")
455
456
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000457# Helper for testing classify_class_attrs.
Tim Peters13b49d32001-09-23 02:00:29 +0000458def attrs_wo_objs(cls):
459 return [t[:3] for t in inspect.classify_class_attrs(cls)]
460
Antoine Pitroub8572a12011-12-21 10:16:14 +0100461
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000462class TestClassesAndFunctions(unittest.TestCase):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000463 def test_classic_mro(self):
464 # Test classic-class method resolution order.
465 class A: pass
466 class B(A): pass
467 class C(A): pass
468 class D(B, C): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000469
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000470 expected = (D, B, A, C)
471 got = inspect.getmro(D)
472 self.assertEqual(expected, got)
Tim Peters13b49d32001-09-23 02:00:29 +0000473
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000474 def test_newstyle_mro(self):
475 # The same w/ new-class MRO.
476 class A(object): 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, C, A, object)
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 assertArgSpecEquals(self, routine, args_e, varargs_e = None,
486 varkw_e = None, defaults_e = None,
487 formatted = None):
488 args, varargs, varkw, defaults = inspect.getargspec(routine)
489 self.assertEqual(args, args_e)
490 self.assertEqual(varargs, varargs_e)
491 self.assertEqual(varkw, varkw_e)
492 self.assertEqual(defaults, defaults_e)
493 if formatted is not None:
494 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults),
495 formatted)
Tim Peters13b49d32001-09-23 02:00:29 +0000496
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000497 def test_getargspec(self):
498 self.assertArgSpecEquals(mod.eggs, ['x', 'y'], formatted = '(x, y)')
Tim Peters13b49d32001-09-23 02:00:29 +0000499
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000500 self.assertArgSpecEquals(mod.spam,
501 ['a', 'b', 'c', 'd', ['e', ['f']]],
502 'g', 'h', (3, (4, (5,))),
503 '(a, b, c, d=3, (e, (f,))=(4, (5,)), *g, **h)')
Tim Peters13b49d32001-09-23 02:00:29 +0000504
Serhiy Storchaka3b230042017-02-01 22:53:03 +0200505 def spam_deref(a, b, c, d=3, (e, (f,))=(4, (5,)), *g, **h):
506 def eggs():
507 return a + b + c + d + e + f + g + h
508 return eggs
509 self.assertArgSpecEquals(spam_deref,
510 ['a', 'b', 'c', 'd', ['e', ['f']]],
511 'g', 'h', (3, (4, (5,))),
512 '(a, b, c, d=3, (e, (f,))=(4, (5,)), *g, **h)')
513
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000514 def test_getargspec_method(self):
515 class A(object):
516 def m(self):
517 pass
518 self.assertArgSpecEquals(A.m, ['self'])
Tim Peters13b49d32001-09-23 02:00:29 +0000519
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000520 def test_getargspec_sublistofone(self):
Florent Xicluna07627882010-03-21 01:14:24 +0000521 with check_py3k_warnings(
522 ("tuple parameter unpacking has been removed", SyntaxWarning),
523 ("parenthesized argument names are invalid", SyntaxWarning)):
524 exec 'def sublistOfOne((foo,)): return 1'
525 self.assertArgSpecEquals(sublistOfOne, [['foo']])
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000526
Serhiy Storchaka3b230042017-02-01 22:53:03 +0200527 exec 'def sublistOfOne((foo,)): return (lambda: foo)'
528 self.assertArgSpecEquals(sublistOfOne, [['foo']])
529
Florent Xicluna07627882010-03-21 01:14:24 +0000530 exec 'def fakeSublistOfOne((foo)): return 1'
531 self.assertArgSpecEquals(fakeSublistOfOne, ['foo'])
Neal Norwitz33b730e2006-03-27 08:58:23 +0000532
Serhiy Storchaka3b230042017-02-01 22:53:03 +0200533 exec 'def sublistOfOne((foo)): return (lambda: foo)'
534 self.assertArgSpecEquals(sublistOfOne, ['foo'])
535
Jean-Paul Calderoneb60ee462010-04-10 19:59:28 +0000536
537 def _classify_test(self, newstyle):
538 """Helper for testing that classify_class_attrs finds a bunch of
539 different kinds of attributes on a given class.
540 """
541 if newstyle:
542 base = object
543 else:
544 class base:
545 pass
546
547 class A(base):
548 def s(): pass
549 s = staticmethod(s)
550
551 def c(cls): pass
552 c = classmethod(c)
553
554 def getp(self): pass
555 p = property(getp)
556
557 def m(self): pass
558
559 def m1(self): pass
560
561 datablob = '1'
562
Antoine Pitroub8572a12011-12-21 10:16:14 +0100563 dd = _BrokenDataDescriptor()
564 md = _BrokenMethodDescriptor()
565
Jean-Paul Calderoneb60ee462010-04-10 19:59:28 +0000566 attrs = attrs_wo_objs(A)
567 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
568 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
569 self.assertIn(('p', 'property', A), attrs, 'missing property')
570 self.assertIn(('m', 'method', A), attrs, 'missing plain method')
571 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
572 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitroub8572a12011-12-21 10:16:14 +0100573 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
574 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Jean-Paul Calderoneb60ee462010-04-10 19:59:28 +0000575
576 class B(A):
577 def m(self): pass
578
579 attrs = attrs_wo_objs(B)
580 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
581 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
582 self.assertIn(('p', 'property', A), attrs, 'missing property')
583 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
584 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
585 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitroub8572a12011-12-21 10:16:14 +0100586 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
587 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Jean-Paul Calderoneb60ee462010-04-10 19:59:28 +0000588
589
590 class C(A):
591 def m(self): pass
592 def c(self): pass
593
594 attrs = attrs_wo_objs(C)
595 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
596 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
597 self.assertIn(('p', 'property', A), attrs, 'missing property')
598 self.assertIn(('m', 'method', C), attrs, 'missing plain method')
599 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
600 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitroub8572a12011-12-21 10:16:14 +0100601 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
602 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Jean-Paul Calderoneb60ee462010-04-10 19:59:28 +0000603
604 class D(B, C):
605 def m1(self): pass
606
607 attrs = attrs_wo_objs(D)
608 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
609 if newstyle:
610 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
611 else:
612 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
613 self.assertIn(('p', 'property', A), attrs, 'missing property')
614 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
615 self.assertIn(('m1', 'method', D), 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
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000621 def test_classify_oldstyle(self):
Jean-Paul Calderoneb60ee462010-04-10 19:59:28 +0000622 """classify_class_attrs finds static methods, class methods,
623 properties, normal methods, and data attributes on an old-style
624 class.
625 """
626 self._classify_test(False)
Tim Peters13b49d32001-09-23 02:00:29 +0000627
628
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000629 def test_classify_newstyle(self):
Jean-Paul Calderoneb60ee462010-04-10 19:59:28 +0000630 """Just like test_classify_oldstyle, but for a new-style class.
631 """
632 self._classify_test(True)
Tim Peters13b49d32001-09-23 02:00:29 +0000633
Antoine Pitroub8572a12011-12-21 10:16:14 +0100634 def test_classify_builtin_types(self):
635 # Simple sanity check that all built-in types can have their
636 # attributes classified.
637 for name in dir(__builtin__):
638 builtin = getattr(__builtin__, name)
639 if isinstance(builtin, type):
640 inspect.classify_class_attrs(builtin)
641
Antoine Pitroue09bc1e2012-01-18 17:39:01 +0100642 def test_getmembers_method(self):
Antoine Pitroub8572a12011-12-21 10:16:14 +0100643 # Old-style classes
Antoine Pitroue09bc1e2012-01-18 17:39:01 +0100644 class B:
645 def f(self):
646 pass
Antoine Pitroub8572a12011-12-21 10:16:14 +0100647
Antoine Pitroue09bc1e2012-01-18 17:39:01 +0100648 self.assertIn(('f', B.f), inspect.getmembers(B))
649 # contrary to spec, ismethod() is also True for unbound methods
650 # (see #1785)
651 self.assertIn(('f', B.f), inspect.getmembers(B, inspect.ismethod))
652 b = B()
653 self.assertIn(('f', b.f), inspect.getmembers(b))
654 self.assertIn(('f', b.f), inspect.getmembers(b, inspect.ismethod))
Antoine Pitroub8572a12011-12-21 10:16:14 +0100655
656 # New-style classes
Antoine Pitroue09bc1e2012-01-18 17:39:01 +0100657 class B(object):
658 def f(self):
Antoine Pitroub8572a12011-12-21 10:16:14 +0100659 pass
Antoine Pitroub8572a12011-12-21 10:16:14 +0100660
Antoine Pitroue09bc1e2012-01-18 17:39:01 +0100661 self.assertIn(('f', B.f), inspect.getmembers(B))
662 self.assertIn(('f', B.f), inspect.getmembers(B, inspect.ismethod))
663 b = B()
664 self.assertIn(('f', b.f), inspect.getmembers(b))
665 self.assertIn(('f', b.f), inspect.getmembers(b, inspect.ismethod))
Tim Peters13b49d32001-09-23 02:00:29 +0000666
Jeremy Hyltonc4bf5ed2003-06-27 18:43:12 +0000667
Benjamin Peterson7e213252010-03-30 17:58:13 +0000668class TestGetcallargsFunctions(unittest.TestCase):
669
670 # tuple parameters are named '.1', '.2', etc.
671 is_tuplename = re.compile(r'^\.\d+$').match
672
673 def assertEqualCallArgs(self, func, call_params_string, locs=None):
674 locs = dict(locs or {}, func=func)
675 r1 = eval('func(%s)' % call_params_string, None, locs)
676 r2 = eval('inspect.getcallargs(func, %s)' % call_params_string, None,
677 locs)
678 self.assertEqual(r1, r2)
679
680 def assertEqualException(self, func, call_param_string, locs=None):
681 locs = dict(locs or {}, func=func)
682 try:
683 eval('func(%s)' % call_param_string, None, locs)
684 except Exception, ex1:
685 pass
686 else:
687 self.fail('Exception not raised')
688 try:
689 eval('inspect.getcallargs(func, %s)' % call_param_string, None,
690 locs)
691 except Exception, ex2:
692 pass
693 else:
694 self.fail('Exception not raised')
695 self.assertIs(type(ex1), type(ex2))
696 self.assertEqual(str(ex1), str(ex2))
697
698 def makeCallable(self, signature):
699 """Create a function that returns its locals(), excluding the
700 autogenerated '.1', '.2', etc. tuple param names (if any)."""
Ezio Melottifcc500e2010-03-31 08:33:50 +0000701 with check_py3k_warnings(
702 ("tuple parameter unpacking has been removed", SyntaxWarning),
703 quiet=True):
704 code = ("lambda %s: dict(i for i in locals().items() "
705 "if not is_tuplename(i[0]))")
706 return eval(code % signature, {'is_tuplename' : self.is_tuplename})
Benjamin Peterson7e213252010-03-30 17:58:13 +0000707
708 def test_plain(self):
709 f = self.makeCallable('a, b=1')
710 self.assertEqualCallArgs(f, '2')
711 self.assertEqualCallArgs(f, '2, 3')
712 self.assertEqualCallArgs(f, 'a=2')
713 self.assertEqualCallArgs(f, 'b=3, a=2')
714 self.assertEqualCallArgs(f, '2, b=3')
715 # expand *iterable / **mapping
716 self.assertEqualCallArgs(f, '*(2,)')
717 self.assertEqualCallArgs(f, '*[2]')
718 self.assertEqualCallArgs(f, '*(2, 3)')
719 self.assertEqualCallArgs(f, '*[2, 3]')
720 self.assertEqualCallArgs(f, '**{"a":2}')
721 self.assertEqualCallArgs(f, 'b=3, **{"a":2}')
722 self.assertEqualCallArgs(f, '2, **{"b":3}')
723 self.assertEqualCallArgs(f, '**{"b":3, "a":2}')
724 # expand UserList / UserDict
725 self.assertEqualCallArgs(f, '*UserList([2])')
726 self.assertEqualCallArgs(f, '*UserList([2, 3])')
727 self.assertEqualCallArgs(f, '**UserDict(a=2)')
728 self.assertEqualCallArgs(f, '2, **UserDict(b=3)')
729 self.assertEqualCallArgs(f, 'b=2, **UserDict(a=3)')
730 # unicode keyword args
731 self.assertEqualCallArgs(f, '**{u"a":2}')
732 self.assertEqualCallArgs(f, 'b=3, **{u"a":2}')
733 self.assertEqualCallArgs(f, '2, **{u"b":3}')
734 self.assertEqualCallArgs(f, '**{u"b":3, u"a":2}')
735
736 def test_varargs(self):
737 f = self.makeCallable('a, b=1, *c')
738 self.assertEqualCallArgs(f, '2')
739 self.assertEqualCallArgs(f, '2, 3')
740 self.assertEqualCallArgs(f, '2, 3, 4')
741 self.assertEqualCallArgs(f, '*(2,3,4)')
742 self.assertEqualCallArgs(f, '2, *[3,4]')
743 self.assertEqualCallArgs(f, '2, 3, *UserList([4])')
744
745 def test_varkw(self):
746 f = self.makeCallable('a, b=1, **c')
747 self.assertEqualCallArgs(f, 'a=2')
748 self.assertEqualCallArgs(f, '2, b=3, c=4')
749 self.assertEqualCallArgs(f, 'b=3, a=2, c=4')
750 self.assertEqualCallArgs(f, 'c=4, **{"a":2, "b":3}')
751 self.assertEqualCallArgs(f, '2, c=4, **{"b":3}')
752 self.assertEqualCallArgs(f, 'b=2, **{"a":3, "c":4}')
753 self.assertEqualCallArgs(f, '**UserDict(a=2, b=3, c=4)')
754 self.assertEqualCallArgs(f, '2, c=4, **UserDict(b=3)')
755 self.assertEqualCallArgs(f, 'b=2, **UserDict(a=3, c=4)')
756 # unicode keyword args
757 self.assertEqualCallArgs(f, 'c=4, **{u"a":2, u"b":3}')
758 self.assertEqualCallArgs(f, '2, c=4, **{u"b":3}')
759 self.assertEqualCallArgs(f, 'b=2, **{u"a":3, u"c":4}')
760
Benjamin Peterson77d46602011-03-28 17:32:31 -0500761 def test_varkw_only(self):
762 # issue11256:
763 f = self.makeCallable('**c')
764 self.assertEqualCallArgs(f, '')
765 self.assertEqualCallArgs(f, 'a=1')
766 self.assertEqualCallArgs(f, 'a=1, b=2')
767 self.assertEqualCallArgs(f, 'c=3, **{"a": 1, "b": 2}')
768 self.assertEqualCallArgs(f, '**UserDict(a=1, b=2)')
769 self.assertEqualCallArgs(f, 'c=3, **UserDict(a=1, b=2)')
770
Benjamin Peterson7e213252010-03-30 17:58:13 +0000771 def test_tupleargs(self):
772 f = self.makeCallable('(b,c), (d,(e,f))=(0,[1,2])')
773 self.assertEqualCallArgs(f, '(2,3)')
774 self.assertEqualCallArgs(f, '[2,3]')
775 self.assertEqualCallArgs(f, 'UserList([2,3])')
776 self.assertEqualCallArgs(f, '(2,3), (4,(5,6))')
777 self.assertEqualCallArgs(f, '(2,3), (4,[5,6])')
778 self.assertEqualCallArgs(f, '(2,3), [4,UserList([5,6])]')
779
780 def test_multiple_features(self):
781 f = self.makeCallable('a, b=2, (c,(d,e))=(3,[4,5]), *f, **g')
782 self.assertEqualCallArgs(f, '2, 3, (4,[5,6]), 7')
783 self.assertEqualCallArgs(f, '2, 3, *[(4,[5,6]), 7], x=8')
784 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
785 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9')
786 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9')
787 self.assertEqualCallArgs(f, 'x=8, *UserList([2, 3, (4,[5,6])]), '
788 '**{"y":9, "z":10}')
789 self.assertEqualCallArgs(f, '2, x=8, *UserList([3, (4,[5,6])]), '
790 '**UserDict(y=9, z=10)')
791
792 def test_errors(self):
793 f0 = self.makeCallable('')
794 f1 = self.makeCallable('a, b')
795 f2 = self.makeCallable('a, b=1')
796 # f0 takes no arguments
797 self.assertEqualException(f0, '1')
798 self.assertEqualException(f0, 'x=1')
799 self.assertEqualException(f0, '1,x=1')
800 # f1 takes exactly 2 arguments
801 self.assertEqualException(f1, '')
802 self.assertEqualException(f1, '1')
803 self.assertEqualException(f1, 'a=2')
804 self.assertEqualException(f1, 'b=3')
805 # f2 takes at least 1 argument
806 self.assertEqualException(f2, '')
807 self.assertEqualException(f2, 'b=3')
808 for f in f1, f2:
809 # f1/f2 takes exactly/at most 2 arguments
810 self.assertEqualException(f, '2, 3, 4')
811 self.assertEqualException(f, '1, 2, 3, a=1')
812 self.assertEqualException(f, '2, 3, 4, c=5')
813 self.assertEqualException(f, '2, 3, 4, a=1, c=5')
814 # f got an unexpected keyword argument
815 self.assertEqualException(f, 'c=2')
816 self.assertEqualException(f, '2, c=3')
817 self.assertEqualException(f, '2, 3, c=4')
818 self.assertEqualException(f, '2, c=4, b=3')
Serhiy Storchakad6bfa942015-05-31 08:01:00 +0300819 if have_unicode:
820 self.assertEqualException(f, '**{u"\u03c0\u03b9": 4}')
Benjamin Peterson7e213252010-03-30 17:58:13 +0000821 # f got multiple values for keyword argument
822 self.assertEqualException(f, '1, a=2')
823 self.assertEqualException(f, '1, **{"a":2}')
824 self.assertEqualException(f, '1, 2, b=3')
825 # XXX: Python inconsistency
826 # - for functions and bound methods: unexpected keyword 'c'
827 # - for unbound methods: multiple values for keyword 'a'
828 #self.assertEqualException(f, '1, c=3, a=2')
829 f = self.makeCallable('(a,b)=(0,1)')
830 self.assertEqualException(f, '1')
831 self.assertEqualException(f, '[1]')
832 self.assertEqualException(f, '(1,2,3)')
Benjamin Peterson77d46602011-03-28 17:32:31 -0500833 # issue11256:
834 f3 = self.makeCallable('**c')
835 self.assertEqualException(f3, '1, 2')
836 self.assertEqualException(f3, '1, 2, a=1, b=2')
Benjamin Peterson7e213252010-03-30 17:58:13 +0000837
Serhiy Storchaka3b230042017-02-01 22:53:03 +0200838
839class TestGetcallargsFunctionsCellVars(TestGetcallargsFunctions):
840
841 def makeCallable(self, signature):
842 """Create a function that returns its locals(), excluding the
843 autogenerated '.1', '.2', etc. tuple param names (if any)."""
844 with check_py3k_warnings(
845 ("tuple parameter unpacking has been removed", SyntaxWarning),
846 quiet=True):
847 code = """lambda %s: (
848 (lambda: a+b+c+d+d+e+f+g+h), # make parameters cell vars
849 dict(i for i in locals().items()
850 if not is_tuplename(i[0]))
851 )[1]"""
852 return eval(code % signature, {'is_tuplename' : self.is_tuplename})
853
854
Benjamin Peterson7e213252010-03-30 17:58:13 +0000855class TestGetcallargsMethods(TestGetcallargsFunctions):
856
857 def setUp(self):
858 class Foo(object):
859 pass
860 self.cls = Foo
861 self.inst = Foo()
862
863 def makeCallable(self, signature):
864 assert 'self' not in signature
865 mk = super(TestGetcallargsMethods, self).makeCallable
866 self.cls.method = mk('self, ' + signature)
867 return self.inst.method
868
869class TestGetcallargsUnboundMethods(TestGetcallargsMethods):
870
871 def makeCallable(self, signature):
872 super(TestGetcallargsUnboundMethods, self).makeCallable(signature)
873 return self.cls.method
874
875 def assertEqualCallArgs(self, func, call_params_string, locs=None):
876 return super(TestGetcallargsUnboundMethods, self).assertEqualCallArgs(
877 *self._getAssertEqualParams(func, call_params_string, locs))
878
879 def assertEqualException(self, func, call_params_string, locs=None):
880 return super(TestGetcallargsUnboundMethods, self).assertEqualException(
881 *self._getAssertEqualParams(func, call_params_string, locs))
882
883 def _getAssertEqualParams(self, func, call_params_string, locs=None):
884 assert 'inst' not in call_params_string
885 locs = dict(locs or {}, inst=self.inst)
886 return (func, 'inst,' + call_params_string, locs)
887
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000888def test_main():
Benjamin Peterson7e213252010-03-30 17:58:13 +0000889 run_unittest(
890 TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBuggyCases,
891 TestInterpreterStack, TestClassesAndFunctions, TestPredicates,
Serhiy Storchaka3b230042017-02-01 22:53:03 +0200892 TestGetcallargsFunctions, TestGetcallargsFunctionsCellVars,
893 TestGetcallargsMethods, TestGetcallargsUnboundMethods)
Martin v. Löwis893ffa42003-10-31 15:35:53 +0000894
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000895if __name__ == "__main__":
896 test_main()