blob: 4130cd0b502bcc92443d817aea104598dfa1ba89 [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
Florent Xicluna07627882010-03-21 01:14:24 +000011from test.test_support import run_unittest, check_py3k_warnings
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
R. David Murray87855542009-05-14 16:12:57 +000020import unicodedata
R. David Murray996ba022009-05-13 17:14:11 +000021
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000022# Functions tested in this suite:
23# ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode,
Facundo Batista759bfc62008-02-18 03:43:43 +000024# isbuiltin, isroutine, isgenerator, isgeneratorfunction, getmembers,
25# getdoc, getfile, getmodule, getsourcefile, getcomments, getsource,
26# getclasstree, getargspec, getargvalues, formatargspec, formatargvalues,
27# currentframe, stack, trace, isdatadescriptor
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000028
Nick Coghlana2053472008-12-14 10:54:50 +000029# NOTE: There are some additional tests relating to interaction with
30# zipimport in the test_zipimport_support test module.
31
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000032modfile = mod.__file__
Georg Brandlb2afe852006-06-09 20:43:48 +000033if modfile.endswith(('c', 'o')):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000034 modfile = modfile[:-1]
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000035
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000036import __builtin__
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000037
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000038try:
Florent Xicluna07627882010-03-21 01:14:24 +000039 1 // 0
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000040except:
41 tb = sys.exc_traceback
42
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000043git = mod.StupidGit()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000044
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000045class IsTestBase(unittest.TestCase):
46 predicates = set([inspect.isbuiltin, inspect.isclass, inspect.iscode,
47 inspect.isframe, inspect.isfunction, inspect.ismethod,
Facundo Batista759bfc62008-02-18 03:43:43 +000048 inspect.ismodule, inspect.istraceback,
49 inspect.isgenerator, inspect.isgeneratorfunction])
Tim Peters5a9fb3c2005-01-07 16:01:32 +000050
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000051 def istest(self, predicate, exp):
52 obj = eval(exp)
Benjamin Peterson5c8da862009-06-30 22:57:08 +000053 self.assertTrue(predicate(obj), '%s(%s)' % (predicate.__name__, exp))
Tim Peters5a9fb3c2005-01-07 16:01:32 +000054
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000055 for other in self.predicates - set([predicate]):
Facundo Batista759bfc62008-02-18 03:43:43 +000056 if predicate == inspect.isgeneratorfunction and\
57 other == inspect.isfunction:
58 continue
Benjamin Peterson5c8da862009-06-30 22:57:08 +000059 self.assertFalse(other(obj), 'not %s(%s)' % (other.__name__, exp))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000060
Facundo Batista759bfc62008-02-18 03:43:43 +000061def generator_function_example(self):
62 for i in xrange(2):
63 yield i
64
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000065class TestPredicates(IsTestBase):
Christian Heimes728bee82008-03-03 20:30:29 +000066 def test_sixteen(self):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000067 count = len(filter(lambda x:x.startswith('is'), dir(inspect)))
Facundo Batista759bfc62008-02-18 03:43:43 +000068 # This test is here for remember you to update Doc/library/inspect.rst
Georg Brandl26bc1772008-03-03 20:39:00 +000069 # which claims there are 16 such functions
Christian Heimes728bee82008-03-03 20:30:29 +000070 expected = 16
Neal Norwitzdf80af72006-07-28 04:22:34 +000071 err_msg = "There are %d (not %d) is* functions" % (count, expected)
72 self.assertEqual(count, expected, err_msg)
Tim Peters5a9fb3c2005-01-07 16:01:32 +000073
Facundo Batista759bfc62008-02-18 03:43:43 +000074
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000075 def test_excluding_predicates(self):
76 self.istest(inspect.isbuiltin, 'sys.exit')
77 self.istest(inspect.isbuiltin, '[].append')
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000078 self.istest(inspect.iscode, 'mod.spam.func_code')
79 self.istest(inspect.isframe, 'tb.tb_frame')
80 self.istest(inspect.isfunction, 'mod.spam')
81 self.istest(inspect.ismethod, 'mod.StupidGit.abuse')
82 self.istest(inspect.ismethod, 'git.argue')
83 self.istest(inspect.ismodule, 'mod')
84 self.istest(inspect.istraceback, 'tb')
85 self.istest(inspect.isdatadescriptor, '__builtin__.file.closed')
86 self.istest(inspect.isdatadescriptor, '__builtin__.file.softspace')
Facundo Batista759bfc62008-02-18 03:43:43 +000087 self.istest(inspect.isgenerator, '(x for x in xrange(2))')
88 self.istest(inspect.isgeneratorfunction, 'generator_function_example')
Barry Warsaw00decd72006-07-27 23:43:15 +000089 if hasattr(types, 'GetSetDescriptorType'):
90 self.istest(inspect.isgetsetdescriptor,
91 'type(tb.tb_frame).f_locals')
92 else:
Benjamin Peterson5c8da862009-06-30 22:57:08 +000093 self.assertFalse(inspect.isgetsetdescriptor(type(tb.tb_frame).f_locals))
Barry Warsaw00decd72006-07-27 23:43:15 +000094 if hasattr(types, 'MemberDescriptorType'):
95 self.istest(inspect.ismemberdescriptor, 'datetime.timedelta.days')
96 else:
Benjamin Peterson5c8da862009-06-30 22:57:08 +000097 self.assertFalse(inspect.ismemberdescriptor(datetime.timedelta.days))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000098
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000099 def test_isroutine(self):
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000100 self.assertTrue(inspect.isroutine(mod.spam))
101 self.assertTrue(inspect.isroutine([].count))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000102
Benjamin Peterson5e5fbb62009-01-17 22:27:54 +0000103 def test_isclass(self):
104 self.istest(inspect.isclass, 'mod.StupidGit')
105 self.assertTrue(inspect.isclass(list))
106
107 class newstyle(object): pass
108 self.assertTrue(inspect.isclass(newstyle))
109
110 class CustomGetattr(object):
111 def __getattr__(self, attr):
112 return None
113 self.assertFalse(inspect.isclass(CustomGetattr()))
114
Amaury Forgeot d'Arcb54447f2009-01-13 23:39:22 +0000115 def test_get_slot_members(self):
116 class C(object):
117 __slots__ = ("a", "b")
118
119 x = C()
120 x.a = 42
121 members = dict(inspect.getmembers(x))
Ezio Melottiaa980582010-01-23 23:04:36 +0000122 self.assertIn('a', members)
123 self.assertNotIn('b', members)
Amaury Forgeot d'Arcb54447f2009-01-13 23:39:22 +0000124
Benjamin Petersonc63457b2009-10-15 03:06:55 +0000125 def test_isabstract(self):
126 from abc import ABCMeta, abstractmethod
127
128 class AbstractClassExample(object):
129 __metaclass__ = ABCMeta
130
131 @abstractmethod
132 def foo(self):
133 pass
134
135 class ClassExample(AbstractClassExample):
136 def foo(self):
137 pass
138
139 a = ClassExample()
140
141 # Test general behaviour.
142 self.assertTrue(inspect.isabstract(AbstractClassExample))
143 self.assertFalse(inspect.isabstract(ClassExample))
144 self.assertFalse(inspect.isabstract(a))
145 self.assertFalse(inspect.isabstract(int))
146 self.assertFalse(inspect.isabstract(5))
147
Amaury Forgeot d'Arcb54447f2009-01-13 23:39:22 +0000148
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000149class TestInterpreterStack(IsTestBase):
150 def __init__(self, *args, **kwargs):
151 unittest.TestCase.__init__(self, *args, **kwargs)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000152
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000153 git.abuse(7, 8, 9)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000154
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000155 def test_abuse_done(self):
156 self.istest(inspect.istraceback, 'git.ex[2]')
157 self.istest(inspect.isframe, 'mod.fr')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000158
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000159 def test_stack(self):
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000160 self.assertTrue(len(mod.st) >= 5)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000161 self.assertEqual(mod.st[0][1:],
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000162 (modfile, 16, 'eggs', [' st = inspect.stack()\n'], 0))
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000163 self.assertEqual(mod.st[1][1:],
164 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
165 self.assertEqual(mod.st[2][1:],
166 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
167 self.assertEqual(mod.st[3][1:],
168 (modfile, 39, 'abuse', [' self.argue(a, b, c)\n'], 0))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000169
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000170 def test_trace(self):
171 self.assertEqual(len(git.tr), 3)
172 self.assertEqual(git.tr[0][1:], (modfile, 43, 'argue',
173 [' spam(a, b, c)\n'], 0))
174 self.assertEqual(git.tr[1][1:], (modfile, 9, 'spam',
175 [' eggs(b + d, c + f)\n'], 0))
176 self.assertEqual(git.tr[2][1:], (modfile, 18, 'eggs',
Mark Dickinsonc68e9f02010-02-03 16:50:14 +0000177 [' q = y // 0\n'], 0))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000178
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000179 def test_frame(self):
180 args, varargs, varkw, locals = inspect.getargvalues(mod.fr)
181 self.assertEqual(args, ['x', 'y'])
182 self.assertEqual(varargs, None)
183 self.assertEqual(varkw, None)
184 self.assertEqual(locals, {'x': 11, 'p': 11, 'y': 14})
185 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
186 '(x=11, y=14)')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000187
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000188 def test_previous_frame(self):
189 args, varargs, varkw, locals = inspect.getargvalues(mod.fr.f_back)
190 self.assertEqual(args, ['a', 'b', 'c', 'd', ['e', ['f']]])
191 self.assertEqual(varargs, 'g')
192 self.assertEqual(varkw, 'h')
193 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
194 '(a=7, b=8, c=9, d=3, (e=4, (f=5,)), *g=(), **h={})')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000195
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000196class GetSourceBase(unittest.TestCase):
197 # Subclasses must override.
198 fodderFile = None
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000199
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000200 def __init__(self, *args, **kwargs):
201 unittest.TestCase.__init__(self, *args, **kwargs)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000202
Philip Jenvey6a111022009-05-28 05:58:44 +0000203 with open(inspect.getsourcefile(self.fodderFile)) as fp:
204 self.source = fp.read()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000205
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000206 def sourcerange(self, top, bottom):
207 lines = self.source.split("\n")
208 return "\n".join(lines[top-1:bottom]) + "\n"
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000209
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000210 def assertSourceEqual(self, obj, top, bottom):
211 self.assertEqual(inspect.getsource(obj),
212 self.sourcerange(top, bottom))
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000213
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000214class TestRetrievingSourceCode(GetSourceBase):
215 fodderFile = mod
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000216
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000217 def test_getclasses(self):
218 classes = inspect.getmembers(mod, inspect.isclass)
219 self.assertEqual(classes,
220 [('FesteringGob', mod.FesteringGob),
221 ('MalodorousPervert', mod.MalodorousPervert),
222 ('ParrotDroppings', mod.ParrotDroppings),
Serhiy Storchaka6db9e882013-09-05 17:28:10 +0300223 ('StupidGit', mod.StupidGit),
224 ('Tit', mod.MalodorousPervert),
225 ])
226 tree = inspect.getclasstree([cls[1] for cls in classes])
227 self.assertEqual(tree,
228 [(mod.ParrotDroppings, ()),
229 [(mod.FesteringGob, (mod.MalodorousPervert,
230 mod.ParrotDroppings))
231 ],
232 (mod.StupidGit, ()),
233 [(mod.MalodorousPervert, (mod.StupidGit,)),
234 [(mod.FesteringGob, (mod.MalodorousPervert,
235 mod.ParrotDroppings))
236 ]
237 ]
238 ])
239 tree = inspect.getclasstree([cls[1] for cls in classes], True)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000240 self.assertEqual(tree,
241 [(mod.ParrotDroppings, ()),
242 (mod.StupidGit, ()),
243 [(mod.MalodorousPervert, (mod.StupidGit,)),
244 [(mod.FesteringGob, (mod.MalodorousPervert,
245 mod.ParrotDroppings))
246 ]
247 ]
248 ])
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000249
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000250 def test_getfunctions(self):
251 functions = inspect.getmembers(mod, inspect.isfunction)
252 self.assertEqual(functions, [('eggs', mod.eggs),
253 ('spam', mod.spam)])
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000254
R. David Murrayf28fd242010-02-23 00:24:49 +0000255 @unittest.skipIf(sys.flags.optimize >= 2,
256 "Docstrings are omitted with -O2 and above")
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000257 def test_getdoc(self):
258 self.assertEqual(inspect.getdoc(mod), 'A module docstring.')
259 self.assertEqual(inspect.getdoc(mod.StupidGit),
260 'A longer,\n\nindented\n\ndocstring.')
261 self.assertEqual(inspect.getdoc(git.abuse),
262 'Another\n\ndocstring\n\ncontaining\n\ntabs')
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000263
Georg Brandl7be19aa2008-06-07 15:59:10 +0000264 def test_cleandoc(self):
265 self.assertEqual(inspect.cleandoc('An\n indented\n docstring.'),
266 'An\nindented\ndocstring.')
267
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000268 def test_getcomments(self):
269 self.assertEqual(inspect.getcomments(mod), '# line 1\n')
270 self.assertEqual(inspect.getcomments(mod.StupidGit), '# line 20\n')
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000271
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000272 def test_getmodule(self):
Nick Coghlanc495c662006-09-07 10:50:34 +0000273 # Check actual module
274 self.assertEqual(inspect.getmodule(mod), mod)
275 # Check class (uses __module__ attribute)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000276 self.assertEqual(inspect.getmodule(mod.StupidGit), mod)
Nick Coghlanc495c662006-09-07 10:50:34 +0000277 # Check a method (no __module__ attribute, falls back to filename)
278 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
279 # Do it again (check the caching isn't broken)
280 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
281 # Check a builtin
282 self.assertEqual(inspect.getmodule(str), sys.modules["__builtin__"])
283 # Check filename override
284 self.assertEqual(inspect.getmodule(None, modfile), mod)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000285
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000286 def test_getsource(self):
287 self.assertSourceEqual(git.abuse, 29, 39)
288 self.assertSourceEqual(mod.StupidGit, 21, 46)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000289
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000290 def test_getsourcefile(self):
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000291 self.assertEqual(inspect.getsourcefile(mod.spam), modfile)
292 self.assertEqual(inspect.getsourcefile(git.abuse), modfile)
R. David Murraydf1cf302010-06-17 01:36:52 +0000293 fn = "_non_existing_filename_used_for_sourcefile_test.py"
294 co = compile("None", fn, "exec")
295 self.assertEqual(inspect.getsourcefile(co), None)
296 linecache.cache[co.co_filename] = (1, None, "None", co.co_filename)
297 self.assertEqual(inspect.getsourcefile(co), fn)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000298
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000299 def test_getfile(self):
300 self.assertEqual(inspect.getfile(mod.StupidGit), mod.__file__)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000301
Phillip J. Eby5d86bdb2006-07-10 19:03:29 +0000302 def test_getmodule_recursion(self):
Christian Heimesc756d002007-11-27 21:34:01 +0000303 from types import ModuleType
Phillip J. Eby5d86bdb2006-07-10 19:03:29 +0000304 name = '__inspect_dummy'
Christian Heimesc756d002007-11-27 21:34:01 +0000305 m = sys.modules[name] = ModuleType(name)
Tim Peters722b8832006-07-10 21:11:49 +0000306 m.__file__ = "<string>" # hopefully not a real filename...
Phillip J. Eby5d86bdb2006-07-10 19:03:29 +0000307 m.__loader__ = "dummy" # pretend the filename is understood by a loader
308 exec "def x(): pass" in m.__dict__
309 self.assertEqual(inspect.getsourcefile(m.x.func_code), '<string>')
310 del sys.modules[name]
Phillip J. Eby1a2959c2006-07-20 15:54:16 +0000311 inspect.getmodule(compile('a=10','','single'))
Phillip J. Eby5d86bdb2006-07-10 19:03:29 +0000312
Benjamin Peterson0eb4ac42011-06-11 15:53:11 -0500313 def test_proceed_with_fake_filename(self):
314 '''doctest monkeypatches linecache to enable inspection'''
315 fn, source = '<test>', 'def x(): pass\n'
316 getlines = linecache.getlines
317 def monkey(filename, module_globals=None):
318 if filename == fn:
319 return source.splitlines(True)
320 else:
321 return getlines(filename, module_globals)
322 linecache.getlines = monkey
323 try:
324 ns = {}
325 exec compile(source, fn, 'single') in ns
326 inspect.getsource(ns["x"])
327 finally:
328 linecache.getlines = getlines
329
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000330class TestDecorators(GetSourceBase):
331 fodderFile = mod2
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000332
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000333 def test_wrapped_decorator(self):
334 self.assertSourceEqual(mod2.wrapped, 14, 17)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000335
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000336 def test_replacing_decorator(self):
337 self.assertSourceEqual(mod2.gone, 9, 10)
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000338
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000339class TestOneliners(GetSourceBase):
340 fodderFile = mod2
341 def test_oneline_lambda(self):
342 # Test inspect.getsource with a one-line lambda function.
343 self.assertSourceEqual(mod2.oll, 25, 25)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000344
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000345 def test_threeline_lambda(self):
346 # Test inspect.getsource with a three-line lambda function,
347 # where the second and third lines are _not_ indented.
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000348 self.assertSourceEqual(mod2.tll, 28, 30)
349
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000350 def test_twoline_indented_lambda(self):
351 # Test inspect.getsource with a two-line lambda function,
352 # where the second line _is_ indented.
353 self.assertSourceEqual(mod2.tlli, 33, 34)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000354
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000355 def test_onelinefunc(self):
356 # Test inspect.getsource with a regular one-line function.
357 self.assertSourceEqual(mod2.onelinefunc, 37, 37)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000358
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000359 def test_manyargs(self):
360 # Test inspect.getsource with a regular function where
361 # the arguments are on two lines and _not_ indented and
362 # the body on the second line with the last arguments.
363 self.assertSourceEqual(mod2.manyargs, 40, 41)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000364
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000365 def test_twolinefunc(self):
366 # Test inspect.getsource with a regular function where
367 # the body is on two lines, following the argument list and
368 # continued on the next line by a \\.
369 self.assertSourceEqual(mod2.twolinefunc, 44, 45)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000370
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000371 def test_lambda_in_list(self):
372 # Test inspect.getsource with a one-line lambda function
373 # defined in a list, indented.
374 self.assertSourceEqual(mod2.a[1], 49, 49)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000375
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000376 def test_anonymous(self):
377 # Test inspect.getsource with a lambda function defined
378 # as argument to another function.
379 self.assertSourceEqual(mod2.anonymous, 55, 55)
380
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000381class TestBuggyCases(GetSourceBase):
382 fodderFile = mod2
383
384 def test_with_comment(self):
385 self.assertSourceEqual(mod2.with_comment, 58, 59)
386
387 def test_multiline_sig(self):
388 self.assertSourceEqual(mod2.multiline_sig[0], 63, 64)
389
Armin Rigodd5c0232005-09-25 11:45:45 +0000390 def test_nested_class(self):
391 self.assertSourceEqual(mod2.func69().func71, 71, 72)
392
393 def test_one_liner_followed_by_non_name(self):
394 self.assertSourceEqual(mod2.func77, 77, 77)
395
396 def test_one_liner_dedent_non_name(self):
397 self.assertSourceEqual(mod2.cls82.func83, 83, 83)
398
399 def test_with_comment_instead_of_docstring(self):
400 self.assertSourceEqual(mod2.func88, 88, 90)
401
Georg Brandl2463f8f2006-08-14 21:34:08 +0000402 def test_method_in_dynamic_class(self):
403 self.assertSourceEqual(mod2.method_in_dynamic_class, 95, 97)
404
R. David Murray87855542009-05-14 16:12:57 +0000405 @unittest.skipIf(
406 not hasattr(unicodedata, '__file__') or
407 unicodedata.__file__[-4:] in (".pyc", ".pyo"),
408 "unicodedata is not an external binary module")
R. David Murray996ba022009-05-13 17:14:11 +0000409 def test_findsource_binary(self):
R. David Murray87855542009-05-14 16:12:57 +0000410 self.assertRaises(IOError, inspect.getsource, unicodedata)
411 self.assertRaises(IOError, inspect.findsource, unicodedata)
R. David Murray996ba022009-05-13 17:14:11 +0000412
R. David Murraydf1cf302010-06-17 01:36:52 +0000413 def test_findsource_code_in_linecache(self):
414 lines = ["x=1"]
415 co = compile(lines[0], "_dynamically_created_file", "exec")
416 self.assertRaises(IOError, inspect.findsource, co)
417 self.assertRaises(IOError, inspect.getsource, co)
418 linecache.cache[co.co_filename] = (1, None, lines, co.co_filename)
Ezio Melotti2623a372010-11-21 13:34:58 +0000419 self.assertEqual(inspect.findsource(co), (lines,0))
420 self.assertEqual(inspect.getsource(co), lines[0])
R. David Murraydf1cf302010-06-17 01:36:52 +0000421
Ezio Melottie66e7de2013-03-30 05:10:28 +0200422 def test_findsource_without_filename(self):
423 for fname in ['', '<string>']:
424 co = compile('x=1', fname, "exec")
425 self.assertRaises(IOError, inspect.findsource, co)
426 self.assertRaises(IOError, inspect.getsource, co)
427
Antoine Pitroub8572a12011-12-21 10:16:14 +0100428
429class _BrokenDataDescriptor(object):
430 """
431 A broken data descriptor. See bug #1785.
432 """
433 def __get__(*args):
434 raise AssertionError("should not __get__ data descriptors")
435
436 def __set__(*args):
437 raise RuntimeError
438
439 def __getattr__(*args):
440 raise AssertionError("should not __getattr__ data descriptors")
441
442
443class _BrokenMethodDescriptor(object):
444 """
445 A broken method descriptor. See bug #1785.
446 """
447 def __get__(*args):
448 raise AssertionError("should not __get__ method descriptors")
449
450 def __getattr__(*args):
451 raise AssertionError("should not __getattr__ method descriptors")
452
453
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000454# Helper for testing classify_class_attrs.
Tim Peters13b49d32001-09-23 02:00:29 +0000455def attrs_wo_objs(cls):
456 return [t[:3] for t in inspect.classify_class_attrs(cls)]
457
Antoine Pitroub8572a12011-12-21 10:16:14 +0100458
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000459class TestClassesAndFunctions(unittest.TestCase):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000460 def test_classic_mro(self):
461 # Test classic-class method resolution order.
462 class A: pass
463 class B(A): pass
464 class C(A): pass
465 class D(B, C): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000466
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000467 expected = (D, B, A, C)
468 got = inspect.getmro(D)
469 self.assertEqual(expected, got)
Tim Peters13b49d32001-09-23 02:00:29 +0000470
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000471 def test_newstyle_mro(self):
472 # The same w/ new-class MRO.
473 class A(object): pass
474 class B(A): pass
475 class C(A): pass
476 class D(B, C): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000477
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000478 expected = (D, B, C, A, object)
479 got = inspect.getmro(D)
480 self.assertEqual(expected, got)
Tim Peters13b49d32001-09-23 02:00:29 +0000481
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000482 def assertArgSpecEquals(self, routine, args_e, varargs_e = None,
483 varkw_e = None, defaults_e = None,
484 formatted = None):
485 args, varargs, varkw, defaults = inspect.getargspec(routine)
486 self.assertEqual(args, args_e)
487 self.assertEqual(varargs, varargs_e)
488 self.assertEqual(varkw, varkw_e)
489 self.assertEqual(defaults, defaults_e)
490 if formatted is not None:
491 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults),
492 formatted)
Tim Peters13b49d32001-09-23 02:00:29 +0000493
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000494 def test_getargspec(self):
495 self.assertArgSpecEquals(mod.eggs, ['x', 'y'], formatted = '(x, y)')
Tim Peters13b49d32001-09-23 02:00:29 +0000496
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000497 self.assertArgSpecEquals(mod.spam,
498 ['a', 'b', 'c', 'd', ['e', ['f']]],
499 'g', 'h', (3, (4, (5,))),
500 '(a, b, c, d=3, (e, (f,))=(4, (5,)), *g, **h)')
Tim Peters13b49d32001-09-23 02:00:29 +0000501
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000502 def test_getargspec_method(self):
503 class A(object):
504 def m(self):
505 pass
506 self.assertArgSpecEquals(A.m, ['self'])
Tim Peters13b49d32001-09-23 02:00:29 +0000507
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000508 def test_getargspec_sublistofone(self):
Florent Xicluna07627882010-03-21 01:14:24 +0000509 with check_py3k_warnings(
510 ("tuple parameter unpacking has been removed", SyntaxWarning),
511 ("parenthesized argument names are invalid", SyntaxWarning)):
512 exec 'def sublistOfOne((foo,)): return 1'
513 self.assertArgSpecEquals(sublistOfOne, [['foo']])
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000514
Florent Xicluna07627882010-03-21 01:14:24 +0000515 exec 'def fakeSublistOfOne((foo)): return 1'
516 self.assertArgSpecEquals(fakeSublistOfOne, ['foo'])
Neal Norwitz33b730e2006-03-27 08:58:23 +0000517
Jean-Paul Calderoneb60ee462010-04-10 19:59:28 +0000518
519 def _classify_test(self, newstyle):
520 """Helper for testing that classify_class_attrs finds a bunch of
521 different kinds of attributes on a given class.
522 """
523 if newstyle:
524 base = object
525 else:
526 class base:
527 pass
528
529 class A(base):
530 def s(): pass
531 s = staticmethod(s)
532
533 def c(cls): pass
534 c = classmethod(c)
535
536 def getp(self): pass
537 p = property(getp)
538
539 def m(self): pass
540
541 def m1(self): pass
542
543 datablob = '1'
544
Antoine Pitroub8572a12011-12-21 10:16:14 +0100545 dd = _BrokenDataDescriptor()
546 md = _BrokenMethodDescriptor()
547
Jean-Paul Calderoneb60ee462010-04-10 19:59:28 +0000548 attrs = attrs_wo_objs(A)
549 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
550 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
551 self.assertIn(('p', 'property', A), attrs, 'missing property')
552 self.assertIn(('m', 'method', A), attrs, 'missing plain method')
553 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
554 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitroub8572a12011-12-21 10:16:14 +0100555 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
556 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Jean-Paul Calderoneb60ee462010-04-10 19:59:28 +0000557
558 class B(A):
559 def m(self): pass
560
561 attrs = attrs_wo_objs(B)
562 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
563 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
564 self.assertIn(('p', 'property', A), attrs, 'missing property')
565 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
566 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
567 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitroub8572a12011-12-21 10:16:14 +0100568 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
569 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Jean-Paul Calderoneb60ee462010-04-10 19:59:28 +0000570
571
572 class C(A):
573 def m(self): pass
574 def c(self): pass
575
576 attrs = attrs_wo_objs(C)
577 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
578 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
579 self.assertIn(('p', 'property', A), attrs, 'missing property')
580 self.assertIn(('m', 'method', C), attrs, 'missing plain method')
581 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
582 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitroub8572a12011-12-21 10:16:14 +0100583 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
584 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Jean-Paul Calderoneb60ee462010-04-10 19:59:28 +0000585
586 class D(B, C):
587 def m1(self): pass
588
589 attrs = attrs_wo_objs(D)
590 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
591 if newstyle:
592 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
593 else:
594 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
595 self.assertIn(('p', 'property', A), attrs, 'missing property')
596 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
597 self.assertIn(('m1', 'method', D), attrs, 'missing plain method')
598 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitroub8572a12011-12-21 10:16:14 +0100599 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
600 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Jean-Paul Calderoneb60ee462010-04-10 19:59:28 +0000601
602
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000603 def test_classify_oldstyle(self):
Jean-Paul Calderoneb60ee462010-04-10 19:59:28 +0000604 """classify_class_attrs finds static methods, class methods,
605 properties, normal methods, and data attributes on an old-style
606 class.
607 """
608 self._classify_test(False)
Tim Peters13b49d32001-09-23 02:00:29 +0000609
610
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000611 def test_classify_newstyle(self):
Jean-Paul Calderoneb60ee462010-04-10 19:59:28 +0000612 """Just like test_classify_oldstyle, but for a new-style class.
613 """
614 self._classify_test(True)
Tim Peters13b49d32001-09-23 02:00:29 +0000615
Antoine Pitroub8572a12011-12-21 10:16:14 +0100616 def test_classify_builtin_types(self):
617 # Simple sanity check that all built-in types can have their
618 # attributes classified.
619 for name in dir(__builtin__):
620 builtin = getattr(__builtin__, name)
621 if isinstance(builtin, type):
622 inspect.classify_class_attrs(builtin)
623
Antoine Pitroue09bc1e2012-01-18 17:39:01 +0100624 def test_getmembers_method(self):
Antoine Pitroub8572a12011-12-21 10:16:14 +0100625 # Old-style classes
Antoine Pitroue09bc1e2012-01-18 17:39:01 +0100626 class B:
627 def f(self):
628 pass
Antoine Pitroub8572a12011-12-21 10:16:14 +0100629
Antoine Pitroue09bc1e2012-01-18 17:39:01 +0100630 self.assertIn(('f', B.f), inspect.getmembers(B))
631 # contrary to spec, ismethod() is also True for unbound methods
632 # (see #1785)
633 self.assertIn(('f', B.f), inspect.getmembers(B, inspect.ismethod))
634 b = B()
635 self.assertIn(('f', b.f), inspect.getmembers(b))
636 self.assertIn(('f', b.f), inspect.getmembers(b, inspect.ismethod))
Antoine Pitroub8572a12011-12-21 10:16:14 +0100637
638 # New-style classes
Antoine Pitroue09bc1e2012-01-18 17:39:01 +0100639 class B(object):
640 def f(self):
Antoine Pitroub8572a12011-12-21 10:16:14 +0100641 pass
Antoine Pitroub8572a12011-12-21 10:16:14 +0100642
Antoine Pitroue09bc1e2012-01-18 17:39:01 +0100643 self.assertIn(('f', B.f), inspect.getmembers(B))
644 self.assertIn(('f', B.f), inspect.getmembers(B, inspect.ismethod))
645 b = B()
646 self.assertIn(('f', b.f), inspect.getmembers(b))
647 self.assertIn(('f', b.f), inspect.getmembers(b, inspect.ismethod))
Tim Peters13b49d32001-09-23 02:00:29 +0000648
Jeremy Hyltonc4bf5ed2003-06-27 18:43:12 +0000649
Benjamin Peterson7e213252010-03-30 17:58:13 +0000650class TestGetcallargsFunctions(unittest.TestCase):
651
652 # tuple parameters are named '.1', '.2', etc.
653 is_tuplename = re.compile(r'^\.\d+$').match
654
655 def assertEqualCallArgs(self, func, call_params_string, locs=None):
656 locs = dict(locs or {}, func=func)
657 r1 = eval('func(%s)' % call_params_string, None, locs)
658 r2 = eval('inspect.getcallargs(func, %s)' % call_params_string, None,
659 locs)
660 self.assertEqual(r1, r2)
661
662 def assertEqualException(self, func, call_param_string, locs=None):
663 locs = dict(locs or {}, func=func)
664 try:
665 eval('func(%s)' % call_param_string, None, locs)
666 except Exception, ex1:
667 pass
668 else:
669 self.fail('Exception not raised')
670 try:
671 eval('inspect.getcallargs(func, %s)' % call_param_string, None,
672 locs)
673 except Exception, ex2:
674 pass
675 else:
676 self.fail('Exception not raised')
677 self.assertIs(type(ex1), type(ex2))
678 self.assertEqual(str(ex1), str(ex2))
679
680 def makeCallable(self, signature):
681 """Create a function that returns its locals(), excluding the
682 autogenerated '.1', '.2', etc. tuple param names (if any)."""
Ezio Melottifcc500e2010-03-31 08:33:50 +0000683 with check_py3k_warnings(
684 ("tuple parameter unpacking has been removed", SyntaxWarning),
685 quiet=True):
686 code = ("lambda %s: dict(i for i in locals().items() "
687 "if not is_tuplename(i[0]))")
688 return eval(code % signature, {'is_tuplename' : self.is_tuplename})
Benjamin Peterson7e213252010-03-30 17:58:13 +0000689
690 def test_plain(self):
691 f = self.makeCallable('a, b=1')
692 self.assertEqualCallArgs(f, '2')
693 self.assertEqualCallArgs(f, '2, 3')
694 self.assertEqualCallArgs(f, 'a=2')
695 self.assertEqualCallArgs(f, 'b=3, a=2')
696 self.assertEqualCallArgs(f, '2, b=3')
697 # expand *iterable / **mapping
698 self.assertEqualCallArgs(f, '*(2,)')
699 self.assertEqualCallArgs(f, '*[2]')
700 self.assertEqualCallArgs(f, '*(2, 3)')
701 self.assertEqualCallArgs(f, '*[2, 3]')
702 self.assertEqualCallArgs(f, '**{"a":2}')
703 self.assertEqualCallArgs(f, 'b=3, **{"a":2}')
704 self.assertEqualCallArgs(f, '2, **{"b":3}')
705 self.assertEqualCallArgs(f, '**{"b":3, "a":2}')
706 # expand UserList / UserDict
707 self.assertEqualCallArgs(f, '*UserList([2])')
708 self.assertEqualCallArgs(f, '*UserList([2, 3])')
709 self.assertEqualCallArgs(f, '**UserDict(a=2)')
710 self.assertEqualCallArgs(f, '2, **UserDict(b=3)')
711 self.assertEqualCallArgs(f, 'b=2, **UserDict(a=3)')
712 # unicode keyword args
713 self.assertEqualCallArgs(f, '**{u"a":2}')
714 self.assertEqualCallArgs(f, 'b=3, **{u"a":2}')
715 self.assertEqualCallArgs(f, '2, **{u"b":3}')
716 self.assertEqualCallArgs(f, '**{u"b":3, u"a":2}')
717
718 def test_varargs(self):
719 f = self.makeCallable('a, b=1, *c')
720 self.assertEqualCallArgs(f, '2')
721 self.assertEqualCallArgs(f, '2, 3')
722 self.assertEqualCallArgs(f, '2, 3, 4')
723 self.assertEqualCallArgs(f, '*(2,3,4)')
724 self.assertEqualCallArgs(f, '2, *[3,4]')
725 self.assertEqualCallArgs(f, '2, 3, *UserList([4])')
726
727 def test_varkw(self):
728 f = self.makeCallable('a, b=1, **c')
729 self.assertEqualCallArgs(f, 'a=2')
730 self.assertEqualCallArgs(f, '2, b=3, c=4')
731 self.assertEqualCallArgs(f, 'b=3, a=2, c=4')
732 self.assertEqualCallArgs(f, 'c=4, **{"a":2, "b":3}')
733 self.assertEqualCallArgs(f, '2, c=4, **{"b":3}')
734 self.assertEqualCallArgs(f, 'b=2, **{"a":3, "c":4}')
735 self.assertEqualCallArgs(f, '**UserDict(a=2, b=3, c=4)')
736 self.assertEqualCallArgs(f, '2, c=4, **UserDict(b=3)')
737 self.assertEqualCallArgs(f, 'b=2, **UserDict(a=3, c=4)')
738 # unicode keyword args
739 self.assertEqualCallArgs(f, 'c=4, **{u"a":2, u"b":3}')
740 self.assertEqualCallArgs(f, '2, c=4, **{u"b":3}')
741 self.assertEqualCallArgs(f, 'b=2, **{u"a":3, u"c":4}')
742
Benjamin Peterson77d46602011-03-28 17:32:31 -0500743 def test_varkw_only(self):
744 # issue11256:
745 f = self.makeCallable('**c')
746 self.assertEqualCallArgs(f, '')
747 self.assertEqualCallArgs(f, 'a=1')
748 self.assertEqualCallArgs(f, 'a=1, b=2')
749 self.assertEqualCallArgs(f, 'c=3, **{"a": 1, "b": 2}')
750 self.assertEqualCallArgs(f, '**UserDict(a=1, b=2)')
751 self.assertEqualCallArgs(f, 'c=3, **UserDict(a=1, b=2)')
752
Benjamin Peterson7e213252010-03-30 17:58:13 +0000753 def test_tupleargs(self):
754 f = self.makeCallable('(b,c), (d,(e,f))=(0,[1,2])')
755 self.assertEqualCallArgs(f, '(2,3)')
756 self.assertEqualCallArgs(f, '[2,3]')
757 self.assertEqualCallArgs(f, 'UserList([2,3])')
758 self.assertEqualCallArgs(f, '(2,3), (4,(5,6))')
759 self.assertEqualCallArgs(f, '(2,3), (4,[5,6])')
760 self.assertEqualCallArgs(f, '(2,3), [4,UserList([5,6])]')
761
762 def test_multiple_features(self):
763 f = self.makeCallable('a, b=2, (c,(d,e))=(3,[4,5]), *f, **g')
764 self.assertEqualCallArgs(f, '2, 3, (4,[5,6]), 7')
765 self.assertEqualCallArgs(f, '2, 3, *[(4,[5,6]), 7], x=8')
766 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
767 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9')
768 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9')
769 self.assertEqualCallArgs(f, 'x=8, *UserList([2, 3, (4,[5,6])]), '
770 '**{"y":9, "z":10}')
771 self.assertEqualCallArgs(f, '2, x=8, *UserList([3, (4,[5,6])]), '
772 '**UserDict(y=9, z=10)')
773
774 def test_errors(self):
775 f0 = self.makeCallable('')
776 f1 = self.makeCallable('a, b')
777 f2 = self.makeCallable('a, b=1')
778 # f0 takes no arguments
779 self.assertEqualException(f0, '1')
780 self.assertEqualException(f0, 'x=1')
781 self.assertEqualException(f0, '1,x=1')
782 # f1 takes exactly 2 arguments
783 self.assertEqualException(f1, '')
784 self.assertEqualException(f1, '1')
785 self.assertEqualException(f1, 'a=2')
786 self.assertEqualException(f1, 'b=3')
787 # f2 takes at least 1 argument
788 self.assertEqualException(f2, '')
789 self.assertEqualException(f2, 'b=3')
790 for f in f1, f2:
791 # f1/f2 takes exactly/at most 2 arguments
792 self.assertEqualException(f, '2, 3, 4')
793 self.assertEqualException(f, '1, 2, 3, a=1')
794 self.assertEqualException(f, '2, 3, 4, c=5')
795 self.assertEqualException(f, '2, 3, 4, a=1, c=5')
796 # f got an unexpected keyword argument
797 self.assertEqualException(f, 'c=2')
798 self.assertEqualException(f, '2, c=3')
799 self.assertEqualException(f, '2, 3, c=4')
800 self.assertEqualException(f, '2, c=4, b=3')
801 self.assertEqualException(f, '**{u"\u03c0\u03b9": 4}')
802 # f got multiple values for keyword argument
803 self.assertEqualException(f, '1, a=2')
804 self.assertEqualException(f, '1, **{"a":2}')
805 self.assertEqualException(f, '1, 2, b=3')
806 # XXX: Python inconsistency
807 # - for functions and bound methods: unexpected keyword 'c'
808 # - for unbound methods: multiple values for keyword 'a'
809 #self.assertEqualException(f, '1, c=3, a=2')
810 f = self.makeCallable('(a,b)=(0,1)')
811 self.assertEqualException(f, '1')
812 self.assertEqualException(f, '[1]')
813 self.assertEqualException(f, '(1,2,3)')
Benjamin Peterson77d46602011-03-28 17:32:31 -0500814 # issue11256:
815 f3 = self.makeCallable('**c')
816 self.assertEqualException(f3, '1, 2')
817 self.assertEqualException(f3, '1, 2, a=1, b=2')
Benjamin Peterson7e213252010-03-30 17:58:13 +0000818
819class TestGetcallargsMethods(TestGetcallargsFunctions):
820
821 def setUp(self):
822 class Foo(object):
823 pass
824 self.cls = Foo
825 self.inst = Foo()
826
827 def makeCallable(self, signature):
828 assert 'self' not in signature
829 mk = super(TestGetcallargsMethods, self).makeCallable
830 self.cls.method = mk('self, ' + signature)
831 return self.inst.method
832
833class TestGetcallargsUnboundMethods(TestGetcallargsMethods):
834
835 def makeCallable(self, signature):
836 super(TestGetcallargsUnboundMethods, self).makeCallable(signature)
837 return self.cls.method
838
839 def assertEqualCallArgs(self, func, call_params_string, locs=None):
840 return super(TestGetcallargsUnboundMethods, self).assertEqualCallArgs(
841 *self._getAssertEqualParams(func, call_params_string, locs))
842
843 def assertEqualException(self, func, call_params_string, locs=None):
844 return super(TestGetcallargsUnboundMethods, self).assertEqualException(
845 *self._getAssertEqualParams(func, call_params_string, locs))
846
847 def _getAssertEqualParams(self, func, call_params_string, locs=None):
848 assert 'inst' not in call_params_string
849 locs = dict(locs or {}, inst=self.inst)
850 return (func, 'inst,' + call_params_string, locs)
851
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000852def test_main():
Benjamin Peterson7e213252010-03-30 17:58:13 +0000853 run_unittest(
854 TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBuggyCases,
855 TestInterpreterStack, TestClassesAndFunctions, TestPredicates,
856 TestGetcallargsFunctions, TestGetcallargsMethods,
857 TestGetcallargsUnboundMethods)
Martin v. Löwis893ffa42003-10-31 15:35:53 +0000858
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000859if __name__ == "__main__":
860 test_main()