blob: 2f12e989d907a944f8858da59cf3aa5f66941d0f [file] [log] [blame]
Nick Coghlanf9e227e2014-08-17 14:01:19 +10001import builtins
Guido van Rossum813b0e52007-05-21 18:11:34 +00002import collections
Larry Hastings5c661892014-01-24 06:17:25 -08003import datetime
Nick Coghlane8c45d62013-07-28 20:00:01 +10004import functools
Nick Coghlanf94a16b2013-09-22 22:46:49 +10005import importlib
Larry Hastings5c661892014-01-24 06:17:25 -08006import inspect
7import io
8import linecache
9import os
Christian Heimesa3538eb2007-11-06 11:44:48 +000010from os.path import normcase
Larry Hastings5c661892014-01-24 06:17:25 -080011import _pickle
Yury Selivanova5d63dd2014-03-27 11:31:43 -040012import pickle
Larry Hastings5c661892014-01-24 06:17:25 -080013import shutil
14import sys
15import types
Yury Selivanovef1e7502014-12-08 16:05:34 -050016import textwrap
Larry Hastings5c661892014-01-24 06:17:25 -080017import unicodedata
18import unittest
Yury Selivanova773de02014-02-21 18:30:53 -050019import unittest.mock
Yury Selivanov75445082015-05-11 22:57:16 -040020import warnings
Larry Hastings5c661892014-01-24 06:17:25 -080021
Brett Cannon634a8fc2013-10-02 10:25:42 -040022try:
23 from concurrent.futures import ThreadPoolExecutor
24except ImportError:
25 ThreadPoolExecutor = None
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000026
Serhiy Storchakaf28ba362014-02-07 10:10:55 +020027from test.support import run_unittest, TESTFN, DirsOnSysPath, cpython_only
Nick Coghlanf9e227e2014-08-17 14:01:19 +100028from test.support import MISSING_C_DOCSTRINGS, cpython_only
Berker Peksagce643912015-05-06 06:33:17 +030029from test.support.script_helper import assert_python_ok, assert_python_failure
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000030from test import inspect_fodder as mod
31from test import inspect_fodder2 as mod2
Victor Stinner9def2842016-01-18 12:15:08 +010032from test import support
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000033
Yury Selivanovef1e7502014-12-08 16:05:34 -050034from test.test_import import _ready_to_import
35
R. David Murray74b89242009-05-13 17:33:03 +000036
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000037# Functions tested in this suite:
38# ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode,
Christian Heimes7131fd92008-02-19 14:21:46 +000039# isbuiltin, isroutine, isgenerator, isgeneratorfunction, getmembers,
40# getdoc, getfile, getmodule, getsourcefile, getcomments, getsource,
Berker Peksagfa3922c2015-07-31 04:11:29 +030041# getclasstree, getargvalues, formatargspec, formatargvalues,
Christian Heimes7131fd92008-02-19 14:21:46 +000042# currentframe, stack, trace, isdatadescriptor
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000043
Nick Coghlanf088e5e2008-12-14 11:50:48 +000044# NOTE: There are some additional tests relating to interaction with
45# zipimport in the test_zipimport_support test module.
46
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000047modfile = mod.__file__
Thomas Wouters0e3f5912006-08-11 14:57:12 +000048if modfile.endswith(('c', 'o')):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000049 modfile = modfile[:-1]
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000050
Christian Heimesa3538eb2007-11-06 11:44:48 +000051# Normalize file names: on Windows, the case of file names of compiled
52# modules depends on the path used to start the python executable.
53modfile = normcase(modfile)
54
55def revise(filename, *args):
56 return (normcase(filename),) + args
57
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000058git = mod.StupidGit()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000059
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000060class IsTestBase(unittest.TestCase):
61 predicates = set([inspect.isbuiltin, inspect.isclass, inspect.iscode,
62 inspect.isframe, inspect.isfunction, inspect.ismethod,
Christian Heimes7131fd92008-02-19 14:21:46 +000063 inspect.ismodule, inspect.istraceback,
Yury Selivanov75445082015-05-11 22:57:16 -040064 inspect.isgenerator, inspect.isgeneratorfunction,
Yury Selivanoveb636452016-09-08 22:01:51 -070065 inspect.iscoroutine, inspect.iscoroutinefunction,
66 inspect.isasyncgen, inspect.isasyncgenfunction])
Tim Peters5a9fb3c2005-01-07 16:01:32 +000067
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000068 def istest(self, predicate, exp):
69 obj = eval(exp)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000070 self.assertTrue(predicate(obj), '%s(%s)' % (predicate.__name__, exp))
Tim Peters5a9fb3c2005-01-07 16:01:32 +000071
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000072 for other in self.predicates - set([predicate]):
Yury Selivanov75445082015-05-11 22:57:16 -040073 if (predicate == inspect.isgeneratorfunction or \
Yury Selivanoveb636452016-09-08 22:01:51 -070074 predicate == inspect.isasyncgenfunction or \
Yury Selivanov75445082015-05-11 22:57:16 -040075 predicate == inspect.iscoroutinefunction) and \
Christian Heimes7131fd92008-02-19 14:21:46 +000076 other == inspect.isfunction:
77 continue
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000078 self.assertFalse(other(obj), 'not %s(%s)' % (other.__name__, exp))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000079
Christian Heimes7131fd92008-02-19 14:21:46 +000080def generator_function_example(self):
81 for i in range(2):
82 yield i
83
Yury Selivanoveb636452016-09-08 22:01:51 -070084async def async_generator_function_example(self):
85 async for i in range(2):
86 yield i
87
Yury Selivanov75445082015-05-11 22:57:16 -040088async def coroutine_function_example(self):
89 return 'spam'
90
91@types.coroutine
92def gen_coroutine_function_example(self):
93 yield
94 return 'spam'
95
Serhiy Storchaka3018cc42015-07-18 23:19:05 +030096class EqualsToAll:
97 def __eq__(self, other):
98 return True
Yury Selivanova5d63dd2014-03-27 11:31:43 -040099
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000100class TestPredicates(IsTestBase):
Christian Heimes7131fd92008-02-19 14:21:46 +0000101
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000102 def test_excluding_predicates(self):
Antoine Pitroud5a1a212012-06-17 23:18:07 +0200103 global tb
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000104 self.istest(inspect.isbuiltin, 'sys.exit')
105 self.istest(inspect.isbuiltin, '[].append')
Neal Norwitz221085d2007-02-25 20:55:47 +0000106 self.istest(inspect.iscode, 'mod.spam.__code__')
Antoine Pitroud5a1a212012-06-17 23:18:07 +0200107 try:
108 1/0
109 except:
110 tb = sys.exc_info()[2]
111 self.istest(inspect.isframe, 'tb.tb_frame')
112 self.istest(inspect.istraceback, 'tb')
113 if hasattr(types, 'GetSetDescriptorType'):
114 self.istest(inspect.isgetsetdescriptor,
115 'type(tb.tb_frame).f_locals')
116 else:
117 self.assertFalse(inspect.isgetsetdescriptor(type(tb.tb_frame).f_locals))
118 finally:
119 # Clear traceback and all the frames and local variables hanging to it.
120 tb = None
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000121 self.istest(inspect.isfunction, 'mod.spam')
Christian Heimes4a22b5d2007-11-25 09:39:14 +0000122 self.istest(inspect.isfunction, 'mod.StupidGit.abuse')
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000123 self.istest(inspect.ismethod, 'git.argue')
124 self.istest(inspect.ismodule, 'mod')
Guido van Rossum813b0e52007-05-21 18:11:34 +0000125 self.istest(inspect.isdatadescriptor, 'collections.defaultdict.default_factory')
Christian Heimes7131fd92008-02-19 14:21:46 +0000126 self.istest(inspect.isgenerator, '(x for x in range(2))')
127 self.istest(inspect.isgeneratorfunction, 'generator_function_example')
Yury Selivanoveb636452016-09-08 22:01:51 -0700128 self.istest(inspect.isasyncgen,
129 'async_generator_function_example(1)')
130 self.istest(inspect.isasyncgenfunction,
131 'async_generator_function_example')
Yury Selivanov75445082015-05-11 22:57:16 -0400132
133 with warnings.catch_warnings():
134 warnings.simplefilter("ignore")
135 self.istest(inspect.iscoroutine, 'coroutine_function_example(1)')
136 self.istest(inspect.iscoroutinefunction, 'coroutine_function_example')
137
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000138 if hasattr(types, 'MemberDescriptorType'):
139 self.istest(inspect.ismemberdescriptor, 'datetime.timedelta.days')
140 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000141 self.assertFalse(inspect.ismemberdescriptor(datetime.timedelta.days))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000142
Yury Selivanov75445082015-05-11 22:57:16 -0400143 def test_iscoroutine(self):
144 gen_coro = gen_coroutine_function_example(1)
145 coro = coroutine_function_example(1)
146
Yury Selivanov5376ba92015-06-22 12:19:30 -0400147 self.assertFalse(
Yury Selivanov75445082015-05-11 22:57:16 -0400148 inspect.iscoroutinefunction(gen_coroutine_function_example))
Yury Selivanov5376ba92015-06-22 12:19:30 -0400149 self.assertFalse(inspect.iscoroutine(gen_coro))
Yury Selivanov75445082015-05-11 22:57:16 -0400150
151 self.assertTrue(
152 inspect.isgeneratorfunction(gen_coroutine_function_example))
153 self.assertTrue(inspect.isgenerator(gen_coro))
154
155 self.assertTrue(
156 inspect.iscoroutinefunction(coroutine_function_example))
157 self.assertTrue(inspect.iscoroutine(coro))
158
159 self.assertFalse(
160 inspect.isgeneratorfunction(coroutine_function_example))
161 self.assertFalse(inspect.isgenerator(coro))
162
163 coro.close(); gen_coro.close() # silence warnings
164
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -0400165 def test_isawaitable(self):
166 def gen(): yield
167 self.assertFalse(inspect.isawaitable(gen()))
168
169 coro = coroutine_function_example(1)
170 gen_coro = gen_coroutine_function_example(1)
171
172 self.assertTrue(inspect.isawaitable(coro))
173 self.assertTrue(inspect.isawaitable(gen_coro))
174
175 class Future:
176 def __await__():
177 pass
178 self.assertTrue(inspect.isawaitable(Future()))
179 self.assertFalse(inspect.isawaitable(Future))
180
181 class NotFuture: pass
182 not_fut = NotFuture()
183 not_fut.__await__ = lambda: None
184 self.assertFalse(inspect.isawaitable(not_fut))
185
186 coro.close(); gen_coro.close() # silence warnings
187
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000188 def test_isroutine(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000189 self.assertTrue(inspect.isroutine(mod.spam))
190 self.assertTrue(inspect.isroutine([].count))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000191
Benjamin Petersonc4656002009-01-17 22:41:18 +0000192 def test_isclass(self):
193 self.istest(inspect.isclass, 'mod.StupidGit')
194 self.assertTrue(inspect.isclass(list))
195
196 class CustomGetattr(object):
197 def __getattr__(self, attr):
198 return None
199 self.assertFalse(inspect.isclass(CustomGetattr()))
200
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000201 def test_get_slot_members(self):
202 class C(object):
203 __slots__ = ("a", "b")
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000204 x = C()
205 x.a = 42
206 members = dict(inspect.getmembers(x))
Benjamin Peterson577473f2010-01-19 00:09:57 +0000207 self.assertIn('a', members)
208 self.assertNotIn('b', members)
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000209
Benjamin Petersona0dfa822009-11-13 02:25:08 +0000210 def test_isabstract(self):
211 from abc import ABCMeta, abstractmethod
212
213 class AbstractClassExample(metaclass=ABCMeta):
214
215 @abstractmethod
216 def foo(self):
217 pass
218
219 class ClassExample(AbstractClassExample):
220 def foo(self):
221 pass
222
223 a = ClassExample()
224
225 # Test general behaviour.
226 self.assertTrue(inspect.isabstract(AbstractClassExample))
227 self.assertFalse(inspect.isabstract(ClassExample))
228 self.assertFalse(inspect.isabstract(a))
229 self.assertFalse(inspect.isabstract(int))
230 self.assertFalse(inspect.isabstract(5))
231
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000232
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000233class TestInterpreterStack(IsTestBase):
234 def __init__(self, *args, **kwargs):
235 unittest.TestCase.__init__(self, *args, **kwargs)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000236
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000237 git.abuse(7, 8, 9)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000238
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000239 def test_abuse_done(self):
240 self.istest(inspect.istraceback, 'git.ex[2]')
241 self.istest(inspect.isframe, 'mod.fr')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000242
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000243 def test_stack(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000244 self.assertTrue(len(mod.st) >= 5)
Christian Heimesa3538eb2007-11-06 11:44:48 +0000245 self.assertEqual(revise(*mod.st[0][1:]),
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000246 (modfile, 16, 'eggs', [' st = inspect.stack()\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000247 self.assertEqual(revise(*mod.st[1][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000248 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000249 self.assertEqual(revise(*mod.st[2][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000250 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000251 self.assertEqual(revise(*mod.st[3][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000252 (modfile, 39, 'abuse', [' self.argue(a, b, c)\n'], 0))
Antoine Pitroucdcafb72014-08-24 10:50:28 -0400253 # Test named tuple fields
254 record = mod.st[0]
255 self.assertIs(record.frame, mod.fr)
256 self.assertEqual(record.lineno, 16)
257 self.assertEqual(record.filename, mod.__file__)
258 self.assertEqual(record.function, 'eggs')
259 self.assertIn('inspect.stack()', record.code_context[0])
260 self.assertEqual(record.index, 0)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000261
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000262 def test_trace(self):
263 self.assertEqual(len(git.tr), 3)
Florent Xiclunac8575922010-03-24 17:37:49 +0000264 self.assertEqual(revise(*git.tr[0][1:]),
265 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
266 self.assertEqual(revise(*git.tr[1][1:]),
267 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
268 self.assertEqual(revise(*git.tr[2][1:]),
269 (modfile, 18, 'eggs', [' q = y / 0\n'], 0))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000270
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000271 def test_frame(self):
272 args, varargs, varkw, locals = inspect.getargvalues(mod.fr)
273 self.assertEqual(args, ['x', 'y'])
274 self.assertEqual(varargs, None)
275 self.assertEqual(varkw, None)
276 self.assertEqual(locals, {'x': 11, 'p': 11, 'y': 14})
277 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
278 '(x=11, y=14)')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000279
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000280 def test_previous_frame(self):
281 args, varargs, varkw, locals = inspect.getargvalues(mod.fr.f_back)
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000282 self.assertEqual(args, ['a', 'b', 'c', 'd', 'e', 'f'])
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000283 self.assertEqual(varargs, 'g')
284 self.assertEqual(varkw, 'h')
285 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000286 '(a=7, b=8, c=9, d=3, e=4, f=5, *g=(), **h={})')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000287
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000288class GetSourceBase(unittest.TestCase):
289 # Subclasses must override.
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000290 fodderModule = None
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000291
Yury Selivanov6738b112015-05-16 10:10:21 -0400292 def setUp(self):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000293 with open(inspect.getsourcefile(self.fodderModule)) as fp:
Philip Jenveya27c5bd2009-05-28 06:09:08 +0000294 self.source = fp.read()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000295
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000296 def sourcerange(self, top, bottom):
297 lines = self.source.split("\n")
298 return "\n".join(lines[top-1:bottom]) + "\n"
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000299
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000300 def assertSourceEqual(self, obj, top, bottom):
301 self.assertEqual(inspect.getsource(obj),
302 self.sourcerange(top, bottom))
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000303
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000304class TestRetrievingSourceCode(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000305 fodderModule = mod
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000306
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000307 def test_getclasses(self):
308 classes = inspect.getmembers(mod, inspect.isclass)
309 self.assertEqual(classes,
310 [('FesteringGob', mod.FesteringGob),
311 ('MalodorousPervert', mod.MalodorousPervert),
312 ('ParrotDroppings', mod.ParrotDroppings),
Serhiy Storchaka362c1b52013-09-05 17:14:32 +0300313 ('StupidGit', mod.StupidGit),
314 ('Tit', mod.MalodorousPervert),
315 ])
316 tree = inspect.getclasstree([cls[1] for cls in classes])
317 self.assertEqual(tree,
318 [(object, ()),
319 [(mod.ParrotDroppings, (object,)),
320 [(mod.FesteringGob, (mod.MalodorousPervert,
321 mod.ParrotDroppings))
322 ],
323 (mod.StupidGit, (object,)),
324 [(mod.MalodorousPervert, (mod.StupidGit,)),
325 [(mod.FesteringGob, (mod.MalodorousPervert,
326 mod.ParrotDroppings))
327 ]
328 ]
329 ]
330 ])
331 tree = inspect.getclasstree([cls[1] for cls in classes], True)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000332 self.assertEqual(tree,
Thomas Wouters725af872006-04-15 09:13:19 +0000333 [(object, ()),
334 [(mod.ParrotDroppings, (object,)),
335 (mod.StupidGit, (object,)),
336 [(mod.MalodorousPervert, (mod.StupidGit,)),
337 [(mod.FesteringGob, (mod.MalodorousPervert,
338 mod.ParrotDroppings))
339 ]
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000340 ]
341 ]
342 ])
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000343
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000344 def test_getfunctions(self):
345 functions = inspect.getmembers(mod, inspect.isfunction)
346 self.assertEqual(functions, [('eggs', mod.eggs),
Yury Selivanove4e811d2015-07-21 19:01:52 +0300347 ('lobbest', mod.lobbest),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000348 ('spam', mod.spam)])
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000349
R. David Murray378c0cf2010-02-24 01:46:21 +0000350 @unittest.skipIf(sys.flags.optimize >= 2,
351 "Docstrings are omitted with -O2 and above")
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000352 def test_getdoc(self):
353 self.assertEqual(inspect.getdoc(mod), 'A module docstring.')
354 self.assertEqual(inspect.getdoc(mod.StupidGit),
355 'A longer,\n\nindented\n\ndocstring.')
356 self.assertEqual(inspect.getdoc(git.abuse),
357 'Another\n\ndocstring\n\ncontaining\n\ntabs')
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000358
Serhiy Storchaka5cf2b7252015-04-03 22:38:53 +0300359 @unittest.skipIf(sys.flags.optimize >= 2,
360 "Docstrings are omitted with -O2 and above")
361 def test_getdoc_inherited(self):
362 self.assertEqual(inspect.getdoc(mod.FesteringGob),
363 'A longer,\n\nindented\n\ndocstring.')
364 self.assertEqual(inspect.getdoc(mod.FesteringGob.abuse),
365 'Another\n\ndocstring\n\ncontaining\n\ntabs')
366 self.assertEqual(inspect.getdoc(mod.FesteringGob().abuse),
367 'Another\n\ndocstring\n\ncontaining\n\ntabs')
368 self.assertEqual(inspect.getdoc(mod.FesteringGob.contradiction),
369 'The automatic gainsaying.')
370
371 @unittest.skipIf(MISSING_C_DOCSTRINGS, "test requires docstrings")
372 def test_finddoc(self):
373 finddoc = inspect._finddoc
374 self.assertEqual(finddoc(int), int.__doc__)
375 self.assertEqual(finddoc(int.to_bytes), int.to_bytes.__doc__)
376 self.assertEqual(finddoc(int().to_bytes), int.to_bytes.__doc__)
377 self.assertEqual(finddoc(int.from_bytes), int.from_bytes.__doc__)
378 self.assertEqual(finddoc(int.real), int.real.__doc__)
379
Georg Brandl0c77a822008-06-10 16:37:50 +0000380 def test_cleandoc(self):
381 self.assertEqual(inspect.cleandoc('An\n indented\n docstring.'),
382 'An\nindented\ndocstring.')
383
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000384 def test_getcomments(self):
385 self.assertEqual(inspect.getcomments(mod), '# line 1\n')
386 self.assertEqual(inspect.getcomments(mod.StupidGit), '# line 20\n')
Marco Buttu3f2155f2017-03-17 09:50:23 +0100387 # If the object source file is not available, return None.
388 co = compile('x=1', '_non_existing_filename.py', 'exec')
389 self.assertIsNone(inspect.getcomments(co))
390 # If the object has been defined in C, return None.
391 self.assertIsNone(inspect.getcomments(list))
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000392
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000393 def test_getmodule(self):
Thomas Wouters89f507f2006-12-13 04:49:30 +0000394 # Check actual module
395 self.assertEqual(inspect.getmodule(mod), mod)
396 # Check class (uses __module__ attribute)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000397 self.assertEqual(inspect.getmodule(mod.StupidGit), mod)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000398 # Check a method (no __module__ attribute, falls back to filename)
399 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
400 # Do it again (check the caching isn't broken)
401 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
402 # Check a builtin
Georg Brandl1a3284e2007-12-02 09:40:06 +0000403 self.assertEqual(inspect.getmodule(str), sys.modules["builtins"])
Thomas Wouters89f507f2006-12-13 04:49:30 +0000404 # Check filename override
405 self.assertEqual(inspect.getmodule(None, modfile), mod)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000406
Berker Peksagff0e3b72017-01-02 06:57:43 +0300407 def test_getframeinfo_get_first_line(self):
408 frame_info = inspect.getframeinfo(self.fodderModule.fr, 50)
409 self.assertEqual(frame_info.code_context[0], "# line 1\n")
410 self.assertEqual(frame_info.code_context[1], "'A module docstring.'\n")
411
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000412 def test_getsource(self):
413 self.assertSourceEqual(git.abuse, 29, 39)
Serhiy Storchakaac4bdcc2015-10-29 08:15:50 +0200414 self.assertSourceEqual(mod.StupidGit, 21, 51)
415 self.assertSourceEqual(mod.lobbest, 75, 76)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000416
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000417 def test_getsourcefile(self):
Christian Heimesa3538eb2007-11-06 11:44:48 +0000418 self.assertEqual(normcase(inspect.getsourcefile(mod.spam)), modfile)
419 self.assertEqual(normcase(inspect.getsourcefile(git.abuse)), modfile)
R. David Murraya1b37402010-06-17 02:04:29 +0000420 fn = "_non_existing_filename_used_for_sourcefile_test.py"
Victor Stinner51d8c522016-02-08 17:57:02 +0100421 co = compile("x=1", fn, "exec")
R. David Murray4155f972010-06-17 13:23:18 +0000422 self.assertEqual(inspect.getsourcefile(co), None)
R. David Murraya1b37402010-06-17 02:04:29 +0000423 linecache.cache[co.co_filename] = (1, None, "None", co.co_filename)
Antoine Pitrou5d62a612012-07-08 13:48:46 +0200424 try:
425 self.assertEqual(normcase(inspect.getsourcefile(co)), fn)
426 finally:
427 del linecache.cache[co.co_filename]
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000428
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000429 def test_getfile(self):
430 self.assertEqual(inspect.getfile(mod.StupidGit), mod.__file__)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000431
Yury Selivanov2eed8b72014-01-27 13:24:56 -0500432 def test_getfile_class_without_module(self):
433 class CM(type):
434 @property
435 def __module__(cls):
436 raise AttributeError
437 class C(metaclass=CM):
438 pass
439 with self.assertRaises(TypeError):
440 inspect.getfile(C)
441
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000442 def test_getmodule_recursion(self):
Christian Heimes45f9af32007-11-27 21:50:00 +0000443 from types import ModuleType
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000444 name = '__inspect_dummy'
Christian Heimes45f9af32007-11-27 21:50:00 +0000445 m = sys.modules[name] = ModuleType(name)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000446 m.__file__ = "<string>" # hopefully not a real filename...
447 m.__loader__ = "dummy" # pretend the filename is understood by a loader
Georg Brandl7cae87c2006-09-06 06:51:57 +0000448 exec("def x(): pass", m.__dict__)
Neal Norwitz221085d2007-02-25 20:55:47 +0000449 self.assertEqual(inspect.getsourcefile(m.x.__code__), '<string>')
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000450 del sys.modules[name]
451 inspect.getmodule(compile('a=10','','single'))
452
Benjamin Peterson9620cc02011-06-11 15:53:11 -0500453 def test_proceed_with_fake_filename(self):
454 '''doctest monkeypatches linecache to enable inspection'''
455 fn, source = '<test>', 'def x(): pass\n'
456 getlines = linecache.getlines
457 def monkey(filename, module_globals=None):
458 if filename == fn:
Ezio Melottid8b509b2011-09-28 17:37:55 +0300459 return source.splitlines(keepends=True)
Benjamin Peterson9620cc02011-06-11 15:53:11 -0500460 else:
461 return getlines(filename, module_globals)
462 linecache.getlines = monkey
463 try:
464 ns = {}
465 exec(compile(source, fn, 'single'), ns)
466 inspect.getsource(ns["x"])
467 finally:
468 linecache.getlines = getlines
469
Antoine Pitroua8723a02015-04-15 00:41:29 +0200470 def test_getsource_on_code_object(self):
471 self.assertSourceEqual(mod.eggs.__code__, 12, 18)
472
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000473class TestDecorators(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000474 fodderModule = mod2
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000475
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000476 def test_wrapped_decorator(self):
Christian Heimes09aaa882008-02-23 15:01:06 +0000477 self.assertSourceEqual(mod2.wrapped, 14, 17)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000478
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000479 def test_replacing_decorator(self):
480 self.assertSourceEqual(mod2.gone, 9, 10)
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000481
Yury Selivanov081bbf62014-09-26 17:34:54 -0400482 def test_getsource_unwrap(self):
Antoine Pitroua8723a02015-04-15 00:41:29 +0200483 self.assertSourceEqual(mod2.real, 130, 132)
484
485 def test_decorator_with_lambda(self):
486 self.assertSourceEqual(mod2.func114, 113, 115)
Yury Selivanov081bbf62014-09-26 17:34:54 -0400487
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000488class TestOneliners(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000489 fodderModule = mod2
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000490 def test_oneline_lambda(self):
491 # Test inspect.getsource with a one-line lambda function.
492 self.assertSourceEqual(mod2.oll, 25, 25)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000493
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000494 def test_threeline_lambda(self):
495 # Test inspect.getsource with a three-line lambda function,
496 # where the second and third lines are _not_ indented.
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000497 self.assertSourceEqual(mod2.tll, 28, 30)
498
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000499 def test_twoline_indented_lambda(self):
500 # Test inspect.getsource with a two-line lambda function,
501 # where the second line _is_ indented.
502 self.assertSourceEqual(mod2.tlli, 33, 34)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000503
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000504 def test_onelinefunc(self):
505 # Test inspect.getsource with a regular one-line function.
506 self.assertSourceEqual(mod2.onelinefunc, 37, 37)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000507
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000508 def test_manyargs(self):
509 # Test inspect.getsource with a regular function where
510 # the arguments are on two lines and _not_ indented and
511 # the body on the second line with the last arguments.
512 self.assertSourceEqual(mod2.manyargs, 40, 41)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000513
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000514 def test_twolinefunc(self):
515 # Test inspect.getsource with a regular function where
516 # the body is on two lines, following the argument list and
517 # continued on the next line by a \\.
518 self.assertSourceEqual(mod2.twolinefunc, 44, 45)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000519
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000520 def test_lambda_in_list(self):
521 # Test inspect.getsource with a one-line lambda function
522 # defined in a list, indented.
523 self.assertSourceEqual(mod2.a[1], 49, 49)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000524
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000525 def test_anonymous(self):
526 # Test inspect.getsource with a lambda function defined
527 # as argument to another function.
528 self.assertSourceEqual(mod2.anonymous, 55, 55)
529
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000530class TestBuggyCases(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000531 fodderModule = mod2
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000532
533 def test_with_comment(self):
534 self.assertSourceEqual(mod2.with_comment, 58, 59)
535
536 def test_multiline_sig(self):
537 self.assertSourceEqual(mod2.multiline_sig[0], 63, 64)
538
Armin Rigodd5c0232005-09-25 11:45:45 +0000539 def test_nested_class(self):
540 self.assertSourceEqual(mod2.func69().func71, 71, 72)
541
542 def test_one_liner_followed_by_non_name(self):
543 self.assertSourceEqual(mod2.func77, 77, 77)
544
545 def test_one_liner_dedent_non_name(self):
546 self.assertSourceEqual(mod2.cls82.func83, 83, 83)
547
548 def test_with_comment_instead_of_docstring(self):
549 self.assertSourceEqual(mod2.func88, 88, 90)
550
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000551 def test_method_in_dynamic_class(self):
552 self.assertSourceEqual(mod2.method_in_dynamic_class, 95, 97)
553
R David Murray32562d72014-10-03 11:15:38 -0400554 # This should not skip for CPython, but might on a repackaged python where
555 # unicodedata is not an external module, or on pypy.
556 @unittest.skipIf(not hasattr(unicodedata, '__file__') or
557 unicodedata.__file__.endswith('.py'),
558 "unicodedata is not an external binary module")
R. David Murray74b89242009-05-13 17:33:03 +0000559 def test_findsource_binary(self):
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200560 self.assertRaises(OSError, inspect.getsource, unicodedata)
561 self.assertRaises(OSError, inspect.findsource, unicodedata)
R. David Murray74b89242009-05-13 17:33:03 +0000562
R. David Murraya1b37402010-06-17 02:04:29 +0000563 def test_findsource_code_in_linecache(self):
564 lines = ["x=1"]
565 co = compile(lines[0], "_dynamically_created_file", "exec")
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200566 self.assertRaises(OSError, inspect.findsource, co)
567 self.assertRaises(OSError, inspect.getsource, co)
R. David Murraya1b37402010-06-17 02:04:29 +0000568 linecache.cache[co.co_filename] = (1, None, lines, co.co_filename)
Antoine Pitrou5d62a612012-07-08 13:48:46 +0200569 try:
570 self.assertEqual(inspect.findsource(co), (lines,0))
571 self.assertEqual(inspect.getsource(co), lines[0])
572 finally:
573 del linecache.cache[co.co_filename]
R. David Murraya1b37402010-06-17 02:04:29 +0000574
Ezio Melotti1b145922013-03-30 05:17:24 +0200575 def test_findsource_without_filename(self):
576 for fname in ['', '<string>']:
577 co = compile('x=1', fname, "exec")
578 self.assertRaises(IOError, inspect.findsource, co)
579 self.assertRaises(IOError, inspect.getsource, co)
580
Antoine Pitroua8723a02015-04-15 00:41:29 +0200581 def test_getsource_on_method(self):
582 self.assertSourceEqual(mod2.ClassWithMethod.method, 118, 119)
583
Yury Selivanov4f4913b2015-07-23 17:10:00 +0300584 def test_nested_func(self):
585 self.assertSourceEqual(mod2.cls135.func136, 136, 139)
586
587
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000588class TestNoEOL(GetSourceBase):
Yury Selivanov6738b112015-05-16 10:10:21 -0400589 def setUp(self):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000590 self.tempdir = TESTFN + '_dir'
591 os.mkdir(self.tempdir)
592 with open(os.path.join(self.tempdir,
593 'inspect_fodder3%spy' % os.extsep), 'w') as f:
594 f.write("class X:\n pass # No EOL")
595 with DirsOnSysPath(self.tempdir):
596 import inspect_fodder3 as mod3
597 self.fodderModule = mod3
Yury Selivanov6738b112015-05-16 10:10:21 -0400598 super().setUp()
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000599
600 def tearDown(self):
601 shutil.rmtree(self.tempdir)
602
603 def test_class(self):
604 self.assertSourceEqual(self.fodderModule.X, 1, 2)
605
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100606
607class _BrokenDataDescriptor(object):
608 """
609 A broken data descriptor. See bug #1785.
610 """
611 def __get__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700612 raise AttributeError("broken data descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100613
614 def __set__(*args):
615 raise RuntimeError
616
617 def __getattr__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700618 raise AttributeError("broken data descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100619
620
621class _BrokenMethodDescriptor(object):
622 """
623 A broken method descriptor. See bug #1785.
624 """
625 def __get__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700626 raise AttributeError("broken method descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100627
628 def __getattr__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700629 raise AttributeError("broken method descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100630
631
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000632# Helper for testing classify_class_attrs.
Tim Peters13b49d32001-09-23 02:00:29 +0000633def attrs_wo_objs(cls):
634 return [t[:3] for t in inspect.classify_class_attrs(cls)]
635
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100636
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000637class TestClassesAndFunctions(unittest.TestCase):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000638 def test_newstyle_mro(self):
639 # The same w/ new-class MRO.
640 class A(object): pass
641 class B(A): pass
642 class C(A): pass
643 class D(B, C): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000644
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000645 expected = (D, B, C, A, object)
646 got = inspect.getmro(D)
647 self.assertEqual(expected, got)
Tim Peters13b49d32001-09-23 02:00:29 +0000648
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500649 def assertArgSpecEquals(self, routine, args_e, varargs_e=None,
650 varkw_e=None, defaults_e=None, formatted=None):
651 with self.assertWarns(DeprecationWarning):
652 args, varargs, varkw, defaults = inspect.getargspec(routine)
653 self.assertEqual(args, args_e)
654 self.assertEqual(varargs, varargs_e)
655 self.assertEqual(varkw, varkw_e)
656 self.assertEqual(defaults, defaults_e)
657 if formatted is not None:
658 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults),
659 formatted)
660
Christian Heimes3795b532007-11-08 13:48:53 +0000661 def assertFullArgSpecEquals(self, routine, args_e, varargs_e=None,
662 varkw_e=None, defaults_e=None,
663 kwonlyargs_e=[], kwonlydefaults_e=None,
664 ann_e={}, formatted=None):
665 args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \
666 inspect.getfullargspec(routine)
667 self.assertEqual(args, args_e)
668 self.assertEqual(varargs, varargs_e)
669 self.assertEqual(varkw, varkw_e)
670 self.assertEqual(defaults, defaults_e)
671 self.assertEqual(kwonlyargs, kwonlyargs_e)
672 self.assertEqual(kwonlydefaults, kwonlydefaults_e)
673 self.assertEqual(ann, ann_e)
674 if formatted is not None:
675 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults,
676 kwonlyargs, kwonlydefaults, ann),
677 formatted)
678
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500679 def test_getargspec(self):
680 self.assertArgSpecEquals(mod.eggs, ['x', 'y'], formatted='(x, y)')
681
682 self.assertArgSpecEquals(mod.spam,
683 ['a', 'b', 'c', 'd', 'e', 'f'],
684 'g', 'h', (3, 4, 5),
685 '(a, b, c, d=3, e=4, f=5, *g, **h)')
686
687 self.assertRaises(ValueError, self.assertArgSpecEquals,
688 mod2.keyworded, [])
689
690 self.assertRaises(ValueError, self.assertArgSpecEquals,
691 mod2.annotated, [])
692 self.assertRaises(ValueError, self.assertArgSpecEquals,
693 mod2.keyword_only_arg, [])
694
695
Christian Heimes3795b532007-11-08 13:48:53 +0000696 def test_getfullargspec(self):
697 self.assertFullArgSpecEquals(mod2.keyworded, [], varargs_e='arg1',
698 kwonlyargs_e=['arg2'],
699 kwonlydefaults_e={'arg2':1},
700 formatted='(*arg1, arg2=1)')
701
702 self.assertFullArgSpecEquals(mod2.annotated, ['arg1'],
Christian Heimesc9543e42007-11-28 08:28:28 +0000703 ann_e={'arg1' : list},
Christian Heimes3795b532007-11-08 13:48:53 +0000704 formatted='(arg1: list)')
Benjamin Peterson9953a8d2009-01-17 04:15:01 +0000705 self.assertFullArgSpecEquals(mod2.keyword_only_arg, [],
706 kwonlyargs_e=['arg'],
707 formatted='(*, arg)')
708
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500709 def test_argspec_api_ignores_wrapped(self):
Yury Selivanov57d240e2014-02-19 16:27:23 -0500710 # Issue 20684: low level introspection API must ignore __wrapped__
711 @functools.wraps(mod.spam)
712 def ham(x, y):
713 pass
714 # Basic check
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500715 self.assertArgSpecEquals(ham, ['x', 'y'], formatted='(x, y)')
Yury Selivanov57d240e2014-02-19 16:27:23 -0500716 self.assertFullArgSpecEquals(ham, ['x', 'y'], formatted='(x, y)')
717 self.assertFullArgSpecEquals(functools.partial(ham),
718 ['x', 'y'], formatted='(x, y)')
719 # Other variants
720 def check_method(f):
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500721 self.assertArgSpecEquals(f, ['self', 'x', 'y'],
722 formatted='(self, x, y)')
Yury Selivanov57d240e2014-02-19 16:27:23 -0500723 class C:
724 @functools.wraps(mod.spam)
725 def ham(self, x, y):
726 pass
727 pham = functools.partialmethod(ham)
728 @functools.wraps(mod.spam)
729 def __call__(self, x, y):
730 pass
731 check_method(C())
732 check_method(C.ham)
733 check_method(C().ham)
734 check_method(C.pham)
735 check_method(C().pham)
736
737 class C_new:
738 @functools.wraps(mod.spam)
739 def __new__(self, x, y):
740 pass
741 check_method(C_new)
742
743 class C_init:
744 @functools.wraps(mod.spam)
745 def __init__(self, x, y):
746 pass
747 check_method(C_init)
748
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500749 def test_getfullargspec_signature_attr(self):
750 def test():
751 pass
752 spam_param = inspect.Parameter('spam', inspect.Parameter.POSITIONAL_ONLY)
753 test.__signature__ = inspect.Signature(parameters=(spam_param,))
754
755 self.assertFullArgSpecEquals(test, args_e=['spam'], formatted='(spam)')
756
Yury Selivanov4cb93912014-01-29 11:54:12 -0500757 def test_getfullargspec_signature_annos(self):
758 def test(a:'spam') -> 'ham': pass
759 spec = inspect.getfullargspec(test)
760 self.assertEqual(test.__annotations__, spec.annotations)
761
762 def test(): pass
763 spec = inspect.getfullargspec(test)
764 self.assertEqual(test.__annotations__, spec.annotations)
765
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500766 @unittest.skipIf(MISSING_C_DOCSTRINGS,
767 "Signature information for builtins requires docstrings")
768 def test_getfullargspec_builtin_methods(self):
769 self.assertFullArgSpecEquals(_pickle.Pickler.dump,
770 args_e=['self', 'obj'], formatted='(self, obj)')
771
772 self.assertFullArgSpecEquals(_pickle.Pickler(io.BytesIO()).dump,
773 args_e=['self', 'obj'], formatted='(self, obj)')
774
Yury Selivanov8c185ee2014-02-21 01:32:42 -0500775 self.assertFullArgSpecEquals(
776 os.stat,
777 args_e=['path'],
778 kwonlyargs_e=['dir_fd', 'follow_symlinks'],
779 kwonlydefaults_e={'dir_fd': None, 'follow_symlinks': True},
780 formatted='(path, *, dir_fd=None, follow_symlinks=True)')
781
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200782 @cpython_only
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500783 @unittest.skipIf(MISSING_C_DOCSTRINGS,
784 "Signature information for builtins requires docstrings")
785 def test_getfullagrspec_builtin_func(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200786 import _testcapi
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500787 builtin = _testcapi.docstring_with_signature_with_defaults
788 spec = inspect.getfullargspec(builtin)
789 self.assertEqual(spec.defaults[0], 'avocado')
790
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200791 @cpython_only
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500792 @unittest.skipIf(MISSING_C_DOCSTRINGS,
793 "Signature information for builtins requires docstrings")
794 def test_getfullagrspec_builtin_func_no_signature(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200795 import _testcapi
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500796 builtin = _testcapi.docstring_no_signature
797 with self.assertRaises(TypeError):
798 inspect.getfullargspec(builtin)
Christian Heimes3795b532007-11-08 13:48:53 +0000799
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500800 def test_getargspec_method(self):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000801 class A(object):
802 def m(self):
803 pass
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500804 self.assertArgSpecEquals(A.m, ['self'])
Tim Peters13b49d32001-09-23 02:00:29 +0000805
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000806 def test_classify_newstyle(self):
807 class A(object):
Tim Peters13b49d32001-09-23 02:00:29 +0000808
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000809 def s(): pass
810 s = staticmethod(s)
Tim Peters13b49d32001-09-23 02:00:29 +0000811
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000812 def c(cls): pass
813 c = classmethod(c)
Tim Peters13b49d32001-09-23 02:00:29 +0000814
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000815 def getp(self): pass
816 p = property(getp)
Tim Peters13b49d32001-09-23 02:00:29 +0000817
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000818 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000819
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000820 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000821
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000822 datablob = '1'
Tim Peters13b49d32001-09-23 02:00:29 +0000823
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100824 dd = _BrokenDataDescriptor()
825 md = _BrokenMethodDescriptor()
826
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000827 attrs = attrs_wo_objs(A)
Yury Selivanov0860a0b2014-01-31 14:28:44 -0500828
829 self.assertIn(('__new__', 'method', object), attrs, 'missing __new__')
830 self.assertIn(('__init__', 'method', object), attrs, 'missing __init__')
831
Benjamin Peterson577473f2010-01-19 00:09:57 +0000832 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
833 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
834 self.assertIn(('p', 'property', A), attrs, 'missing property')
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000835 self.assertIn(('m', 'method', A), attrs,
836 'missing plain method: %r' % attrs)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000837 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
838 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100839 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
840 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000841
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000842 class B(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000843
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000844 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000845
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000846 attrs = attrs_wo_objs(B)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000847 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
848 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
849 self.assertIn(('p', 'property', A), attrs, 'missing property')
850 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
851 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
852 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100853 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
854 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000855
856
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000857 class C(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000858
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000859 def m(self): pass
860 def c(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000861
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000862 attrs = attrs_wo_objs(C)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000863 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
864 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
865 self.assertIn(('p', 'property', A), attrs, 'missing property')
866 self.assertIn(('m', 'method', C), attrs, 'missing plain method')
867 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
868 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100869 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
870 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000871
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000872 class D(B, C):
Tim Peters13b49d32001-09-23 02:00:29 +0000873
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000874 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000875
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000876 attrs = attrs_wo_objs(D)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000877 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
878 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
879 self.assertIn(('p', 'property', A), attrs, 'missing property')
880 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
881 self.assertIn(('m1', 'method', D), attrs, 'missing plain method')
882 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100883 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
884 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
885
886 def test_classify_builtin_types(self):
887 # Simple sanity check that all built-in types can have their
888 # attributes classified.
889 for name in dir(__builtins__):
890 builtin = getattr(__builtins__, name)
891 if isinstance(builtin, type):
892 inspect.classify_class_attrs(builtin)
893
Ethan Furman63c141c2013-10-18 00:27:39 -0700894 def test_classify_DynamicClassAttribute(self):
895 class Meta(type):
896 def __getattr__(self, name):
897 if name == 'ham':
898 return 'spam'
899 return super().__getattr__(name)
900 class VA(metaclass=Meta):
Ethan Furmane03ea372013-09-25 07:14:41 -0700901 @types.DynamicClassAttribute
902 def ham(self):
903 return 'eggs'
Ethan Furman63c141c2013-10-18 00:27:39 -0700904 should_find_dca = inspect.Attribute('ham', 'data', VA, VA.__dict__['ham'])
905 self.assertIn(should_find_dca, inspect.classify_class_attrs(VA))
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700906 should_find_ga = inspect.Attribute('ham', 'data', Meta, 'spam')
Ethan Furman63c141c2013-10-18 00:27:39 -0700907 self.assertIn(should_find_ga, inspect.classify_class_attrs(VA))
908
Yury Selivanovbf341fb2015-05-21 15:41:57 -0400909 def test_classify_overrides_bool(self):
910 class NoBool(object):
911 def __eq__(self, other):
912 return NoBool()
913
914 def __bool__(self):
915 raise NotImplementedError(
916 "This object does not specify a boolean value")
917
918 class HasNB(object):
919 dd = NoBool()
920
921 should_find_attr = inspect.Attribute('dd', 'data', HasNB, HasNB.dd)
922 self.assertIn(should_find_attr, inspect.classify_class_attrs(HasNB))
923
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700924 def test_classify_metaclass_class_attribute(self):
925 class Meta(type):
926 fish = 'slap'
927 def __dir__(self):
Serhiy Storchakaa60c2fe2015-03-12 21:56:08 +0200928 return ['__class__', '__module__', '__name__', 'fish']
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700929 class Class(metaclass=Meta):
930 pass
931 should_find = inspect.Attribute('fish', 'data', Meta, 'slap')
932 self.assertIn(should_find, inspect.classify_class_attrs(Class))
933
Ethan Furman63c141c2013-10-18 00:27:39 -0700934 def test_classify_VirtualAttribute(self):
935 class Meta(type):
936 def __dir__(cls):
937 return ['__class__', '__module__', '__name__', 'BOOM']
938 def __getattr__(self, name):
939 if name =='BOOM':
940 return 42
941 return super().__getattr(name)
942 class Class(metaclass=Meta):
943 pass
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700944 should_find = inspect.Attribute('BOOM', 'data', Meta, 42)
Ethan Furman63c141c2013-10-18 00:27:39 -0700945 self.assertIn(should_find, inspect.classify_class_attrs(Class))
946
947 def test_classify_VirtualAttribute_multi_classes(self):
948 class Meta1(type):
949 def __dir__(cls):
950 return ['__class__', '__module__', '__name__', 'one']
951 def __getattr__(self, name):
952 if name =='one':
953 return 1
954 return super().__getattr__(name)
955 class Meta2(type):
956 def __dir__(cls):
957 return ['__class__', '__module__', '__name__', 'two']
958 def __getattr__(self, name):
959 if name =='two':
960 return 2
961 return super().__getattr__(name)
962 class Meta3(Meta1, Meta2):
963 def __dir__(cls):
964 return list(sorted(set(['__class__', '__module__', '__name__', 'three'] +
965 Meta1.__dir__(cls) + Meta2.__dir__(cls))))
966 def __getattr__(self, name):
967 if name =='three':
968 return 3
969 return super().__getattr__(name)
970 class Class1(metaclass=Meta1):
971 pass
972 class Class2(Class1, metaclass=Meta3):
973 pass
974
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700975 should_find1 = inspect.Attribute('one', 'data', Meta1, 1)
976 should_find2 = inspect.Attribute('two', 'data', Meta2, 2)
977 should_find3 = inspect.Attribute('three', 'data', Meta3, 3)
Ethan Furman63c141c2013-10-18 00:27:39 -0700978 cca = inspect.classify_class_attrs(Class2)
979 for sf in (should_find1, should_find2, should_find3):
980 self.assertIn(sf, cca)
981
982 def test_classify_class_attrs_with_buggy_dir(self):
983 class M(type):
984 def __dir__(cls):
985 return ['__class__', '__name__', 'missing']
986 class C(metaclass=M):
987 pass
988 attrs = [a[0] for a in inspect.classify_class_attrs(C)]
989 self.assertNotIn('missing', attrs)
Ethan Furmane03ea372013-09-25 07:14:41 -0700990
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100991 def test_getmembers_descriptors(self):
992 class A(object):
993 dd = _BrokenDataDescriptor()
994 md = _BrokenMethodDescriptor()
995
996 def pred_wrapper(pred):
997 # A quick'n'dirty way to discard standard attributes of new-style
998 # classes.
999 class Empty(object):
1000 pass
1001 def wrapped(x):
1002 if '__name__' in dir(x) and hasattr(Empty, x.__name__):
1003 return False
1004 return pred(x)
1005 return wrapped
1006
1007 ismethoddescriptor = pred_wrapper(inspect.ismethoddescriptor)
1008 isdatadescriptor = pred_wrapper(inspect.isdatadescriptor)
1009
1010 self.assertEqual(inspect.getmembers(A, ismethoddescriptor),
1011 [('md', A.__dict__['md'])])
1012 self.assertEqual(inspect.getmembers(A, isdatadescriptor),
1013 [('dd', A.__dict__['dd'])])
1014
1015 class B(A):
1016 pass
1017
1018 self.assertEqual(inspect.getmembers(B, ismethoddescriptor),
1019 [('md', A.__dict__['md'])])
1020 self.assertEqual(inspect.getmembers(B, isdatadescriptor),
1021 [('dd', A.__dict__['dd'])])
1022
Antoine Pitrou0c603812012-01-18 17:40:18 +01001023 def test_getmembers_method(self):
1024 class B:
1025 def f(self):
1026 pass
1027
1028 self.assertIn(('f', B.f), inspect.getmembers(B))
1029 self.assertNotIn(('f', B.f), inspect.getmembers(B, inspect.ismethod))
1030 b = B()
1031 self.assertIn(('f', b.f), inspect.getmembers(b))
1032 self.assertIn(('f', b.f), inspect.getmembers(b, inspect.ismethod))
1033
Ethan Furmane03ea372013-09-25 07:14:41 -07001034 def test_getmembers_VirtualAttribute(self):
Ethan Furman63c141c2013-10-18 00:27:39 -07001035 class M(type):
1036 def __getattr__(cls, name):
1037 if name == 'eggs':
1038 return 'scrambled'
1039 return super().__getattr__(name)
1040 class A(metaclass=M):
Ethan Furmane03ea372013-09-25 07:14:41 -07001041 @types.DynamicClassAttribute
1042 def eggs(self):
1043 return 'spam'
Ethan Furman63c141c2013-10-18 00:27:39 -07001044 self.assertIn(('eggs', 'scrambled'), inspect.getmembers(A))
1045 self.assertIn(('eggs', 'spam'), inspect.getmembers(A()))
1046
1047 def test_getmembers_with_buggy_dir(self):
1048 class M(type):
1049 def __dir__(cls):
1050 return ['__class__', '__name__', 'missing']
1051 class C(metaclass=M):
1052 pass
1053 attrs = [a[0] for a in inspect.getmembers(C)]
1054 self.assertNotIn('missing', attrs)
Ethan Furmane03ea372013-09-25 07:14:41 -07001055
Jeremy Hyltonc4bf5ed2003-06-27 18:43:12 +00001056
Nick Coghlan2f92e542012-06-23 19:39:55 +10001057_global_ref = object()
1058class TestGetClosureVars(unittest.TestCase):
1059
1060 def test_name_resolution(self):
1061 # Basic test of the 4 different resolution mechanisms
1062 def f(nonlocal_ref):
1063 def g(local_ref):
1064 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
1065 return g
1066 _arg = object()
1067 nonlocal_vars = {"nonlocal_ref": _arg}
1068 global_vars = {"_global_ref": _global_ref}
1069 builtin_vars = {"print": print}
1070 unbound_names = {"unbound_ref"}
1071 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
1072 builtin_vars, unbound_names)
1073 self.assertEqual(inspect.getclosurevars(f(_arg)), expected)
1074
1075 def test_generator_closure(self):
1076 def f(nonlocal_ref):
1077 def g(local_ref):
1078 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
1079 yield
1080 return g
1081 _arg = object()
1082 nonlocal_vars = {"nonlocal_ref": _arg}
1083 global_vars = {"_global_ref": _global_ref}
1084 builtin_vars = {"print": print}
1085 unbound_names = {"unbound_ref"}
1086 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
1087 builtin_vars, unbound_names)
1088 self.assertEqual(inspect.getclosurevars(f(_arg)), expected)
1089
1090 def test_method_closure(self):
1091 class C:
1092 def f(self, nonlocal_ref):
1093 def g(local_ref):
1094 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
1095 return g
1096 _arg = object()
1097 nonlocal_vars = {"nonlocal_ref": _arg}
1098 global_vars = {"_global_ref": _global_ref}
1099 builtin_vars = {"print": print}
1100 unbound_names = {"unbound_ref"}
1101 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
1102 builtin_vars, unbound_names)
1103 self.assertEqual(inspect.getclosurevars(C().f(_arg)), expected)
1104
1105 def test_nonlocal_vars(self):
1106 # More complex tests of nonlocal resolution
1107 def _nonlocal_vars(f):
1108 return inspect.getclosurevars(f).nonlocals
1109
1110 def make_adder(x):
1111 def add(y):
1112 return x + y
1113 return add
1114
1115 def curry(func, arg1):
1116 return lambda arg2: func(arg1, arg2)
1117
1118 def less_than(a, b):
1119 return a < b
1120
1121 # The infamous Y combinator.
1122 def Y(le):
1123 def g(f):
1124 return le(lambda x: f(f)(x))
1125 Y.g_ref = g
1126 return g(g)
1127
1128 def check_y_combinator(func):
1129 self.assertEqual(_nonlocal_vars(func), {'f': Y.g_ref})
1130
1131 inc = make_adder(1)
1132 add_two = make_adder(2)
1133 greater_than_five = curry(less_than, 5)
1134
1135 self.assertEqual(_nonlocal_vars(inc), {'x': 1})
1136 self.assertEqual(_nonlocal_vars(add_two), {'x': 2})
1137 self.assertEqual(_nonlocal_vars(greater_than_five),
1138 {'arg1': 5, 'func': less_than})
1139 self.assertEqual(_nonlocal_vars((lambda x: lambda y: x + y)(3)),
1140 {'x': 3})
1141 Y(check_y_combinator)
1142
1143 def test_getclosurevars_empty(self):
1144 def foo(): pass
1145 _empty = inspect.ClosureVars({}, {}, {}, set())
1146 self.assertEqual(inspect.getclosurevars(lambda: True), _empty)
1147 self.assertEqual(inspect.getclosurevars(foo), _empty)
1148
1149 def test_getclosurevars_error(self):
1150 class T: pass
1151 self.assertRaises(TypeError, inspect.getclosurevars, 1)
1152 self.assertRaises(TypeError, inspect.getclosurevars, list)
1153 self.assertRaises(TypeError, inspect.getclosurevars, {})
1154
Nick Coghlan6c6e2542012-06-23 20:07:39 +10001155 def _private_globals(self):
1156 code = """def f(): print(path)"""
1157 ns = {}
1158 exec(code, ns)
1159 return ns["f"], ns
1160
1161 def test_builtins_fallback(self):
1162 f, ns = self._private_globals()
1163 ns.pop("__builtins__", None)
1164 expected = inspect.ClosureVars({}, {}, {"print":print}, {"path"})
1165 self.assertEqual(inspect.getclosurevars(f), expected)
1166
1167 def test_builtins_as_dict(self):
1168 f, ns = self._private_globals()
1169 ns["__builtins__"] = {"path":1}
1170 expected = inspect.ClosureVars({}, {}, {"path":1}, {"print"})
1171 self.assertEqual(inspect.getclosurevars(f), expected)
1172
1173 def test_builtins_as_module(self):
1174 f, ns = self._private_globals()
1175 ns["__builtins__"] = os
1176 expected = inspect.ClosureVars({}, {}, {"path":os.path}, {"print"})
1177 self.assertEqual(inspect.getclosurevars(f), expected)
1178
Nick Coghlan2f92e542012-06-23 19:39:55 +10001179
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001180class TestGetcallargsFunctions(unittest.TestCase):
1181
1182 def assertEqualCallArgs(self, func, call_params_string, locs=None):
1183 locs = dict(locs or {}, func=func)
1184 r1 = eval('func(%s)' % call_params_string, None, locs)
1185 r2 = eval('inspect.getcallargs(func, %s)' % call_params_string, None,
1186 locs)
1187 self.assertEqual(r1, r2)
1188
1189 def assertEqualException(self, func, call_param_string, locs=None):
1190 locs = dict(locs or {}, func=func)
1191 try:
1192 eval('func(%s)' % call_param_string, None, locs)
1193 except Exception as e:
1194 ex1 = e
1195 else:
1196 self.fail('Exception not raised')
1197 try:
1198 eval('inspect.getcallargs(func, %s)' % call_param_string, None,
1199 locs)
1200 except Exception as e:
1201 ex2 = e
1202 else:
1203 self.fail('Exception not raised')
1204 self.assertIs(type(ex1), type(ex2))
1205 self.assertEqual(str(ex1), str(ex2))
1206 del ex1, ex2
1207
1208 def makeCallable(self, signature):
1209 """Create a function that returns its locals()"""
1210 code = "lambda %s: locals()"
1211 return eval(code % signature)
1212
1213 def test_plain(self):
1214 f = self.makeCallable('a, b=1')
1215 self.assertEqualCallArgs(f, '2')
1216 self.assertEqualCallArgs(f, '2, 3')
1217 self.assertEqualCallArgs(f, 'a=2')
1218 self.assertEqualCallArgs(f, 'b=3, a=2')
1219 self.assertEqualCallArgs(f, '2, b=3')
1220 # expand *iterable / **mapping
1221 self.assertEqualCallArgs(f, '*(2,)')
1222 self.assertEqualCallArgs(f, '*[2]')
1223 self.assertEqualCallArgs(f, '*(2, 3)')
1224 self.assertEqualCallArgs(f, '*[2, 3]')
1225 self.assertEqualCallArgs(f, '**{"a":2}')
1226 self.assertEqualCallArgs(f, 'b=3, **{"a":2}')
1227 self.assertEqualCallArgs(f, '2, **{"b":3}')
1228 self.assertEqualCallArgs(f, '**{"b":3, "a":2}')
1229 # expand UserList / UserDict
1230 self.assertEqualCallArgs(f, '*collections.UserList([2])')
1231 self.assertEqualCallArgs(f, '*collections.UserList([2, 3])')
1232 self.assertEqualCallArgs(f, '**collections.UserDict(a=2)')
1233 self.assertEqualCallArgs(f, '2, **collections.UserDict(b=3)')
1234 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3)')
1235
1236 def test_varargs(self):
1237 f = self.makeCallable('a, b=1, *c')
1238 self.assertEqualCallArgs(f, '2')
1239 self.assertEqualCallArgs(f, '2, 3')
1240 self.assertEqualCallArgs(f, '2, 3, 4')
1241 self.assertEqualCallArgs(f, '*(2,3,4)')
1242 self.assertEqualCallArgs(f, '2, *[3,4]')
1243 self.assertEqualCallArgs(f, '2, 3, *collections.UserList([4])')
1244
1245 def test_varkw(self):
1246 f = self.makeCallable('a, b=1, **c')
1247 self.assertEqualCallArgs(f, 'a=2')
1248 self.assertEqualCallArgs(f, '2, b=3, c=4')
1249 self.assertEqualCallArgs(f, 'b=3, a=2, c=4')
1250 self.assertEqualCallArgs(f, 'c=4, **{"a":2, "b":3}')
1251 self.assertEqualCallArgs(f, '2, c=4, **{"b":3}')
1252 self.assertEqualCallArgs(f, 'b=2, **{"a":3, "c":4}')
1253 self.assertEqualCallArgs(f, '**collections.UserDict(a=2, b=3, c=4)')
1254 self.assertEqualCallArgs(f, '2, c=4, **collections.UserDict(b=3)')
1255 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3, c=4)')
1256
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001257 def test_varkw_only(self):
1258 # issue11256:
1259 f = self.makeCallable('**c')
1260 self.assertEqualCallArgs(f, '')
1261 self.assertEqualCallArgs(f, 'a=1')
1262 self.assertEqualCallArgs(f, 'a=1, b=2')
1263 self.assertEqualCallArgs(f, 'c=3, **{"a": 1, "b": 2}')
1264 self.assertEqualCallArgs(f, '**collections.UserDict(a=1, b=2)')
1265 self.assertEqualCallArgs(f, 'c=3, **collections.UserDict(a=1, b=2)')
1266
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001267 def test_keyword_only(self):
1268 f = self.makeCallable('a=3, *, c, d=2')
1269 self.assertEqualCallArgs(f, 'c=3')
1270 self.assertEqualCallArgs(f, 'c=3, a=3')
1271 self.assertEqualCallArgs(f, 'a=2, c=4')
1272 self.assertEqualCallArgs(f, '4, c=4')
1273 self.assertEqualException(f, '')
1274 self.assertEqualException(f, '3')
1275 self.assertEqualException(f, 'a=3')
1276 self.assertEqualException(f, 'd=4')
1277
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001278 f = self.makeCallable('*, c, d=2')
1279 self.assertEqualCallArgs(f, 'c=3')
1280 self.assertEqualCallArgs(f, 'c=3, d=4')
1281 self.assertEqualCallArgs(f, 'd=4, c=3')
1282
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001283 def test_multiple_features(self):
1284 f = self.makeCallable('a, b=2, *f, **g')
1285 self.assertEqualCallArgs(f, '2, 3, 7')
1286 self.assertEqualCallArgs(f, '2, 3, x=8')
1287 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
1288 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9')
1289 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9')
1290 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
1291 '[2, 3, (4,[5,6])]), **{"y":9, "z":10}')
1292 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
1293 '(4,[5,6])]), **collections.UserDict('
1294 'y=9, z=10)')
1295
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001296 f = self.makeCallable('a, b=2, *f, x, y=99, **g')
1297 self.assertEqualCallArgs(f, '2, 3, x=8')
1298 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
1299 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9, z=10')
1300 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9, z=10')
1301 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
1302 '[2, 3, (4,[5,6])]), q=0, **{"y":9, "z":10}')
1303 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
1304 '(4,[5,6])]), q=0, **collections.UserDict('
1305 'y=9, z=10)')
1306
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001307 def test_errors(self):
1308 f0 = self.makeCallable('')
1309 f1 = self.makeCallable('a, b')
1310 f2 = self.makeCallable('a, b=1')
1311 # f0 takes no arguments
1312 self.assertEqualException(f0, '1')
1313 self.assertEqualException(f0, 'x=1')
1314 self.assertEqualException(f0, '1,x=1')
1315 # f1 takes exactly 2 arguments
1316 self.assertEqualException(f1, '')
1317 self.assertEqualException(f1, '1')
1318 self.assertEqualException(f1, 'a=2')
1319 self.assertEqualException(f1, 'b=3')
1320 # f2 takes at least 1 argument
1321 self.assertEqualException(f2, '')
1322 self.assertEqualException(f2, 'b=3')
1323 for f in f1, f2:
1324 # f1/f2 takes exactly/at most 2 arguments
1325 self.assertEqualException(f, '2, 3, 4')
1326 self.assertEqualException(f, '1, 2, 3, a=1')
1327 self.assertEqualException(f, '2, 3, 4, c=5')
Georg Brandl178e5ea2012-02-21 00:32:36 +01001328 # XXX: success of this one depends on dict order
1329 ## self.assertEqualException(f, '2, 3, 4, a=1, c=5')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001330 # f got an unexpected keyword argument
1331 self.assertEqualException(f, 'c=2')
1332 self.assertEqualException(f, '2, c=3')
1333 self.assertEqualException(f, '2, 3, c=4')
1334 self.assertEqualException(f, '2, c=4, b=3')
1335 self.assertEqualException(f, '**{u"\u03c0\u03b9": 4}')
1336 # f got multiple values for keyword argument
1337 self.assertEqualException(f, '1, a=2')
1338 self.assertEqualException(f, '1, **{"a":2}')
1339 self.assertEqualException(f, '1, 2, b=3')
1340 # XXX: Python inconsistency
1341 # - for functions and bound methods: unexpected keyword 'c'
1342 # - for unbound methods: multiple values for keyword 'a'
1343 #self.assertEqualException(f, '1, c=3, a=2')
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001344 # issue11256:
1345 f3 = self.makeCallable('**c')
1346 self.assertEqualException(f3, '1, 2')
1347 self.assertEqualException(f3, '1, 2, a=1, b=2')
1348 f4 = self.makeCallable('*, a, b=0')
1349 self.assertEqualException(f3, '1, 2')
1350 self.assertEqualException(f3, '1, 2, a=1, b=2')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001351
Yury Selivanov875df202014-03-27 18:23:03 -04001352 # issue #20816: getcallargs() fails to iterate over non-existent
1353 # kwonlydefaults and raises a wrong TypeError
1354 def f5(*, a): pass
1355 with self.assertRaisesRegex(TypeError,
1356 'missing 1 required keyword-only'):
1357 inspect.getcallargs(f5)
1358
1359
Yury Selivanovdccfa132014-03-27 18:42:52 -04001360 # issue20817:
1361 def f6(a, b, c):
1362 pass
1363 with self.assertRaisesRegex(TypeError, "'a', 'b' and 'c'"):
1364 inspect.getcallargs(f6)
1365
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001366class TestGetcallargsMethods(TestGetcallargsFunctions):
1367
1368 def setUp(self):
1369 class Foo(object):
1370 pass
1371 self.cls = Foo
1372 self.inst = Foo()
1373
1374 def makeCallable(self, signature):
1375 assert 'self' not in signature
1376 mk = super(TestGetcallargsMethods, self).makeCallable
1377 self.cls.method = mk('self, ' + signature)
1378 return self.inst.method
1379
1380class TestGetcallargsUnboundMethods(TestGetcallargsMethods):
1381
1382 def makeCallable(self, signature):
1383 super(TestGetcallargsUnboundMethods, self).makeCallable(signature)
1384 return self.cls.method
1385
1386 def assertEqualCallArgs(self, func, call_params_string, locs=None):
1387 return super(TestGetcallargsUnboundMethods, self).assertEqualCallArgs(
1388 *self._getAssertEqualParams(func, call_params_string, locs))
1389
1390 def assertEqualException(self, func, call_params_string, locs=None):
1391 return super(TestGetcallargsUnboundMethods, self).assertEqualException(
1392 *self._getAssertEqualParams(func, call_params_string, locs))
1393
1394 def _getAssertEqualParams(self, func, call_params_string, locs=None):
1395 assert 'inst' not in call_params_string
1396 locs = dict(locs or {}, inst=self.inst)
1397 return (func, 'inst,' + call_params_string, locs)
1398
Michael Foord95fc51d2010-11-20 15:07:30 +00001399
1400class TestGetattrStatic(unittest.TestCase):
1401
1402 def test_basic(self):
1403 class Thing(object):
1404 x = object()
1405
1406 thing = Thing()
1407 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1408 self.assertEqual(inspect.getattr_static(thing, 'x', None), Thing.x)
1409 with self.assertRaises(AttributeError):
1410 inspect.getattr_static(thing, 'y')
1411
1412 self.assertEqual(inspect.getattr_static(thing, 'y', 3), 3)
1413
1414 def test_inherited(self):
1415 class Thing(object):
1416 x = object()
1417 class OtherThing(Thing):
1418 pass
1419
1420 something = OtherThing()
1421 self.assertEqual(inspect.getattr_static(something, 'x'), Thing.x)
1422
1423 def test_instance_attr(self):
1424 class Thing(object):
1425 x = 2
1426 def __init__(self, x):
1427 self.x = x
1428 thing = Thing(3)
1429 self.assertEqual(inspect.getattr_static(thing, 'x'), 3)
1430 del thing.x
1431 self.assertEqual(inspect.getattr_static(thing, 'x'), 2)
1432
1433 def test_property(self):
1434 class Thing(object):
1435 @property
1436 def x(self):
1437 raise AttributeError("I'm pretending not to exist")
1438 thing = Thing()
1439 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1440
Ezio Melotti75cbd732011-04-28 00:59:29 +03001441 def test_descriptor_raises_AttributeError(self):
Michael Foord95fc51d2010-11-20 15:07:30 +00001442 class descriptor(object):
1443 def __get__(*_):
1444 raise AttributeError("I'm pretending not to exist")
1445 desc = descriptor()
1446 class Thing(object):
1447 x = desc
1448 thing = Thing()
1449 self.assertEqual(inspect.getattr_static(thing, 'x'), desc)
1450
1451 def test_classAttribute(self):
1452 class Thing(object):
1453 x = object()
1454
1455 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.x)
1456
Ethan Furmane03ea372013-09-25 07:14:41 -07001457 def test_classVirtualAttribute(self):
1458 class Thing(object):
1459 @types.DynamicClassAttribute
1460 def x(self):
1461 return self._x
1462 _x = object()
1463
1464 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.__dict__['x'])
1465
Michael Foord95fc51d2010-11-20 15:07:30 +00001466 def test_inherited_classattribute(self):
1467 class Thing(object):
1468 x = object()
1469 class OtherThing(Thing):
1470 pass
1471
1472 self.assertEqual(inspect.getattr_static(OtherThing, 'x'), Thing.x)
1473
1474 def test_slots(self):
1475 class Thing(object):
1476 y = 'bar'
1477 __slots__ = ['x']
1478 def __init__(self):
1479 self.x = 'foo'
1480 thing = Thing()
1481 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1482 self.assertEqual(inspect.getattr_static(thing, 'y'), 'bar')
1483
1484 del thing.x
1485 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1486
1487 def test_metaclass(self):
1488 class meta(type):
1489 attr = 'foo'
1490 class Thing(object, metaclass=meta):
1491 pass
1492 self.assertEqual(inspect.getattr_static(Thing, 'attr'), 'foo')
1493
1494 class sub(meta):
1495 pass
1496 class OtherThing(object, metaclass=sub):
1497 x = 3
1498 self.assertEqual(inspect.getattr_static(OtherThing, 'attr'), 'foo')
1499
1500 class OtherOtherThing(OtherThing):
1501 pass
1502 # this test is odd, but it was added as it exposed a bug
1503 self.assertEqual(inspect.getattr_static(OtherOtherThing, 'x'), 3)
1504
1505 def test_no_dict_no_slots(self):
1506 self.assertEqual(inspect.getattr_static(1, 'foo', None), None)
1507 self.assertNotEqual(inspect.getattr_static('foo', 'lower'), None)
1508
1509 def test_no_dict_no_slots_instance_member(self):
1510 # returns descriptor
1511 with open(__file__) as handle:
1512 self.assertEqual(inspect.getattr_static(handle, 'name'), type(handle).name)
1513
1514 def test_inherited_slots(self):
1515 # returns descriptor
1516 class Thing(object):
1517 __slots__ = ['x']
1518 def __init__(self):
1519 self.x = 'foo'
1520
1521 class OtherThing(Thing):
1522 pass
1523 # it would be nice if this worked...
1524 # we get the descriptor instead of the instance attribute
1525 self.assertEqual(inspect.getattr_static(OtherThing(), 'x'), Thing.x)
1526
1527 def test_descriptor(self):
1528 class descriptor(object):
1529 def __get__(self, instance, owner):
1530 return 3
1531 class Foo(object):
1532 d = descriptor()
1533
1534 foo = Foo()
1535
1536 # for a non data descriptor we return the instance attribute
1537 foo.__dict__['d'] = 1
1538 self.assertEqual(inspect.getattr_static(foo, 'd'), 1)
1539
1540 # if the descriptor is a data-desciptor we should return the
1541 # descriptor
1542 descriptor.__set__ = lambda s, i, v: None
1543 self.assertEqual(inspect.getattr_static(foo, 'd'), Foo.__dict__['d'])
1544
1545
1546 def test_metaclass_with_descriptor(self):
1547 class descriptor(object):
1548 def __get__(self, instance, owner):
1549 return 3
1550 class meta(type):
1551 d = descriptor()
1552 class Thing(object, metaclass=meta):
1553 pass
1554 self.assertEqual(inspect.getattr_static(Thing, 'd'), meta.__dict__['d'])
1555
1556
Michael Foordcc7ebb82010-11-20 16:20:16 +00001557 def test_class_as_property(self):
1558 class Base(object):
1559 foo = 3
1560
1561 class Something(Base):
Michael Foord35184ed2010-11-20 16:58:30 +00001562 executed = False
Michael Foordcc7ebb82010-11-20 16:20:16 +00001563 @property
1564 def __class__(self):
Michael Foord35184ed2010-11-20 16:58:30 +00001565 self.executed = True
Michael Foordcc7ebb82010-11-20 16:20:16 +00001566 return object
1567
Michael Foord35184ed2010-11-20 16:58:30 +00001568 instance = Something()
1569 self.assertEqual(inspect.getattr_static(instance, 'foo'), 3)
1570 self.assertFalse(instance.executed)
Michael Foordcc7ebb82010-11-20 16:20:16 +00001571 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1572
Michael Foorde5162652010-11-20 16:40:44 +00001573 def test_mro_as_property(self):
1574 class Meta(type):
1575 @property
1576 def __mro__(self):
1577 return (object,)
1578
1579 class Base(object):
1580 foo = 3
1581
1582 class Something(Base, metaclass=Meta):
1583 pass
1584
1585 self.assertEqual(inspect.getattr_static(Something(), 'foo'), 3)
1586 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1587
Michael Foorddcebe0f2011-03-15 19:20:44 -04001588 def test_dict_as_property(self):
1589 test = self
1590 test.called = False
1591
1592 class Foo(dict):
1593 a = 3
1594 @property
1595 def __dict__(self):
1596 test.called = True
1597 return {}
1598
1599 foo = Foo()
1600 foo.a = 4
1601 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1602 self.assertFalse(test.called)
1603
1604 def test_custom_object_dict(self):
1605 test = self
1606 test.called = False
1607
1608 class Custom(dict):
1609 def get(self, key, default=None):
1610 test.called = True
1611 super().get(key, default)
1612
1613 class Foo(object):
1614 a = 3
1615 foo = Foo()
1616 foo.__dict__ = Custom()
1617 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1618 self.assertFalse(test.called)
1619
1620 def test_metaclass_dict_as_property(self):
1621 class Meta(type):
1622 @property
1623 def __dict__(self):
1624 self.executed = True
1625
1626 class Thing(metaclass=Meta):
1627 executed = False
1628
1629 def __init__(self):
1630 self.spam = 42
1631
1632 instance = Thing()
1633 self.assertEqual(inspect.getattr_static(instance, "spam"), 42)
1634 self.assertFalse(Thing.executed)
Michael Foorde5162652010-11-20 16:40:44 +00001635
Michael Foorda51623b2011-12-18 22:01:40 +00001636 def test_module(self):
1637 sentinel = object()
1638 self.assertIsNot(inspect.getattr_static(sys, "version", sentinel),
1639 sentinel)
1640
Michael Foord3ba95f82011-12-22 01:13:37 +00001641 def test_metaclass_with_metaclass_with_dict_as_property(self):
1642 class MetaMeta(type):
1643 @property
1644 def __dict__(self):
1645 self.executed = True
1646 return dict(spam=42)
1647
1648 class Meta(type, metaclass=MetaMeta):
1649 executed = False
1650
1651 class Thing(metaclass=Meta):
1652 pass
1653
1654 with self.assertRaises(AttributeError):
1655 inspect.getattr_static(Thing, "spam")
1656 self.assertFalse(Thing.executed)
1657
Nick Coghlane0f04652010-11-21 03:44:04 +00001658class TestGetGeneratorState(unittest.TestCase):
1659
1660 def setUp(self):
1661 def number_generator():
1662 for number in range(5):
1663 yield number
1664 self.generator = number_generator()
1665
1666 def _generatorstate(self):
1667 return inspect.getgeneratorstate(self.generator)
1668
1669 def test_created(self):
1670 self.assertEqual(self._generatorstate(), inspect.GEN_CREATED)
1671
1672 def test_suspended(self):
1673 next(self.generator)
1674 self.assertEqual(self._generatorstate(), inspect.GEN_SUSPENDED)
1675
1676 def test_closed_after_exhaustion(self):
1677 for i in self.generator:
1678 pass
1679 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1680
1681 def test_closed_after_immediate_exception(self):
1682 with self.assertRaises(RuntimeError):
1683 self.generator.throw(RuntimeError)
1684 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1685
1686 def test_running(self):
1687 # As mentioned on issue #10220, checking for the RUNNING state only
1688 # makes sense inside the generator itself.
1689 # The following generator checks for this by using the closure's
1690 # reference to self and the generator state checking helper method
1691 def running_check_generator():
1692 for number in range(5):
1693 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1694 yield number
1695 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1696 self.generator = running_check_generator()
1697 # Running up to the first yield
1698 next(self.generator)
1699 # Running after the first yield
1700 next(self.generator)
1701
Nick Coghlan7921b9f2010-11-30 06:36:04 +00001702 def test_easy_debugging(self):
1703 # repr() and str() of a generator state should contain the state name
1704 names = 'GEN_CREATED GEN_RUNNING GEN_SUSPENDED GEN_CLOSED'.split()
1705 for name in names:
1706 state = getattr(inspect, name)
1707 self.assertIn(name, repr(state))
1708 self.assertIn(name, str(state))
1709
Nick Coghlan04e2e3f2012-06-23 19:52:05 +10001710 def test_getgeneratorlocals(self):
1711 def each(lst, a=None):
1712 b=(1, 2, 3)
1713 for v in lst:
1714 if v == 3:
1715 c = 12
1716 yield v
1717
1718 numbers = each([1, 2, 3])
1719 self.assertEqual(inspect.getgeneratorlocals(numbers),
1720 {'a': None, 'lst': [1, 2, 3]})
1721 next(numbers)
1722 self.assertEqual(inspect.getgeneratorlocals(numbers),
1723 {'a': None, 'lst': [1, 2, 3], 'v': 1,
1724 'b': (1, 2, 3)})
1725 next(numbers)
1726 self.assertEqual(inspect.getgeneratorlocals(numbers),
1727 {'a': None, 'lst': [1, 2, 3], 'v': 2,
1728 'b': (1, 2, 3)})
1729 next(numbers)
1730 self.assertEqual(inspect.getgeneratorlocals(numbers),
1731 {'a': None, 'lst': [1, 2, 3], 'v': 3,
1732 'b': (1, 2, 3), 'c': 12})
1733 try:
1734 next(numbers)
1735 except StopIteration:
1736 pass
1737 self.assertEqual(inspect.getgeneratorlocals(numbers), {})
1738
1739 def test_getgeneratorlocals_empty(self):
1740 def yield_one():
1741 yield 1
1742 one = yield_one()
1743 self.assertEqual(inspect.getgeneratorlocals(one), {})
1744 try:
1745 next(one)
1746 except StopIteration:
1747 pass
1748 self.assertEqual(inspect.getgeneratorlocals(one), {})
1749
1750 def test_getgeneratorlocals_error(self):
1751 self.assertRaises(TypeError, inspect.getgeneratorlocals, 1)
1752 self.assertRaises(TypeError, inspect.getgeneratorlocals, lambda x: True)
1753 self.assertRaises(TypeError, inspect.getgeneratorlocals, set)
1754 self.assertRaises(TypeError, inspect.getgeneratorlocals, (2,3))
1755
Nick Coghlane0f04652010-11-21 03:44:04 +00001756
Yury Selivanov5376ba92015-06-22 12:19:30 -04001757class TestGetCoroutineState(unittest.TestCase):
1758
1759 def setUp(self):
1760 @types.coroutine
1761 def number_coroutine():
1762 for number in range(5):
1763 yield number
1764 async def coroutine():
1765 await number_coroutine()
1766 self.coroutine = coroutine()
1767
1768 def tearDown(self):
1769 self.coroutine.close()
1770
1771 def _coroutinestate(self):
1772 return inspect.getcoroutinestate(self.coroutine)
1773
1774 def test_created(self):
1775 self.assertEqual(self._coroutinestate(), inspect.CORO_CREATED)
1776
1777 def test_suspended(self):
1778 self.coroutine.send(None)
1779 self.assertEqual(self._coroutinestate(), inspect.CORO_SUSPENDED)
1780
1781 def test_closed_after_exhaustion(self):
1782 while True:
1783 try:
1784 self.coroutine.send(None)
1785 except StopIteration:
1786 break
1787
1788 self.assertEqual(self._coroutinestate(), inspect.CORO_CLOSED)
1789
1790 def test_closed_after_immediate_exception(self):
1791 with self.assertRaises(RuntimeError):
1792 self.coroutine.throw(RuntimeError)
1793 self.assertEqual(self._coroutinestate(), inspect.CORO_CLOSED)
1794
1795 def test_easy_debugging(self):
1796 # repr() and str() of a coroutine state should contain the state name
1797 names = 'CORO_CREATED CORO_RUNNING CORO_SUSPENDED CORO_CLOSED'.split()
1798 for name in names:
1799 state = getattr(inspect, name)
1800 self.assertIn(name, repr(state))
1801 self.assertIn(name, str(state))
1802
1803 def test_getcoroutinelocals(self):
1804 @types.coroutine
1805 def gencoro():
1806 yield
1807
1808 gencoro = gencoro()
1809 async def func(a=None):
1810 b = 'spam'
1811 await gencoro
1812
1813 coro = func()
1814 self.assertEqual(inspect.getcoroutinelocals(coro),
1815 {'a': None, 'gencoro': gencoro})
1816 coro.send(None)
1817 self.assertEqual(inspect.getcoroutinelocals(coro),
1818 {'a': None, 'gencoro': gencoro, 'b': 'spam'})
1819
1820
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001821class MySignature(inspect.Signature):
1822 # Top-level to make it picklable;
1823 # used in test_signature_object_pickle
1824 pass
1825
1826class MyParameter(inspect.Parameter):
1827 # Top-level to make it picklable;
1828 # used in test_signature_object_pickle
1829 pass
1830
Nick Coghlanf9e227e2014-08-17 14:01:19 +10001831
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001832
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001833class TestSignatureObject(unittest.TestCase):
1834 @staticmethod
Yury Selivanovbcd4fc12015-05-20 14:30:08 -04001835 def signature(func, **kw):
1836 sig = inspect.signature(func, **kw)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001837 return (tuple((param.name,
1838 (... if param.default is param.empty else param.default),
1839 (... if param.annotation is param.empty
1840 else param.annotation),
1841 str(param.kind).lower())
1842 for param in sig.parameters.values()),
1843 (... if sig.return_annotation is sig.empty
1844 else sig.return_annotation))
1845
1846 def test_signature_object(self):
1847 S = inspect.Signature
1848 P = inspect.Parameter
1849
1850 self.assertEqual(str(S()), '()')
1851
Yury Selivanov07a9e452014-01-29 10:58:16 -05001852 def test(po, pk, pod=42, pkd=100, *args, ko, **kwargs):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001853 pass
1854 sig = inspect.signature(test)
1855 po = sig.parameters['po'].replace(kind=P.POSITIONAL_ONLY)
Yury Selivanov07a9e452014-01-29 10:58:16 -05001856 pod = sig.parameters['pod'].replace(kind=P.POSITIONAL_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001857 pk = sig.parameters['pk']
Yury Selivanov07a9e452014-01-29 10:58:16 -05001858 pkd = sig.parameters['pkd']
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001859 args = sig.parameters['args']
1860 ko = sig.parameters['ko']
1861 kwargs = sig.parameters['kwargs']
1862
1863 S((po, pk, args, ko, kwargs))
1864
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001865 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001866 S((pk, po, args, ko, kwargs))
1867
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001868 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001869 S((po, args, pk, ko, kwargs))
1870
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001871 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001872 S((args, po, pk, ko, kwargs))
1873
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001874 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001875 S((po, pk, args, kwargs, ko))
1876
1877 kwargs2 = kwargs.replace(name='args')
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001878 with self.assertRaisesRegex(ValueError, 'duplicate parameter name'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001879 S((po, pk, args, kwargs2, ko))
1880
Yury Selivanov07a9e452014-01-29 10:58:16 -05001881 with self.assertRaisesRegex(ValueError, 'follows default argument'):
1882 S((pod, po))
1883
1884 with self.assertRaisesRegex(ValueError, 'follows default argument'):
1885 S((po, pkd, pk))
1886
1887 with self.assertRaisesRegex(ValueError, 'follows default argument'):
1888 S((pkd, pk))
1889
Yury Selivanov374375d2014-03-27 12:41:53 -04001890 self.assertTrue(repr(sig).startswith('<Signature'))
Yury Selivanov0cd2bf42015-05-15 12:55:20 -04001891 self.assertTrue('(po, pk' in repr(sig))
Yury Selivanov374375d2014-03-27 12:41:53 -04001892
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001893 def test_signature_object_pickle(self):
1894 def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
1895 foo_partial = functools.partial(foo, a=1)
1896
1897 sig = inspect.signature(foo_partial)
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001898
1899 for ver in range(pickle.HIGHEST_PROTOCOL + 1):
1900 with self.subTest(pickle_ver=ver, subclass=False):
1901 sig_pickled = pickle.loads(pickle.dumps(sig, ver))
1902 self.assertEqual(sig, sig_pickled)
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001903
1904 # Test that basic sub-classing works
1905 sig = inspect.signature(foo)
1906 myparam = MyParameter(name='z', kind=inspect.Parameter.POSITIONAL_ONLY)
1907 myparams = collections.OrderedDict(sig.parameters, a=myparam)
1908 mysig = MySignature().replace(parameters=myparams.values(),
1909 return_annotation=sig.return_annotation)
1910 self.assertTrue(isinstance(mysig, MySignature))
1911 self.assertTrue(isinstance(mysig.parameters['z'], MyParameter))
1912
1913 for ver in range(pickle.HIGHEST_PROTOCOL + 1):
1914 with self.subTest(pickle_ver=ver, subclass=True):
1915 sig_pickled = pickle.loads(pickle.dumps(mysig, ver))
1916 self.assertEqual(mysig, sig_pickled)
1917 self.assertTrue(isinstance(sig_pickled, MySignature))
1918 self.assertTrue(isinstance(sig_pickled.parameters['z'],
1919 MyParameter))
1920
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001921 def test_signature_immutability(self):
1922 def test(a):
1923 pass
1924 sig = inspect.signature(test)
1925
1926 with self.assertRaises(AttributeError):
1927 sig.foo = 'bar'
1928
1929 with self.assertRaises(TypeError):
1930 sig.parameters['a'] = None
1931
1932 def test_signature_on_noarg(self):
1933 def test():
1934 pass
1935 self.assertEqual(self.signature(test), ((), ...))
1936
1937 def test_signature_on_wargs(self):
1938 def test(a, b:'foo') -> 123:
1939 pass
1940 self.assertEqual(self.signature(test),
1941 ((('a', ..., ..., "positional_or_keyword"),
1942 ('b', ..., 'foo', "positional_or_keyword")),
1943 123))
1944
1945 def test_signature_on_wkwonly(self):
1946 def test(*, a:float, b:str) -> int:
1947 pass
1948 self.assertEqual(self.signature(test),
1949 ((('a', ..., float, "keyword_only"),
1950 ('b', ..., str, "keyword_only")),
1951 int))
1952
1953 def test_signature_on_complex_args(self):
1954 def test(a, b:'foo'=10, *args:'bar', spam:'baz', ham=123, **kwargs:int):
1955 pass
1956 self.assertEqual(self.signature(test),
1957 ((('a', ..., ..., "positional_or_keyword"),
1958 ('b', 10, 'foo', "positional_or_keyword"),
1959 ('args', ..., 'bar', "var_positional"),
1960 ('spam', ..., 'baz', "keyword_only"),
1961 ('ham', 123, ..., "keyword_only"),
1962 ('kwargs', ..., int, "var_keyword")),
1963 ...))
1964
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02001965 @cpython_only
Larry Hastingsfcafe432013-11-23 17:35:48 -08001966 @unittest.skipIf(MISSING_C_DOCSTRINGS,
1967 "Signature information for builtins requires docstrings")
1968 def test_signature_on_builtins(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02001969 import _testcapi
Larry Hastings16c51912014-01-07 11:53:01 -08001970
Larry Hastings5c661892014-01-24 06:17:25 -08001971 def test_unbound_method(o):
1972 """Use this to test unbound methods (things that should have a self)"""
1973 signature = inspect.signature(o)
1974 self.assertTrue(isinstance(signature, inspect.Signature))
1975 self.assertEqual(list(signature.parameters.values())[0].name, 'self')
1976 return signature
1977
1978 def test_callable(o):
1979 """Use this to test bound methods or normal callables (things that don't expect self)"""
1980 signature = inspect.signature(o)
1981 self.assertTrue(isinstance(signature, inspect.Signature))
1982 if signature.parameters:
1983 self.assertNotEqual(list(signature.parameters.values())[0].name, 'self')
1984 return signature
1985
1986 signature = test_callable(_testcapi.docstring_with_signature_with_defaults)
Larry Hastings16c51912014-01-07 11:53:01 -08001987 def p(name): return signature.parameters[name].default
1988 self.assertEqual(p('s'), 'avocado')
Larry Hastings2a727912014-01-16 11:32:01 -08001989 self.assertEqual(p('b'), b'bytes')
Larry Hastings16c51912014-01-07 11:53:01 -08001990 self.assertEqual(p('d'), 3.14)
1991 self.assertEqual(p('i'), 35)
Larry Hastings16c51912014-01-07 11:53:01 -08001992 self.assertEqual(p('n'), None)
1993 self.assertEqual(p('t'), True)
1994 self.assertEqual(p('f'), False)
Larry Hastings2a727912014-01-16 11:32:01 -08001995 self.assertEqual(p('local'), 3)
1996 self.assertEqual(p('sys'), sys.maxsize)
1997 self.assertEqual(p('exp'), sys.maxsize - 1)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001998
Larry Hastings5c661892014-01-24 06:17:25 -08001999 test_callable(object)
2000
2001 # normal method
2002 # (PyMethodDescr_Type, "method_descriptor")
2003 test_unbound_method(_pickle.Pickler.dump)
2004 d = _pickle.Pickler(io.StringIO())
2005 test_callable(d.dump)
2006
2007 # static method
2008 test_callable(str.maketrans)
2009 test_callable('abc'.maketrans)
2010
2011 # class method
2012 test_callable(dict.fromkeys)
2013 test_callable({}.fromkeys)
2014
2015 # wrapper around slot (PyWrapperDescr_Type, "wrapper_descriptor")
2016 test_unbound_method(type.__call__)
2017 test_unbound_method(int.__add__)
2018 test_callable((3).__add__)
2019
2020 # _PyMethodWrapper_Type
2021 # support for 'method-wrapper'
2022 test_callable(min.__call__)
2023
Larry Hastings2623c8c2014-02-08 22:15:29 -08002024 # This doesn't work now.
2025 # (We don't have a valid signature for "type" in 3.4)
2026 with self.assertRaisesRegex(ValueError, "no signature found"):
2027 class ThisWorksNow:
2028 __call__ = type
2029 test_callable(ThisWorksNow())
Larry Hastings5c661892014-01-24 06:17:25 -08002030
Yury Selivanov056e2652014-03-02 12:25:27 -05002031 # Regression test for issue #20786
2032 test_unbound_method(dict.__delitem__)
2033 test_unbound_method(property.__delete__)
2034
Zachary Ware8ef887c2015-04-13 18:22:35 -05002035 # Regression test for issue #20586
2036 test_callable(_testcapi.docstring_with_signature_but_no_doc)
2037
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002038 @cpython_only
Yury Selivanov76c6c592014-01-29 10:52:57 -05002039 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2040 "Signature information for builtins requires docstrings")
2041 def test_signature_on_decorated_builtins(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002042 import _testcapi
Yury Selivanov76c6c592014-01-29 10:52:57 -05002043 func = _testcapi.docstring_with_signature_with_defaults
2044
2045 def decorator(func):
2046 @functools.wraps(func)
2047 def wrapper(*args, **kwargs) -> int:
2048 return func(*args, **kwargs)
2049 return wrapper
2050
2051 decorated_func = decorator(func)
2052
2053 self.assertEqual(inspect.signature(func),
2054 inspect.signature(decorated_func))
Larry Hastings5c661892014-01-24 06:17:25 -08002055
Yury Selivanovbcd4fc12015-05-20 14:30:08 -04002056 def wrapper_like(*args, **kwargs) -> int: pass
2057 self.assertEqual(inspect.signature(decorated_func,
2058 follow_wrapped=False),
2059 inspect.signature(wrapper_like))
2060
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002061 @cpython_only
Larry Hastings5c661892014-01-24 06:17:25 -08002062 def test_signature_on_builtins_no_signature(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002063 import _testcapi
Yury Selivanovbf304fc2015-05-30 17:08:36 -04002064 with self.assertRaisesRegex(ValueError,
2065 'no signature found for builtin'):
Larry Hastings5c661892014-01-24 06:17:25 -08002066 inspect.signature(_testcapi.docstring_no_signature)
2067
Yury Selivanovbf304fc2015-05-30 17:08:36 -04002068 with self.assertRaisesRegex(ValueError,
2069 'no signature found for builtin'):
2070 inspect.signature(str)
2071
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002072 def test_signature_on_non_function(self):
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002073 with self.assertRaisesRegex(TypeError, 'is not a callable object'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002074 inspect.signature(42)
2075
Yury Selivanov63da7c72014-01-31 14:48:37 -05002076 def test_signature_from_functionlike_object(self):
2077 def func(a,b, *args, kwonly=True, kwonlyreq, **kwargs):
2078 pass
2079
2080 class funclike:
2081 # Has to be callable, and have correct
2082 # __code__, __annotations__, __defaults__, __name__,
2083 # and __kwdefaults__ attributes
2084
2085 def __init__(self, func):
2086 self.__name__ = func.__name__
2087 self.__code__ = func.__code__
2088 self.__annotations__ = func.__annotations__
2089 self.__defaults__ = func.__defaults__
2090 self.__kwdefaults__ = func.__kwdefaults__
2091 self.func = func
2092
2093 def __call__(self, *args, **kwargs):
2094 return self.func(*args, **kwargs)
2095
Yury Selivanov57c74fc2015-05-20 23:07:02 -04002096 sig_func = inspect.Signature.from_callable(func)
Yury Selivanov63da7c72014-01-31 14:48:37 -05002097
Yury Selivanov57c74fc2015-05-20 23:07:02 -04002098 sig_funclike = inspect.Signature.from_callable(funclike(func))
Yury Selivanov63da7c72014-01-31 14:48:37 -05002099 self.assertEqual(sig_funclike, sig_func)
2100
2101 sig_funclike = inspect.signature(funclike(func))
2102 self.assertEqual(sig_funclike, sig_func)
2103
2104 # If object is not a duck type of function, then
2105 # signature will try to get a signature for its '__call__'
2106 # method
2107 fl = funclike(func)
2108 del fl.__defaults__
2109 self.assertEqual(self.signature(fl),
2110 ((('args', ..., ..., "var_positional"),
2111 ('kwargs', ..., ..., "var_keyword")),
2112 ...))
2113
Yury Selivanova773de02014-02-21 18:30:53 -05002114 # Test with cython-like builtins:
2115 _orig_isdesc = inspect.ismethoddescriptor
2116 def _isdesc(obj):
2117 if hasattr(obj, '_builtinmock'):
2118 return True
2119 return _orig_isdesc(obj)
2120
2121 with unittest.mock.patch('inspect.ismethoddescriptor', _isdesc):
2122 builtin_func = funclike(func)
2123 # Make sure that our mock setup is working
2124 self.assertFalse(inspect.ismethoddescriptor(builtin_func))
2125 builtin_func._builtinmock = True
2126 self.assertTrue(inspect.ismethoddescriptor(builtin_func))
2127 self.assertEqual(inspect.signature(builtin_func), sig_func)
2128
Yury Selivanov63da7c72014-01-31 14:48:37 -05002129 def test_signature_functionlike_class(self):
2130 # We only want to duck type function-like objects,
2131 # not classes.
2132
2133 def func(a,b, *args, kwonly=True, kwonlyreq, **kwargs):
2134 pass
2135
2136 class funclike:
2137 def __init__(self, marker):
2138 pass
2139
2140 __name__ = func.__name__
2141 __code__ = func.__code__
2142 __annotations__ = func.__annotations__
2143 __defaults__ = func.__defaults__
2144 __kwdefaults__ = func.__kwdefaults__
2145
Yury Selivanov63da7c72014-01-31 14:48:37 -05002146 self.assertEqual(str(inspect.signature(funclike)), '(marker)')
2147
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002148 def test_signature_on_method(self):
2149 class Test:
Yury Selivanov62560fb2014-01-28 12:26:24 -05002150 def __init__(*args):
2151 pass
2152 def m1(self, arg1, arg2=1) -> int:
2153 pass
2154 def m2(*args):
2155 pass
2156 def __call__(*, a):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002157 pass
2158
Yury Selivanov62560fb2014-01-28 12:26:24 -05002159 self.assertEqual(self.signature(Test().m1),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002160 ((('arg1', ..., ..., "positional_or_keyword"),
2161 ('arg2', 1, ..., "positional_or_keyword")),
2162 int))
2163
Yury Selivanov62560fb2014-01-28 12:26:24 -05002164 self.assertEqual(self.signature(Test().m2),
2165 ((('args', ..., ..., "var_positional"),),
2166 ...))
2167
2168 self.assertEqual(self.signature(Test),
2169 ((('args', ..., ..., "var_positional"),),
2170 ...))
2171
2172 with self.assertRaisesRegex(ValueError, 'invalid method signature'):
2173 self.signature(Test())
2174
Yury Selivanov46c759d2015-05-27 21:56:53 -04002175 def test_signature_wrapped_bound_method(self):
2176 # Issue 24298
2177 class Test:
2178 def m1(self, arg1, arg2=1) -> int:
2179 pass
2180 @functools.wraps(Test().m1)
2181 def m1d(*args, **kwargs):
2182 pass
2183 self.assertEqual(self.signature(m1d),
2184 ((('arg1', ..., ..., "positional_or_keyword"),
2185 ('arg2', 1, ..., "positional_or_keyword")),
2186 int))
2187
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002188 def test_signature_on_classmethod(self):
2189 class Test:
2190 @classmethod
2191 def foo(cls, arg1, *, arg2=1):
2192 pass
2193
2194 meth = Test().foo
2195 self.assertEqual(self.signature(meth),
2196 ((('arg1', ..., ..., "positional_or_keyword"),
2197 ('arg2', 1, ..., "keyword_only")),
2198 ...))
2199
2200 meth = Test.foo
2201 self.assertEqual(self.signature(meth),
2202 ((('arg1', ..., ..., "positional_or_keyword"),
2203 ('arg2', 1, ..., "keyword_only")),
2204 ...))
2205
2206 def test_signature_on_staticmethod(self):
2207 class Test:
2208 @staticmethod
2209 def foo(cls, *, arg):
2210 pass
2211
2212 meth = Test().foo
2213 self.assertEqual(self.signature(meth),
2214 ((('cls', ..., ..., "positional_or_keyword"),
2215 ('arg', ..., ..., "keyword_only")),
2216 ...))
2217
2218 meth = Test.foo
2219 self.assertEqual(self.signature(meth),
2220 ((('cls', ..., ..., "positional_or_keyword"),
2221 ('arg', ..., ..., "keyword_only")),
2222 ...))
2223
2224 def test_signature_on_partial(self):
2225 from functools import partial
2226
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002227 Parameter = inspect.Parameter
2228
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002229 def test():
2230 pass
2231
2232 self.assertEqual(self.signature(partial(test)), ((), ...))
2233
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002234 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002235 inspect.signature(partial(test, 1))
2236
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002237 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002238 inspect.signature(partial(test, a=1))
2239
2240 def test(a, b, *, c, d):
2241 pass
2242
2243 self.assertEqual(self.signature(partial(test)),
2244 ((('a', ..., ..., "positional_or_keyword"),
2245 ('b', ..., ..., "positional_or_keyword"),
2246 ('c', ..., ..., "keyword_only"),
2247 ('d', ..., ..., "keyword_only")),
2248 ...))
2249
2250 self.assertEqual(self.signature(partial(test, 1)),
2251 ((('b', ..., ..., "positional_or_keyword"),
2252 ('c', ..., ..., "keyword_only"),
2253 ('d', ..., ..., "keyword_only")),
2254 ...))
2255
2256 self.assertEqual(self.signature(partial(test, 1, c=2)),
2257 ((('b', ..., ..., "positional_or_keyword"),
2258 ('c', 2, ..., "keyword_only"),
2259 ('d', ..., ..., "keyword_only")),
2260 ...))
2261
2262 self.assertEqual(self.signature(partial(test, b=1, c=2)),
2263 ((('a', ..., ..., "positional_or_keyword"),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002264 ('b', 1, ..., "keyword_only"),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002265 ('c', 2, ..., "keyword_only"),
2266 ('d', ..., ..., "keyword_only")),
2267 ...))
2268
2269 self.assertEqual(self.signature(partial(test, 0, b=1, c=2)),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002270 ((('b', 1, ..., "keyword_only"),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002271 ('c', 2, ..., "keyword_only"),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002272 ('d', ..., ..., "keyword_only")),
2273 ...))
2274
2275 self.assertEqual(self.signature(partial(test, a=1)),
2276 ((('a', 1, ..., "keyword_only"),
2277 ('b', ..., ..., "keyword_only"),
2278 ('c', ..., ..., "keyword_only"),
2279 ('d', ..., ..., "keyword_only")),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002280 ...))
2281
2282 def test(a, *args, b, **kwargs):
2283 pass
2284
2285 self.assertEqual(self.signature(partial(test, 1)),
2286 ((('args', ..., ..., "var_positional"),
2287 ('b', ..., ..., "keyword_only"),
2288 ('kwargs', ..., ..., "var_keyword")),
2289 ...))
2290
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002291 self.assertEqual(self.signature(partial(test, a=1)),
2292 ((('a', 1, ..., "keyword_only"),
2293 ('b', ..., ..., "keyword_only"),
2294 ('kwargs', ..., ..., "var_keyword")),
2295 ...))
2296
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002297 self.assertEqual(self.signature(partial(test, 1, 2, 3)),
2298 ((('args', ..., ..., "var_positional"),
2299 ('b', ..., ..., "keyword_only"),
2300 ('kwargs', ..., ..., "var_keyword")),
2301 ...))
2302
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002303 self.assertEqual(self.signature(partial(test, 1, 2, 3, test=True)),
2304 ((('args', ..., ..., "var_positional"),
2305 ('b', ..., ..., "keyword_only"),
2306 ('kwargs', ..., ..., "var_keyword")),
2307 ...))
2308
2309 self.assertEqual(self.signature(partial(test, 1, 2, 3, test=1, b=0)),
2310 ((('args', ..., ..., "var_positional"),
2311 ('b', 0, ..., "keyword_only"),
2312 ('kwargs', ..., ..., "var_keyword")),
2313 ...))
2314
2315 self.assertEqual(self.signature(partial(test, b=0)),
2316 ((('a', ..., ..., "positional_or_keyword"),
2317 ('args', ..., ..., "var_positional"),
2318 ('b', 0, ..., "keyword_only"),
2319 ('kwargs', ..., ..., "var_keyword")),
2320 ...))
2321
2322 self.assertEqual(self.signature(partial(test, b=0, test=1)),
2323 ((('a', ..., ..., "positional_or_keyword"),
2324 ('args', ..., ..., "var_positional"),
2325 ('b', 0, ..., "keyword_only"),
2326 ('kwargs', ..., ..., "var_keyword")),
2327 ...))
2328
2329 def test(a, b, c:int) -> 42:
2330 pass
2331
2332 sig = test.__signature__ = inspect.signature(test)
2333
2334 self.assertEqual(self.signature(partial(partial(test, 1))),
2335 ((('b', ..., ..., "positional_or_keyword"),
2336 ('c', ..., int, "positional_or_keyword")),
2337 42))
2338
2339 self.assertEqual(self.signature(partial(partial(test, 1), 2)),
2340 ((('c', ..., int, "positional_or_keyword"),),
2341 42))
2342
2343 psig = inspect.signature(partial(partial(test, 1), 2))
2344
2345 def foo(a):
2346 return a
2347 _foo = partial(partial(foo, a=10), a=20)
2348 self.assertEqual(self.signature(_foo),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002349 ((('a', 20, ..., "keyword_only"),),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002350 ...))
2351 # check that we don't have any side-effects in signature(),
2352 # and the partial object is still functioning
2353 self.assertEqual(_foo(), 20)
2354
2355 def foo(a, b, c):
2356 return a, b, c
2357 _foo = partial(partial(foo, 1, b=20), b=30)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002358
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002359 self.assertEqual(self.signature(_foo),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002360 ((('b', 30, ..., "keyword_only"),
2361 ('c', ..., ..., "keyword_only")),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002362 ...))
2363 self.assertEqual(_foo(c=10), (1, 30, 10))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002364
2365 def foo(a, b, c, *, d):
2366 return a, b, c, d
2367 _foo = partial(partial(foo, d=20, c=20), b=10, d=30)
2368 self.assertEqual(self.signature(_foo),
2369 ((('a', ..., ..., "positional_or_keyword"),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002370 ('b', 10, ..., "keyword_only"),
2371 ('c', 20, ..., "keyword_only"),
2372 ('d', 30, ..., "keyword_only"),
2373 ),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002374 ...))
2375 ba = inspect.signature(_foo).bind(a=200, b=11)
2376 self.assertEqual(_foo(*ba.args, **ba.kwargs), (200, 11, 20, 30))
2377
2378 def foo(a=1, b=2, c=3):
2379 return a, b, c
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002380 _foo = partial(foo, c=13) # (a=1, b=2, *, c=13)
2381
2382 ba = inspect.signature(_foo).bind(a=11)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002383 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 2, 13))
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002384
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002385 ba = inspect.signature(_foo).bind(11, 12)
2386 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002387
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002388 ba = inspect.signature(_foo).bind(11, b=12)
2389 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002390
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002391 ba = inspect.signature(_foo).bind(b=12)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002392 self.assertEqual(_foo(*ba.args, **ba.kwargs), (1, 12, 13))
2393
2394 _foo = partial(_foo, b=10, c=20)
2395 ba = inspect.signature(_foo).bind(12)
2396 self.assertEqual(_foo(*ba.args, **ba.kwargs), (12, 10, 20))
2397
2398
2399 def foo(a, b, c, d, **kwargs):
2400 pass
2401 sig = inspect.signature(foo)
2402 params = sig.parameters.copy()
2403 params['a'] = params['a'].replace(kind=Parameter.POSITIONAL_ONLY)
2404 params['b'] = params['b'].replace(kind=Parameter.POSITIONAL_ONLY)
2405 foo.__signature__ = inspect.Signature(params.values())
2406 sig = inspect.signature(foo)
2407 self.assertEqual(str(sig), '(a, b, /, c, d, **kwargs)')
2408
2409 self.assertEqual(self.signature(partial(foo, 1)),
2410 ((('b', ..., ..., 'positional_only'),
2411 ('c', ..., ..., 'positional_or_keyword'),
2412 ('d', ..., ..., 'positional_or_keyword'),
2413 ('kwargs', ..., ..., 'var_keyword')),
2414 ...))
2415
2416 self.assertEqual(self.signature(partial(foo, 1, 2)),
2417 ((('c', ..., ..., 'positional_or_keyword'),
2418 ('d', ..., ..., 'positional_or_keyword'),
2419 ('kwargs', ..., ..., 'var_keyword')),
2420 ...))
2421
2422 self.assertEqual(self.signature(partial(foo, 1, 2, 3)),
2423 ((('d', ..., ..., 'positional_or_keyword'),
2424 ('kwargs', ..., ..., 'var_keyword')),
2425 ...))
2426
2427 self.assertEqual(self.signature(partial(foo, 1, 2, c=3)),
2428 ((('c', 3, ..., 'keyword_only'),
2429 ('d', ..., ..., 'keyword_only'),
2430 ('kwargs', ..., ..., 'var_keyword')),
2431 ...))
2432
2433 self.assertEqual(self.signature(partial(foo, 1, c=3)),
2434 ((('b', ..., ..., 'positional_only'),
2435 ('c', 3, ..., 'keyword_only'),
2436 ('d', ..., ..., 'keyword_only'),
2437 ('kwargs', ..., ..., 'var_keyword')),
2438 ...))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002439
Yury Selivanovda5fe4f2014-01-27 17:28:37 -05002440 def test_signature_on_partialmethod(self):
2441 from functools import partialmethod
2442
2443 class Spam:
2444 def test():
2445 pass
2446 ham = partialmethod(test)
2447
2448 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
2449 inspect.signature(Spam.ham)
2450
2451 class Spam:
2452 def test(it, a, *, c) -> 'spam':
2453 pass
2454 ham = partialmethod(test, c=1)
2455
2456 self.assertEqual(self.signature(Spam.ham),
2457 ((('it', ..., ..., 'positional_or_keyword'),
2458 ('a', ..., ..., 'positional_or_keyword'),
2459 ('c', 1, ..., 'keyword_only')),
2460 'spam'))
2461
2462 self.assertEqual(self.signature(Spam().ham),
2463 ((('a', ..., ..., 'positional_or_keyword'),
2464 ('c', 1, ..., 'keyword_only')),
2465 'spam'))
2466
Yury Selivanov0486f812014-01-29 12:18:59 -05002467 def test_signature_on_fake_partialmethod(self):
2468 def foo(a): pass
2469 foo._partialmethod = 'spam'
2470 self.assertEqual(str(inspect.signature(foo)), '(a)')
2471
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002472 def test_signature_on_decorated(self):
2473 import functools
2474
2475 def decorator(func):
2476 @functools.wraps(func)
2477 def wrapper(*args, **kwargs) -> int:
2478 return func(*args, **kwargs)
2479 return wrapper
2480
2481 class Foo:
2482 @decorator
2483 def bar(self, a, b):
2484 pass
2485
2486 self.assertEqual(self.signature(Foo.bar),
2487 ((('self', ..., ..., "positional_or_keyword"),
2488 ('a', ..., ..., "positional_or_keyword"),
2489 ('b', ..., ..., "positional_or_keyword")),
2490 ...))
2491
2492 self.assertEqual(self.signature(Foo().bar),
2493 ((('a', ..., ..., "positional_or_keyword"),
2494 ('b', ..., ..., "positional_or_keyword")),
2495 ...))
2496
Yury Selivanovbcd4fc12015-05-20 14:30:08 -04002497 self.assertEqual(self.signature(Foo.bar, follow_wrapped=False),
2498 ((('args', ..., ..., "var_positional"),
2499 ('kwargs', ..., ..., "var_keyword")),
2500 ...)) # functools.wraps will copy __annotations__
2501 # from "func" to "wrapper", hence no
2502 # return_annotation
2503
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002504 # Test that we handle method wrappers correctly
2505 def decorator(func):
2506 @functools.wraps(func)
2507 def wrapper(*args, **kwargs) -> int:
2508 return func(42, *args, **kwargs)
2509 sig = inspect.signature(func)
2510 new_params = tuple(sig.parameters.values())[1:]
2511 wrapper.__signature__ = sig.replace(parameters=new_params)
2512 return wrapper
2513
2514 class Foo:
2515 @decorator
2516 def __call__(self, a, b):
2517 pass
2518
2519 self.assertEqual(self.signature(Foo.__call__),
2520 ((('a', ..., ..., "positional_or_keyword"),
2521 ('b', ..., ..., "positional_or_keyword")),
2522 ...))
2523
2524 self.assertEqual(self.signature(Foo().__call__),
2525 ((('b', ..., ..., "positional_or_keyword"),),
2526 ...))
2527
Nick Coghlane8c45d62013-07-28 20:00:01 +10002528 # Test we handle __signature__ partway down the wrapper stack
2529 def wrapped_foo_call():
2530 pass
2531 wrapped_foo_call.__wrapped__ = Foo.__call__
2532
2533 self.assertEqual(self.signature(wrapped_foo_call),
2534 ((('a', ..., ..., "positional_or_keyword"),
2535 ('b', ..., ..., "positional_or_keyword")),
2536 ...))
2537
2538
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002539 def test_signature_on_class(self):
2540 class C:
2541 def __init__(self, a):
2542 pass
2543
2544 self.assertEqual(self.signature(C),
2545 ((('a', ..., ..., "positional_or_keyword"),),
2546 ...))
2547
2548 class CM(type):
2549 def __call__(cls, a):
2550 pass
2551 class C(metaclass=CM):
2552 def __init__(self, b):
2553 pass
2554
2555 self.assertEqual(self.signature(C),
2556 ((('a', ..., ..., "positional_or_keyword"),),
2557 ...))
2558
2559 class CM(type):
2560 def __new__(mcls, name, bases, dct, *, foo=1):
2561 return super().__new__(mcls, name, bases, dct)
2562 class C(metaclass=CM):
2563 def __init__(self, b):
2564 pass
2565
2566 self.assertEqual(self.signature(C),
2567 ((('b', ..., ..., "positional_or_keyword"),),
2568 ...))
2569
2570 self.assertEqual(self.signature(CM),
2571 ((('name', ..., ..., "positional_or_keyword"),
2572 ('bases', ..., ..., "positional_or_keyword"),
2573 ('dct', ..., ..., "positional_or_keyword"),
2574 ('foo', 1, ..., "keyword_only")),
2575 ...))
2576
2577 class CMM(type):
2578 def __new__(mcls, name, bases, dct, *, foo=1):
2579 return super().__new__(mcls, name, bases, dct)
2580 def __call__(cls, nm, bs, dt):
2581 return type(nm, bs, dt)
2582 class CM(type, metaclass=CMM):
2583 def __new__(mcls, name, bases, dct, *, bar=2):
2584 return super().__new__(mcls, name, bases, dct)
2585 class C(metaclass=CM):
2586 def __init__(self, b):
2587 pass
2588
2589 self.assertEqual(self.signature(CMM),
2590 ((('name', ..., ..., "positional_or_keyword"),
2591 ('bases', ..., ..., "positional_or_keyword"),
2592 ('dct', ..., ..., "positional_or_keyword"),
2593 ('foo', 1, ..., "keyword_only")),
2594 ...))
2595
2596 self.assertEqual(self.signature(CM),
2597 ((('nm', ..., ..., "positional_or_keyword"),
2598 ('bs', ..., ..., "positional_or_keyword"),
2599 ('dt', ..., ..., "positional_or_keyword")),
2600 ...))
2601
2602 self.assertEqual(self.signature(C),
2603 ((('b', ..., ..., "positional_or_keyword"),),
2604 ...))
2605
2606 class CM(type):
2607 def __init__(cls, name, bases, dct, *, bar=2):
2608 return super().__init__(name, bases, dct)
2609 class C(metaclass=CM):
2610 def __init__(self, b):
2611 pass
2612
2613 self.assertEqual(self.signature(CM),
2614 ((('name', ..., ..., "positional_or_keyword"),
2615 ('bases', ..., ..., "positional_or_keyword"),
2616 ('dct', ..., ..., "positional_or_keyword"),
2617 ('bar', 2, ..., "keyword_only")),
2618 ...))
2619
Yury Selivanov145dff82014-02-01 13:49:29 -05002620 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2621 "Signature information for builtins requires docstrings")
2622 def test_signature_on_class_without_init(self):
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002623 # Test classes without user-defined __init__ or __new__
2624 class C: pass
2625 self.assertEqual(str(inspect.signature(C)), '()')
2626 class D(C): pass
2627 self.assertEqual(str(inspect.signature(D)), '()')
2628
2629 # Test meta-classes without user-defined __init__ or __new__
2630 class C(type): pass
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002631 class D(C): pass
Larry Hastings2623c8c2014-02-08 22:15:29 -08002632 with self.assertRaisesRegex(ValueError, "callable.*is not supported"):
2633 self.assertEqual(inspect.signature(C), None)
2634 with self.assertRaisesRegex(ValueError, "callable.*is not supported"):
2635 self.assertEqual(inspect.signature(D), None)
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002636
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002637 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2638 "Signature information for builtins requires docstrings")
2639 def test_signature_on_builtin_class(self):
2640 self.assertEqual(str(inspect.signature(_pickle.Pickler)),
2641 '(file, protocol=None, fix_imports=True)')
2642
2643 class P(_pickle.Pickler): pass
2644 class EmptyTrait: pass
2645 class P2(EmptyTrait, P): pass
2646 self.assertEqual(str(inspect.signature(P)),
2647 '(file, protocol=None, fix_imports=True)')
2648 self.assertEqual(str(inspect.signature(P2)),
2649 '(file, protocol=None, fix_imports=True)')
2650
2651 class P3(P2):
2652 def __init__(self, spam):
2653 pass
2654 self.assertEqual(str(inspect.signature(P3)), '(spam)')
2655
2656 class MetaP(type):
2657 def __call__(cls, foo, bar):
2658 pass
2659 class P4(P2, metaclass=MetaP):
2660 pass
2661 self.assertEqual(str(inspect.signature(P4)), '(foo, bar)')
2662
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002663 def test_signature_on_callable_objects(self):
2664 class Foo:
2665 def __call__(self, a):
2666 pass
2667
2668 self.assertEqual(self.signature(Foo()),
2669 ((('a', ..., ..., "positional_or_keyword"),),
2670 ...))
2671
2672 class Spam:
2673 pass
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002674 with self.assertRaisesRegex(TypeError, "is not a callable object"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002675 inspect.signature(Spam())
2676
2677 class Bar(Spam, Foo):
2678 pass
2679
2680 self.assertEqual(self.signature(Bar()),
2681 ((('a', ..., ..., "positional_or_keyword"),),
2682 ...))
2683
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002684 class Wrapped:
2685 pass
2686 Wrapped.__wrapped__ = lambda a: None
2687 self.assertEqual(self.signature(Wrapped),
2688 ((('a', ..., ..., "positional_or_keyword"),),
2689 ...))
Nick Coghlane8c45d62013-07-28 20:00:01 +10002690 # wrapper loop:
2691 Wrapped.__wrapped__ = Wrapped
2692 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
2693 self.signature(Wrapped)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002694
2695 def test_signature_on_lambdas(self):
2696 self.assertEqual(self.signature((lambda a=10: a)),
2697 ((('a', 10, ..., "positional_or_keyword"),),
2698 ...))
2699
2700 def test_signature_equality(self):
2701 def foo(a, *, b:int) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002702 self.assertFalse(inspect.signature(foo) == 42)
2703 self.assertTrue(inspect.signature(foo) != 42)
2704 self.assertTrue(inspect.signature(foo) == EqualsToAll())
2705 self.assertFalse(inspect.signature(foo) != EqualsToAll())
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002706
2707 def bar(a, *, b:int) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002708 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
2709 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002710 self.assertEqual(
2711 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002712
2713 def bar(a, *, b:int) -> int: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002714 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
2715 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002716 self.assertNotEqual(
2717 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002718
2719 def bar(a, *, b:int): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002720 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
2721 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002722 self.assertNotEqual(
2723 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002724
2725 def bar(a, *, b:int=42) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002726 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
2727 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002728 self.assertNotEqual(
2729 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002730
2731 def bar(a, *, c) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002732 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
2733 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002734 self.assertNotEqual(
2735 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002736
2737 def bar(a, b:int) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002738 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
2739 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002740 self.assertNotEqual(
2741 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002742 def spam(b:int, a) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002743 self.assertFalse(inspect.signature(spam) == inspect.signature(bar))
2744 self.assertTrue(inspect.signature(spam) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002745 self.assertNotEqual(
2746 hash(inspect.signature(spam)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002747
2748 def foo(*, a, b, c): pass
2749 def bar(*, c, b, a): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002750 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
2751 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002752 self.assertEqual(
2753 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002754
2755 def foo(*, a=1, b, c): pass
2756 def bar(*, c, b, a=1): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002757 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
2758 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002759 self.assertEqual(
2760 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002761
2762 def foo(pos, *, a=1, b, c): pass
2763 def bar(pos, *, c, b, a=1): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002764 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
2765 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002766 self.assertEqual(
2767 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002768
2769 def foo(pos, *, a, b, c): pass
2770 def bar(pos, *, c, b, a=1): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002771 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
2772 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002773 self.assertNotEqual(
2774 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002775
2776 def foo(pos, *args, a=42, b, c, **kwargs:int): pass
2777 def bar(pos, *args, c, b, a=42, **kwargs:int): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002778 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
2779 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002780 self.assertEqual(
2781 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002782
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002783 def test_signature_hashable(self):
2784 S = inspect.Signature
2785 P = inspect.Parameter
2786
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002787 def foo(a): pass
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002788 foo_sig = inspect.signature(foo)
2789
2790 manual_sig = S(parameters=[P('a', P.POSITIONAL_OR_KEYWORD)])
2791
2792 self.assertEqual(hash(foo_sig), hash(manual_sig))
2793 self.assertNotEqual(hash(foo_sig),
2794 hash(manual_sig.replace(return_annotation='spam')))
2795
2796 def bar(a) -> 1: pass
2797 self.assertNotEqual(hash(foo_sig), hash(inspect.signature(bar)))
2798
2799 def foo(a={}): pass
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002800 with self.assertRaisesRegex(TypeError, 'unhashable type'):
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002801 hash(inspect.signature(foo))
2802
2803 def foo(a) -> {}: pass
2804 with self.assertRaisesRegex(TypeError, 'unhashable type'):
2805 hash(inspect.signature(foo))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002806
2807 def test_signature_str(self):
2808 def foo(a:int=1, *, b, c=None, **kwargs) -> 42:
2809 pass
2810 self.assertEqual(str(inspect.signature(foo)),
2811 '(a:int=1, *, b, c=None, **kwargs) -> 42')
2812
2813 def foo(a:int=1, *args, b, c=None, **kwargs) -> 42:
2814 pass
2815 self.assertEqual(str(inspect.signature(foo)),
2816 '(a:int=1, *args, b, c=None, **kwargs) -> 42')
2817
2818 def foo():
2819 pass
2820 self.assertEqual(str(inspect.signature(foo)), '()')
2821
2822 def test_signature_str_positional_only(self):
2823 P = inspect.Parameter
Yury Selivanov2393dca2014-01-27 15:07:58 -05002824 S = inspect.Signature
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002825
2826 def test(a_po, *, b, **kwargs):
2827 return a_po, kwargs
2828
2829 sig = inspect.signature(test)
2830 new_params = list(sig.parameters.values())
2831 new_params[0] = new_params[0].replace(kind=P.POSITIONAL_ONLY)
2832 test.__signature__ = sig.replace(parameters=new_params)
2833
2834 self.assertEqual(str(inspect.signature(test)),
Yury Selivanov2393dca2014-01-27 15:07:58 -05002835 '(a_po, /, *, b, **kwargs)')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002836
Yury Selivanov2393dca2014-01-27 15:07:58 -05002837 self.assertEqual(str(S(parameters=[P('foo', P.POSITIONAL_ONLY)])),
2838 '(foo, /)')
2839
2840 self.assertEqual(str(S(parameters=[
2841 P('foo', P.POSITIONAL_ONLY),
2842 P('bar', P.VAR_KEYWORD)])),
2843 '(foo, /, **bar)')
2844
2845 self.assertEqual(str(S(parameters=[
2846 P('foo', P.POSITIONAL_ONLY),
2847 P('bar', P.VAR_POSITIONAL)])),
2848 '(foo, /, *bar)')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002849
2850 def test_signature_replace_anno(self):
2851 def test() -> 42:
2852 pass
2853
2854 sig = inspect.signature(test)
2855 sig = sig.replace(return_annotation=None)
2856 self.assertIs(sig.return_annotation, None)
2857 sig = sig.replace(return_annotation=sig.empty)
2858 self.assertIs(sig.return_annotation, sig.empty)
2859 sig = sig.replace(return_annotation=42)
2860 self.assertEqual(sig.return_annotation, 42)
2861 self.assertEqual(sig, inspect.signature(test))
2862
Yury Selivanov34ce99f2014-02-18 12:49:41 -05002863 def test_signature_on_mangled_parameters(self):
2864 class Spam:
2865 def foo(self, __p1:1=2, *, __p2:2=3):
2866 pass
2867 class Ham(Spam):
2868 pass
2869
2870 self.assertEqual(self.signature(Spam.foo),
2871 ((('self', ..., ..., "positional_or_keyword"),
2872 ('_Spam__p1', 2, 1, "positional_or_keyword"),
2873 ('_Spam__p2', 3, 2, "keyword_only")),
2874 ...))
2875
2876 self.assertEqual(self.signature(Spam.foo),
2877 self.signature(Ham.foo))
2878
Yury Selivanovda396452014-03-27 12:09:24 -04002879 def test_signature_from_callable_python_obj(self):
2880 class MySignature(inspect.Signature): pass
2881 def foo(a, *, b:1): pass
2882 foo_sig = MySignature.from_callable(foo)
2883 self.assertTrue(isinstance(foo_sig, MySignature))
2884
2885 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2886 "Signature information for builtins requires docstrings")
2887 def test_signature_from_callable_builtin_obj(self):
2888 class MySignature(inspect.Signature): pass
2889 sig = MySignature.from_callable(_pickle.Pickler)
2890 self.assertTrue(isinstance(sig, MySignature))
2891
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002892
2893class TestParameterObject(unittest.TestCase):
2894 def test_signature_parameter_kinds(self):
2895 P = inspect.Parameter
2896 self.assertTrue(P.POSITIONAL_ONLY < P.POSITIONAL_OR_KEYWORD < \
2897 P.VAR_POSITIONAL < P.KEYWORD_ONLY < P.VAR_KEYWORD)
2898
2899 self.assertEqual(str(P.POSITIONAL_ONLY), 'POSITIONAL_ONLY')
2900 self.assertTrue('POSITIONAL_ONLY' in repr(P.POSITIONAL_ONLY))
2901
2902 def test_signature_parameter_object(self):
2903 p = inspect.Parameter('foo', default=10,
2904 kind=inspect.Parameter.POSITIONAL_ONLY)
2905 self.assertEqual(p.name, 'foo')
2906 self.assertEqual(p.default, 10)
2907 self.assertIs(p.annotation, p.empty)
2908 self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY)
2909
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002910 with self.assertRaisesRegex(ValueError, 'invalid value'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002911 inspect.Parameter('foo', default=10, kind='123')
2912
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002913 with self.assertRaisesRegex(ValueError, 'not a valid parameter name'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002914 inspect.Parameter('1', kind=inspect.Parameter.VAR_KEYWORD)
2915
Yury Selivanov2393dca2014-01-27 15:07:58 -05002916 with self.assertRaisesRegex(TypeError, 'name must be a str'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002917 inspect.Parameter(None, kind=inspect.Parameter.VAR_KEYWORD)
2918
Yury Selivanov2393dca2014-01-27 15:07:58 -05002919 with self.assertRaisesRegex(ValueError,
2920 'is not a valid parameter name'):
2921 inspect.Parameter('$', kind=inspect.Parameter.VAR_KEYWORD)
2922
Nick Coghlanb4b966e2016-06-04 14:40:03 -07002923 with self.assertRaisesRegex(ValueError,
2924 'is not a valid parameter name'):
2925 inspect.Parameter('.a', kind=inspect.Parameter.VAR_KEYWORD)
2926
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002927 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002928 inspect.Parameter('a', default=42,
2929 kind=inspect.Parameter.VAR_KEYWORD)
2930
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002931 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002932 inspect.Parameter('a', default=42,
2933 kind=inspect.Parameter.VAR_POSITIONAL)
2934
2935 p = inspect.Parameter('a', default=42,
2936 kind=inspect.Parameter.POSITIONAL_OR_KEYWORD)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002937 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002938 p.replace(kind=inspect.Parameter.VAR_POSITIONAL)
2939
2940 self.assertTrue(repr(p).startswith('<Parameter'))
Yury Selivanov374375d2014-03-27 12:41:53 -04002941 self.assertTrue('"a=42"' in repr(p))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002942
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002943 def test_signature_parameter_hashable(self):
2944 P = inspect.Parameter
2945 foo = P('foo', kind=P.POSITIONAL_ONLY)
2946 self.assertEqual(hash(foo), hash(P('foo', kind=P.POSITIONAL_ONLY)))
2947 self.assertNotEqual(hash(foo), hash(P('foo', kind=P.POSITIONAL_ONLY,
2948 default=42)))
2949 self.assertNotEqual(hash(foo),
2950 hash(foo.replace(kind=P.VAR_POSITIONAL)))
2951
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002952 def test_signature_parameter_equality(self):
2953 P = inspect.Parameter
2954 p = P('foo', default=42, kind=inspect.Parameter.KEYWORD_ONLY)
2955
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002956 self.assertTrue(p == p)
2957 self.assertFalse(p != p)
2958 self.assertFalse(p == 42)
2959 self.assertTrue(p != 42)
2960 self.assertTrue(p == EqualsToAll())
2961 self.assertFalse(p != EqualsToAll())
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002962
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002963 self.assertTrue(p == P('foo', default=42,
2964 kind=inspect.Parameter.KEYWORD_ONLY))
2965 self.assertFalse(p != P('foo', default=42,
2966 kind=inspect.Parameter.KEYWORD_ONLY))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002967
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002968 def test_signature_parameter_replace(self):
2969 p = inspect.Parameter('foo', default=42,
2970 kind=inspect.Parameter.KEYWORD_ONLY)
2971
2972 self.assertIsNot(p, p.replace())
2973 self.assertEqual(p, p.replace())
2974
2975 p2 = p.replace(annotation=1)
2976 self.assertEqual(p2.annotation, 1)
2977 p2 = p2.replace(annotation=p2.empty)
2978 self.assertEqual(p, p2)
2979
2980 p2 = p2.replace(name='bar')
2981 self.assertEqual(p2.name, 'bar')
2982 self.assertNotEqual(p2, p)
2983
Yury Selivanov2393dca2014-01-27 15:07:58 -05002984 with self.assertRaisesRegex(ValueError,
2985 'name is a required attribute'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002986 p2 = p2.replace(name=p2.empty)
2987
2988 p2 = p2.replace(name='foo', default=None)
2989 self.assertIs(p2.default, None)
2990 self.assertNotEqual(p2, p)
2991
2992 p2 = p2.replace(name='foo', default=p2.empty)
2993 self.assertIs(p2.default, p2.empty)
2994
2995
2996 p2 = p2.replace(default=42, kind=p2.POSITIONAL_OR_KEYWORD)
2997 self.assertEqual(p2.kind, p2.POSITIONAL_OR_KEYWORD)
2998 self.assertNotEqual(p2, p)
2999
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003000 with self.assertRaisesRegex(ValueError, 'invalid value for'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003001 p2 = p2.replace(kind=p2.empty)
3002
3003 p2 = p2.replace(kind=p2.KEYWORD_ONLY)
3004 self.assertEqual(p2, p)
3005
3006 def test_signature_parameter_positional_only(self):
Yury Selivanov2393dca2014-01-27 15:07:58 -05003007 with self.assertRaisesRegex(TypeError, 'name must be a str'):
3008 inspect.Parameter(None, kind=inspect.Parameter.POSITIONAL_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003009
Nick Coghlanb4b966e2016-06-04 14:40:03 -07003010 @cpython_only
3011 def test_signature_parameter_implicit(self):
3012 with self.assertRaisesRegex(ValueError,
3013 'implicit arguments must be passed in as'):
3014 inspect.Parameter('.0', kind=inspect.Parameter.POSITIONAL_ONLY)
3015
3016 param = inspect.Parameter(
3017 '.0', kind=inspect.Parameter.POSITIONAL_OR_KEYWORD)
3018 self.assertEqual(param.kind, inspect.Parameter.POSITIONAL_ONLY)
3019 self.assertEqual(param.name, 'implicit0')
3020
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003021 def test_signature_parameter_immutability(self):
Yury Selivanov2393dca2014-01-27 15:07:58 -05003022 p = inspect.Parameter('spam', kind=inspect.Parameter.KEYWORD_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003023
3024 with self.assertRaises(AttributeError):
3025 p.foo = 'bar'
3026
3027 with self.assertRaises(AttributeError):
3028 p.kind = 123
3029
3030
3031class TestSignatureBind(unittest.TestCase):
3032 @staticmethod
3033 def call(func, *args, **kwargs):
3034 sig = inspect.signature(func)
3035 ba = sig.bind(*args, **kwargs)
3036 return func(*ba.args, **ba.kwargs)
3037
3038 def test_signature_bind_empty(self):
3039 def test():
3040 return 42
3041
3042 self.assertEqual(self.call(test), 42)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003043 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003044 self.call(test, 1)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003045 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003046 self.call(test, 1, spam=10)
Yury Selivanov86872752015-05-19 00:27:49 -04003047 with self.assertRaisesRegex(
3048 TypeError, "got an unexpected keyword argument 'spam'"):
3049
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003050 self.call(test, spam=1)
3051
3052 def test_signature_bind_var(self):
3053 def test(*args, **kwargs):
3054 return args, kwargs
3055
3056 self.assertEqual(self.call(test), ((), {}))
3057 self.assertEqual(self.call(test, 1), ((1,), {}))
3058 self.assertEqual(self.call(test, 1, 2), ((1, 2), {}))
3059 self.assertEqual(self.call(test, foo='bar'), ((), {'foo': 'bar'}))
3060 self.assertEqual(self.call(test, 1, foo='bar'), ((1,), {'foo': 'bar'}))
3061 self.assertEqual(self.call(test, args=10), ((), {'args': 10}))
3062 self.assertEqual(self.call(test, 1, 2, foo='bar'),
3063 ((1, 2), {'foo': 'bar'}))
3064
3065 def test_signature_bind_just_args(self):
3066 def test(a, b, c):
3067 return a, b, c
3068
3069 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
3070
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003071 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003072 self.call(test, 1, 2, 3, 4)
3073
Yury Selivanov86872752015-05-19 00:27:49 -04003074 with self.assertRaisesRegex(TypeError,
3075 "missing a required argument: 'b'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003076 self.call(test, 1)
3077
Yury Selivanov86872752015-05-19 00:27:49 -04003078 with self.assertRaisesRegex(TypeError,
3079 "missing a required argument: 'a'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003080 self.call(test)
3081
3082 def test(a, b, c=10):
3083 return a, b, c
3084 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
3085 self.assertEqual(self.call(test, 1, 2), (1, 2, 10))
3086
3087 def test(a=1, b=2, c=3):
3088 return a, b, c
3089 self.assertEqual(self.call(test, a=10, c=13), (10, 2, 13))
3090 self.assertEqual(self.call(test, a=10), (10, 2, 3))
3091 self.assertEqual(self.call(test, b=10), (1, 10, 3))
3092
3093 def test_signature_bind_varargs_order(self):
3094 def test(*args):
3095 return args
3096
3097 self.assertEqual(self.call(test), ())
3098 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
3099
3100 def test_signature_bind_args_and_varargs(self):
3101 def test(a, b, c=3, *args):
3102 return a, b, c, args
3103
3104 self.assertEqual(self.call(test, 1, 2, 3, 4, 5), (1, 2, 3, (4, 5)))
3105 self.assertEqual(self.call(test, 1, 2), (1, 2, 3, ()))
3106 self.assertEqual(self.call(test, b=1, a=2), (2, 1, 3, ()))
3107 self.assertEqual(self.call(test, 1, b=2), (1, 2, 3, ()))
3108
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003109 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003110 "multiple values for argument 'c'"):
3111 self.call(test, 1, 2, 3, c=4)
3112
3113 def test_signature_bind_just_kwargs(self):
3114 def test(**kwargs):
3115 return kwargs
3116
3117 self.assertEqual(self.call(test), {})
3118 self.assertEqual(self.call(test, foo='bar', spam='ham'),
3119 {'foo': 'bar', 'spam': 'ham'})
3120
3121 def test_signature_bind_args_and_kwargs(self):
3122 def test(a, b, c=3, **kwargs):
3123 return a, b, c, kwargs
3124
3125 self.assertEqual(self.call(test, 1, 2), (1, 2, 3, {}))
3126 self.assertEqual(self.call(test, 1, 2, foo='bar', spam='ham'),
3127 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3128 self.assertEqual(self.call(test, b=2, a=1, foo='bar', spam='ham'),
3129 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3130 self.assertEqual(self.call(test, a=1, b=2, foo='bar', spam='ham'),
3131 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3132 self.assertEqual(self.call(test, 1, b=2, foo='bar', spam='ham'),
3133 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3134 self.assertEqual(self.call(test, 1, b=2, c=4, foo='bar', spam='ham'),
3135 (1, 2, 4, {'foo': 'bar', 'spam': 'ham'}))
3136 self.assertEqual(self.call(test, 1, 2, 4, foo='bar'),
3137 (1, 2, 4, {'foo': 'bar'}))
3138 self.assertEqual(self.call(test, c=5, a=4, b=3),
3139 (4, 3, 5, {}))
3140
3141 def test_signature_bind_kwonly(self):
3142 def test(*, foo):
3143 return foo
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003144 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003145 'too many positional arguments'):
3146 self.call(test, 1)
3147 self.assertEqual(self.call(test, foo=1), 1)
3148
3149 def test(a, *, foo=1, bar):
3150 return foo
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003151 with self.assertRaisesRegex(TypeError,
Yury Selivanov86872752015-05-19 00:27:49 -04003152 "missing a required argument: 'bar'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003153 self.call(test, 1)
3154
3155 def test(foo, *, bar):
3156 return foo, bar
3157 self.assertEqual(self.call(test, 1, bar=2), (1, 2))
3158 self.assertEqual(self.call(test, bar=2, foo=1), (1, 2))
3159
Yury Selivanov86872752015-05-19 00:27:49 -04003160 with self.assertRaisesRegex(
3161 TypeError, "got an unexpected keyword argument 'spam'"):
3162
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003163 self.call(test, bar=2, foo=1, spam=10)
3164
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003165 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003166 'too many positional arguments'):
3167 self.call(test, 1, 2)
3168
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003169 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003170 'too many positional arguments'):
3171 self.call(test, 1, 2, bar=2)
3172
Yury Selivanov86872752015-05-19 00:27:49 -04003173 with self.assertRaisesRegex(
3174 TypeError, "got an unexpected keyword argument 'spam'"):
3175
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003176 self.call(test, 1, bar=2, spam='ham')
3177
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003178 with self.assertRaisesRegex(TypeError,
Yury Selivanov86872752015-05-19 00:27:49 -04003179 "missing a required argument: 'bar'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003180 self.call(test, 1)
3181
3182 def test(foo, *, bar, **bin):
3183 return foo, bar, bin
3184 self.assertEqual(self.call(test, 1, bar=2), (1, 2, {}))
3185 self.assertEqual(self.call(test, foo=1, bar=2), (1, 2, {}))
3186 self.assertEqual(self.call(test, 1, bar=2, spam='ham'),
3187 (1, 2, {'spam': 'ham'}))
3188 self.assertEqual(self.call(test, spam='ham', foo=1, bar=2),
3189 (1, 2, {'spam': 'ham'}))
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003190 with self.assertRaisesRegex(TypeError,
Yury Selivanov86872752015-05-19 00:27:49 -04003191 "missing a required argument: 'foo'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003192 self.call(test, spam='ham', bar=2)
3193 self.assertEqual(self.call(test, 1, bar=2, bin=1, spam=10),
3194 (1, 2, {'bin': 1, 'spam': 10}))
3195
3196 def test_signature_bind_arguments(self):
3197 def test(a, *args, b, z=100, **kwargs):
3198 pass
3199 sig = inspect.signature(test)
3200 ba = sig.bind(10, 20, b=30, c=40, args=50, kwargs=60)
3201 # we won't have 'z' argument in the bound arguments object, as we didn't
3202 # pass it to the 'bind'
3203 self.assertEqual(tuple(ba.arguments.items()),
3204 (('a', 10), ('args', (20,)), ('b', 30),
3205 ('kwargs', {'c': 40, 'args': 50, 'kwargs': 60})))
3206 self.assertEqual(ba.kwargs,
3207 {'b': 30, 'c': 40, 'args': 50, 'kwargs': 60})
3208 self.assertEqual(ba.args, (10, 20))
3209
3210 def test_signature_bind_positional_only(self):
3211 P = inspect.Parameter
3212
3213 def test(a_po, b_po, c_po=3, foo=42, *, bar=50, **kwargs):
3214 return a_po, b_po, c_po, foo, bar, kwargs
3215
3216 sig = inspect.signature(test)
3217 new_params = collections.OrderedDict(tuple(sig.parameters.items()))
3218 for name in ('a_po', 'b_po', 'c_po'):
3219 new_params[name] = new_params[name].replace(kind=P.POSITIONAL_ONLY)
3220 new_sig = sig.replace(parameters=new_params.values())
3221 test.__signature__ = new_sig
3222
3223 self.assertEqual(self.call(test, 1, 2, 4, 5, bar=6),
3224 (1, 2, 4, 5, 6, {}))
3225
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05003226 self.assertEqual(self.call(test, 1, 2),
3227 (1, 2, 3, 42, 50, {}))
3228
3229 self.assertEqual(self.call(test, 1, 2, foo=4, bar=5),
3230 (1, 2, 3, 4, 5, {}))
3231
3232 with self.assertRaisesRegex(TypeError, "but was passed as a keyword"):
3233 self.call(test, 1, 2, foo=4, bar=5, c_po=10)
3234
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003235 with self.assertRaisesRegex(TypeError, "parameter is positional only"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003236 self.call(test, 1, 2, c_po=4)
3237
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003238 with self.assertRaisesRegex(TypeError, "parameter is positional only"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003239 self.call(test, a_po=1, b_po=2)
3240
Antoine Pitroubd41d1b2013-01-29 21:20:57 +01003241 def test_signature_bind_with_self_arg(self):
3242 # Issue #17071: one of the parameters is named "self
3243 def test(a, self, b):
3244 pass
3245 sig = inspect.signature(test)
3246 ba = sig.bind(1, 2, 3)
3247 self.assertEqual(ba.args, (1, 2, 3))
3248 ba = sig.bind(1, self=2, b=3)
3249 self.assertEqual(ba.args, (1, 2, 3))
3250
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05003251 def test_signature_bind_vararg_name(self):
3252 def test(a, *args):
3253 return a, args
3254 sig = inspect.signature(test)
3255
Yury Selivanov86872752015-05-19 00:27:49 -04003256 with self.assertRaisesRegex(
3257 TypeError, "got an unexpected keyword argument 'args'"):
3258
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05003259 sig.bind(a=0, args=1)
3260
3261 def test(*args, **kwargs):
3262 return args, kwargs
3263 self.assertEqual(self.call(test, args=1), ((), {'args': 1}))
3264
3265 sig = inspect.signature(test)
3266 ba = sig.bind(args=1)
3267 self.assertEqual(ba.arguments, {'kwargs': {'args': 1}})
3268
Nick Coghlanb4b966e2016-06-04 14:40:03 -07003269 @cpython_only
3270 def test_signature_bind_implicit_arg(self):
3271 # Issue #19611: getcallargs should work with set comprehensions
3272 def make_set():
3273 return {z * z for z in range(5)}
3274 setcomp_code = make_set.__code__.co_consts[1]
3275 setcomp_func = types.FunctionType(setcomp_code, {})
3276
3277 iterator = iter(range(5))
3278 self.assertEqual(self.call(setcomp_func, iterator), {0, 1, 4, 9, 16})
3279
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003280
3281class TestBoundArguments(unittest.TestCase):
3282 def test_signature_bound_arguments_unhashable(self):
3283 def foo(a): pass
3284 ba = inspect.signature(foo).bind(1)
3285
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003286 with self.assertRaisesRegex(TypeError, 'unhashable type'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003287 hash(ba)
3288
3289 def test_signature_bound_arguments_equality(self):
3290 def foo(a): pass
3291 ba = inspect.signature(foo).bind(1)
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003292 self.assertTrue(ba == ba)
3293 self.assertFalse(ba != ba)
3294 self.assertTrue(ba == EqualsToAll())
3295 self.assertFalse(ba != EqualsToAll())
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003296
3297 ba2 = inspect.signature(foo).bind(1)
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003298 self.assertTrue(ba == ba2)
3299 self.assertFalse(ba != ba2)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003300
3301 ba3 = inspect.signature(foo).bind(2)
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003302 self.assertFalse(ba == ba3)
3303 self.assertTrue(ba != ba3)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003304 ba3.arguments['a'] = 1
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003305 self.assertTrue(ba == ba3)
3306 self.assertFalse(ba != ba3)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003307
3308 def bar(b): pass
3309 ba4 = inspect.signature(bar).bind(1)
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003310 self.assertFalse(ba == ba4)
3311 self.assertTrue(ba != ba4)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003312
Yury Selivanov4cfd4ea2015-05-14 18:30:27 -04003313 def foo(*, a, b): pass
3314 sig = inspect.signature(foo)
3315 ba1 = sig.bind(a=1, b=2)
3316 ba2 = sig.bind(b=2, a=1)
Serhiy Storchaka2489bd52015-07-18 23:20:50 +03003317 self.assertTrue(ba1 == ba2)
3318 self.assertFalse(ba1 != ba2)
Yury Selivanov4cfd4ea2015-05-14 18:30:27 -04003319
Yury Selivanova5d63dd2014-03-27 11:31:43 -04003320 def test_signature_bound_arguments_pickle(self):
3321 def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
3322 sig = inspect.signature(foo)
3323 ba = sig.bind(20, 30, z={})
3324
3325 for ver in range(pickle.HIGHEST_PROTOCOL + 1):
3326 with self.subTest(pickle_ver=ver):
3327 ba_pickled = pickle.loads(pickle.dumps(ba, ver))
3328 self.assertEqual(ba, ba_pickled)
3329
Yury Selivanov3f6538f2015-05-14 18:47:17 -04003330 def test_signature_bound_arguments_repr(self):
3331 def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
3332 sig = inspect.signature(foo)
3333 ba = sig.bind(20, 30, z={})
Yury Selivanovf229bc52015-05-15 12:53:56 -04003334 self.assertRegex(repr(ba), r'<BoundArguments \(a=20,.*\}\}\)>')
Yury Selivanov3f6538f2015-05-14 18:47:17 -04003335
Yury Selivanovb907a512015-05-16 13:45:09 -04003336 def test_signature_bound_arguments_apply_defaults(self):
3337 def foo(a, b=1, *args, c:1={}, **kw): pass
3338 sig = inspect.signature(foo)
3339
3340 ba = sig.bind(20)
3341 ba.apply_defaults()
3342 self.assertEqual(
3343 list(ba.arguments.items()),
3344 [('a', 20), ('b', 1), ('args', ()), ('c', {}), ('kw', {})])
3345
3346 # Make sure that we preserve the order:
3347 # i.e. 'c' should be *before* 'kw'.
3348 ba = sig.bind(10, 20, 30, d=1)
3349 ba.apply_defaults()
3350 self.assertEqual(
3351 list(ba.arguments.items()),
3352 [('a', 10), ('b', 20), ('args', (30,)), ('c', {}), ('kw', {'d':1})])
3353
3354 # Make sure that BoundArguments produced by bind_partial()
3355 # are supported.
3356 def foo(a, b): pass
3357 sig = inspect.signature(foo)
3358 ba = sig.bind_partial(20)
3359 ba.apply_defaults()
3360 self.assertEqual(
3361 list(ba.arguments.items()),
3362 [('a', 20)])
3363
3364 # Test no args
3365 def foo(): pass
3366 sig = inspect.signature(foo)
3367 ba = sig.bind()
3368 ba.apply_defaults()
3369 self.assertEqual(list(ba.arguments.items()), [])
3370
Yury Selivanovf9e1f2b2016-03-02 11:07:47 -05003371 # Make sure a no-args binding still acquires proper defaults.
3372 def foo(a='spam'): pass
3373 sig = inspect.signature(foo)
3374 ba = sig.bind()
3375 ba.apply_defaults()
3376 self.assertEqual(list(ba.arguments.items()), [('a', 'spam')])
3377
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003378
Yury Selivanovd82eddc2014-01-29 11:24:39 -05003379class TestSignaturePrivateHelpers(unittest.TestCase):
3380 def test_signature_get_bound_param(self):
3381 getter = inspect._signature_get_bound_param
3382
3383 self.assertEqual(getter('($self)'), 'self')
3384 self.assertEqual(getter('($self, obj)'), 'self')
3385 self.assertEqual(getter('($cls, /, obj)'), 'cls')
3386
Larry Hastings2623c8c2014-02-08 22:15:29 -08003387 def _strip_non_python_syntax(self, input,
3388 clean_signature, self_parameter, last_positional_only):
3389 computed_clean_signature, \
3390 computed_self_parameter, \
3391 computed_last_positional_only = \
3392 inspect._signature_strip_non_python_syntax(input)
3393 self.assertEqual(computed_clean_signature, clean_signature)
3394 self.assertEqual(computed_self_parameter, self_parameter)
3395 self.assertEqual(computed_last_positional_only, last_positional_only)
3396
3397 def test_signature_strip_non_python_syntax(self):
3398 self._strip_non_python_syntax(
3399 "($module, /, path, mode, *, dir_fd=None, " +
3400 "effective_ids=False,\n follow_symlinks=True)",
3401 "(module, path, mode, *, dir_fd=None, " +
3402 "effective_ids=False, follow_symlinks=True)",
3403 0,
3404 0)
3405
3406 self._strip_non_python_syntax(
3407 "($module, word, salt, /)",
3408 "(module, word, salt)",
3409 0,
3410 2)
3411
3412 self._strip_non_python_syntax(
3413 "(x, y=None, z=None, /)",
3414 "(x, y=None, z=None)",
3415 None,
3416 2)
3417
3418 self._strip_non_python_syntax(
3419 "(x, y=None, z=None)",
3420 "(x, y=None, z=None)",
3421 None,
3422 None)
3423
3424 self._strip_non_python_syntax(
3425 "(x,\n y=None,\n z = None )",
3426 "(x, y=None, z=None)",
3427 None,
3428 None)
3429
3430 self._strip_non_python_syntax(
3431 "",
3432 "",
3433 None,
3434 None)
3435
3436 self._strip_non_python_syntax(
3437 None,
3438 None,
3439 None,
3440 None)
3441
Nick Coghlan9c680b02015-04-13 12:54:54 -04003442class TestSignatureDefinitions(unittest.TestCase):
3443 # This test case provides a home for checking that particular APIs
3444 # have signatures available for introspection
3445
3446 @cpython_only
3447 @unittest.skipIf(MISSING_C_DOCSTRINGS,
3448 "Signature information for builtins requires docstrings")
3449 def test_builtins_have_signatures(self):
3450 # This checks all builtin callables in CPython have signatures
3451 # A few have signatures Signature can't yet handle, so we skip those
3452 # since they will have to wait until PEP 457 adds the required
3453 # introspection support to the inspect module
3454 # Some others also haven't been converted yet for various other
3455 # reasons, so we also skip those for the time being, but design
3456 # the test to fail in order to indicate when it needs to be
3457 # updated.
3458 no_signature = set()
3459 # These need PEP 457 groups
3460 needs_groups = {"range", "slice", "dir", "getattr",
3461 "next", "iter", "vars"}
3462 no_signature |= needs_groups
3463 # These need PEP 457 groups or a signature change to accept None
3464 needs_semantic_update = {"round"}
3465 no_signature |= needs_semantic_update
3466 # These need *args support in Argument Clinic
3467 needs_varargs = {"min", "max", "print", "__build_class__"}
3468 no_signature |= needs_varargs
3469 # These simply weren't covered in the initial AC conversion
3470 # for builtin callables
3471 not_converted_yet = {"open", "__import__"}
3472 no_signature |= not_converted_yet
3473 # These builtin types are expected to provide introspection info
3474 types_with_signatures = set()
3475 # Check the signatures we expect to be there
3476 ns = vars(builtins)
3477 for name, obj in sorted(ns.items()):
3478 if not callable(obj):
3479 continue
3480 # The builtin types haven't been converted to AC yet
3481 if isinstance(obj, type) and (name not in types_with_signatures):
3482 # Note that this also skips all the exception types
3483 no_signature.add(name)
3484 if (name in no_signature):
3485 # Not yet converted
3486 continue
3487 with self.subTest(builtin=name):
3488 self.assertIsNotNone(inspect.signature(obj))
3489 # Check callables that haven't been converted don't claim a signature
3490 # This ensures this test will start failing as more signatures are
3491 # added, so the affected items can be moved into the scope of the
3492 # regression test above
3493 for name in no_signature:
3494 with self.subTest(builtin=name):
3495 self.assertIsNone(obj.__text_signature__)
3496
Yury Selivanovd82eddc2014-01-29 11:24:39 -05003497
Nick Coghlane8c45d62013-07-28 20:00:01 +10003498class TestUnwrap(unittest.TestCase):
3499
3500 def test_unwrap_one(self):
3501 def func(a, b):
3502 return a + b
3503 wrapper = functools.lru_cache(maxsize=20)(func)
3504 self.assertIs(inspect.unwrap(wrapper), func)
3505
3506 def test_unwrap_several(self):
3507 def func(a, b):
3508 return a + b
3509 wrapper = func
3510 for __ in range(10):
3511 @functools.wraps(wrapper)
3512 def wrapper():
3513 pass
3514 self.assertIsNot(wrapper.__wrapped__, func)
3515 self.assertIs(inspect.unwrap(wrapper), func)
3516
3517 def test_stop(self):
3518 def func1(a, b):
3519 return a + b
3520 @functools.wraps(func1)
3521 def func2():
3522 pass
3523 @functools.wraps(func2)
3524 def wrapper():
3525 pass
3526 func2.stop_here = 1
3527 unwrapped = inspect.unwrap(wrapper,
3528 stop=(lambda f: hasattr(f, "stop_here")))
3529 self.assertIs(unwrapped, func2)
3530
3531 def test_cycle(self):
3532 def func1(): pass
3533 func1.__wrapped__ = func1
3534 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3535 inspect.unwrap(func1)
3536
3537 def func2(): pass
3538 func2.__wrapped__ = func1
3539 func1.__wrapped__ = func2
3540 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3541 inspect.unwrap(func1)
3542 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3543 inspect.unwrap(func2)
3544
3545 def test_unhashable(self):
3546 def func(): pass
3547 func.__wrapped__ = None
3548 class C:
3549 __hash__ = None
3550 __wrapped__ = func
3551 self.assertIsNone(inspect.unwrap(C()))
3552
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003553class TestMain(unittest.TestCase):
3554 def test_only_source(self):
3555 module = importlib.import_module('unittest')
3556 rc, out, err = assert_python_ok('-m', 'inspect',
3557 'unittest')
3558 lines = out.decode().splitlines()
3559 # ignore the final newline
3560 self.assertEqual(lines[:-1], inspect.getsource(module).splitlines())
3561 self.assertEqual(err, b'')
3562
Yury Selivanov42407ab2014-06-23 10:23:50 -07003563 def test_custom_getattr(self):
3564 def foo():
3565 pass
3566 foo.__signature__ = 42
3567 with self.assertRaises(TypeError):
3568 inspect.signature(foo)
3569
Brett Cannon634a8fc2013-10-02 10:25:42 -04003570 @unittest.skipIf(ThreadPoolExecutor is None,
Brett Cannon0de3f012013-10-02 10:58:58 -04003571 'threads required to test __qualname__ for source files')
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003572 def test_qualname_source(self):
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003573 rc, out, err = assert_python_ok('-m', 'inspect',
3574 'concurrent.futures:ThreadPoolExecutor')
3575 lines = out.decode().splitlines()
3576 # ignore the final newline
3577 self.assertEqual(lines[:-1],
Brett Cannon634a8fc2013-10-02 10:25:42 -04003578 inspect.getsource(ThreadPoolExecutor).splitlines())
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003579 self.assertEqual(err, b'')
3580
3581 def test_builtins(self):
3582 module = importlib.import_module('unittest')
3583 _, out, err = assert_python_failure('-m', 'inspect',
3584 'sys')
3585 lines = err.decode().splitlines()
3586 self.assertEqual(lines, ["Can't get info for builtin modules."])
3587
3588 def test_details(self):
3589 module = importlib.import_module('unittest')
Victor Stinner9def2842016-01-18 12:15:08 +01003590 args = support.optim_args_from_interpreter_flags()
3591 rc, out, err = assert_python_ok(*args, '-m', 'inspect',
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003592 'unittest', '--details')
3593 output = out.decode()
3594 # Just a quick sanity check on the output
3595 self.assertIn(module.__name__, output)
3596 self.assertIn(module.__file__, output)
Victor Stinner9def2842016-01-18 12:15:08 +01003597 self.assertIn(module.__cached__, output)
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003598 self.assertEqual(err, b'')
3599
3600
Yury Selivanovef1e7502014-12-08 16:05:34 -05003601class TestReload(unittest.TestCase):
3602
3603 src_before = textwrap.dedent("""\
3604def foo():
3605 print("Bla")
3606 """)
3607
3608 src_after = textwrap.dedent("""\
3609def foo():
3610 print("Oh no!")
3611 """)
3612
3613 def assertInspectEqual(self, path, source):
3614 inspected_src = inspect.getsource(source)
3615 with open(path) as src:
3616 self.assertEqual(
3617 src.read().splitlines(True),
3618 inspected_src.splitlines(True)
3619 )
3620
3621 def test_getsource_reload(self):
3622 # see issue 1218234
3623 with _ready_to_import('reload_bug', self.src_before) as (name, path):
3624 module = importlib.import_module(name)
3625 self.assertInspectEqual(path, module)
3626 with open(path, 'w') as src:
3627 src.write(self.src_after)
3628 self.assertInspectEqual(path, module)
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003629
Nick Coghlane8c45d62013-07-28 20:00:01 +10003630
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00003631def test_main():
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00003632 run_unittest(
3633 TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBuggyCases,
3634 TestInterpreterStack, TestClassesAndFunctions, TestPredicates,
3635 TestGetcallargsFunctions, TestGetcallargsMethods,
Alexander Belopolskyf546e702010-12-02 00:10:11 +00003636 TestGetcallargsUnboundMethods, TestGetattrStatic, TestGetGeneratorState,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003637 TestNoEOL, TestSignatureObject, TestSignatureBind, TestParameterObject,
Nick Coghlan9c680b02015-04-13 12:54:54 -04003638 TestBoundArguments, TestSignaturePrivateHelpers,
3639 TestSignatureDefinitions,
Yury Selivanov5376ba92015-06-22 12:19:30 -04003640 TestGetClosureVars, TestUnwrap, TestMain, TestReload,
3641 TestGetCoroutineState
Michael Foord95fc51d2010-11-20 15:07:30 +00003642 )
Martin v. Löwis893ffa42003-10-31 15:35:53 +00003643
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00003644if __name__ == "__main__":
3645 test_main()