blob: e8eddbedf7e1af0d4ef271ec7ada26008359d20d [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
Natefcfe80e2017-04-24 10:06:15 -0700232 def test_isabstract_during_init_subclass(self):
233 from abc import ABCMeta, abstractmethod
234 isabstract_checks = []
235 class AbstractChecker(metaclass=ABCMeta):
236 def __init_subclass__(cls):
237 isabstract_checks.append(inspect.isabstract(cls))
238 class AbstractClassExample(AbstractChecker):
239 @abstractmethod
240 def foo(self):
241 pass
242 class ClassExample(AbstractClassExample):
243 def foo(self):
244 pass
245 self.assertEqual(isabstract_checks, [True, False])
246
247 isabstract_checks.clear()
248 class AbstractChild(AbstractClassExample):
249 pass
250 class AbstractGrandchild(AbstractChild):
251 pass
252 class ConcreteGrandchild(ClassExample):
253 pass
254 self.assertEqual(isabstract_checks, [True, True, False])
255
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000256
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000257class TestInterpreterStack(IsTestBase):
258 def __init__(self, *args, **kwargs):
259 unittest.TestCase.__init__(self, *args, **kwargs)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000260
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000261 git.abuse(7, 8, 9)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000262
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000263 def test_abuse_done(self):
264 self.istest(inspect.istraceback, 'git.ex[2]')
265 self.istest(inspect.isframe, 'mod.fr')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000266
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000267 def test_stack(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000268 self.assertTrue(len(mod.st) >= 5)
Christian Heimesa3538eb2007-11-06 11:44:48 +0000269 self.assertEqual(revise(*mod.st[0][1:]),
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000270 (modfile, 16, 'eggs', [' st = inspect.stack()\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000271 self.assertEqual(revise(*mod.st[1][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000272 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000273 self.assertEqual(revise(*mod.st[2][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000274 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000275 self.assertEqual(revise(*mod.st[3][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000276 (modfile, 39, 'abuse', [' self.argue(a, b, c)\n'], 0))
Antoine Pitroucdcafb72014-08-24 10:50:28 -0400277 # Test named tuple fields
278 record = mod.st[0]
279 self.assertIs(record.frame, mod.fr)
280 self.assertEqual(record.lineno, 16)
281 self.assertEqual(record.filename, mod.__file__)
282 self.assertEqual(record.function, 'eggs')
283 self.assertIn('inspect.stack()', record.code_context[0])
284 self.assertEqual(record.index, 0)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000285
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000286 def test_trace(self):
287 self.assertEqual(len(git.tr), 3)
Florent Xiclunac8575922010-03-24 17:37:49 +0000288 self.assertEqual(revise(*git.tr[0][1:]),
289 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
290 self.assertEqual(revise(*git.tr[1][1:]),
291 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
292 self.assertEqual(revise(*git.tr[2][1:]),
293 (modfile, 18, 'eggs', [' q = y / 0\n'], 0))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000294
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000295 def test_frame(self):
296 args, varargs, varkw, locals = inspect.getargvalues(mod.fr)
297 self.assertEqual(args, ['x', 'y'])
298 self.assertEqual(varargs, None)
299 self.assertEqual(varkw, None)
300 self.assertEqual(locals, {'x': 11, 'p': 11, 'y': 14})
301 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
302 '(x=11, y=14)')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000303
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000304 def test_previous_frame(self):
305 args, varargs, varkw, locals = inspect.getargvalues(mod.fr.f_back)
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000306 self.assertEqual(args, ['a', 'b', 'c', 'd', 'e', 'f'])
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000307 self.assertEqual(varargs, 'g')
308 self.assertEqual(varkw, 'h')
309 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000310 '(a=7, b=8, c=9, d=3, e=4, f=5, *g=(), **h={})')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000311
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000312class GetSourceBase(unittest.TestCase):
313 # Subclasses must override.
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000314 fodderModule = None
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000315
Yury Selivanov6738b112015-05-16 10:10:21 -0400316 def setUp(self):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000317 with open(inspect.getsourcefile(self.fodderModule)) as fp:
Philip Jenveya27c5bd2009-05-28 06:09:08 +0000318 self.source = fp.read()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000319
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000320 def sourcerange(self, top, bottom):
321 lines = self.source.split("\n")
322 return "\n".join(lines[top-1:bottom]) + "\n"
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000323
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000324 def assertSourceEqual(self, obj, top, bottom):
325 self.assertEqual(inspect.getsource(obj),
326 self.sourcerange(top, bottom))
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000327
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000328class TestRetrievingSourceCode(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000329 fodderModule = mod
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000330
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000331 def test_getclasses(self):
332 classes = inspect.getmembers(mod, inspect.isclass)
333 self.assertEqual(classes,
334 [('FesteringGob', mod.FesteringGob),
335 ('MalodorousPervert', mod.MalodorousPervert),
336 ('ParrotDroppings', mod.ParrotDroppings),
Serhiy Storchaka362c1b52013-09-05 17:14:32 +0300337 ('StupidGit', mod.StupidGit),
338 ('Tit', mod.MalodorousPervert),
339 ])
340 tree = inspect.getclasstree([cls[1] for cls in classes])
341 self.assertEqual(tree,
342 [(object, ()),
343 [(mod.ParrotDroppings, (object,)),
344 [(mod.FesteringGob, (mod.MalodorousPervert,
345 mod.ParrotDroppings))
346 ],
347 (mod.StupidGit, (object,)),
348 [(mod.MalodorousPervert, (mod.StupidGit,)),
349 [(mod.FesteringGob, (mod.MalodorousPervert,
350 mod.ParrotDroppings))
351 ]
352 ]
353 ]
354 ])
355 tree = inspect.getclasstree([cls[1] for cls in classes], True)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000356 self.assertEqual(tree,
Thomas Wouters725af872006-04-15 09:13:19 +0000357 [(object, ()),
358 [(mod.ParrotDroppings, (object,)),
359 (mod.StupidGit, (object,)),
360 [(mod.MalodorousPervert, (mod.StupidGit,)),
361 [(mod.FesteringGob, (mod.MalodorousPervert,
362 mod.ParrotDroppings))
363 ]
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000364 ]
365 ]
366 ])
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000367
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000368 def test_getfunctions(self):
369 functions = inspect.getmembers(mod, inspect.isfunction)
370 self.assertEqual(functions, [('eggs', mod.eggs),
Yury Selivanove4e811d2015-07-21 19:01:52 +0300371 ('lobbest', mod.lobbest),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000372 ('spam', mod.spam)])
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000373
R. David Murray378c0cf2010-02-24 01:46:21 +0000374 @unittest.skipIf(sys.flags.optimize >= 2,
375 "Docstrings are omitted with -O2 and above")
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000376 def test_getdoc(self):
377 self.assertEqual(inspect.getdoc(mod), 'A module docstring.')
378 self.assertEqual(inspect.getdoc(mod.StupidGit),
379 'A longer,\n\nindented\n\ndocstring.')
380 self.assertEqual(inspect.getdoc(git.abuse),
381 'Another\n\ndocstring\n\ncontaining\n\ntabs')
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000382
Serhiy Storchaka5cf2b7252015-04-03 22:38:53 +0300383 @unittest.skipIf(sys.flags.optimize >= 2,
384 "Docstrings are omitted with -O2 and above")
385 def test_getdoc_inherited(self):
386 self.assertEqual(inspect.getdoc(mod.FesteringGob),
387 'A longer,\n\nindented\n\ndocstring.')
388 self.assertEqual(inspect.getdoc(mod.FesteringGob.abuse),
389 'Another\n\ndocstring\n\ncontaining\n\ntabs')
390 self.assertEqual(inspect.getdoc(mod.FesteringGob().abuse),
391 'Another\n\ndocstring\n\ncontaining\n\ntabs')
392 self.assertEqual(inspect.getdoc(mod.FesteringGob.contradiction),
393 'The automatic gainsaying.')
394
395 @unittest.skipIf(MISSING_C_DOCSTRINGS, "test requires docstrings")
396 def test_finddoc(self):
397 finddoc = inspect._finddoc
398 self.assertEqual(finddoc(int), int.__doc__)
399 self.assertEqual(finddoc(int.to_bytes), int.to_bytes.__doc__)
400 self.assertEqual(finddoc(int().to_bytes), int.to_bytes.__doc__)
401 self.assertEqual(finddoc(int.from_bytes), int.from_bytes.__doc__)
402 self.assertEqual(finddoc(int.real), int.real.__doc__)
403
Georg Brandl0c77a822008-06-10 16:37:50 +0000404 def test_cleandoc(self):
405 self.assertEqual(inspect.cleandoc('An\n indented\n docstring.'),
406 'An\nindented\ndocstring.')
407
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000408 def test_getcomments(self):
409 self.assertEqual(inspect.getcomments(mod), '# line 1\n')
410 self.assertEqual(inspect.getcomments(mod.StupidGit), '# line 20\n')
Marco Buttu3f2155f2017-03-17 09:50:23 +0100411 # If the object source file is not available, return None.
412 co = compile('x=1', '_non_existing_filename.py', 'exec')
413 self.assertIsNone(inspect.getcomments(co))
414 # If the object has been defined in C, return None.
415 self.assertIsNone(inspect.getcomments(list))
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000416
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000417 def test_getmodule(self):
Thomas Wouters89f507f2006-12-13 04:49:30 +0000418 # Check actual module
419 self.assertEqual(inspect.getmodule(mod), mod)
420 # Check class (uses __module__ attribute)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000421 self.assertEqual(inspect.getmodule(mod.StupidGit), mod)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000422 # Check a method (no __module__ attribute, falls back to filename)
423 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
424 # Do it again (check the caching isn't broken)
425 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
426 # Check a builtin
Georg Brandl1a3284e2007-12-02 09:40:06 +0000427 self.assertEqual(inspect.getmodule(str), sys.modules["builtins"])
Thomas Wouters89f507f2006-12-13 04:49:30 +0000428 # Check filename override
429 self.assertEqual(inspect.getmodule(None, modfile), mod)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000430
Berker Peksagff0e3b72017-01-02 06:57:43 +0300431 def test_getframeinfo_get_first_line(self):
432 frame_info = inspect.getframeinfo(self.fodderModule.fr, 50)
433 self.assertEqual(frame_info.code_context[0], "# line 1\n")
434 self.assertEqual(frame_info.code_context[1], "'A module docstring.'\n")
435
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000436 def test_getsource(self):
437 self.assertSourceEqual(git.abuse, 29, 39)
Serhiy Storchakaac4bdcc2015-10-29 08:15:50 +0200438 self.assertSourceEqual(mod.StupidGit, 21, 51)
439 self.assertSourceEqual(mod.lobbest, 75, 76)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000440
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000441 def test_getsourcefile(self):
Christian Heimesa3538eb2007-11-06 11:44:48 +0000442 self.assertEqual(normcase(inspect.getsourcefile(mod.spam)), modfile)
443 self.assertEqual(normcase(inspect.getsourcefile(git.abuse)), modfile)
R. David Murraya1b37402010-06-17 02:04:29 +0000444 fn = "_non_existing_filename_used_for_sourcefile_test.py"
Victor Stinner51d8c522016-02-08 17:57:02 +0100445 co = compile("x=1", fn, "exec")
R. David Murray4155f972010-06-17 13:23:18 +0000446 self.assertEqual(inspect.getsourcefile(co), None)
R. David Murraya1b37402010-06-17 02:04:29 +0000447 linecache.cache[co.co_filename] = (1, None, "None", co.co_filename)
Antoine Pitrou5d62a612012-07-08 13:48:46 +0200448 try:
449 self.assertEqual(normcase(inspect.getsourcefile(co)), fn)
450 finally:
451 del linecache.cache[co.co_filename]
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000452
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000453 def test_getfile(self):
454 self.assertEqual(inspect.getfile(mod.StupidGit), mod.__file__)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000455
Yury Selivanov2eed8b72014-01-27 13:24:56 -0500456 def test_getfile_class_without_module(self):
457 class CM(type):
458 @property
459 def __module__(cls):
460 raise AttributeError
461 class C(metaclass=CM):
462 pass
463 with self.assertRaises(TypeError):
464 inspect.getfile(C)
465
Thomas Kluyvere968bc732017-10-24 13:42:36 +0100466 def test_getfile_broken_repr(self):
467 class ErrorRepr:
468 def __repr__(self):
469 raise Exception('xyz')
470 er = ErrorRepr()
471 with self.assertRaises(TypeError):
472 inspect.getfile(er)
473
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000474 def test_getmodule_recursion(self):
Christian Heimes45f9af32007-11-27 21:50:00 +0000475 from types import ModuleType
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000476 name = '__inspect_dummy'
Christian Heimes45f9af32007-11-27 21:50:00 +0000477 m = sys.modules[name] = ModuleType(name)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000478 m.__file__ = "<string>" # hopefully not a real filename...
479 m.__loader__ = "dummy" # pretend the filename is understood by a loader
Georg Brandl7cae87c2006-09-06 06:51:57 +0000480 exec("def x(): pass", m.__dict__)
Neal Norwitz221085d2007-02-25 20:55:47 +0000481 self.assertEqual(inspect.getsourcefile(m.x.__code__), '<string>')
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000482 del sys.modules[name]
483 inspect.getmodule(compile('a=10','','single'))
484
Benjamin Peterson9620cc02011-06-11 15:53:11 -0500485 def test_proceed_with_fake_filename(self):
486 '''doctest monkeypatches linecache to enable inspection'''
487 fn, source = '<test>', 'def x(): pass\n'
488 getlines = linecache.getlines
489 def monkey(filename, module_globals=None):
490 if filename == fn:
Ezio Melottid8b509b2011-09-28 17:37:55 +0300491 return source.splitlines(keepends=True)
Benjamin Peterson9620cc02011-06-11 15:53:11 -0500492 else:
493 return getlines(filename, module_globals)
494 linecache.getlines = monkey
495 try:
496 ns = {}
497 exec(compile(source, fn, 'single'), ns)
498 inspect.getsource(ns["x"])
499 finally:
500 linecache.getlines = getlines
501
Antoine Pitroua8723a02015-04-15 00:41:29 +0200502 def test_getsource_on_code_object(self):
503 self.assertSourceEqual(mod.eggs.__code__, 12, 18)
504
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000505class TestDecorators(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000506 fodderModule = mod2
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000507
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000508 def test_wrapped_decorator(self):
Christian Heimes09aaa882008-02-23 15:01:06 +0000509 self.assertSourceEqual(mod2.wrapped, 14, 17)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000510
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000511 def test_replacing_decorator(self):
512 self.assertSourceEqual(mod2.gone, 9, 10)
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000513
Yury Selivanov081bbf62014-09-26 17:34:54 -0400514 def test_getsource_unwrap(self):
Antoine Pitroua8723a02015-04-15 00:41:29 +0200515 self.assertSourceEqual(mod2.real, 130, 132)
516
517 def test_decorator_with_lambda(self):
518 self.assertSourceEqual(mod2.func114, 113, 115)
Yury Selivanov081bbf62014-09-26 17:34:54 -0400519
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000520class TestOneliners(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000521 fodderModule = mod2
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000522 def test_oneline_lambda(self):
523 # Test inspect.getsource with a one-line lambda function.
524 self.assertSourceEqual(mod2.oll, 25, 25)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000525
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000526 def test_threeline_lambda(self):
527 # Test inspect.getsource with a three-line lambda function,
528 # where the second and third lines are _not_ indented.
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000529 self.assertSourceEqual(mod2.tll, 28, 30)
530
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000531 def test_twoline_indented_lambda(self):
532 # Test inspect.getsource with a two-line lambda function,
533 # where the second line _is_ indented.
534 self.assertSourceEqual(mod2.tlli, 33, 34)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000535
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000536 def test_onelinefunc(self):
537 # Test inspect.getsource with a regular one-line function.
538 self.assertSourceEqual(mod2.onelinefunc, 37, 37)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000539
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000540 def test_manyargs(self):
541 # Test inspect.getsource with a regular function where
542 # the arguments are on two lines and _not_ indented and
543 # the body on the second line with the last arguments.
544 self.assertSourceEqual(mod2.manyargs, 40, 41)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000545
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000546 def test_twolinefunc(self):
547 # Test inspect.getsource with a regular function where
548 # the body is on two lines, following the argument list and
549 # continued on the next line by a \\.
550 self.assertSourceEqual(mod2.twolinefunc, 44, 45)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000551
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000552 def test_lambda_in_list(self):
553 # Test inspect.getsource with a one-line lambda function
554 # defined in a list, indented.
555 self.assertSourceEqual(mod2.a[1], 49, 49)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000556
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000557 def test_anonymous(self):
558 # Test inspect.getsource with a lambda function defined
559 # as argument to another function.
560 self.assertSourceEqual(mod2.anonymous, 55, 55)
561
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000562class TestBuggyCases(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000563 fodderModule = mod2
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000564
565 def test_with_comment(self):
566 self.assertSourceEqual(mod2.with_comment, 58, 59)
567
568 def test_multiline_sig(self):
569 self.assertSourceEqual(mod2.multiline_sig[0], 63, 64)
570
Armin Rigodd5c0232005-09-25 11:45:45 +0000571 def test_nested_class(self):
572 self.assertSourceEqual(mod2.func69().func71, 71, 72)
573
574 def test_one_liner_followed_by_non_name(self):
575 self.assertSourceEqual(mod2.func77, 77, 77)
576
577 def test_one_liner_dedent_non_name(self):
578 self.assertSourceEqual(mod2.cls82.func83, 83, 83)
579
580 def test_with_comment_instead_of_docstring(self):
581 self.assertSourceEqual(mod2.func88, 88, 90)
582
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000583 def test_method_in_dynamic_class(self):
584 self.assertSourceEqual(mod2.method_in_dynamic_class, 95, 97)
585
R David Murray32562d72014-10-03 11:15:38 -0400586 # This should not skip for CPython, but might on a repackaged python where
587 # unicodedata is not an external module, or on pypy.
588 @unittest.skipIf(not hasattr(unicodedata, '__file__') or
589 unicodedata.__file__.endswith('.py'),
590 "unicodedata is not an external binary module")
R. David Murray74b89242009-05-13 17:33:03 +0000591 def test_findsource_binary(self):
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200592 self.assertRaises(OSError, inspect.getsource, unicodedata)
593 self.assertRaises(OSError, inspect.findsource, unicodedata)
R. David Murray74b89242009-05-13 17:33:03 +0000594
R. David Murraya1b37402010-06-17 02:04:29 +0000595 def test_findsource_code_in_linecache(self):
596 lines = ["x=1"]
597 co = compile(lines[0], "_dynamically_created_file", "exec")
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200598 self.assertRaises(OSError, inspect.findsource, co)
599 self.assertRaises(OSError, inspect.getsource, co)
R. David Murraya1b37402010-06-17 02:04:29 +0000600 linecache.cache[co.co_filename] = (1, None, lines, co.co_filename)
Antoine Pitrou5d62a612012-07-08 13:48:46 +0200601 try:
602 self.assertEqual(inspect.findsource(co), (lines,0))
603 self.assertEqual(inspect.getsource(co), lines[0])
604 finally:
605 del linecache.cache[co.co_filename]
R. David Murraya1b37402010-06-17 02:04:29 +0000606
Ezio Melotti1b145922013-03-30 05:17:24 +0200607 def test_findsource_without_filename(self):
608 for fname in ['', '<string>']:
609 co = compile('x=1', fname, "exec")
610 self.assertRaises(IOError, inspect.findsource, co)
611 self.assertRaises(IOError, inspect.getsource, co)
612
Antoine Pitroua8723a02015-04-15 00:41:29 +0200613 def test_getsource_on_method(self):
614 self.assertSourceEqual(mod2.ClassWithMethod.method, 118, 119)
615
Yury Selivanov4f4913b2015-07-23 17:10:00 +0300616 def test_nested_func(self):
617 self.assertSourceEqual(mod2.cls135.func136, 136, 139)
618
619
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000620class TestNoEOL(GetSourceBase):
Yury Selivanov6738b112015-05-16 10:10:21 -0400621 def setUp(self):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000622 self.tempdir = TESTFN + '_dir'
623 os.mkdir(self.tempdir)
624 with open(os.path.join(self.tempdir,
625 'inspect_fodder3%spy' % os.extsep), 'w') as f:
626 f.write("class X:\n pass # No EOL")
627 with DirsOnSysPath(self.tempdir):
628 import inspect_fodder3 as mod3
629 self.fodderModule = mod3
Yury Selivanov6738b112015-05-16 10:10:21 -0400630 super().setUp()
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000631
632 def tearDown(self):
633 shutil.rmtree(self.tempdir)
634
635 def test_class(self):
636 self.assertSourceEqual(self.fodderModule.X, 1, 2)
637
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100638
639class _BrokenDataDescriptor(object):
640 """
641 A broken data descriptor. See bug #1785.
642 """
643 def __get__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700644 raise AttributeError("broken data descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100645
646 def __set__(*args):
647 raise RuntimeError
648
649 def __getattr__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700650 raise AttributeError("broken data descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100651
652
653class _BrokenMethodDescriptor(object):
654 """
655 A broken method descriptor. See bug #1785.
656 """
657 def __get__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700658 raise AttributeError("broken method descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100659
660 def __getattr__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700661 raise AttributeError("broken method descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100662
663
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000664# Helper for testing classify_class_attrs.
Tim Peters13b49d32001-09-23 02:00:29 +0000665def attrs_wo_objs(cls):
666 return [t[:3] for t in inspect.classify_class_attrs(cls)]
667
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100668
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000669class TestClassesAndFunctions(unittest.TestCase):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000670 def test_newstyle_mro(self):
671 # The same w/ new-class MRO.
672 class A(object): pass
673 class B(A): pass
674 class C(A): pass
675 class D(B, C): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000676
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000677 expected = (D, B, C, A, object)
678 got = inspect.getmro(D)
679 self.assertEqual(expected, got)
Tim Peters13b49d32001-09-23 02:00:29 +0000680
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500681 def assertArgSpecEquals(self, routine, args_e, varargs_e=None,
682 varkw_e=None, defaults_e=None, formatted=None):
683 with self.assertWarns(DeprecationWarning):
684 args, varargs, varkw, defaults = inspect.getargspec(routine)
685 self.assertEqual(args, args_e)
686 self.assertEqual(varargs, varargs_e)
687 self.assertEqual(varkw, varkw_e)
688 self.assertEqual(defaults, defaults_e)
689 if formatted is not None:
690 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults),
691 formatted)
692
Christian Heimes3795b532007-11-08 13:48:53 +0000693 def assertFullArgSpecEquals(self, routine, args_e, varargs_e=None,
694 varkw_e=None, defaults_e=None,
695 kwonlyargs_e=[], kwonlydefaults_e=None,
696 ann_e={}, formatted=None):
697 args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \
698 inspect.getfullargspec(routine)
699 self.assertEqual(args, args_e)
700 self.assertEqual(varargs, varargs_e)
701 self.assertEqual(varkw, varkw_e)
702 self.assertEqual(defaults, defaults_e)
703 self.assertEqual(kwonlyargs, kwonlyargs_e)
704 self.assertEqual(kwonlydefaults, kwonlydefaults_e)
705 self.assertEqual(ann, ann_e)
706 if formatted is not None:
707 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults,
708 kwonlyargs, kwonlydefaults, ann),
709 formatted)
710
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500711 def test_getargspec(self):
712 self.assertArgSpecEquals(mod.eggs, ['x', 'y'], formatted='(x, y)')
713
714 self.assertArgSpecEquals(mod.spam,
715 ['a', 'b', 'c', 'd', 'e', 'f'],
716 'g', 'h', (3, 4, 5),
717 '(a, b, c, d=3, e=4, f=5, *g, **h)')
718
719 self.assertRaises(ValueError, self.assertArgSpecEquals,
720 mod2.keyworded, [])
721
722 self.assertRaises(ValueError, self.assertArgSpecEquals,
723 mod2.annotated, [])
724 self.assertRaises(ValueError, self.assertArgSpecEquals,
725 mod2.keyword_only_arg, [])
726
727
Christian Heimes3795b532007-11-08 13:48:53 +0000728 def test_getfullargspec(self):
729 self.assertFullArgSpecEquals(mod2.keyworded, [], varargs_e='arg1',
730 kwonlyargs_e=['arg2'],
731 kwonlydefaults_e={'arg2':1},
732 formatted='(*arg1, arg2=1)')
733
734 self.assertFullArgSpecEquals(mod2.annotated, ['arg1'],
Christian Heimesc9543e42007-11-28 08:28:28 +0000735 ann_e={'arg1' : list},
Christian Heimes3795b532007-11-08 13:48:53 +0000736 formatted='(arg1: list)')
Benjamin Peterson9953a8d2009-01-17 04:15:01 +0000737 self.assertFullArgSpecEquals(mod2.keyword_only_arg, [],
738 kwonlyargs_e=['arg'],
739 formatted='(*, arg)')
740
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500741 def test_argspec_api_ignores_wrapped(self):
Yury Selivanov57d240e2014-02-19 16:27:23 -0500742 # Issue 20684: low level introspection API must ignore __wrapped__
743 @functools.wraps(mod.spam)
744 def ham(x, y):
745 pass
746 # Basic check
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500747 self.assertArgSpecEquals(ham, ['x', 'y'], formatted='(x, y)')
Yury Selivanov57d240e2014-02-19 16:27:23 -0500748 self.assertFullArgSpecEquals(ham, ['x', 'y'], formatted='(x, y)')
749 self.assertFullArgSpecEquals(functools.partial(ham),
750 ['x', 'y'], formatted='(x, y)')
751 # Other variants
752 def check_method(f):
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500753 self.assertArgSpecEquals(f, ['self', 'x', 'y'],
754 formatted='(self, x, y)')
Yury Selivanov57d240e2014-02-19 16:27:23 -0500755 class C:
756 @functools.wraps(mod.spam)
757 def ham(self, x, y):
758 pass
759 pham = functools.partialmethod(ham)
760 @functools.wraps(mod.spam)
761 def __call__(self, x, y):
762 pass
763 check_method(C())
764 check_method(C.ham)
765 check_method(C().ham)
766 check_method(C.pham)
767 check_method(C().pham)
768
769 class C_new:
770 @functools.wraps(mod.spam)
771 def __new__(self, x, y):
772 pass
773 check_method(C_new)
774
775 class C_init:
776 @functools.wraps(mod.spam)
777 def __init__(self, x, y):
778 pass
779 check_method(C_init)
780
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500781 def test_getfullargspec_signature_attr(self):
782 def test():
783 pass
784 spam_param = inspect.Parameter('spam', inspect.Parameter.POSITIONAL_ONLY)
785 test.__signature__ = inspect.Signature(parameters=(spam_param,))
786
787 self.assertFullArgSpecEquals(test, args_e=['spam'], formatted='(spam)')
788
Yury Selivanov4cb93912014-01-29 11:54:12 -0500789 def test_getfullargspec_signature_annos(self):
790 def test(a:'spam') -> 'ham': pass
791 spec = inspect.getfullargspec(test)
792 self.assertEqual(test.__annotations__, spec.annotations)
793
794 def test(): pass
795 spec = inspect.getfullargspec(test)
796 self.assertEqual(test.__annotations__, spec.annotations)
797
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500798 @unittest.skipIf(MISSING_C_DOCSTRINGS,
799 "Signature information for builtins requires docstrings")
800 def test_getfullargspec_builtin_methods(self):
801 self.assertFullArgSpecEquals(_pickle.Pickler.dump,
802 args_e=['self', 'obj'], formatted='(self, obj)')
803
804 self.assertFullArgSpecEquals(_pickle.Pickler(io.BytesIO()).dump,
805 args_e=['self', 'obj'], formatted='(self, obj)')
806
Yury Selivanov8c185ee2014-02-21 01:32:42 -0500807 self.assertFullArgSpecEquals(
808 os.stat,
809 args_e=['path'],
810 kwonlyargs_e=['dir_fd', 'follow_symlinks'],
811 kwonlydefaults_e={'dir_fd': None, 'follow_symlinks': True},
812 formatted='(path, *, dir_fd=None, follow_symlinks=True)')
813
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200814 @cpython_only
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500815 @unittest.skipIf(MISSING_C_DOCSTRINGS,
816 "Signature information for builtins requires docstrings")
817 def test_getfullagrspec_builtin_func(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200818 import _testcapi
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500819 builtin = _testcapi.docstring_with_signature_with_defaults
820 spec = inspect.getfullargspec(builtin)
821 self.assertEqual(spec.defaults[0], 'avocado')
822
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200823 @cpython_only
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500824 @unittest.skipIf(MISSING_C_DOCSTRINGS,
825 "Signature information for builtins requires docstrings")
826 def test_getfullagrspec_builtin_func_no_signature(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200827 import _testcapi
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500828 builtin = _testcapi.docstring_no_signature
829 with self.assertRaises(TypeError):
830 inspect.getfullargspec(builtin)
Christian Heimes3795b532007-11-08 13:48:53 +0000831
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500832 def test_getargspec_method(self):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000833 class A(object):
834 def m(self):
835 pass
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500836 self.assertArgSpecEquals(A.m, ['self'])
Tim Peters13b49d32001-09-23 02:00:29 +0000837
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000838 def test_classify_newstyle(self):
839 class A(object):
Tim Peters13b49d32001-09-23 02:00:29 +0000840
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000841 def s(): pass
842 s = staticmethod(s)
Tim Peters13b49d32001-09-23 02:00:29 +0000843
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000844 def c(cls): pass
845 c = classmethod(c)
Tim Peters13b49d32001-09-23 02:00:29 +0000846
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000847 def getp(self): pass
848 p = property(getp)
Tim Peters13b49d32001-09-23 02:00:29 +0000849
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000850 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000851
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000852 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000853
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000854 datablob = '1'
Tim Peters13b49d32001-09-23 02:00:29 +0000855
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100856 dd = _BrokenDataDescriptor()
857 md = _BrokenMethodDescriptor()
858
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000859 attrs = attrs_wo_objs(A)
Yury Selivanov0860a0b2014-01-31 14:28:44 -0500860
Serhiy Storchaka3327a2d2017-12-15 14:13:41 +0200861 self.assertIn(('__new__', 'static method', object), attrs,
862 'missing __new__')
Yury Selivanov0860a0b2014-01-31 14:28:44 -0500863 self.assertIn(('__init__', 'method', object), attrs, 'missing __init__')
864
Benjamin Peterson577473f2010-01-19 00:09:57 +0000865 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
866 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
867 self.assertIn(('p', 'property', A), attrs, 'missing property')
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000868 self.assertIn(('m', 'method', A), attrs,
869 'missing plain method: %r' % attrs)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000870 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
871 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100872 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
873 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000874
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000875 class B(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000876
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000877 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000878
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000879 attrs = attrs_wo_objs(B)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000880 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
881 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
882 self.assertIn(('p', 'property', A), attrs, 'missing property')
883 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
884 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
885 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100886 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
887 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000888
889
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000890 class C(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000891
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000892 def m(self): pass
893 def c(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000894
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000895 attrs = attrs_wo_objs(C)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000896 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
897 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
898 self.assertIn(('p', 'property', A), attrs, 'missing property')
899 self.assertIn(('m', 'method', C), attrs, 'missing plain method')
900 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
901 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100902 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
903 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000904
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000905 class D(B, C):
Tim Peters13b49d32001-09-23 02:00:29 +0000906
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000907 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000908
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000909 attrs = attrs_wo_objs(D)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000910 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
911 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
912 self.assertIn(('p', 'property', A), attrs, 'missing property')
913 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
914 self.assertIn(('m1', 'method', D), attrs, 'missing plain method')
915 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100916 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
917 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
918
919 def test_classify_builtin_types(self):
920 # Simple sanity check that all built-in types can have their
921 # attributes classified.
922 for name in dir(__builtins__):
923 builtin = getattr(__builtins__, name)
924 if isinstance(builtin, type):
925 inspect.classify_class_attrs(builtin)
926
Serhiy Storchaka3327a2d2017-12-15 14:13:41 +0200927 attrs = attrs_wo_objs(bool)
928 self.assertIn(('__new__', 'static method', bool), attrs,
929 'missing __new__')
930 self.assertIn(('from_bytes', 'class method', int), attrs,
931 'missing class method')
932 self.assertIn(('to_bytes', 'method', int), attrs,
933 'missing plain method')
934 self.assertIn(('__add__', 'method', int), attrs,
935 'missing plain method')
936 self.assertIn(('__and__', 'method', bool), attrs,
937 'missing plain method')
938
Ethan Furman63c141c2013-10-18 00:27:39 -0700939 def test_classify_DynamicClassAttribute(self):
940 class Meta(type):
941 def __getattr__(self, name):
942 if name == 'ham':
943 return 'spam'
944 return super().__getattr__(name)
945 class VA(metaclass=Meta):
Ethan Furmane03ea372013-09-25 07:14:41 -0700946 @types.DynamicClassAttribute
947 def ham(self):
948 return 'eggs'
Ethan Furman63c141c2013-10-18 00:27:39 -0700949 should_find_dca = inspect.Attribute('ham', 'data', VA, VA.__dict__['ham'])
950 self.assertIn(should_find_dca, inspect.classify_class_attrs(VA))
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700951 should_find_ga = inspect.Attribute('ham', 'data', Meta, 'spam')
Ethan Furman63c141c2013-10-18 00:27:39 -0700952 self.assertIn(should_find_ga, inspect.classify_class_attrs(VA))
953
Yury Selivanovbf341fb2015-05-21 15:41:57 -0400954 def test_classify_overrides_bool(self):
955 class NoBool(object):
956 def __eq__(self, other):
957 return NoBool()
958
959 def __bool__(self):
960 raise NotImplementedError(
961 "This object does not specify a boolean value")
962
963 class HasNB(object):
964 dd = NoBool()
965
966 should_find_attr = inspect.Attribute('dd', 'data', HasNB, HasNB.dd)
967 self.assertIn(should_find_attr, inspect.classify_class_attrs(HasNB))
968
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700969 def test_classify_metaclass_class_attribute(self):
970 class Meta(type):
971 fish = 'slap'
972 def __dir__(self):
Serhiy Storchakaa60c2fe2015-03-12 21:56:08 +0200973 return ['__class__', '__module__', '__name__', 'fish']
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700974 class Class(metaclass=Meta):
975 pass
976 should_find = inspect.Attribute('fish', 'data', Meta, 'slap')
977 self.assertIn(should_find, inspect.classify_class_attrs(Class))
978
Ethan Furman63c141c2013-10-18 00:27:39 -0700979 def test_classify_VirtualAttribute(self):
980 class Meta(type):
981 def __dir__(cls):
982 return ['__class__', '__module__', '__name__', 'BOOM']
983 def __getattr__(self, name):
984 if name =='BOOM':
985 return 42
986 return super().__getattr(name)
987 class Class(metaclass=Meta):
988 pass
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700989 should_find = inspect.Attribute('BOOM', 'data', Meta, 42)
Ethan Furman63c141c2013-10-18 00:27:39 -0700990 self.assertIn(should_find, inspect.classify_class_attrs(Class))
991
992 def test_classify_VirtualAttribute_multi_classes(self):
993 class Meta1(type):
994 def __dir__(cls):
995 return ['__class__', '__module__', '__name__', 'one']
996 def __getattr__(self, name):
997 if name =='one':
998 return 1
999 return super().__getattr__(name)
1000 class Meta2(type):
1001 def __dir__(cls):
1002 return ['__class__', '__module__', '__name__', 'two']
1003 def __getattr__(self, name):
1004 if name =='two':
1005 return 2
1006 return super().__getattr__(name)
1007 class Meta3(Meta1, Meta2):
1008 def __dir__(cls):
1009 return list(sorted(set(['__class__', '__module__', '__name__', 'three'] +
1010 Meta1.__dir__(cls) + Meta2.__dir__(cls))))
1011 def __getattr__(self, name):
1012 if name =='three':
1013 return 3
1014 return super().__getattr__(name)
1015 class Class1(metaclass=Meta1):
1016 pass
1017 class Class2(Class1, metaclass=Meta3):
1018 pass
1019
Ethan Furmanb0c84cd2013-10-20 22:37:39 -07001020 should_find1 = inspect.Attribute('one', 'data', Meta1, 1)
1021 should_find2 = inspect.Attribute('two', 'data', Meta2, 2)
1022 should_find3 = inspect.Attribute('three', 'data', Meta3, 3)
Ethan Furman63c141c2013-10-18 00:27:39 -07001023 cca = inspect.classify_class_attrs(Class2)
1024 for sf in (should_find1, should_find2, should_find3):
1025 self.assertIn(sf, cca)
1026
1027 def test_classify_class_attrs_with_buggy_dir(self):
1028 class M(type):
1029 def __dir__(cls):
1030 return ['__class__', '__name__', 'missing']
1031 class C(metaclass=M):
1032 pass
1033 attrs = [a[0] for a in inspect.classify_class_attrs(C)]
1034 self.assertNotIn('missing', attrs)
Ethan Furmane03ea372013-09-25 07:14:41 -07001035
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +01001036 def test_getmembers_descriptors(self):
1037 class A(object):
1038 dd = _BrokenDataDescriptor()
1039 md = _BrokenMethodDescriptor()
1040
1041 def pred_wrapper(pred):
1042 # A quick'n'dirty way to discard standard attributes of new-style
1043 # classes.
1044 class Empty(object):
1045 pass
1046 def wrapped(x):
1047 if '__name__' in dir(x) and hasattr(Empty, x.__name__):
1048 return False
1049 return pred(x)
1050 return wrapped
1051
1052 ismethoddescriptor = pred_wrapper(inspect.ismethoddescriptor)
1053 isdatadescriptor = pred_wrapper(inspect.isdatadescriptor)
1054
1055 self.assertEqual(inspect.getmembers(A, ismethoddescriptor),
1056 [('md', A.__dict__['md'])])
1057 self.assertEqual(inspect.getmembers(A, isdatadescriptor),
1058 [('dd', A.__dict__['dd'])])
1059
1060 class B(A):
1061 pass
1062
1063 self.assertEqual(inspect.getmembers(B, ismethoddescriptor),
1064 [('md', A.__dict__['md'])])
1065 self.assertEqual(inspect.getmembers(B, isdatadescriptor),
1066 [('dd', A.__dict__['dd'])])
1067
Antoine Pitrou0c603812012-01-18 17:40:18 +01001068 def test_getmembers_method(self):
1069 class B:
1070 def f(self):
1071 pass
1072
1073 self.assertIn(('f', B.f), inspect.getmembers(B))
1074 self.assertNotIn(('f', B.f), inspect.getmembers(B, inspect.ismethod))
1075 b = B()
1076 self.assertIn(('f', b.f), inspect.getmembers(b))
1077 self.assertIn(('f', b.f), inspect.getmembers(b, inspect.ismethod))
1078
Ethan Furmane03ea372013-09-25 07:14:41 -07001079 def test_getmembers_VirtualAttribute(self):
Ethan Furman63c141c2013-10-18 00:27:39 -07001080 class M(type):
1081 def __getattr__(cls, name):
1082 if name == 'eggs':
1083 return 'scrambled'
1084 return super().__getattr__(name)
1085 class A(metaclass=M):
Ethan Furmane03ea372013-09-25 07:14:41 -07001086 @types.DynamicClassAttribute
1087 def eggs(self):
1088 return 'spam'
Ethan Furman63c141c2013-10-18 00:27:39 -07001089 self.assertIn(('eggs', 'scrambled'), inspect.getmembers(A))
1090 self.assertIn(('eggs', 'spam'), inspect.getmembers(A()))
1091
1092 def test_getmembers_with_buggy_dir(self):
1093 class M(type):
1094 def __dir__(cls):
1095 return ['__class__', '__name__', 'missing']
1096 class C(metaclass=M):
1097 pass
1098 attrs = [a[0] for a in inspect.getmembers(C)]
1099 self.assertNotIn('missing', attrs)
Ethan Furmane03ea372013-09-25 07:14:41 -07001100
Jeremy Hyltonc4bf5ed2003-06-27 18:43:12 +00001101
Nick Coghlan2f92e542012-06-23 19:39:55 +10001102_global_ref = object()
1103class TestGetClosureVars(unittest.TestCase):
1104
1105 def test_name_resolution(self):
1106 # Basic test of the 4 different resolution mechanisms
1107 def f(nonlocal_ref):
1108 def g(local_ref):
1109 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
1110 return g
1111 _arg = object()
1112 nonlocal_vars = {"nonlocal_ref": _arg}
1113 global_vars = {"_global_ref": _global_ref}
1114 builtin_vars = {"print": print}
1115 unbound_names = {"unbound_ref"}
1116 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
1117 builtin_vars, unbound_names)
1118 self.assertEqual(inspect.getclosurevars(f(_arg)), expected)
1119
1120 def test_generator_closure(self):
1121 def f(nonlocal_ref):
1122 def g(local_ref):
1123 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
1124 yield
1125 return g
1126 _arg = object()
1127 nonlocal_vars = {"nonlocal_ref": _arg}
1128 global_vars = {"_global_ref": _global_ref}
1129 builtin_vars = {"print": print}
1130 unbound_names = {"unbound_ref"}
1131 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
1132 builtin_vars, unbound_names)
1133 self.assertEqual(inspect.getclosurevars(f(_arg)), expected)
1134
1135 def test_method_closure(self):
1136 class C:
1137 def f(self, nonlocal_ref):
1138 def g(local_ref):
1139 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
1140 return g
1141 _arg = object()
1142 nonlocal_vars = {"nonlocal_ref": _arg}
1143 global_vars = {"_global_ref": _global_ref}
1144 builtin_vars = {"print": print}
1145 unbound_names = {"unbound_ref"}
1146 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
1147 builtin_vars, unbound_names)
1148 self.assertEqual(inspect.getclosurevars(C().f(_arg)), expected)
1149
1150 def test_nonlocal_vars(self):
1151 # More complex tests of nonlocal resolution
1152 def _nonlocal_vars(f):
1153 return inspect.getclosurevars(f).nonlocals
1154
1155 def make_adder(x):
1156 def add(y):
1157 return x + y
1158 return add
1159
1160 def curry(func, arg1):
1161 return lambda arg2: func(arg1, arg2)
1162
1163 def less_than(a, b):
1164 return a < b
1165
1166 # The infamous Y combinator.
1167 def Y(le):
1168 def g(f):
1169 return le(lambda x: f(f)(x))
1170 Y.g_ref = g
1171 return g(g)
1172
1173 def check_y_combinator(func):
1174 self.assertEqual(_nonlocal_vars(func), {'f': Y.g_ref})
1175
1176 inc = make_adder(1)
1177 add_two = make_adder(2)
1178 greater_than_five = curry(less_than, 5)
1179
1180 self.assertEqual(_nonlocal_vars(inc), {'x': 1})
1181 self.assertEqual(_nonlocal_vars(add_two), {'x': 2})
1182 self.assertEqual(_nonlocal_vars(greater_than_five),
1183 {'arg1': 5, 'func': less_than})
1184 self.assertEqual(_nonlocal_vars((lambda x: lambda y: x + y)(3)),
1185 {'x': 3})
1186 Y(check_y_combinator)
1187
1188 def test_getclosurevars_empty(self):
1189 def foo(): pass
1190 _empty = inspect.ClosureVars({}, {}, {}, set())
1191 self.assertEqual(inspect.getclosurevars(lambda: True), _empty)
1192 self.assertEqual(inspect.getclosurevars(foo), _empty)
1193
1194 def test_getclosurevars_error(self):
1195 class T: pass
1196 self.assertRaises(TypeError, inspect.getclosurevars, 1)
1197 self.assertRaises(TypeError, inspect.getclosurevars, list)
1198 self.assertRaises(TypeError, inspect.getclosurevars, {})
1199
Nick Coghlan6c6e2542012-06-23 20:07:39 +10001200 def _private_globals(self):
1201 code = """def f(): print(path)"""
1202 ns = {}
1203 exec(code, ns)
1204 return ns["f"], ns
1205
1206 def test_builtins_fallback(self):
1207 f, ns = self._private_globals()
1208 ns.pop("__builtins__", None)
1209 expected = inspect.ClosureVars({}, {}, {"print":print}, {"path"})
1210 self.assertEqual(inspect.getclosurevars(f), expected)
1211
1212 def test_builtins_as_dict(self):
1213 f, ns = self._private_globals()
1214 ns["__builtins__"] = {"path":1}
1215 expected = inspect.ClosureVars({}, {}, {"path":1}, {"print"})
1216 self.assertEqual(inspect.getclosurevars(f), expected)
1217
1218 def test_builtins_as_module(self):
1219 f, ns = self._private_globals()
1220 ns["__builtins__"] = os
1221 expected = inspect.ClosureVars({}, {}, {"path":os.path}, {"print"})
1222 self.assertEqual(inspect.getclosurevars(f), expected)
1223
Nick Coghlan2f92e542012-06-23 19:39:55 +10001224
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001225class TestGetcallargsFunctions(unittest.TestCase):
1226
1227 def assertEqualCallArgs(self, func, call_params_string, locs=None):
1228 locs = dict(locs or {}, func=func)
1229 r1 = eval('func(%s)' % call_params_string, None, locs)
1230 r2 = eval('inspect.getcallargs(func, %s)' % call_params_string, None,
1231 locs)
1232 self.assertEqual(r1, r2)
1233
1234 def assertEqualException(self, func, call_param_string, locs=None):
1235 locs = dict(locs or {}, func=func)
1236 try:
1237 eval('func(%s)' % call_param_string, None, locs)
1238 except Exception as e:
1239 ex1 = e
1240 else:
1241 self.fail('Exception not raised')
1242 try:
1243 eval('inspect.getcallargs(func, %s)' % call_param_string, None,
1244 locs)
1245 except Exception as e:
1246 ex2 = e
1247 else:
1248 self.fail('Exception not raised')
1249 self.assertIs(type(ex1), type(ex2))
1250 self.assertEqual(str(ex1), str(ex2))
1251 del ex1, ex2
1252
1253 def makeCallable(self, signature):
1254 """Create a function that returns its locals()"""
1255 code = "lambda %s: locals()"
1256 return eval(code % signature)
1257
1258 def test_plain(self):
1259 f = self.makeCallable('a, b=1')
1260 self.assertEqualCallArgs(f, '2')
1261 self.assertEqualCallArgs(f, '2, 3')
1262 self.assertEqualCallArgs(f, 'a=2')
1263 self.assertEqualCallArgs(f, 'b=3, a=2')
1264 self.assertEqualCallArgs(f, '2, b=3')
1265 # expand *iterable / **mapping
1266 self.assertEqualCallArgs(f, '*(2,)')
1267 self.assertEqualCallArgs(f, '*[2]')
1268 self.assertEqualCallArgs(f, '*(2, 3)')
1269 self.assertEqualCallArgs(f, '*[2, 3]')
1270 self.assertEqualCallArgs(f, '**{"a":2}')
1271 self.assertEqualCallArgs(f, 'b=3, **{"a":2}')
1272 self.assertEqualCallArgs(f, '2, **{"b":3}')
1273 self.assertEqualCallArgs(f, '**{"b":3, "a":2}')
1274 # expand UserList / UserDict
1275 self.assertEqualCallArgs(f, '*collections.UserList([2])')
1276 self.assertEqualCallArgs(f, '*collections.UserList([2, 3])')
1277 self.assertEqualCallArgs(f, '**collections.UserDict(a=2)')
1278 self.assertEqualCallArgs(f, '2, **collections.UserDict(b=3)')
1279 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3)')
1280
1281 def test_varargs(self):
1282 f = self.makeCallable('a, b=1, *c')
1283 self.assertEqualCallArgs(f, '2')
1284 self.assertEqualCallArgs(f, '2, 3')
1285 self.assertEqualCallArgs(f, '2, 3, 4')
1286 self.assertEqualCallArgs(f, '*(2,3,4)')
1287 self.assertEqualCallArgs(f, '2, *[3,4]')
1288 self.assertEqualCallArgs(f, '2, 3, *collections.UserList([4])')
1289
1290 def test_varkw(self):
1291 f = self.makeCallable('a, b=1, **c')
1292 self.assertEqualCallArgs(f, 'a=2')
1293 self.assertEqualCallArgs(f, '2, b=3, c=4')
1294 self.assertEqualCallArgs(f, 'b=3, a=2, c=4')
1295 self.assertEqualCallArgs(f, 'c=4, **{"a":2, "b":3}')
1296 self.assertEqualCallArgs(f, '2, c=4, **{"b":3}')
1297 self.assertEqualCallArgs(f, 'b=2, **{"a":3, "c":4}')
1298 self.assertEqualCallArgs(f, '**collections.UserDict(a=2, b=3, c=4)')
1299 self.assertEqualCallArgs(f, '2, c=4, **collections.UserDict(b=3)')
1300 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3, c=4)')
1301
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001302 def test_varkw_only(self):
1303 # issue11256:
1304 f = self.makeCallable('**c')
1305 self.assertEqualCallArgs(f, '')
1306 self.assertEqualCallArgs(f, 'a=1')
1307 self.assertEqualCallArgs(f, 'a=1, b=2')
1308 self.assertEqualCallArgs(f, 'c=3, **{"a": 1, "b": 2}')
1309 self.assertEqualCallArgs(f, '**collections.UserDict(a=1, b=2)')
1310 self.assertEqualCallArgs(f, 'c=3, **collections.UserDict(a=1, b=2)')
1311
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001312 def test_keyword_only(self):
1313 f = self.makeCallable('a=3, *, c, d=2')
1314 self.assertEqualCallArgs(f, 'c=3')
1315 self.assertEqualCallArgs(f, 'c=3, a=3')
1316 self.assertEqualCallArgs(f, 'a=2, c=4')
1317 self.assertEqualCallArgs(f, '4, c=4')
1318 self.assertEqualException(f, '')
1319 self.assertEqualException(f, '3')
1320 self.assertEqualException(f, 'a=3')
1321 self.assertEqualException(f, 'd=4')
1322
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001323 f = self.makeCallable('*, c, d=2')
1324 self.assertEqualCallArgs(f, 'c=3')
1325 self.assertEqualCallArgs(f, 'c=3, d=4')
1326 self.assertEqualCallArgs(f, 'd=4, c=3')
1327
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001328 def test_multiple_features(self):
1329 f = self.makeCallable('a, b=2, *f, **g')
1330 self.assertEqualCallArgs(f, '2, 3, 7')
1331 self.assertEqualCallArgs(f, '2, 3, x=8')
1332 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
1333 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9')
1334 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9')
1335 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
1336 '[2, 3, (4,[5,6])]), **{"y":9, "z":10}')
1337 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
1338 '(4,[5,6])]), **collections.UserDict('
1339 'y=9, z=10)')
1340
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001341 f = self.makeCallable('a, b=2, *f, x, y=99, **g')
1342 self.assertEqualCallArgs(f, '2, 3, x=8')
1343 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
1344 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9, z=10')
1345 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9, z=10')
1346 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
1347 '[2, 3, (4,[5,6])]), q=0, **{"y":9, "z":10}')
1348 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
1349 '(4,[5,6])]), q=0, **collections.UserDict('
1350 'y=9, z=10)')
1351
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001352 def test_errors(self):
1353 f0 = self.makeCallable('')
1354 f1 = self.makeCallable('a, b')
1355 f2 = self.makeCallable('a, b=1')
1356 # f0 takes no arguments
1357 self.assertEqualException(f0, '1')
1358 self.assertEqualException(f0, 'x=1')
1359 self.assertEqualException(f0, '1,x=1')
1360 # f1 takes exactly 2 arguments
1361 self.assertEqualException(f1, '')
1362 self.assertEqualException(f1, '1')
1363 self.assertEqualException(f1, 'a=2')
1364 self.assertEqualException(f1, 'b=3')
1365 # f2 takes at least 1 argument
1366 self.assertEqualException(f2, '')
1367 self.assertEqualException(f2, 'b=3')
1368 for f in f1, f2:
1369 # f1/f2 takes exactly/at most 2 arguments
1370 self.assertEqualException(f, '2, 3, 4')
1371 self.assertEqualException(f, '1, 2, 3, a=1')
1372 self.assertEqualException(f, '2, 3, 4, c=5')
Georg Brandl178e5ea2012-02-21 00:32:36 +01001373 # XXX: success of this one depends on dict order
1374 ## self.assertEqualException(f, '2, 3, 4, a=1, c=5')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001375 # f got an unexpected keyword argument
1376 self.assertEqualException(f, 'c=2')
1377 self.assertEqualException(f, '2, c=3')
1378 self.assertEqualException(f, '2, 3, c=4')
1379 self.assertEqualException(f, '2, c=4, b=3')
1380 self.assertEqualException(f, '**{u"\u03c0\u03b9": 4}')
1381 # f got multiple values for keyword argument
1382 self.assertEqualException(f, '1, a=2')
1383 self.assertEqualException(f, '1, **{"a":2}')
1384 self.assertEqualException(f, '1, 2, b=3')
1385 # XXX: Python inconsistency
1386 # - for functions and bound methods: unexpected keyword 'c'
1387 # - for unbound methods: multiple values for keyword 'a'
1388 #self.assertEqualException(f, '1, c=3, a=2')
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001389 # issue11256:
1390 f3 = self.makeCallable('**c')
1391 self.assertEqualException(f3, '1, 2')
1392 self.assertEqualException(f3, '1, 2, a=1, b=2')
1393 f4 = self.makeCallable('*, a, b=0')
1394 self.assertEqualException(f3, '1, 2')
1395 self.assertEqualException(f3, '1, 2, a=1, b=2')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001396
Yury Selivanov875df202014-03-27 18:23:03 -04001397 # issue #20816: getcallargs() fails to iterate over non-existent
1398 # kwonlydefaults and raises a wrong TypeError
1399 def f5(*, a): pass
1400 with self.assertRaisesRegex(TypeError,
1401 'missing 1 required keyword-only'):
1402 inspect.getcallargs(f5)
1403
1404
Yury Selivanovdccfa132014-03-27 18:42:52 -04001405 # issue20817:
1406 def f6(a, b, c):
1407 pass
1408 with self.assertRaisesRegex(TypeError, "'a', 'b' and 'c'"):
1409 inspect.getcallargs(f6)
1410
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001411class TestGetcallargsMethods(TestGetcallargsFunctions):
1412
1413 def setUp(self):
1414 class Foo(object):
1415 pass
1416 self.cls = Foo
1417 self.inst = Foo()
1418
1419 def makeCallable(self, signature):
1420 assert 'self' not in signature
1421 mk = super(TestGetcallargsMethods, self).makeCallable
1422 self.cls.method = mk('self, ' + signature)
1423 return self.inst.method
1424
1425class TestGetcallargsUnboundMethods(TestGetcallargsMethods):
1426
1427 def makeCallable(self, signature):
1428 super(TestGetcallargsUnboundMethods, self).makeCallable(signature)
1429 return self.cls.method
1430
1431 def assertEqualCallArgs(self, func, call_params_string, locs=None):
1432 return super(TestGetcallargsUnboundMethods, self).assertEqualCallArgs(
1433 *self._getAssertEqualParams(func, call_params_string, locs))
1434
1435 def assertEqualException(self, func, call_params_string, locs=None):
1436 return super(TestGetcallargsUnboundMethods, self).assertEqualException(
1437 *self._getAssertEqualParams(func, call_params_string, locs))
1438
1439 def _getAssertEqualParams(self, func, call_params_string, locs=None):
1440 assert 'inst' not in call_params_string
1441 locs = dict(locs or {}, inst=self.inst)
1442 return (func, 'inst,' + call_params_string, locs)
1443
Michael Foord95fc51d2010-11-20 15:07:30 +00001444
1445class TestGetattrStatic(unittest.TestCase):
1446
1447 def test_basic(self):
1448 class Thing(object):
1449 x = object()
1450
1451 thing = Thing()
1452 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1453 self.assertEqual(inspect.getattr_static(thing, 'x', None), Thing.x)
1454 with self.assertRaises(AttributeError):
1455 inspect.getattr_static(thing, 'y')
1456
1457 self.assertEqual(inspect.getattr_static(thing, 'y', 3), 3)
1458
1459 def test_inherited(self):
1460 class Thing(object):
1461 x = object()
1462 class OtherThing(Thing):
1463 pass
1464
1465 something = OtherThing()
1466 self.assertEqual(inspect.getattr_static(something, 'x'), Thing.x)
1467
1468 def test_instance_attr(self):
1469 class Thing(object):
1470 x = 2
1471 def __init__(self, x):
1472 self.x = x
1473 thing = Thing(3)
1474 self.assertEqual(inspect.getattr_static(thing, 'x'), 3)
1475 del thing.x
1476 self.assertEqual(inspect.getattr_static(thing, 'x'), 2)
1477
1478 def test_property(self):
1479 class Thing(object):
1480 @property
1481 def x(self):
1482 raise AttributeError("I'm pretending not to exist")
1483 thing = Thing()
1484 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1485
Ezio Melotti75cbd732011-04-28 00:59:29 +03001486 def test_descriptor_raises_AttributeError(self):
Michael Foord95fc51d2010-11-20 15:07:30 +00001487 class descriptor(object):
1488 def __get__(*_):
1489 raise AttributeError("I'm pretending not to exist")
1490 desc = descriptor()
1491 class Thing(object):
1492 x = desc
1493 thing = Thing()
1494 self.assertEqual(inspect.getattr_static(thing, 'x'), desc)
1495
1496 def test_classAttribute(self):
1497 class Thing(object):
1498 x = object()
1499
1500 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.x)
1501
Ethan Furmane03ea372013-09-25 07:14:41 -07001502 def test_classVirtualAttribute(self):
1503 class Thing(object):
1504 @types.DynamicClassAttribute
1505 def x(self):
1506 return self._x
1507 _x = object()
1508
1509 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.__dict__['x'])
1510
Michael Foord95fc51d2010-11-20 15:07:30 +00001511 def test_inherited_classattribute(self):
1512 class Thing(object):
1513 x = object()
1514 class OtherThing(Thing):
1515 pass
1516
1517 self.assertEqual(inspect.getattr_static(OtherThing, 'x'), Thing.x)
1518
1519 def test_slots(self):
1520 class Thing(object):
1521 y = 'bar'
1522 __slots__ = ['x']
1523 def __init__(self):
1524 self.x = 'foo'
1525 thing = Thing()
1526 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1527 self.assertEqual(inspect.getattr_static(thing, 'y'), 'bar')
1528
1529 del thing.x
1530 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1531
1532 def test_metaclass(self):
1533 class meta(type):
1534 attr = 'foo'
1535 class Thing(object, metaclass=meta):
1536 pass
1537 self.assertEqual(inspect.getattr_static(Thing, 'attr'), 'foo')
1538
1539 class sub(meta):
1540 pass
1541 class OtherThing(object, metaclass=sub):
1542 x = 3
1543 self.assertEqual(inspect.getattr_static(OtherThing, 'attr'), 'foo')
1544
1545 class OtherOtherThing(OtherThing):
1546 pass
1547 # this test is odd, but it was added as it exposed a bug
1548 self.assertEqual(inspect.getattr_static(OtherOtherThing, 'x'), 3)
1549
1550 def test_no_dict_no_slots(self):
1551 self.assertEqual(inspect.getattr_static(1, 'foo', None), None)
1552 self.assertNotEqual(inspect.getattr_static('foo', 'lower'), None)
1553
1554 def test_no_dict_no_slots_instance_member(self):
1555 # returns descriptor
1556 with open(__file__) as handle:
1557 self.assertEqual(inspect.getattr_static(handle, 'name'), type(handle).name)
1558
1559 def test_inherited_slots(self):
1560 # returns descriptor
1561 class Thing(object):
1562 __slots__ = ['x']
1563 def __init__(self):
1564 self.x = 'foo'
1565
1566 class OtherThing(Thing):
1567 pass
1568 # it would be nice if this worked...
1569 # we get the descriptor instead of the instance attribute
1570 self.assertEqual(inspect.getattr_static(OtherThing(), 'x'), Thing.x)
1571
1572 def test_descriptor(self):
1573 class descriptor(object):
1574 def __get__(self, instance, owner):
1575 return 3
1576 class Foo(object):
1577 d = descriptor()
1578
1579 foo = Foo()
1580
1581 # for a non data descriptor we return the instance attribute
1582 foo.__dict__['d'] = 1
1583 self.assertEqual(inspect.getattr_static(foo, 'd'), 1)
1584
Mike53f7a7c2017-12-14 14:04:53 +03001585 # if the descriptor is a data-descriptor we should return the
Michael Foord95fc51d2010-11-20 15:07:30 +00001586 # descriptor
1587 descriptor.__set__ = lambda s, i, v: None
1588 self.assertEqual(inspect.getattr_static(foo, 'd'), Foo.__dict__['d'])
1589
1590
1591 def test_metaclass_with_descriptor(self):
1592 class descriptor(object):
1593 def __get__(self, instance, owner):
1594 return 3
1595 class meta(type):
1596 d = descriptor()
1597 class Thing(object, metaclass=meta):
1598 pass
1599 self.assertEqual(inspect.getattr_static(Thing, 'd'), meta.__dict__['d'])
1600
1601
Michael Foordcc7ebb82010-11-20 16:20:16 +00001602 def test_class_as_property(self):
1603 class Base(object):
1604 foo = 3
1605
1606 class Something(Base):
Michael Foord35184ed2010-11-20 16:58:30 +00001607 executed = False
Michael Foordcc7ebb82010-11-20 16:20:16 +00001608 @property
1609 def __class__(self):
Michael Foord35184ed2010-11-20 16:58:30 +00001610 self.executed = True
Michael Foordcc7ebb82010-11-20 16:20:16 +00001611 return object
1612
Michael Foord35184ed2010-11-20 16:58:30 +00001613 instance = Something()
1614 self.assertEqual(inspect.getattr_static(instance, 'foo'), 3)
1615 self.assertFalse(instance.executed)
Michael Foordcc7ebb82010-11-20 16:20:16 +00001616 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1617
Michael Foorde5162652010-11-20 16:40:44 +00001618 def test_mro_as_property(self):
1619 class Meta(type):
1620 @property
1621 def __mro__(self):
1622 return (object,)
1623
1624 class Base(object):
1625 foo = 3
1626
1627 class Something(Base, metaclass=Meta):
1628 pass
1629
1630 self.assertEqual(inspect.getattr_static(Something(), 'foo'), 3)
1631 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1632
Michael Foorddcebe0f2011-03-15 19:20:44 -04001633 def test_dict_as_property(self):
1634 test = self
1635 test.called = False
1636
1637 class Foo(dict):
1638 a = 3
1639 @property
1640 def __dict__(self):
1641 test.called = True
1642 return {}
1643
1644 foo = Foo()
1645 foo.a = 4
1646 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1647 self.assertFalse(test.called)
1648
1649 def test_custom_object_dict(self):
1650 test = self
1651 test.called = False
1652
1653 class Custom(dict):
1654 def get(self, key, default=None):
1655 test.called = True
1656 super().get(key, default)
1657
1658 class Foo(object):
1659 a = 3
1660 foo = Foo()
1661 foo.__dict__ = Custom()
1662 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1663 self.assertFalse(test.called)
1664
1665 def test_metaclass_dict_as_property(self):
1666 class Meta(type):
1667 @property
1668 def __dict__(self):
1669 self.executed = True
1670
1671 class Thing(metaclass=Meta):
1672 executed = False
1673
1674 def __init__(self):
1675 self.spam = 42
1676
1677 instance = Thing()
1678 self.assertEqual(inspect.getattr_static(instance, "spam"), 42)
1679 self.assertFalse(Thing.executed)
Michael Foorde5162652010-11-20 16:40:44 +00001680
Michael Foorda51623b2011-12-18 22:01:40 +00001681 def test_module(self):
1682 sentinel = object()
1683 self.assertIsNot(inspect.getattr_static(sys, "version", sentinel),
1684 sentinel)
1685
Michael Foord3ba95f82011-12-22 01:13:37 +00001686 def test_metaclass_with_metaclass_with_dict_as_property(self):
1687 class MetaMeta(type):
1688 @property
1689 def __dict__(self):
1690 self.executed = True
1691 return dict(spam=42)
1692
1693 class Meta(type, metaclass=MetaMeta):
1694 executed = False
1695
1696 class Thing(metaclass=Meta):
1697 pass
1698
1699 with self.assertRaises(AttributeError):
1700 inspect.getattr_static(Thing, "spam")
1701 self.assertFalse(Thing.executed)
1702
Nick Coghlane0f04652010-11-21 03:44:04 +00001703class TestGetGeneratorState(unittest.TestCase):
1704
1705 def setUp(self):
1706 def number_generator():
1707 for number in range(5):
1708 yield number
1709 self.generator = number_generator()
1710
1711 def _generatorstate(self):
1712 return inspect.getgeneratorstate(self.generator)
1713
1714 def test_created(self):
1715 self.assertEqual(self._generatorstate(), inspect.GEN_CREATED)
1716
1717 def test_suspended(self):
1718 next(self.generator)
1719 self.assertEqual(self._generatorstate(), inspect.GEN_SUSPENDED)
1720
1721 def test_closed_after_exhaustion(self):
1722 for i in self.generator:
1723 pass
1724 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1725
1726 def test_closed_after_immediate_exception(self):
1727 with self.assertRaises(RuntimeError):
1728 self.generator.throw(RuntimeError)
1729 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1730
1731 def test_running(self):
1732 # As mentioned on issue #10220, checking for the RUNNING state only
1733 # makes sense inside the generator itself.
1734 # The following generator checks for this by using the closure's
1735 # reference to self and the generator state checking helper method
1736 def running_check_generator():
1737 for number in range(5):
1738 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1739 yield number
1740 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1741 self.generator = running_check_generator()
1742 # Running up to the first yield
1743 next(self.generator)
1744 # Running after the first yield
1745 next(self.generator)
1746
Nick Coghlan7921b9f2010-11-30 06:36:04 +00001747 def test_easy_debugging(self):
1748 # repr() and str() of a generator state should contain the state name
1749 names = 'GEN_CREATED GEN_RUNNING GEN_SUSPENDED GEN_CLOSED'.split()
1750 for name in names:
1751 state = getattr(inspect, name)
1752 self.assertIn(name, repr(state))
1753 self.assertIn(name, str(state))
1754
Nick Coghlan04e2e3f2012-06-23 19:52:05 +10001755 def test_getgeneratorlocals(self):
1756 def each(lst, a=None):
1757 b=(1, 2, 3)
1758 for v in lst:
1759 if v == 3:
1760 c = 12
1761 yield v
1762
1763 numbers = each([1, 2, 3])
1764 self.assertEqual(inspect.getgeneratorlocals(numbers),
1765 {'a': None, 'lst': [1, 2, 3]})
1766 next(numbers)
1767 self.assertEqual(inspect.getgeneratorlocals(numbers),
1768 {'a': None, 'lst': [1, 2, 3], 'v': 1,
1769 'b': (1, 2, 3)})
1770 next(numbers)
1771 self.assertEqual(inspect.getgeneratorlocals(numbers),
1772 {'a': None, 'lst': [1, 2, 3], 'v': 2,
1773 'b': (1, 2, 3)})
1774 next(numbers)
1775 self.assertEqual(inspect.getgeneratorlocals(numbers),
1776 {'a': None, 'lst': [1, 2, 3], 'v': 3,
1777 'b': (1, 2, 3), 'c': 12})
1778 try:
1779 next(numbers)
1780 except StopIteration:
1781 pass
1782 self.assertEqual(inspect.getgeneratorlocals(numbers), {})
1783
1784 def test_getgeneratorlocals_empty(self):
1785 def yield_one():
1786 yield 1
1787 one = yield_one()
1788 self.assertEqual(inspect.getgeneratorlocals(one), {})
1789 try:
1790 next(one)
1791 except StopIteration:
1792 pass
1793 self.assertEqual(inspect.getgeneratorlocals(one), {})
1794
1795 def test_getgeneratorlocals_error(self):
1796 self.assertRaises(TypeError, inspect.getgeneratorlocals, 1)
1797 self.assertRaises(TypeError, inspect.getgeneratorlocals, lambda x: True)
1798 self.assertRaises(TypeError, inspect.getgeneratorlocals, set)
1799 self.assertRaises(TypeError, inspect.getgeneratorlocals, (2,3))
1800
Nick Coghlane0f04652010-11-21 03:44:04 +00001801
Yury Selivanov5376ba92015-06-22 12:19:30 -04001802class TestGetCoroutineState(unittest.TestCase):
1803
1804 def setUp(self):
1805 @types.coroutine
1806 def number_coroutine():
1807 for number in range(5):
1808 yield number
1809 async def coroutine():
1810 await number_coroutine()
1811 self.coroutine = coroutine()
1812
1813 def tearDown(self):
1814 self.coroutine.close()
1815
1816 def _coroutinestate(self):
1817 return inspect.getcoroutinestate(self.coroutine)
1818
1819 def test_created(self):
1820 self.assertEqual(self._coroutinestate(), inspect.CORO_CREATED)
1821
1822 def test_suspended(self):
1823 self.coroutine.send(None)
1824 self.assertEqual(self._coroutinestate(), inspect.CORO_SUSPENDED)
1825
1826 def test_closed_after_exhaustion(self):
1827 while True:
1828 try:
1829 self.coroutine.send(None)
1830 except StopIteration:
1831 break
1832
1833 self.assertEqual(self._coroutinestate(), inspect.CORO_CLOSED)
1834
1835 def test_closed_after_immediate_exception(self):
1836 with self.assertRaises(RuntimeError):
1837 self.coroutine.throw(RuntimeError)
1838 self.assertEqual(self._coroutinestate(), inspect.CORO_CLOSED)
1839
1840 def test_easy_debugging(self):
1841 # repr() and str() of a coroutine state should contain the state name
1842 names = 'CORO_CREATED CORO_RUNNING CORO_SUSPENDED CORO_CLOSED'.split()
1843 for name in names:
1844 state = getattr(inspect, name)
1845 self.assertIn(name, repr(state))
1846 self.assertIn(name, str(state))
1847
1848 def test_getcoroutinelocals(self):
1849 @types.coroutine
1850 def gencoro():
1851 yield
1852
1853 gencoro = gencoro()
1854 async def func(a=None):
1855 b = 'spam'
1856 await gencoro
1857
1858 coro = func()
1859 self.assertEqual(inspect.getcoroutinelocals(coro),
1860 {'a': None, 'gencoro': gencoro})
1861 coro.send(None)
1862 self.assertEqual(inspect.getcoroutinelocals(coro),
1863 {'a': None, 'gencoro': gencoro, 'b': 'spam'})
1864
1865
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001866class MySignature(inspect.Signature):
1867 # Top-level to make it picklable;
1868 # used in test_signature_object_pickle
1869 pass
1870
1871class MyParameter(inspect.Parameter):
1872 # Top-level to make it picklable;
1873 # used in test_signature_object_pickle
1874 pass
1875
Nick Coghlanf9e227e2014-08-17 14:01:19 +10001876
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001877
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001878class TestSignatureObject(unittest.TestCase):
1879 @staticmethod
Yury Selivanovbcd4fc12015-05-20 14:30:08 -04001880 def signature(func, **kw):
1881 sig = inspect.signature(func, **kw)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001882 return (tuple((param.name,
1883 (... if param.default is param.empty else param.default),
1884 (... if param.annotation is param.empty
1885 else param.annotation),
1886 str(param.kind).lower())
1887 for param in sig.parameters.values()),
1888 (... if sig.return_annotation is sig.empty
1889 else sig.return_annotation))
1890
1891 def test_signature_object(self):
1892 S = inspect.Signature
1893 P = inspect.Parameter
1894
1895 self.assertEqual(str(S()), '()')
1896
Yury Selivanov07a9e452014-01-29 10:58:16 -05001897 def test(po, pk, pod=42, pkd=100, *args, ko, **kwargs):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001898 pass
1899 sig = inspect.signature(test)
1900 po = sig.parameters['po'].replace(kind=P.POSITIONAL_ONLY)
Yury Selivanov07a9e452014-01-29 10:58:16 -05001901 pod = sig.parameters['pod'].replace(kind=P.POSITIONAL_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001902 pk = sig.parameters['pk']
Yury Selivanov07a9e452014-01-29 10:58:16 -05001903 pkd = sig.parameters['pkd']
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001904 args = sig.parameters['args']
1905 ko = sig.parameters['ko']
1906 kwargs = sig.parameters['kwargs']
1907
1908 S((po, pk, args, ko, kwargs))
1909
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001910 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001911 S((pk, po, args, ko, kwargs))
1912
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001913 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001914 S((po, args, pk, ko, kwargs))
1915
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001916 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001917 S((args, po, pk, ko, kwargs))
1918
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001919 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001920 S((po, pk, args, kwargs, ko))
1921
1922 kwargs2 = kwargs.replace(name='args')
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001923 with self.assertRaisesRegex(ValueError, 'duplicate parameter name'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001924 S((po, pk, args, kwargs2, ko))
1925
Yury Selivanov07a9e452014-01-29 10:58:16 -05001926 with self.assertRaisesRegex(ValueError, 'follows default argument'):
1927 S((pod, po))
1928
1929 with self.assertRaisesRegex(ValueError, 'follows default argument'):
1930 S((po, pkd, pk))
1931
1932 with self.assertRaisesRegex(ValueError, 'follows default argument'):
1933 S((pkd, pk))
1934
Yury Selivanov374375d2014-03-27 12:41:53 -04001935 self.assertTrue(repr(sig).startswith('<Signature'))
Yury Selivanov0cd2bf42015-05-15 12:55:20 -04001936 self.assertTrue('(po, pk' in repr(sig))
Yury Selivanov374375d2014-03-27 12:41:53 -04001937
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001938 def test_signature_object_pickle(self):
1939 def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
1940 foo_partial = functools.partial(foo, a=1)
1941
1942 sig = inspect.signature(foo_partial)
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001943
1944 for ver in range(pickle.HIGHEST_PROTOCOL + 1):
1945 with self.subTest(pickle_ver=ver, subclass=False):
1946 sig_pickled = pickle.loads(pickle.dumps(sig, ver))
1947 self.assertEqual(sig, sig_pickled)
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001948
1949 # Test that basic sub-classing works
1950 sig = inspect.signature(foo)
1951 myparam = MyParameter(name='z', kind=inspect.Parameter.POSITIONAL_ONLY)
1952 myparams = collections.OrderedDict(sig.parameters, a=myparam)
1953 mysig = MySignature().replace(parameters=myparams.values(),
1954 return_annotation=sig.return_annotation)
1955 self.assertTrue(isinstance(mysig, MySignature))
1956 self.assertTrue(isinstance(mysig.parameters['z'], MyParameter))
1957
1958 for ver in range(pickle.HIGHEST_PROTOCOL + 1):
1959 with self.subTest(pickle_ver=ver, subclass=True):
1960 sig_pickled = pickle.loads(pickle.dumps(mysig, ver))
1961 self.assertEqual(mysig, sig_pickled)
1962 self.assertTrue(isinstance(sig_pickled, MySignature))
1963 self.assertTrue(isinstance(sig_pickled.parameters['z'],
1964 MyParameter))
1965
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001966 def test_signature_immutability(self):
1967 def test(a):
1968 pass
1969 sig = inspect.signature(test)
1970
1971 with self.assertRaises(AttributeError):
1972 sig.foo = 'bar'
1973
1974 with self.assertRaises(TypeError):
1975 sig.parameters['a'] = None
1976
1977 def test_signature_on_noarg(self):
1978 def test():
1979 pass
1980 self.assertEqual(self.signature(test), ((), ...))
1981
1982 def test_signature_on_wargs(self):
1983 def test(a, b:'foo') -> 123:
1984 pass
1985 self.assertEqual(self.signature(test),
1986 ((('a', ..., ..., "positional_or_keyword"),
1987 ('b', ..., 'foo', "positional_or_keyword")),
1988 123))
1989
1990 def test_signature_on_wkwonly(self):
1991 def test(*, a:float, b:str) -> int:
1992 pass
1993 self.assertEqual(self.signature(test),
1994 ((('a', ..., float, "keyword_only"),
1995 ('b', ..., str, "keyword_only")),
1996 int))
1997
1998 def test_signature_on_complex_args(self):
1999 def test(a, b:'foo'=10, *args:'bar', spam:'baz', ham=123, **kwargs:int):
2000 pass
2001 self.assertEqual(self.signature(test),
2002 ((('a', ..., ..., "positional_or_keyword"),
2003 ('b', 10, 'foo', "positional_or_keyword"),
2004 ('args', ..., 'bar', "var_positional"),
2005 ('spam', ..., 'baz', "keyword_only"),
2006 ('ham', 123, ..., "keyword_only"),
2007 ('kwargs', ..., int, "var_keyword")),
2008 ...))
2009
Dong-hee Na378d7062017-05-18 04:00:51 +09002010 def test_signature_without_self(self):
2011 def test_args_only(*args): # NOQA
2012 pass
2013
2014 def test_args_kwargs_only(*args, **kwargs): # NOQA
2015 pass
2016
2017 class A:
2018 @classmethod
2019 def test_classmethod(*args): # NOQA
2020 pass
2021
2022 @staticmethod
2023 def test_staticmethod(*args): # NOQA
2024 pass
2025
2026 f1 = functools.partialmethod((test_classmethod), 1)
2027 f2 = functools.partialmethod((test_args_only), 1)
2028 f3 = functools.partialmethod((test_staticmethod), 1)
2029 f4 = functools.partialmethod((test_args_kwargs_only),1)
2030
2031 self.assertEqual(self.signature(test_args_only),
2032 ((('args', ..., ..., 'var_positional'),), ...))
2033 self.assertEqual(self.signature(test_args_kwargs_only),
2034 ((('args', ..., ..., 'var_positional'),
2035 ('kwargs', ..., ..., 'var_keyword')), ...))
2036 self.assertEqual(self.signature(A.f1),
2037 ((('args', ..., ..., 'var_positional'),), ...))
2038 self.assertEqual(self.signature(A.f2),
2039 ((('args', ..., ..., 'var_positional'),), ...))
2040 self.assertEqual(self.signature(A.f3),
2041 ((('args', ..., ..., 'var_positional'),), ...))
Serhiy Storchaka13ad3b72017-09-14 09:38:36 +03002042 self.assertEqual(self.signature(A.f4),
Dong-hee Na378d7062017-05-18 04:00:51 +09002043 ((('args', ..., ..., 'var_positional'),
2044 ('kwargs', ..., ..., 'var_keyword')), ...))
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002045 @cpython_only
Larry Hastingsfcafe432013-11-23 17:35:48 -08002046 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2047 "Signature information for builtins requires docstrings")
2048 def test_signature_on_builtins(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002049 import _testcapi
Larry Hastings16c51912014-01-07 11:53:01 -08002050
Larry Hastings5c661892014-01-24 06:17:25 -08002051 def test_unbound_method(o):
2052 """Use this to test unbound methods (things that should have a self)"""
2053 signature = inspect.signature(o)
2054 self.assertTrue(isinstance(signature, inspect.Signature))
2055 self.assertEqual(list(signature.parameters.values())[0].name, 'self')
2056 return signature
2057
2058 def test_callable(o):
2059 """Use this to test bound methods or normal callables (things that don't expect self)"""
2060 signature = inspect.signature(o)
2061 self.assertTrue(isinstance(signature, inspect.Signature))
2062 if signature.parameters:
2063 self.assertNotEqual(list(signature.parameters.values())[0].name, 'self')
2064 return signature
2065
2066 signature = test_callable(_testcapi.docstring_with_signature_with_defaults)
Larry Hastings16c51912014-01-07 11:53:01 -08002067 def p(name): return signature.parameters[name].default
2068 self.assertEqual(p('s'), 'avocado')
Larry Hastings2a727912014-01-16 11:32:01 -08002069 self.assertEqual(p('b'), b'bytes')
Larry Hastings16c51912014-01-07 11:53:01 -08002070 self.assertEqual(p('d'), 3.14)
2071 self.assertEqual(p('i'), 35)
Larry Hastings16c51912014-01-07 11:53:01 -08002072 self.assertEqual(p('n'), None)
2073 self.assertEqual(p('t'), True)
2074 self.assertEqual(p('f'), False)
Larry Hastings2a727912014-01-16 11:32:01 -08002075 self.assertEqual(p('local'), 3)
2076 self.assertEqual(p('sys'), sys.maxsize)
2077 self.assertEqual(p('exp'), sys.maxsize - 1)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002078
Larry Hastings5c661892014-01-24 06:17:25 -08002079 test_callable(object)
2080
2081 # normal method
2082 # (PyMethodDescr_Type, "method_descriptor")
2083 test_unbound_method(_pickle.Pickler.dump)
2084 d = _pickle.Pickler(io.StringIO())
2085 test_callable(d.dump)
2086
2087 # static method
2088 test_callable(str.maketrans)
2089 test_callable('abc'.maketrans)
2090
2091 # class method
2092 test_callable(dict.fromkeys)
2093 test_callable({}.fromkeys)
2094
2095 # wrapper around slot (PyWrapperDescr_Type, "wrapper_descriptor")
2096 test_unbound_method(type.__call__)
2097 test_unbound_method(int.__add__)
2098 test_callable((3).__add__)
2099
2100 # _PyMethodWrapper_Type
2101 # support for 'method-wrapper'
2102 test_callable(min.__call__)
2103
Larry Hastings2623c8c2014-02-08 22:15:29 -08002104 # This doesn't work now.
2105 # (We don't have a valid signature for "type" in 3.4)
2106 with self.assertRaisesRegex(ValueError, "no signature found"):
2107 class ThisWorksNow:
2108 __call__ = type
2109 test_callable(ThisWorksNow())
Larry Hastings5c661892014-01-24 06:17:25 -08002110
Yury Selivanov056e2652014-03-02 12:25:27 -05002111 # Regression test for issue #20786
2112 test_unbound_method(dict.__delitem__)
2113 test_unbound_method(property.__delete__)
2114
Zachary Ware8ef887c2015-04-13 18:22:35 -05002115 # Regression test for issue #20586
2116 test_callable(_testcapi.docstring_with_signature_but_no_doc)
2117
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002118 @cpython_only
Yury Selivanov76c6c592014-01-29 10:52:57 -05002119 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2120 "Signature information for builtins requires docstrings")
2121 def test_signature_on_decorated_builtins(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002122 import _testcapi
Yury Selivanov76c6c592014-01-29 10:52:57 -05002123 func = _testcapi.docstring_with_signature_with_defaults
2124
2125 def decorator(func):
2126 @functools.wraps(func)
2127 def wrapper(*args, **kwargs) -> int:
2128 return func(*args, **kwargs)
2129 return wrapper
2130
2131 decorated_func = decorator(func)
2132
2133 self.assertEqual(inspect.signature(func),
2134 inspect.signature(decorated_func))
Larry Hastings5c661892014-01-24 06:17:25 -08002135
Yury Selivanovbcd4fc12015-05-20 14:30:08 -04002136 def wrapper_like(*args, **kwargs) -> int: pass
2137 self.assertEqual(inspect.signature(decorated_func,
2138 follow_wrapped=False),
2139 inspect.signature(wrapper_like))
2140
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002141 @cpython_only
Larry Hastings5c661892014-01-24 06:17:25 -08002142 def test_signature_on_builtins_no_signature(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002143 import _testcapi
Yury Selivanovbf304fc2015-05-30 17:08:36 -04002144 with self.assertRaisesRegex(ValueError,
2145 'no signature found for builtin'):
Larry Hastings5c661892014-01-24 06:17:25 -08002146 inspect.signature(_testcapi.docstring_no_signature)
2147
Yury Selivanovbf304fc2015-05-30 17:08:36 -04002148 with self.assertRaisesRegex(ValueError,
2149 'no signature found for builtin'):
2150 inspect.signature(str)
2151
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002152 def test_signature_on_non_function(self):
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002153 with self.assertRaisesRegex(TypeError, 'is not a callable object'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002154 inspect.signature(42)
2155
Yury Selivanov63da7c72014-01-31 14:48:37 -05002156 def test_signature_from_functionlike_object(self):
2157 def func(a,b, *args, kwonly=True, kwonlyreq, **kwargs):
2158 pass
2159
2160 class funclike:
2161 # Has to be callable, and have correct
2162 # __code__, __annotations__, __defaults__, __name__,
2163 # and __kwdefaults__ attributes
2164
2165 def __init__(self, func):
2166 self.__name__ = func.__name__
2167 self.__code__ = func.__code__
2168 self.__annotations__ = func.__annotations__
2169 self.__defaults__ = func.__defaults__
2170 self.__kwdefaults__ = func.__kwdefaults__
2171 self.func = func
2172
2173 def __call__(self, *args, **kwargs):
2174 return self.func(*args, **kwargs)
2175
Yury Selivanov57c74fc2015-05-20 23:07:02 -04002176 sig_func = inspect.Signature.from_callable(func)
Yury Selivanov63da7c72014-01-31 14:48:37 -05002177
Yury Selivanov57c74fc2015-05-20 23:07:02 -04002178 sig_funclike = inspect.Signature.from_callable(funclike(func))
Yury Selivanov63da7c72014-01-31 14:48:37 -05002179 self.assertEqual(sig_funclike, sig_func)
2180
2181 sig_funclike = inspect.signature(funclike(func))
2182 self.assertEqual(sig_funclike, sig_func)
2183
2184 # If object is not a duck type of function, then
2185 # signature will try to get a signature for its '__call__'
2186 # method
2187 fl = funclike(func)
2188 del fl.__defaults__
2189 self.assertEqual(self.signature(fl),
2190 ((('args', ..., ..., "var_positional"),
2191 ('kwargs', ..., ..., "var_keyword")),
2192 ...))
2193
Yury Selivanova773de02014-02-21 18:30:53 -05002194 # Test with cython-like builtins:
2195 _orig_isdesc = inspect.ismethoddescriptor
2196 def _isdesc(obj):
2197 if hasattr(obj, '_builtinmock'):
2198 return True
2199 return _orig_isdesc(obj)
2200
2201 with unittest.mock.patch('inspect.ismethoddescriptor', _isdesc):
2202 builtin_func = funclike(func)
2203 # Make sure that our mock setup is working
2204 self.assertFalse(inspect.ismethoddescriptor(builtin_func))
2205 builtin_func._builtinmock = True
2206 self.assertTrue(inspect.ismethoddescriptor(builtin_func))
2207 self.assertEqual(inspect.signature(builtin_func), sig_func)
2208
Yury Selivanov63da7c72014-01-31 14:48:37 -05002209 def test_signature_functionlike_class(self):
2210 # We only want to duck type function-like objects,
2211 # not classes.
2212
2213 def func(a,b, *args, kwonly=True, kwonlyreq, **kwargs):
2214 pass
2215
2216 class funclike:
2217 def __init__(self, marker):
2218 pass
2219
2220 __name__ = func.__name__
2221 __code__ = func.__code__
2222 __annotations__ = func.__annotations__
2223 __defaults__ = func.__defaults__
2224 __kwdefaults__ = func.__kwdefaults__
2225
Yury Selivanov63da7c72014-01-31 14:48:37 -05002226 self.assertEqual(str(inspect.signature(funclike)), '(marker)')
2227
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002228 def test_signature_on_method(self):
2229 class Test:
Yury Selivanov62560fb2014-01-28 12:26:24 -05002230 def __init__(*args):
2231 pass
2232 def m1(self, arg1, arg2=1) -> int:
2233 pass
2234 def m2(*args):
2235 pass
2236 def __call__(*, a):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002237 pass
2238
Yury Selivanov62560fb2014-01-28 12:26:24 -05002239 self.assertEqual(self.signature(Test().m1),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002240 ((('arg1', ..., ..., "positional_or_keyword"),
2241 ('arg2', 1, ..., "positional_or_keyword")),
2242 int))
2243
Yury Selivanov62560fb2014-01-28 12:26:24 -05002244 self.assertEqual(self.signature(Test().m2),
2245 ((('args', ..., ..., "var_positional"),),
2246 ...))
2247
2248 self.assertEqual(self.signature(Test),
2249 ((('args', ..., ..., "var_positional"),),
2250 ...))
2251
2252 with self.assertRaisesRegex(ValueError, 'invalid method signature'):
2253 self.signature(Test())
2254
Yury Selivanov46c759d2015-05-27 21:56:53 -04002255 def test_signature_wrapped_bound_method(self):
2256 # Issue 24298
2257 class Test:
2258 def m1(self, arg1, arg2=1) -> int:
2259 pass
2260 @functools.wraps(Test().m1)
2261 def m1d(*args, **kwargs):
2262 pass
2263 self.assertEqual(self.signature(m1d),
2264 ((('arg1', ..., ..., "positional_or_keyword"),
2265 ('arg2', 1, ..., "positional_or_keyword")),
2266 int))
2267
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002268 def test_signature_on_classmethod(self):
2269 class Test:
2270 @classmethod
2271 def foo(cls, arg1, *, arg2=1):
2272 pass
2273
2274 meth = Test().foo
2275 self.assertEqual(self.signature(meth),
2276 ((('arg1', ..., ..., "positional_or_keyword"),
2277 ('arg2', 1, ..., "keyword_only")),
2278 ...))
2279
2280 meth = Test.foo
2281 self.assertEqual(self.signature(meth),
2282 ((('arg1', ..., ..., "positional_or_keyword"),
2283 ('arg2', 1, ..., "keyword_only")),
2284 ...))
2285
2286 def test_signature_on_staticmethod(self):
2287 class Test:
2288 @staticmethod
2289 def foo(cls, *, arg):
2290 pass
2291
2292 meth = Test().foo
2293 self.assertEqual(self.signature(meth),
2294 ((('cls', ..., ..., "positional_or_keyword"),
2295 ('arg', ..., ..., "keyword_only")),
2296 ...))
2297
2298 meth = Test.foo
2299 self.assertEqual(self.signature(meth),
2300 ((('cls', ..., ..., "positional_or_keyword"),
2301 ('arg', ..., ..., "keyword_only")),
2302 ...))
2303
2304 def test_signature_on_partial(self):
2305 from functools import partial
2306
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002307 Parameter = inspect.Parameter
2308
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002309 def test():
2310 pass
2311
2312 self.assertEqual(self.signature(partial(test)), ((), ...))
2313
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002314 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002315 inspect.signature(partial(test, 1))
2316
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002317 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002318 inspect.signature(partial(test, a=1))
2319
2320 def test(a, b, *, c, d):
2321 pass
2322
2323 self.assertEqual(self.signature(partial(test)),
2324 ((('a', ..., ..., "positional_or_keyword"),
2325 ('b', ..., ..., "positional_or_keyword"),
2326 ('c', ..., ..., "keyword_only"),
2327 ('d', ..., ..., "keyword_only")),
2328 ...))
2329
2330 self.assertEqual(self.signature(partial(test, 1)),
2331 ((('b', ..., ..., "positional_or_keyword"),
2332 ('c', ..., ..., "keyword_only"),
2333 ('d', ..., ..., "keyword_only")),
2334 ...))
2335
2336 self.assertEqual(self.signature(partial(test, 1, c=2)),
2337 ((('b', ..., ..., "positional_or_keyword"),
2338 ('c', 2, ..., "keyword_only"),
2339 ('d', ..., ..., "keyword_only")),
2340 ...))
2341
2342 self.assertEqual(self.signature(partial(test, b=1, c=2)),
2343 ((('a', ..., ..., "positional_or_keyword"),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002344 ('b', 1, ..., "keyword_only"),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002345 ('c', 2, ..., "keyword_only"),
2346 ('d', ..., ..., "keyword_only")),
2347 ...))
2348
2349 self.assertEqual(self.signature(partial(test, 0, b=1, c=2)),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002350 ((('b', 1, ..., "keyword_only"),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002351 ('c', 2, ..., "keyword_only"),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002352 ('d', ..., ..., "keyword_only")),
2353 ...))
2354
2355 self.assertEqual(self.signature(partial(test, a=1)),
2356 ((('a', 1, ..., "keyword_only"),
2357 ('b', ..., ..., "keyword_only"),
2358 ('c', ..., ..., "keyword_only"),
2359 ('d', ..., ..., "keyword_only")),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002360 ...))
2361
2362 def test(a, *args, b, **kwargs):
2363 pass
2364
2365 self.assertEqual(self.signature(partial(test, 1)),
2366 ((('args', ..., ..., "var_positional"),
2367 ('b', ..., ..., "keyword_only"),
2368 ('kwargs', ..., ..., "var_keyword")),
2369 ...))
2370
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002371 self.assertEqual(self.signature(partial(test, a=1)),
2372 ((('a', 1, ..., "keyword_only"),
2373 ('b', ..., ..., "keyword_only"),
2374 ('kwargs', ..., ..., "var_keyword")),
2375 ...))
2376
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002377 self.assertEqual(self.signature(partial(test, 1, 2, 3)),
2378 ((('args', ..., ..., "var_positional"),
2379 ('b', ..., ..., "keyword_only"),
2380 ('kwargs', ..., ..., "var_keyword")),
2381 ...))
2382
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002383 self.assertEqual(self.signature(partial(test, 1, 2, 3, test=True)),
2384 ((('args', ..., ..., "var_positional"),
2385 ('b', ..., ..., "keyword_only"),
2386 ('kwargs', ..., ..., "var_keyword")),
2387 ...))
2388
2389 self.assertEqual(self.signature(partial(test, 1, 2, 3, test=1, b=0)),
2390 ((('args', ..., ..., "var_positional"),
2391 ('b', 0, ..., "keyword_only"),
2392 ('kwargs', ..., ..., "var_keyword")),
2393 ...))
2394
2395 self.assertEqual(self.signature(partial(test, b=0)),
2396 ((('a', ..., ..., "positional_or_keyword"),
2397 ('args', ..., ..., "var_positional"),
2398 ('b', 0, ..., "keyword_only"),
2399 ('kwargs', ..., ..., "var_keyword")),
2400 ...))
2401
2402 self.assertEqual(self.signature(partial(test, b=0, test=1)),
2403 ((('a', ..., ..., "positional_or_keyword"),
2404 ('args', ..., ..., "var_positional"),
2405 ('b', 0, ..., "keyword_only"),
2406 ('kwargs', ..., ..., "var_keyword")),
2407 ...))
2408
2409 def test(a, b, c:int) -> 42:
2410 pass
2411
2412 sig = test.__signature__ = inspect.signature(test)
2413
2414 self.assertEqual(self.signature(partial(partial(test, 1))),
2415 ((('b', ..., ..., "positional_or_keyword"),
2416 ('c', ..., int, "positional_or_keyword")),
2417 42))
2418
2419 self.assertEqual(self.signature(partial(partial(test, 1), 2)),
2420 ((('c', ..., int, "positional_or_keyword"),),
2421 42))
2422
2423 psig = inspect.signature(partial(partial(test, 1), 2))
2424
2425 def foo(a):
2426 return a
2427 _foo = partial(partial(foo, a=10), a=20)
2428 self.assertEqual(self.signature(_foo),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002429 ((('a', 20, ..., "keyword_only"),),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002430 ...))
2431 # check that we don't have any side-effects in signature(),
2432 # and the partial object is still functioning
2433 self.assertEqual(_foo(), 20)
2434
2435 def foo(a, b, c):
2436 return a, b, c
2437 _foo = partial(partial(foo, 1, b=20), b=30)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002438
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002439 self.assertEqual(self.signature(_foo),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002440 ((('b', 30, ..., "keyword_only"),
2441 ('c', ..., ..., "keyword_only")),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002442 ...))
2443 self.assertEqual(_foo(c=10), (1, 30, 10))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002444
2445 def foo(a, b, c, *, d):
2446 return a, b, c, d
2447 _foo = partial(partial(foo, d=20, c=20), b=10, d=30)
2448 self.assertEqual(self.signature(_foo),
2449 ((('a', ..., ..., "positional_or_keyword"),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002450 ('b', 10, ..., "keyword_only"),
2451 ('c', 20, ..., "keyword_only"),
2452 ('d', 30, ..., "keyword_only"),
2453 ),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002454 ...))
2455 ba = inspect.signature(_foo).bind(a=200, b=11)
2456 self.assertEqual(_foo(*ba.args, **ba.kwargs), (200, 11, 20, 30))
2457
2458 def foo(a=1, b=2, c=3):
2459 return a, b, c
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002460 _foo = partial(foo, c=13) # (a=1, b=2, *, c=13)
2461
2462 ba = inspect.signature(_foo).bind(a=11)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002463 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 2, 13))
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002464
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002465 ba = inspect.signature(_foo).bind(11, 12)
2466 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002467
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002468 ba = inspect.signature(_foo).bind(11, b=12)
2469 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002470
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002471 ba = inspect.signature(_foo).bind(b=12)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002472 self.assertEqual(_foo(*ba.args, **ba.kwargs), (1, 12, 13))
2473
2474 _foo = partial(_foo, b=10, c=20)
2475 ba = inspect.signature(_foo).bind(12)
2476 self.assertEqual(_foo(*ba.args, **ba.kwargs), (12, 10, 20))
2477
2478
2479 def foo(a, b, c, d, **kwargs):
2480 pass
2481 sig = inspect.signature(foo)
2482 params = sig.parameters.copy()
2483 params['a'] = params['a'].replace(kind=Parameter.POSITIONAL_ONLY)
2484 params['b'] = params['b'].replace(kind=Parameter.POSITIONAL_ONLY)
2485 foo.__signature__ = inspect.Signature(params.values())
2486 sig = inspect.signature(foo)
2487 self.assertEqual(str(sig), '(a, b, /, c, d, **kwargs)')
2488
2489 self.assertEqual(self.signature(partial(foo, 1)),
2490 ((('b', ..., ..., 'positional_only'),
2491 ('c', ..., ..., 'positional_or_keyword'),
2492 ('d', ..., ..., 'positional_or_keyword'),
2493 ('kwargs', ..., ..., 'var_keyword')),
2494 ...))
2495
2496 self.assertEqual(self.signature(partial(foo, 1, 2)),
2497 ((('c', ..., ..., 'positional_or_keyword'),
2498 ('d', ..., ..., 'positional_or_keyword'),
2499 ('kwargs', ..., ..., 'var_keyword')),
2500 ...))
2501
2502 self.assertEqual(self.signature(partial(foo, 1, 2, 3)),
2503 ((('d', ..., ..., 'positional_or_keyword'),
2504 ('kwargs', ..., ..., 'var_keyword')),
2505 ...))
2506
2507 self.assertEqual(self.signature(partial(foo, 1, 2, c=3)),
2508 ((('c', 3, ..., 'keyword_only'),
2509 ('d', ..., ..., 'keyword_only'),
2510 ('kwargs', ..., ..., 'var_keyword')),
2511 ...))
2512
2513 self.assertEqual(self.signature(partial(foo, 1, c=3)),
2514 ((('b', ..., ..., 'positional_only'),
2515 ('c', 3, ..., 'keyword_only'),
2516 ('d', ..., ..., 'keyword_only'),
2517 ('kwargs', ..., ..., 'var_keyword')),
2518 ...))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002519
Yury Selivanovda5fe4f2014-01-27 17:28:37 -05002520 def test_signature_on_partialmethod(self):
2521 from functools import partialmethod
2522
2523 class Spam:
2524 def test():
2525 pass
2526 ham = partialmethod(test)
2527
2528 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
2529 inspect.signature(Spam.ham)
2530
2531 class Spam:
2532 def test(it, a, *, c) -> 'spam':
2533 pass
2534 ham = partialmethod(test, c=1)
2535
2536 self.assertEqual(self.signature(Spam.ham),
2537 ((('it', ..., ..., 'positional_or_keyword'),
2538 ('a', ..., ..., 'positional_or_keyword'),
2539 ('c', 1, ..., 'keyword_only')),
2540 'spam'))
2541
2542 self.assertEqual(self.signature(Spam().ham),
2543 ((('a', ..., ..., 'positional_or_keyword'),
2544 ('c', 1, ..., 'keyword_only')),
2545 'spam'))
2546
Yury Selivanov0486f812014-01-29 12:18:59 -05002547 def test_signature_on_fake_partialmethod(self):
2548 def foo(a): pass
2549 foo._partialmethod = 'spam'
2550 self.assertEqual(str(inspect.signature(foo)), '(a)')
2551
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002552 def test_signature_on_decorated(self):
2553 import functools
2554
2555 def decorator(func):
2556 @functools.wraps(func)
2557 def wrapper(*args, **kwargs) -> int:
2558 return func(*args, **kwargs)
2559 return wrapper
2560
2561 class Foo:
2562 @decorator
2563 def bar(self, a, b):
2564 pass
2565
2566 self.assertEqual(self.signature(Foo.bar),
2567 ((('self', ..., ..., "positional_or_keyword"),
2568 ('a', ..., ..., "positional_or_keyword"),
2569 ('b', ..., ..., "positional_or_keyword")),
2570 ...))
2571
2572 self.assertEqual(self.signature(Foo().bar),
2573 ((('a', ..., ..., "positional_or_keyword"),
2574 ('b', ..., ..., "positional_or_keyword")),
2575 ...))
2576
Yury Selivanovbcd4fc12015-05-20 14:30:08 -04002577 self.assertEqual(self.signature(Foo.bar, follow_wrapped=False),
2578 ((('args', ..., ..., "var_positional"),
2579 ('kwargs', ..., ..., "var_keyword")),
2580 ...)) # functools.wraps will copy __annotations__
2581 # from "func" to "wrapper", hence no
2582 # return_annotation
2583
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002584 # Test that we handle method wrappers correctly
2585 def decorator(func):
2586 @functools.wraps(func)
2587 def wrapper(*args, **kwargs) -> int:
2588 return func(42, *args, **kwargs)
2589 sig = inspect.signature(func)
2590 new_params = tuple(sig.parameters.values())[1:]
2591 wrapper.__signature__ = sig.replace(parameters=new_params)
2592 return wrapper
2593
2594 class Foo:
2595 @decorator
2596 def __call__(self, a, b):
2597 pass
2598
2599 self.assertEqual(self.signature(Foo.__call__),
2600 ((('a', ..., ..., "positional_or_keyword"),
2601 ('b', ..., ..., "positional_or_keyword")),
2602 ...))
2603
2604 self.assertEqual(self.signature(Foo().__call__),
2605 ((('b', ..., ..., "positional_or_keyword"),),
2606 ...))
2607
Nick Coghlane8c45d62013-07-28 20:00:01 +10002608 # Test we handle __signature__ partway down the wrapper stack
2609 def wrapped_foo_call():
2610 pass
2611 wrapped_foo_call.__wrapped__ = Foo.__call__
2612
2613 self.assertEqual(self.signature(wrapped_foo_call),
2614 ((('a', ..., ..., "positional_or_keyword"),
2615 ('b', ..., ..., "positional_or_keyword")),
2616 ...))
2617
2618
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002619 def test_signature_on_class(self):
2620 class C:
2621 def __init__(self, a):
2622 pass
2623
2624 self.assertEqual(self.signature(C),
2625 ((('a', ..., ..., "positional_or_keyword"),),
2626 ...))
2627
2628 class CM(type):
2629 def __call__(cls, a):
2630 pass
2631 class C(metaclass=CM):
2632 def __init__(self, b):
2633 pass
2634
2635 self.assertEqual(self.signature(C),
2636 ((('a', ..., ..., "positional_or_keyword"),),
2637 ...))
2638
2639 class CM(type):
2640 def __new__(mcls, name, bases, dct, *, foo=1):
2641 return super().__new__(mcls, name, bases, dct)
2642 class C(metaclass=CM):
2643 def __init__(self, b):
2644 pass
2645
2646 self.assertEqual(self.signature(C),
2647 ((('b', ..., ..., "positional_or_keyword"),),
2648 ...))
2649
2650 self.assertEqual(self.signature(CM),
2651 ((('name', ..., ..., "positional_or_keyword"),
2652 ('bases', ..., ..., "positional_or_keyword"),
2653 ('dct', ..., ..., "positional_or_keyword"),
2654 ('foo', 1, ..., "keyword_only")),
2655 ...))
2656
2657 class CMM(type):
2658 def __new__(mcls, name, bases, dct, *, foo=1):
2659 return super().__new__(mcls, name, bases, dct)
2660 def __call__(cls, nm, bs, dt):
2661 return type(nm, bs, dt)
2662 class CM(type, metaclass=CMM):
2663 def __new__(mcls, name, bases, dct, *, bar=2):
2664 return super().__new__(mcls, name, bases, dct)
2665 class C(metaclass=CM):
2666 def __init__(self, b):
2667 pass
2668
2669 self.assertEqual(self.signature(CMM),
2670 ((('name', ..., ..., "positional_or_keyword"),
2671 ('bases', ..., ..., "positional_or_keyword"),
2672 ('dct', ..., ..., "positional_or_keyword"),
2673 ('foo', 1, ..., "keyword_only")),
2674 ...))
2675
2676 self.assertEqual(self.signature(CM),
2677 ((('nm', ..., ..., "positional_or_keyword"),
2678 ('bs', ..., ..., "positional_or_keyword"),
2679 ('dt', ..., ..., "positional_or_keyword")),
2680 ...))
2681
2682 self.assertEqual(self.signature(C),
2683 ((('b', ..., ..., "positional_or_keyword"),),
2684 ...))
2685
2686 class CM(type):
2687 def __init__(cls, name, bases, dct, *, bar=2):
2688 return super().__init__(name, bases, dct)
2689 class C(metaclass=CM):
2690 def __init__(self, b):
2691 pass
2692
2693 self.assertEqual(self.signature(CM),
2694 ((('name', ..., ..., "positional_or_keyword"),
2695 ('bases', ..., ..., "positional_or_keyword"),
2696 ('dct', ..., ..., "positional_or_keyword"),
2697 ('bar', 2, ..., "keyword_only")),
2698 ...))
2699
Yury Selivanov145dff82014-02-01 13:49:29 -05002700 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2701 "Signature information for builtins requires docstrings")
2702 def test_signature_on_class_without_init(self):
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002703 # Test classes without user-defined __init__ or __new__
2704 class C: pass
2705 self.assertEqual(str(inspect.signature(C)), '()')
2706 class D(C): pass
2707 self.assertEqual(str(inspect.signature(D)), '()')
2708
2709 # Test meta-classes without user-defined __init__ or __new__
2710 class C(type): pass
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002711 class D(C): pass
Larry Hastings2623c8c2014-02-08 22:15:29 -08002712 with self.assertRaisesRegex(ValueError, "callable.*is not supported"):
2713 self.assertEqual(inspect.signature(C), None)
2714 with self.assertRaisesRegex(ValueError, "callable.*is not supported"):
2715 self.assertEqual(inspect.signature(D), None)
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002716
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002717 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2718 "Signature information for builtins requires docstrings")
2719 def test_signature_on_builtin_class(self):
2720 self.assertEqual(str(inspect.signature(_pickle.Pickler)),
2721 '(file, protocol=None, fix_imports=True)')
2722
2723 class P(_pickle.Pickler): pass
2724 class EmptyTrait: pass
2725 class P2(EmptyTrait, P): pass
2726 self.assertEqual(str(inspect.signature(P)),
2727 '(file, protocol=None, fix_imports=True)')
2728 self.assertEqual(str(inspect.signature(P2)),
2729 '(file, protocol=None, fix_imports=True)')
2730
2731 class P3(P2):
2732 def __init__(self, spam):
2733 pass
2734 self.assertEqual(str(inspect.signature(P3)), '(spam)')
2735
2736 class MetaP(type):
2737 def __call__(cls, foo, bar):
2738 pass
2739 class P4(P2, metaclass=MetaP):
2740 pass
2741 self.assertEqual(str(inspect.signature(P4)), '(foo, bar)')
2742
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002743 def test_signature_on_callable_objects(self):
2744 class Foo:
2745 def __call__(self, a):
2746 pass
2747
2748 self.assertEqual(self.signature(Foo()),
2749 ((('a', ..., ..., "positional_or_keyword"),),
2750 ...))
2751
2752 class Spam:
2753 pass
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002754 with self.assertRaisesRegex(TypeError, "is not a callable object"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002755 inspect.signature(Spam())
2756
2757 class Bar(Spam, Foo):
2758 pass
2759
2760 self.assertEqual(self.signature(Bar()),
2761 ((('a', ..., ..., "positional_or_keyword"),),
2762 ...))
2763
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002764 class Wrapped:
2765 pass
2766 Wrapped.__wrapped__ = lambda a: None
2767 self.assertEqual(self.signature(Wrapped),
2768 ((('a', ..., ..., "positional_or_keyword"),),
2769 ...))
Nick Coghlane8c45d62013-07-28 20:00:01 +10002770 # wrapper loop:
2771 Wrapped.__wrapped__ = Wrapped
2772 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
2773 self.signature(Wrapped)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002774
2775 def test_signature_on_lambdas(self):
2776 self.assertEqual(self.signature((lambda a=10: a)),
2777 ((('a', 10, ..., "positional_or_keyword"),),
2778 ...))
2779
2780 def test_signature_equality(self):
2781 def foo(a, *, b:int) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002782 self.assertFalse(inspect.signature(foo) == 42)
2783 self.assertTrue(inspect.signature(foo) != 42)
2784 self.assertTrue(inspect.signature(foo) == EqualsToAll())
2785 self.assertFalse(inspect.signature(foo) != EqualsToAll())
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002786
2787 def bar(a, *, b:int) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002788 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
2789 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002790 self.assertEqual(
2791 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002792
2793 def bar(a, *, b:int) -> int: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002794 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
2795 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002796 self.assertNotEqual(
2797 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002798
2799 def bar(a, *, b:int): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002800 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
2801 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002802 self.assertNotEqual(
2803 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002804
2805 def bar(a, *, b:int=42) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002806 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
2807 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002808 self.assertNotEqual(
2809 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002810
2811 def bar(a, *, c) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002812 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
2813 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002814 self.assertNotEqual(
2815 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002816
2817 def bar(a, b:int) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002818 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
2819 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002820 self.assertNotEqual(
2821 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002822 def spam(b:int, a) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002823 self.assertFalse(inspect.signature(spam) == inspect.signature(bar))
2824 self.assertTrue(inspect.signature(spam) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002825 self.assertNotEqual(
2826 hash(inspect.signature(spam)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002827
2828 def foo(*, a, b, c): pass
2829 def bar(*, c, b, a): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002830 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
2831 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002832 self.assertEqual(
2833 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002834
2835 def foo(*, a=1, b, c): pass
2836 def bar(*, c, b, a=1): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002837 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
2838 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002839 self.assertEqual(
2840 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002841
2842 def foo(pos, *, a=1, b, c): pass
2843 def bar(pos, *, c, b, a=1): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002844 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
2845 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002846 self.assertEqual(
2847 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002848
2849 def foo(pos, *, a, b, c): pass
2850 def bar(pos, *, c, b, a=1): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002851 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
2852 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002853 self.assertNotEqual(
2854 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002855
2856 def foo(pos, *args, a=42, b, c, **kwargs:int): pass
2857 def bar(pos, *args, c, b, a=42, **kwargs:int): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002858 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
2859 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002860 self.assertEqual(
2861 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002862
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002863 def test_signature_hashable(self):
2864 S = inspect.Signature
2865 P = inspect.Parameter
2866
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002867 def foo(a): pass
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002868 foo_sig = inspect.signature(foo)
2869
2870 manual_sig = S(parameters=[P('a', P.POSITIONAL_OR_KEYWORD)])
2871
2872 self.assertEqual(hash(foo_sig), hash(manual_sig))
2873 self.assertNotEqual(hash(foo_sig),
2874 hash(manual_sig.replace(return_annotation='spam')))
2875
2876 def bar(a) -> 1: pass
2877 self.assertNotEqual(hash(foo_sig), hash(inspect.signature(bar)))
2878
2879 def foo(a={}): pass
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002880 with self.assertRaisesRegex(TypeError, 'unhashable type'):
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002881 hash(inspect.signature(foo))
2882
2883 def foo(a) -> {}: pass
2884 with self.assertRaisesRegex(TypeError, 'unhashable type'):
2885 hash(inspect.signature(foo))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002886
2887 def test_signature_str(self):
2888 def foo(a:int=1, *, b, c=None, **kwargs) -> 42:
2889 pass
2890 self.assertEqual(str(inspect.signature(foo)),
Dong-hee Na762b9572017-11-16 03:30:59 +09002891 '(a: int = 1, *, b, c=None, **kwargs) -> 42')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002892
2893 def foo(a:int=1, *args, b, c=None, **kwargs) -> 42:
2894 pass
2895 self.assertEqual(str(inspect.signature(foo)),
Dong-hee Na762b9572017-11-16 03:30:59 +09002896 '(a: int = 1, *args, b, c=None, **kwargs) -> 42')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002897
2898 def foo():
2899 pass
2900 self.assertEqual(str(inspect.signature(foo)), '()')
2901
2902 def test_signature_str_positional_only(self):
2903 P = inspect.Parameter
Yury Selivanov2393dca2014-01-27 15:07:58 -05002904 S = inspect.Signature
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002905
2906 def test(a_po, *, b, **kwargs):
2907 return a_po, kwargs
2908
2909 sig = inspect.signature(test)
2910 new_params = list(sig.parameters.values())
2911 new_params[0] = new_params[0].replace(kind=P.POSITIONAL_ONLY)
2912 test.__signature__ = sig.replace(parameters=new_params)
2913
2914 self.assertEqual(str(inspect.signature(test)),
Yury Selivanov2393dca2014-01-27 15:07:58 -05002915 '(a_po, /, *, b, **kwargs)')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002916
Yury Selivanov2393dca2014-01-27 15:07:58 -05002917 self.assertEqual(str(S(parameters=[P('foo', P.POSITIONAL_ONLY)])),
2918 '(foo, /)')
2919
2920 self.assertEqual(str(S(parameters=[
2921 P('foo', P.POSITIONAL_ONLY),
2922 P('bar', P.VAR_KEYWORD)])),
2923 '(foo, /, **bar)')
2924
2925 self.assertEqual(str(S(parameters=[
2926 P('foo', P.POSITIONAL_ONLY),
2927 P('bar', P.VAR_POSITIONAL)])),
2928 '(foo, /, *bar)')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002929
2930 def test_signature_replace_anno(self):
2931 def test() -> 42:
2932 pass
2933
2934 sig = inspect.signature(test)
2935 sig = sig.replace(return_annotation=None)
2936 self.assertIs(sig.return_annotation, None)
2937 sig = sig.replace(return_annotation=sig.empty)
2938 self.assertIs(sig.return_annotation, sig.empty)
2939 sig = sig.replace(return_annotation=42)
2940 self.assertEqual(sig.return_annotation, 42)
2941 self.assertEqual(sig, inspect.signature(test))
2942
Yury Selivanov34ce99f2014-02-18 12:49:41 -05002943 def test_signature_on_mangled_parameters(self):
2944 class Spam:
2945 def foo(self, __p1:1=2, *, __p2:2=3):
2946 pass
2947 class Ham(Spam):
2948 pass
2949
2950 self.assertEqual(self.signature(Spam.foo),
2951 ((('self', ..., ..., "positional_or_keyword"),
2952 ('_Spam__p1', 2, 1, "positional_or_keyword"),
2953 ('_Spam__p2', 3, 2, "keyword_only")),
2954 ...))
2955
2956 self.assertEqual(self.signature(Spam.foo),
2957 self.signature(Ham.foo))
2958
Yury Selivanovda396452014-03-27 12:09:24 -04002959 def test_signature_from_callable_python_obj(self):
2960 class MySignature(inspect.Signature): pass
2961 def foo(a, *, b:1): pass
2962 foo_sig = MySignature.from_callable(foo)
2963 self.assertTrue(isinstance(foo_sig, MySignature))
2964
2965 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2966 "Signature information for builtins requires docstrings")
2967 def test_signature_from_callable_builtin_obj(self):
2968 class MySignature(inspect.Signature): pass
2969 sig = MySignature.from_callable(_pickle.Pickler)
2970 self.assertTrue(isinstance(sig, MySignature))
2971
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002972
2973class TestParameterObject(unittest.TestCase):
2974 def test_signature_parameter_kinds(self):
2975 P = inspect.Parameter
2976 self.assertTrue(P.POSITIONAL_ONLY < P.POSITIONAL_OR_KEYWORD < \
2977 P.VAR_POSITIONAL < P.KEYWORD_ONLY < P.VAR_KEYWORD)
2978
2979 self.assertEqual(str(P.POSITIONAL_ONLY), 'POSITIONAL_ONLY')
2980 self.assertTrue('POSITIONAL_ONLY' in repr(P.POSITIONAL_ONLY))
2981
2982 def test_signature_parameter_object(self):
2983 p = inspect.Parameter('foo', default=10,
2984 kind=inspect.Parameter.POSITIONAL_ONLY)
2985 self.assertEqual(p.name, 'foo')
2986 self.assertEqual(p.default, 10)
2987 self.assertIs(p.annotation, p.empty)
2988 self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY)
2989
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002990 with self.assertRaisesRegex(ValueError, 'invalid value'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002991 inspect.Parameter('foo', default=10, kind='123')
2992
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002993 with self.assertRaisesRegex(ValueError, 'not a valid parameter name'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002994 inspect.Parameter('1', kind=inspect.Parameter.VAR_KEYWORD)
2995
Yury Selivanov2393dca2014-01-27 15:07:58 -05002996 with self.assertRaisesRegex(TypeError, 'name must be a str'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002997 inspect.Parameter(None, kind=inspect.Parameter.VAR_KEYWORD)
2998
Yury Selivanov2393dca2014-01-27 15:07:58 -05002999 with self.assertRaisesRegex(ValueError,
3000 'is not a valid parameter name'):
3001 inspect.Parameter('$', kind=inspect.Parameter.VAR_KEYWORD)
3002
Nick Coghlanb4b966e2016-06-04 14:40:03 -07003003 with self.assertRaisesRegex(ValueError,
3004 'is not a valid parameter name'):
3005 inspect.Parameter('.a', kind=inspect.Parameter.VAR_KEYWORD)
3006
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003007 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003008 inspect.Parameter('a', default=42,
3009 kind=inspect.Parameter.VAR_KEYWORD)
3010
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003011 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003012 inspect.Parameter('a', default=42,
3013 kind=inspect.Parameter.VAR_POSITIONAL)
3014
3015 p = inspect.Parameter('a', default=42,
3016 kind=inspect.Parameter.POSITIONAL_OR_KEYWORD)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003017 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003018 p.replace(kind=inspect.Parameter.VAR_POSITIONAL)
3019
3020 self.assertTrue(repr(p).startswith('<Parameter'))
Yury Selivanov374375d2014-03-27 12:41:53 -04003021 self.assertTrue('"a=42"' in repr(p))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003022
Yury Selivanov67ae50e2014-04-08 11:46:50 -04003023 def test_signature_parameter_hashable(self):
3024 P = inspect.Parameter
3025 foo = P('foo', kind=P.POSITIONAL_ONLY)
3026 self.assertEqual(hash(foo), hash(P('foo', kind=P.POSITIONAL_ONLY)))
3027 self.assertNotEqual(hash(foo), hash(P('foo', kind=P.POSITIONAL_ONLY,
3028 default=42)))
3029 self.assertNotEqual(hash(foo),
3030 hash(foo.replace(kind=P.VAR_POSITIONAL)))
3031
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003032 def test_signature_parameter_equality(self):
3033 P = inspect.Parameter
3034 p = P('foo', default=42, kind=inspect.Parameter.KEYWORD_ONLY)
3035
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003036 self.assertTrue(p == p)
3037 self.assertFalse(p != p)
3038 self.assertFalse(p == 42)
3039 self.assertTrue(p != 42)
3040 self.assertTrue(p == EqualsToAll())
3041 self.assertFalse(p != EqualsToAll())
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003042
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003043 self.assertTrue(p == P('foo', default=42,
3044 kind=inspect.Parameter.KEYWORD_ONLY))
3045 self.assertFalse(p != P('foo', default=42,
3046 kind=inspect.Parameter.KEYWORD_ONLY))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003047
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003048 def test_signature_parameter_replace(self):
3049 p = inspect.Parameter('foo', default=42,
3050 kind=inspect.Parameter.KEYWORD_ONLY)
3051
3052 self.assertIsNot(p, p.replace())
3053 self.assertEqual(p, p.replace())
3054
3055 p2 = p.replace(annotation=1)
3056 self.assertEqual(p2.annotation, 1)
3057 p2 = p2.replace(annotation=p2.empty)
3058 self.assertEqual(p, p2)
3059
3060 p2 = p2.replace(name='bar')
3061 self.assertEqual(p2.name, 'bar')
3062 self.assertNotEqual(p2, p)
3063
Yury Selivanov2393dca2014-01-27 15:07:58 -05003064 with self.assertRaisesRegex(ValueError,
3065 'name is a required attribute'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003066 p2 = p2.replace(name=p2.empty)
3067
3068 p2 = p2.replace(name='foo', default=None)
3069 self.assertIs(p2.default, None)
3070 self.assertNotEqual(p2, p)
3071
3072 p2 = p2.replace(name='foo', default=p2.empty)
3073 self.assertIs(p2.default, p2.empty)
3074
3075
3076 p2 = p2.replace(default=42, kind=p2.POSITIONAL_OR_KEYWORD)
3077 self.assertEqual(p2.kind, p2.POSITIONAL_OR_KEYWORD)
3078 self.assertNotEqual(p2, p)
3079
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003080 with self.assertRaisesRegex(ValueError, 'invalid value for'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003081 p2 = p2.replace(kind=p2.empty)
3082
3083 p2 = p2.replace(kind=p2.KEYWORD_ONLY)
3084 self.assertEqual(p2, p)
3085
3086 def test_signature_parameter_positional_only(self):
Yury Selivanov2393dca2014-01-27 15:07:58 -05003087 with self.assertRaisesRegex(TypeError, 'name must be a str'):
3088 inspect.Parameter(None, kind=inspect.Parameter.POSITIONAL_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003089
Nick Coghlanb4b966e2016-06-04 14:40:03 -07003090 @cpython_only
3091 def test_signature_parameter_implicit(self):
3092 with self.assertRaisesRegex(ValueError,
3093 'implicit arguments must be passed in as'):
3094 inspect.Parameter('.0', kind=inspect.Parameter.POSITIONAL_ONLY)
3095
3096 param = inspect.Parameter(
3097 '.0', kind=inspect.Parameter.POSITIONAL_OR_KEYWORD)
3098 self.assertEqual(param.kind, inspect.Parameter.POSITIONAL_ONLY)
3099 self.assertEqual(param.name, 'implicit0')
3100
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003101 def test_signature_parameter_immutability(self):
Yury Selivanov2393dca2014-01-27 15:07:58 -05003102 p = inspect.Parameter('spam', kind=inspect.Parameter.KEYWORD_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003103
3104 with self.assertRaises(AttributeError):
3105 p.foo = 'bar'
3106
3107 with self.assertRaises(AttributeError):
3108 p.kind = 123
3109
3110
3111class TestSignatureBind(unittest.TestCase):
3112 @staticmethod
3113 def call(func, *args, **kwargs):
3114 sig = inspect.signature(func)
3115 ba = sig.bind(*args, **kwargs)
3116 return func(*ba.args, **ba.kwargs)
3117
3118 def test_signature_bind_empty(self):
3119 def test():
3120 return 42
3121
3122 self.assertEqual(self.call(test), 42)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003123 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003124 self.call(test, 1)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003125 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003126 self.call(test, 1, spam=10)
Yury Selivanov86872752015-05-19 00:27:49 -04003127 with self.assertRaisesRegex(
3128 TypeError, "got an unexpected keyword argument 'spam'"):
3129
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003130 self.call(test, spam=1)
3131
3132 def test_signature_bind_var(self):
3133 def test(*args, **kwargs):
3134 return args, kwargs
3135
3136 self.assertEqual(self.call(test), ((), {}))
3137 self.assertEqual(self.call(test, 1), ((1,), {}))
3138 self.assertEqual(self.call(test, 1, 2), ((1, 2), {}))
3139 self.assertEqual(self.call(test, foo='bar'), ((), {'foo': 'bar'}))
3140 self.assertEqual(self.call(test, 1, foo='bar'), ((1,), {'foo': 'bar'}))
3141 self.assertEqual(self.call(test, args=10), ((), {'args': 10}))
3142 self.assertEqual(self.call(test, 1, 2, foo='bar'),
3143 ((1, 2), {'foo': 'bar'}))
3144
3145 def test_signature_bind_just_args(self):
3146 def test(a, b, c):
3147 return a, b, c
3148
3149 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
3150
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003151 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003152 self.call(test, 1, 2, 3, 4)
3153
Yury Selivanov86872752015-05-19 00:27:49 -04003154 with self.assertRaisesRegex(TypeError,
3155 "missing a required argument: 'b'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003156 self.call(test, 1)
3157
Yury Selivanov86872752015-05-19 00:27:49 -04003158 with self.assertRaisesRegex(TypeError,
3159 "missing a required argument: 'a'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003160 self.call(test)
3161
3162 def test(a, b, c=10):
3163 return a, b, c
3164 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
3165 self.assertEqual(self.call(test, 1, 2), (1, 2, 10))
3166
3167 def test(a=1, b=2, c=3):
3168 return a, b, c
3169 self.assertEqual(self.call(test, a=10, c=13), (10, 2, 13))
3170 self.assertEqual(self.call(test, a=10), (10, 2, 3))
3171 self.assertEqual(self.call(test, b=10), (1, 10, 3))
3172
3173 def test_signature_bind_varargs_order(self):
3174 def test(*args):
3175 return args
3176
3177 self.assertEqual(self.call(test), ())
3178 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
3179
3180 def test_signature_bind_args_and_varargs(self):
3181 def test(a, b, c=3, *args):
3182 return a, b, c, args
3183
3184 self.assertEqual(self.call(test, 1, 2, 3, 4, 5), (1, 2, 3, (4, 5)))
3185 self.assertEqual(self.call(test, 1, 2), (1, 2, 3, ()))
3186 self.assertEqual(self.call(test, b=1, a=2), (2, 1, 3, ()))
3187 self.assertEqual(self.call(test, 1, b=2), (1, 2, 3, ()))
3188
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003189 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003190 "multiple values for argument 'c'"):
3191 self.call(test, 1, 2, 3, c=4)
3192
3193 def test_signature_bind_just_kwargs(self):
3194 def test(**kwargs):
3195 return kwargs
3196
3197 self.assertEqual(self.call(test), {})
3198 self.assertEqual(self.call(test, foo='bar', spam='ham'),
3199 {'foo': 'bar', 'spam': 'ham'})
3200
3201 def test_signature_bind_args_and_kwargs(self):
3202 def test(a, b, c=3, **kwargs):
3203 return a, b, c, kwargs
3204
3205 self.assertEqual(self.call(test, 1, 2), (1, 2, 3, {}))
3206 self.assertEqual(self.call(test, 1, 2, foo='bar', spam='ham'),
3207 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3208 self.assertEqual(self.call(test, b=2, a=1, foo='bar', spam='ham'),
3209 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3210 self.assertEqual(self.call(test, a=1, b=2, foo='bar', spam='ham'),
3211 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3212 self.assertEqual(self.call(test, 1, b=2, foo='bar', spam='ham'),
3213 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3214 self.assertEqual(self.call(test, 1, b=2, c=4, foo='bar', spam='ham'),
3215 (1, 2, 4, {'foo': 'bar', 'spam': 'ham'}))
3216 self.assertEqual(self.call(test, 1, 2, 4, foo='bar'),
3217 (1, 2, 4, {'foo': 'bar'}))
3218 self.assertEqual(self.call(test, c=5, a=4, b=3),
3219 (4, 3, 5, {}))
3220
3221 def test_signature_bind_kwonly(self):
3222 def test(*, foo):
3223 return foo
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003224 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003225 'too many positional arguments'):
3226 self.call(test, 1)
3227 self.assertEqual(self.call(test, foo=1), 1)
3228
3229 def test(a, *, foo=1, bar):
3230 return foo
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003231 with self.assertRaisesRegex(TypeError,
Yury Selivanov86872752015-05-19 00:27:49 -04003232 "missing a required argument: 'bar'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003233 self.call(test, 1)
3234
3235 def test(foo, *, bar):
3236 return foo, bar
3237 self.assertEqual(self.call(test, 1, bar=2), (1, 2))
3238 self.assertEqual(self.call(test, bar=2, foo=1), (1, 2))
3239
Yury Selivanov86872752015-05-19 00:27:49 -04003240 with self.assertRaisesRegex(
3241 TypeError, "got an unexpected keyword argument 'spam'"):
3242
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003243 self.call(test, bar=2, foo=1, spam=10)
3244
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003245 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003246 'too many positional arguments'):
3247 self.call(test, 1, 2)
3248
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003249 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003250 'too many positional arguments'):
3251 self.call(test, 1, 2, bar=2)
3252
Yury Selivanov86872752015-05-19 00:27:49 -04003253 with self.assertRaisesRegex(
3254 TypeError, "got an unexpected keyword argument 'spam'"):
3255
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003256 self.call(test, 1, bar=2, spam='ham')
3257
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003258 with self.assertRaisesRegex(TypeError,
Yury Selivanov86872752015-05-19 00:27:49 -04003259 "missing a required argument: 'bar'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003260 self.call(test, 1)
3261
3262 def test(foo, *, bar, **bin):
3263 return foo, bar, bin
3264 self.assertEqual(self.call(test, 1, bar=2), (1, 2, {}))
3265 self.assertEqual(self.call(test, foo=1, bar=2), (1, 2, {}))
3266 self.assertEqual(self.call(test, 1, bar=2, spam='ham'),
3267 (1, 2, {'spam': 'ham'}))
3268 self.assertEqual(self.call(test, spam='ham', foo=1, bar=2),
3269 (1, 2, {'spam': 'ham'}))
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003270 with self.assertRaisesRegex(TypeError,
Yury Selivanov86872752015-05-19 00:27:49 -04003271 "missing a required argument: 'foo'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003272 self.call(test, spam='ham', bar=2)
3273 self.assertEqual(self.call(test, 1, bar=2, bin=1, spam=10),
3274 (1, 2, {'bin': 1, 'spam': 10}))
3275
3276 def test_signature_bind_arguments(self):
3277 def test(a, *args, b, z=100, **kwargs):
3278 pass
3279 sig = inspect.signature(test)
3280 ba = sig.bind(10, 20, b=30, c=40, args=50, kwargs=60)
3281 # we won't have 'z' argument in the bound arguments object, as we didn't
3282 # pass it to the 'bind'
3283 self.assertEqual(tuple(ba.arguments.items()),
3284 (('a', 10), ('args', (20,)), ('b', 30),
3285 ('kwargs', {'c': 40, 'args': 50, 'kwargs': 60})))
3286 self.assertEqual(ba.kwargs,
3287 {'b': 30, 'c': 40, 'args': 50, 'kwargs': 60})
3288 self.assertEqual(ba.args, (10, 20))
3289
3290 def test_signature_bind_positional_only(self):
3291 P = inspect.Parameter
3292
3293 def test(a_po, b_po, c_po=3, foo=42, *, bar=50, **kwargs):
3294 return a_po, b_po, c_po, foo, bar, kwargs
3295
3296 sig = inspect.signature(test)
3297 new_params = collections.OrderedDict(tuple(sig.parameters.items()))
3298 for name in ('a_po', 'b_po', 'c_po'):
3299 new_params[name] = new_params[name].replace(kind=P.POSITIONAL_ONLY)
3300 new_sig = sig.replace(parameters=new_params.values())
3301 test.__signature__ = new_sig
3302
3303 self.assertEqual(self.call(test, 1, 2, 4, 5, bar=6),
3304 (1, 2, 4, 5, 6, {}))
3305
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05003306 self.assertEqual(self.call(test, 1, 2),
3307 (1, 2, 3, 42, 50, {}))
3308
3309 self.assertEqual(self.call(test, 1, 2, foo=4, bar=5),
3310 (1, 2, 3, 4, 5, {}))
3311
3312 with self.assertRaisesRegex(TypeError, "but was passed as a keyword"):
3313 self.call(test, 1, 2, foo=4, bar=5, c_po=10)
3314
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003315 with self.assertRaisesRegex(TypeError, "parameter is positional only"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003316 self.call(test, 1, 2, c_po=4)
3317
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003318 with self.assertRaisesRegex(TypeError, "parameter is positional only"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003319 self.call(test, a_po=1, b_po=2)
3320
Antoine Pitroubd41d1b2013-01-29 21:20:57 +01003321 def test_signature_bind_with_self_arg(self):
3322 # Issue #17071: one of the parameters is named "self
3323 def test(a, self, b):
3324 pass
3325 sig = inspect.signature(test)
3326 ba = sig.bind(1, 2, 3)
3327 self.assertEqual(ba.args, (1, 2, 3))
3328 ba = sig.bind(1, self=2, b=3)
3329 self.assertEqual(ba.args, (1, 2, 3))
3330
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05003331 def test_signature_bind_vararg_name(self):
3332 def test(a, *args):
3333 return a, args
3334 sig = inspect.signature(test)
3335
Yury Selivanov86872752015-05-19 00:27:49 -04003336 with self.assertRaisesRegex(
3337 TypeError, "got an unexpected keyword argument 'args'"):
3338
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05003339 sig.bind(a=0, args=1)
3340
3341 def test(*args, **kwargs):
3342 return args, kwargs
3343 self.assertEqual(self.call(test, args=1), ((), {'args': 1}))
3344
3345 sig = inspect.signature(test)
3346 ba = sig.bind(args=1)
3347 self.assertEqual(ba.arguments, {'kwargs': {'args': 1}})
3348
Nick Coghlanb4b966e2016-06-04 14:40:03 -07003349 @cpython_only
3350 def test_signature_bind_implicit_arg(self):
3351 # Issue #19611: getcallargs should work with set comprehensions
3352 def make_set():
3353 return {z * z for z in range(5)}
3354 setcomp_code = make_set.__code__.co_consts[1]
3355 setcomp_func = types.FunctionType(setcomp_code, {})
3356
3357 iterator = iter(range(5))
3358 self.assertEqual(self.call(setcomp_func, iterator), {0, 1, 4, 9, 16})
3359
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003360
3361class TestBoundArguments(unittest.TestCase):
3362 def test_signature_bound_arguments_unhashable(self):
3363 def foo(a): pass
3364 ba = inspect.signature(foo).bind(1)
3365
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003366 with self.assertRaisesRegex(TypeError, 'unhashable type'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003367 hash(ba)
3368
3369 def test_signature_bound_arguments_equality(self):
3370 def foo(a): pass
3371 ba = inspect.signature(foo).bind(1)
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003372 self.assertTrue(ba == ba)
3373 self.assertFalse(ba != ba)
3374 self.assertTrue(ba == EqualsToAll())
3375 self.assertFalse(ba != EqualsToAll())
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003376
3377 ba2 = inspect.signature(foo).bind(1)
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003378 self.assertTrue(ba == ba2)
3379 self.assertFalse(ba != ba2)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003380
3381 ba3 = inspect.signature(foo).bind(2)
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003382 self.assertFalse(ba == ba3)
3383 self.assertTrue(ba != ba3)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003384 ba3.arguments['a'] = 1
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003385 self.assertTrue(ba == ba3)
3386 self.assertFalse(ba != ba3)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003387
3388 def bar(b): pass
3389 ba4 = inspect.signature(bar).bind(1)
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003390 self.assertFalse(ba == ba4)
3391 self.assertTrue(ba != ba4)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003392
Yury Selivanov4cfd4ea2015-05-14 18:30:27 -04003393 def foo(*, a, b): pass
3394 sig = inspect.signature(foo)
3395 ba1 = sig.bind(a=1, b=2)
3396 ba2 = sig.bind(b=2, a=1)
Serhiy Storchaka2489bd52015-07-18 23:20:50 +03003397 self.assertTrue(ba1 == ba2)
3398 self.assertFalse(ba1 != ba2)
Yury Selivanov4cfd4ea2015-05-14 18:30:27 -04003399
Yury Selivanova5d63dd2014-03-27 11:31:43 -04003400 def test_signature_bound_arguments_pickle(self):
3401 def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
3402 sig = inspect.signature(foo)
3403 ba = sig.bind(20, 30, z={})
3404
3405 for ver in range(pickle.HIGHEST_PROTOCOL + 1):
3406 with self.subTest(pickle_ver=ver):
3407 ba_pickled = pickle.loads(pickle.dumps(ba, ver))
3408 self.assertEqual(ba, ba_pickled)
3409
Yury Selivanov3f6538f2015-05-14 18:47:17 -04003410 def test_signature_bound_arguments_repr(self):
3411 def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
3412 sig = inspect.signature(foo)
3413 ba = sig.bind(20, 30, z={})
Yury Selivanovf229bc52015-05-15 12:53:56 -04003414 self.assertRegex(repr(ba), r'<BoundArguments \(a=20,.*\}\}\)>')
Yury Selivanov3f6538f2015-05-14 18:47:17 -04003415
Yury Selivanovb907a512015-05-16 13:45:09 -04003416 def test_signature_bound_arguments_apply_defaults(self):
3417 def foo(a, b=1, *args, c:1={}, **kw): pass
3418 sig = inspect.signature(foo)
3419
3420 ba = sig.bind(20)
3421 ba.apply_defaults()
3422 self.assertEqual(
3423 list(ba.arguments.items()),
3424 [('a', 20), ('b', 1), ('args', ()), ('c', {}), ('kw', {})])
3425
3426 # Make sure that we preserve the order:
3427 # i.e. 'c' should be *before* 'kw'.
3428 ba = sig.bind(10, 20, 30, d=1)
3429 ba.apply_defaults()
3430 self.assertEqual(
3431 list(ba.arguments.items()),
3432 [('a', 10), ('b', 20), ('args', (30,)), ('c', {}), ('kw', {'d':1})])
3433
3434 # Make sure that BoundArguments produced by bind_partial()
3435 # are supported.
3436 def foo(a, b): pass
3437 sig = inspect.signature(foo)
3438 ba = sig.bind_partial(20)
3439 ba.apply_defaults()
3440 self.assertEqual(
3441 list(ba.arguments.items()),
3442 [('a', 20)])
3443
3444 # Test no args
3445 def foo(): pass
3446 sig = inspect.signature(foo)
3447 ba = sig.bind()
3448 ba.apply_defaults()
3449 self.assertEqual(list(ba.arguments.items()), [])
3450
Yury Selivanovf9e1f2b2016-03-02 11:07:47 -05003451 # Make sure a no-args binding still acquires proper defaults.
3452 def foo(a='spam'): pass
3453 sig = inspect.signature(foo)
3454 ba = sig.bind()
3455 ba.apply_defaults()
3456 self.assertEqual(list(ba.arguments.items()), [('a', 'spam')])
3457
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003458
Yury Selivanovd82eddc2014-01-29 11:24:39 -05003459class TestSignaturePrivateHelpers(unittest.TestCase):
3460 def test_signature_get_bound_param(self):
3461 getter = inspect._signature_get_bound_param
3462
3463 self.assertEqual(getter('($self)'), 'self')
3464 self.assertEqual(getter('($self, obj)'), 'self')
3465 self.assertEqual(getter('($cls, /, obj)'), 'cls')
3466
Larry Hastings2623c8c2014-02-08 22:15:29 -08003467 def _strip_non_python_syntax(self, input,
3468 clean_signature, self_parameter, last_positional_only):
3469 computed_clean_signature, \
3470 computed_self_parameter, \
3471 computed_last_positional_only = \
3472 inspect._signature_strip_non_python_syntax(input)
3473 self.assertEqual(computed_clean_signature, clean_signature)
3474 self.assertEqual(computed_self_parameter, self_parameter)
3475 self.assertEqual(computed_last_positional_only, last_positional_only)
3476
3477 def test_signature_strip_non_python_syntax(self):
3478 self._strip_non_python_syntax(
3479 "($module, /, path, mode, *, dir_fd=None, " +
3480 "effective_ids=False,\n follow_symlinks=True)",
3481 "(module, path, mode, *, dir_fd=None, " +
3482 "effective_ids=False, follow_symlinks=True)",
3483 0,
3484 0)
3485
3486 self._strip_non_python_syntax(
3487 "($module, word, salt, /)",
3488 "(module, word, salt)",
3489 0,
3490 2)
3491
3492 self._strip_non_python_syntax(
3493 "(x, y=None, z=None, /)",
3494 "(x, y=None, z=None)",
3495 None,
3496 2)
3497
3498 self._strip_non_python_syntax(
3499 "(x, y=None, z=None)",
3500 "(x, y=None, z=None)",
3501 None,
3502 None)
3503
3504 self._strip_non_python_syntax(
3505 "(x,\n y=None,\n z = None )",
3506 "(x, y=None, z=None)",
3507 None,
3508 None)
3509
3510 self._strip_non_python_syntax(
3511 "",
3512 "",
3513 None,
3514 None)
3515
3516 self._strip_non_python_syntax(
3517 None,
3518 None,
3519 None,
3520 None)
3521
Nick Coghlan9c680b02015-04-13 12:54:54 -04003522class TestSignatureDefinitions(unittest.TestCase):
3523 # This test case provides a home for checking that particular APIs
3524 # have signatures available for introspection
3525
3526 @cpython_only
3527 @unittest.skipIf(MISSING_C_DOCSTRINGS,
3528 "Signature information for builtins requires docstrings")
3529 def test_builtins_have_signatures(self):
3530 # This checks all builtin callables in CPython have signatures
3531 # A few have signatures Signature can't yet handle, so we skip those
3532 # since they will have to wait until PEP 457 adds the required
3533 # introspection support to the inspect module
3534 # Some others also haven't been converted yet for various other
3535 # reasons, so we also skip those for the time being, but design
3536 # the test to fail in order to indicate when it needs to be
3537 # updated.
3538 no_signature = set()
3539 # These need PEP 457 groups
3540 needs_groups = {"range", "slice", "dir", "getattr",
3541 "next", "iter", "vars"}
3542 no_signature |= needs_groups
3543 # These need PEP 457 groups or a signature change to accept None
3544 needs_semantic_update = {"round"}
3545 no_signature |= needs_semantic_update
3546 # These need *args support in Argument Clinic
Barry Warsaw36c1d1f2017-10-05 12:11:18 -04003547 needs_varargs = {"breakpoint", "min", "max", "print",
3548 "__build_class__"}
Nick Coghlan9c680b02015-04-13 12:54:54 -04003549 no_signature |= needs_varargs
3550 # These simply weren't covered in the initial AC conversion
3551 # for builtin callables
3552 not_converted_yet = {"open", "__import__"}
3553 no_signature |= not_converted_yet
3554 # These builtin types are expected to provide introspection info
3555 types_with_signatures = set()
3556 # Check the signatures we expect to be there
3557 ns = vars(builtins)
3558 for name, obj in sorted(ns.items()):
3559 if not callable(obj):
3560 continue
3561 # The builtin types haven't been converted to AC yet
3562 if isinstance(obj, type) and (name not in types_with_signatures):
3563 # Note that this also skips all the exception types
3564 no_signature.add(name)
3565 if (name in no_signature):
3566 # Not yet converted
3567 continue
3568 with self.subTest(builtin=name):
3569 self.assertIsNotNone(inspect.signature(obj))
3570 # Check callables that haven't been converted don't claim a signature
3571 # This ensures this test will start failing as more signatures are
3572 # added, so the affected items can be moved into the scope of the
3573 # regression test above
3574 for name in no_signature:
3575 with self.subTest(builtin=name):
3576 self.assertIsNone(obj.__text_signature__)
3577
Yury Selivanovd82eddc2014-01-29 11:24:39 -05003578
Thomas Kluyverf9169ce2017-05-23 04:27:52 +01003579class NTimesUnwrappable:
3580 def __init__(self, n):
3581 self.n = n
3582 self._next = None
3583
3584 @property
3585 def __wrapped__(self):
3586 if self.n <= 0:
3587 raise Exception("Unwrapped too many times")
3588 if self._next is None:
3589 self._next = NTimesUnwrappable(self.n - 1)
3590 return self._next
3591
Nick Coghlane8c45d62013-07-28 20:00:01 +10003592class TestUnwrap(unittest.TestCase):
3593
3594 def test_unwrap_one(self):
3595 def func(a, b):
3596 return a + b
3597 wrapper = functools.lru_cache(maxsize=20)(func)
3598 self.assertIs(inspect.unwrap(wrapper), func)
3599
3600 def test_unwrap_several(self):
3601 def func(a, b):
3602 return a + b
3603 wrapper = func
3604 for __ in range(10):
3605 @functools.wraps(wrapper)
3606 def wrapper():
3607 pass
3608 self.assertIsNot(wrapper.__wrapped__, func)
3609 self.assertIs(inspect.unwrap(wrapper), func)
3610
3611 def test_stop(self):
3612 def func1(a, b):
3613 return a + b
3614 @functools.wraps(func1)
3615 def func2():
3616 pass
3617 @functools.wraps(func2)
3618 def wrapper():
3619 pass
3620 func2.stop_here = 1
3621 unwrapped = inspect.unwrap(wrapper,
3622 stop=(lambda f: hasattr(f, "stop_here")))
3623 self.assertIs(unwrapped, func2)
3624
3625 def test_cycle(self):
3626 def func1(): pass
3627 func1.__wrapped__ = func1
3628 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3629 inspect.unwrap(func1)
3630
3631 def func2(): pass
3632 func2.__wrapped__ = func1
3633 func1.__wrapped__ = func2
3634 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3635 inspect.unwrap(func1)
3636 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3637 inspect.unwrap(func2)
3638
3639 def test_unhashable(self):
3640 def func(): pass
3641 func.__wrapped__ = None
3642 class C:
3643 __hash__ = None
3644 __wrapped__ = func
3645 self.assertIsNone(inspect.unwrap(C()))
3646
Thomas Kluyverf9169ce2017-05-23 04:27:52 +01003647 def test_recursion_limit(self):
3648 obj = NTimesUnwrappable(sys.getrecursionlimit() + 1)
3649 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3650 inspect.unwrap(obj)
3651
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003652class TestMain(unittest.TestCase):
3653 def test_only_source(self):
3654 module = importlib.import_module('unittest')
3655 rc, out, err = assert_python_ok('-m', 'inspect',
3656 'unittest')
3657 lines = out.decode().splitlines()
3658 # ignore the final newline
3659 self.assertEqual(lines[:-1], inspect.getsource(module).splitlines())
3660 self.assertEqual(err, b'')
3661
Yury Selivanov42407ab2014-06-23 10:23:50 -07003662 def test_custom_getattr(self):
3663 def foo():
3664 pass
3665 foo.__signature__ = 42
3666 with self.assertRaises(TypeError):
3667 inspect.signature(foo)
3668
Brett Cannon634a8fc2013-10-02 10:25:42 -04003669 @unittest.skipIf(ThreadPoolExecutor is None,
Brett Cannon0de3f012013-10-02 10:58:58 -04003670 'threads required to test __qualname__ for source files')
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003671 def test_qualname_source(self):
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003672 rc, out, err = assert_python_ok('-m', 'inspect',
3673 'concurrent.futures:ThreadPoolExecutor')
3674 lines = out.decode().splitlines()
3675 # ignore the final newline
3676 self.assertEqual(lines[:-1],
Brett Cannon634a8fc2013-10-02 10:25:42 -04003677 inspect.getsource(ThreadPoolExecutor).splitlines())
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003678 self.assertEqual(err, b'')
3679
3680 def test_builtins(self):
3681 module = importlib.import_module('unittest')
3682 _, out, err = assert_python_failure('-m', 'inspect',
3683 'sys')
3684 lines = err.decode().splitlines()
3685 self.assertEqual(lines, ["Can't get info for builtin modules."])
3686
3687 def test_details(self):
3688 module = importlib.import_module('unittest')
Victor Stinner9def2842016-01-18 12:15:08 +01003689 args = support.optim_args_from_interpreter_flags()
3690 rc, out, err = assert_python_ok(*args, '-m', 'inspect',
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003691 'unittest', '--details')
3692 output = out.decode()
3693 # Just a quick sanity check on the output
3694 self.assertIn(module.__name__, output)
3695 self.assertIn(module.__file__, output)
Victor Stinner9def2842016-01-18 12:15:08 +01003696 self.assertIn(module.__cached__, output)
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003697 self.assertEqual(err, b'')
3698
3699
Yury Selivanovef1e7502014-12-08 16:05:34 -05003700class TestReload(unittest.TestCase):
3701
3702 src_before = textwrap.dedent("""\
3703def foo():
3704 print("Bla")
3705 """)
3706
3707 src_after = textwrap.dedent("""\
3708def foo():
3709 print("Oh no!")
3710 """)
3711
3712 def assertInspectEqual(self, path, source):
3713 inspected_src = inspect.getsource(source)
3714 with open(path) as src:
3715 self.assertEqual(
3716 src.read().splitlines(True),
3717 inspected_src.splitlines(True)
3718 )
3719
3720 def test_getsource_reload(self):
3721 # see issue 1218234
3722 with _ready_to_import('reload_bug', self.src_before) as (name, path):
3723 module = importlib.import_module(name)
3724 self.assertInspectEqual(path, module)
3725 with open(path, 'w') as src:
3726 src.write(self.src_after)
3727 self.assertInspectEqual(path, module)
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003728
Nick Coghlane8c45d62013-07-28 20:00:01 +10003729
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00003730def test_main():
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00003731 run_unittest(
3732 TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBuggyCases,
3733 TestInterpreterStack, TestClassesAndFunctions, TestPredicates,
3734 TestGetcallargsFunctions, TestGetcallargsMethods,
Alexander Belopolskyf546e702010-12-02 00:10:11 +00003735 TestGetcallargsUnboundMethods, TestGetattrStatic, TestGetGeneratorState,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003736 TestNoEOL, TestSignatureObject, TestSignatureBind, TestParameterObject,
Nick Coghlan9c680b02015-04-13 12:54:54 -04003737 TestBoundArguments, TestSignaturePrivateHelpers,
3738 TestSignatureDefinitions,
Yury Selivanov5376ba92015-06-22 12:19:30 -04003739 TestGetClosureVars, TestUnwrap, TestMain, TestReload,
3740 TestGetCoroutineState
Michael Foord95fc51d2010-11-20 15:07:30 +00003741 )
Martin v. Löwis893ffa42003-10-31 15:35:53 +00003742
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00003743if __name__ == "__main__":
3744 test_main()