blob: 71c4f27d27b982a641480e825b86421ae0669f22 [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
Hai Shic7decc22020-08-04 23:53:12 +080027from test.support import run_unittest, cpython_only
Serhiy Storchaka7d44e7a2019-08-08 08:43:18 +030028from test.support import MISSING_C_DOCSTRINGS, ALWAYS_EQ
Hai Shic7decc22020-08-04 23:53:12 +080029from test.support.import_helper import DirsOnSysPath
30from test.support.os_helper import TESTFN
Berker Peksagce643912015-05-06 06:33:17 +030031from test.support.script_helper import assert_python_ok, assert_python_failure
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000032from test import inspect_fodder as mod
33from test import inspect_fodder2 as mod2
Victor Stinner9def2842016-01-18 12:15:08 +010034from test import support
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000035
Yury Selivanovef1e7502014-12-08 16:05:34 -050036from test.test_import import _ready_to_import
37
R. David Murray74b89242009-05-13 17:33:03 +000038
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000039# Functions tested in this suite:
40# ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode,
Christian Heimes7131fd92008-02-19 14:21:46 +000041# isbuiltin, isroutine, isgenerator, isgeneratorfunction, getmembers,
42# getdoc, getfile, getmodule, getsourcefile, getcomments, getsource,
Berker Peksagfa3922c2015-07-31 04:11:29 +030043# getclasstree, getargvalues, formatargspec, formatargvalues,
Christian Heimes7131fd92008-02-19 14:21:46 +000044# currentframe, stack, trace, isdatadescriptor
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000045
Nick Coghlanf088e5e2008-12-14 11:50:48 +000046# NOTE: There are some additional tests relating to interaction with
47# zipimport in the test_zipimport_support test module.
48
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000049modfile = mod.__file__
Thomas Wouters0e3f5912006-08-11 14:57:12 +000050if modfile.endswith(('c', 'o')):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000051 modfile = modfile[:-1]
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000052
Christian Heimesa3538eb2007-11-06 11:44:48 +000053# Normalize file names: on Windows, the case of file names of compiled
54# modules depends on the path used to start the python executable.
55modfile = normcase(modfile)
56
57def revise(filename, *args):
58 return (normcase(filename),) + args
59
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000060git = mod.StupidGit()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000061
larryhastingsf36ba122018-01-28 11:13:09 -080062
63def signatures_with_lexicographic_keyword_only_parameters():
64 """
65 Yields a whole bunch of functions with only keyword-only parameters,
66 where those parameters are always in lexicographically sorted order.
67 """
68 parameters = ['a', 'bar', 'c', 'delta', 'ephraim', 'magical', 'yoyo', 'z']
69 for i in range(1, 2**len(parameters)):
70 p = []
71 bit = 1
72 for j in range(len(parameters)):
73 if i & (bit << j):
74 p.append(parameters[j])
75 fn_text = "def foo(*, " + ", ".join(p) + "): pass"
76 symbols = {}
77 exec(fn_text, symbols, symbols)
78 yield symbols['foo']
79
80
81def unsorted_keyword_only_parameters_fn(*, throw, out, the, baby, with_,
82 the_, bathwater):
83 pass
84
85unsorted_keyword_only_parameters = 'throw out the baby with_ the_ bathwater'.split()
86
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000087class IsTestBase(unittest.TestCase):
88 predicates = set([inspect.isbuiltin, inspect.isclass, inspect.iscode,
89 inspect.isframe, inspect.isfunction, inspect.ismethod,
Christian Heimes7131fd92008-02-19 14:21:46 +000090 inspect.ismodule, inspect.istraceback,
Yury Selivanov75445082015-05-11 22:57:16 -040091 inspect.isgenerator, inspect.isgeneratorfunction,
Yury Selivanoveb636452016-09-08 22:01:51 -070092 inspect.iscoroutine, inspect.iscoroutinefunction,
93 inspect.isasyncgen, inspect.isasyncgenfunction])
Tim Peters5a9fb3c2005-01-07 16:01:32 +000094
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000095 def istest(self, predicate, exp):
96 obj = eval(exp)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000097 self.assertTrue(predicate(obj), '%s(%s)' % (predicate.__name__, exp))
Tim Peters5a9fb3c2005-01-07 16:01:32 +000098
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000099 for other in self.predicates - set([predicate]):
Yury Selivanov75445082015-05-11 22:57:16 -0400100 if (predicate == inspect.isgeneratorfunction or \
Yury Selivanoveb636452016-09-08 22:01:51 -0700101 predicate == inspect.isasyncgenfunction or \
Yury Selivanov75445082015-05-11 22:57:16 -0400102 predicate == inspect.iscoroutinefunction) and \
Christian Heimes7131fd92008-02-19 14:21:46 +0000103 other == inspect.isfunction:
104 continue
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000105 self.assertFalse(other(obj), 'not %s(%s)' % (other.__name__, exp))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000106
Christian Heimes7131fd92008-02-19 14:21:46 +0000107def generator_function_example(self):
108 for i in range(2):
109 yield i
110
Yury Selivanoveb636452016-09-08 22:01:51 -0700111async def async_generator_function_example(self):
112 async for i in range(2):
113 yield i
114
Yury Selivanov75445082015-05-11 22:57:16 -0400115async def coroutine_function_example(self):
116 return 'spam'
117
118@types.coroutine
119def gen_coroutine_function_example(self):
120 yield
121 return 'spam'
122
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000123class TestPredicates(IsTestBase):
Christian Heimes7131fd92008-02-19 14:21:46 +0000124
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000125 def test_excluding_predicates(self):
Antoine Pitroud5a1a212012-06-17 23:18:07 +0200126 global tb
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000127 self.istest(inspect.isbuiltin, 'sys.exit')
128 self.istest(inspect.isbuiltin, '[].append')
Neal Norwitz221085d2007-02-25 20:55:47 +0000129 self.istest(inspect.iscode, 'mod.spam.__code__')
Antoine Pitroud5a1a212012-06-17 23:18:07 +0200130 try:
131 1/0
132 except:
133 tb = sys.exc_info()[2]
134 self.istest(inspect.isframe, 'tb.tb_frame')
135 self.istest(inspect.istraceback, 'tb')
136 if hasattr(types, 'GetSetDescriptorType'):
137 self.istest(inspect.isgetsetdescriptor,
138 'type(tb.tb_frame).f_locals')
139 else:
140 self.assertFalse(inspect.isgetsetdescriptor(type(tb.tb_frame).f_locals))
141 finally:
142 # Clear traceback and all the frames and local variables hanging to it.
143 tb = None
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000144 self.istest(inspect.isfunction, 'mod.spam')
Christian Heimes4a22b5d2007-11-25 09:39:14 +0000145 self.istest(inspect.isfunction, 'mod.StupidGit.abuse')
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000146 self.istest(inspect.ismethod, 'git.argue')
Jeroen Demeyerfcef60f2019-04-02 16:03:42 +0200147 self.istest(inspect.ismethod, 'mod.custom_method')
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000148 self.istest(inspect.ismodule, 'mod')
Guido van Rossum813b0e52007-05-21 18:11:34 +0000149 self.istest(inspect.isdatadescriptor, 'collections.defaultdict.default_factory')
Christian Heimes7131fd92008-02-19 14:21:46 +0000150 self.istest(inspect.isgenerator, '(x for x in range(2))')
151 self.istest(inspect.isgeneratorfunction, 'generator_function_example')
Yury Selivanoveb636452016-09-08 22:01:51 -0700152 self.istest(inspect.isasyncgen,
153 'async_generator_function_example(1)')
154 self.istest(inspect.isasyncgenfunction,
155 'async_generator_function_example')
Yury Selivanov75445082015-05-11 22:57:16 -0400156
157 with warnings.catch_warnings():
158 warnings.simplefilter("ignore")
159 self.istest(inspect.iscoroutine, 'coroutine_function_example(1)')
160 self.istest(inspect.iscoroutinefunction, 'coroutine_function_example')
161
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000162 if hasattr(types, 'MemberDescriptorType'):
163 self.istest(inspect.ismemberdescriptor, 'datetime.timedelta.days')
164 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000165 self.assertFalse(inspect.ismemberdescriptor(datetime.timedelta.days))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000166
Yury Selivanov75445082015-05-11 22:57:16 -0400167 def test_iscoroutine(self):
Pablo Galindo7cd25432018-10-26 12:19:14 +0100168 async_gen_coro = async_generator_function_example(1)
Yury Selivanov75445082015-05-11 22:57:16 -0400169 gen_coro = gen_coroutine_function_example(1)
170 coro = coroutine_function_example(1)
171
Yury Selivanov5376ba92015-06-22 12:19:30 -0400172 self.assertFalse(
Yury Selivanov75445082015-05-11 22:57:16 -0400173 inspect.iscoroutinefunction(gen_coroutine_function_example))
Pablo Galindo7cd25432018-10-26 12:19:14 +0100174 self.assertFalse(
175 inspect.iscoroutinefunction(
176 functools.partial(functools.partial(
177 gen_coroutine_function_example))))
Yury Selivanov5376ba92015-06-22 12:19:30 -0400178 self.assertFalse(inspect.iscoroutine(gen_coro))
Yury Selivanov75445082015-05-11 22:57:16 -0400179
180 self.assertTrue(
181 inspect.isgeneratorfunction(gen_coroutine_function_example))
Pablo Galindo7cd25432018-10-26 12:19:14 +0100182 self.assertTrue(
183 inspect.isgeneratorfunction(
184 functools.partial(functools.partial(
185 gen_coroutine_function_example))))
Yury Selivanov75445082015-05-11 22:57:16 -0400186 self.assertTrue(inspect.isgenerator(gen_coro))
187
188 self.assertTrue(
189 inspect.iscoroutinefunction(coroutine_function_example))
Pablo Galindo7cd25432018-10-26 12:19:14 +0100190 self.assertTrue(
191 inspect.iscoroutinefunction(
192 functools.partial(functools.partial(
193 coroutine_function_example))))
Yury Selivanov75445082015-05-11 22:57:16 -0400194 self.assertTrue(inspect.iscoroutine(coro))
195
196 self.assertFalse(
197 inspect.isgeneratorfunction(coroutine_function_example))
Pablo Galindo7cd25432018-10-26 12:19:14 +0100198 self.assertFalse(
199 inspect.isgeneratorfunction(
200 functools.partial(functools.partial(
201 coroutine_function_example))))
Yury Selivanov75445082015-05-11 22:57:16 -0400202 self.assertFalse(inspect.isgenerator(coro))
203
Pablo Galindo7cd25432018-10-26 12:19:14 +0100204 self.assertTrue(
205 inspect.isasyncgenfunction(async_generator_function_example))
206 self.assertTrue(
207 inspect.isasyncgenfunction(
208 functools.partial(functools.partial(
209 async_generator_function_example))))
210 self.assertTrue(inspect.isasyncgen(async_gen_coro))
211
212 coro.close(); gen_coro.close(); # silence warnings
Yury Selivanov75445082015-05-11 22:57:16 -0400213
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -0400214 def test_isawaitable(self):
215 def gen(): yield
216 self.assertFalse(inspect.isawaitable(gen()))
217
218 coro = coroutine_function_example(1)
219 gen_coro = gen_coroutine_function_example(1)
220
221 self.assertTrue(inspect.isawaitable(coro))
222 self.assertTrue(inspect.isawaitable(gen_coro))
223
224 class Future:
225 def __await__():
226 pass
227 self.assertTrue(inspect.isawaitable(Future()))
228 self.assertFalse(inspect.isawaitable(Future))
229
230 class NotFuture: pass
231 not_fut = NotFuture()
232 not_fut.__await__ = lambda: None
233 self.assertFalse(inspect.isawaitable(not_fut))
234
235 coro.close(); gen_coro.close() # silence warnings
236
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000237 def test_isroutine(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000238 self.assertTrue(inspect.isroutine(mod.spam))
239 self.assertTrue(inspect.isroutine([].count))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000240
Benjamin Petersonc4656002009-01-17 22:41:18 +0000241 def test_isclass(self):
242 self.istest(inspect.isclass, 'mod.StupidGit')
243 self.assertTrue(inspect.isclass(list))
244
245 class CustomGetattr(object):
246 def __getattr__(self, attr):
247 return None
248 self.assertFalse(inspect.isclass(CustomGetattr()))
249
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000250 def test_get_slot_members(self):
251 class C(object):
252 __slots__ = ("a", "b")
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000253 x = C()
254 x.a = 42
255 members = dict(inspect.getmembers(x))
Benjamin Peterson577473f2010-01-19 00:09:57 +0000256 self.assertIn('a', members)
257 self.assertNotIn('b', members)
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000258
Benjamin Petersona0dfa822009-11-13 02:25:08 +0000259 def test_isabstract(self):
260 from abc import ABCMeta, abstractmethod
261
262 class AbstractClassExample(metaclass=ABCMeta):
263
264 @abstractmethod
265 def foo(self):
266 pass
267
268 class ClassExample(AbstractClassExample):
269 def foo(self):
270 pass
271
272 a = ClassExample()
273
274 # Test general behaviour.
275 self.assertTrue(inspect.isabstract(AbstractClassExample))
276 self.assertFalse(inspect.isabstract(ClassExample))
277 self.assertFalse(inspect.isabstract(a))
278 self.assertFalse(inspect.isabstract(int))
279 self.assertFalse(inspect.isabstract(5))
280
Natefcfe80e2017-04-24 10:06:15 -0700281 def test_isabstract_during_init_subclass(self):
282 from abc import ABCMeta, abstractmethod
283 isabstract_checks = []
284 class AbstractChecker(metaclass=ABCMeta):
285 def __init_subclass__(cls):
286 isabstract_checks.append(inspect.isabstract(cls))
287 class AbstractClassExample(AbstractChecker):
288 @abstractmethod
289 def foo(self):
290 pass
291 class ClassExample(AbstractClassExample):
292 def foo(self):
293 pass
294 self.assertEqual(isabstract_checks, [True, False])
295
296 isabstract_checks.clear()
297 class AbstractChild(AbstractClassExample):
298 pass
299 class AbstractGrandchild(AbstractChild):
300 pass
301 class ConcreteGrandchild(ClassExample):
302 pass
303 self.assertEqual(isabstract_checks, [True, True, False])
304
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000305
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000306class TestInterpreterStack(IsTestBase):
307 def __init__(self, *args, **kwargs):
308 unittest.TestCase.__init__(self, *args, **kwargs)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000309
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000310 git.abuse(7, 8, 9)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000311
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000312 def test_abuse_done(self):
313 self.istest(inspect.istraceback, 'git.ex[2]')
314 self.istest(inspect.isframe, 'mod.fr')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000315
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000316 def test_stack(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000317 self.assertTrue(len(mod.st) >= 5)
Christian Heimesa3538eb2007-11-06 11:44:48 +0000318 self.assertEqual(revise(*mod.st[0][1:]),
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000319 (modfile, 16, 'eggs', [' st = inspect.stack()\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000320 self.assertEqual(revise(*mod.st[1][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000321 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000322 self.assertEqual(revise(*mod.st[2][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000323 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000324 self.assertEqual(revise(*mod.st[3][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000325 (modfile, 39, 'abuse', [' self.argue(a, b, c)\n'], 0))
Antoine Pitroucdcafb72014-08-24 10:50:28 -0400326 # Test named tuple fields
327 record = mod.st[0]
328 self.assertIs(record.frame, mod.fr)
329 self.assertEqual(record.lineno, 16)
330 self.assertEqual(record.filename, mod.__file__)
331 self.assertEqual(record.function, 'eggs')
332 self.assertIn('inspect.stack()', record.code_context[0])
333 self.assertEqual(record.index, 0)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000334
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000335 def test_trace(self):
336 self.assertEqual(len(git.tr), 3)
Florent Xiclunac8575922010-03-24 17:37:49 +0000337 self.assertEqual(revise(*git.tr[0][1:]),
338 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
339 self.assertEqual(revise(*git.tr[1][1:]),
340 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
341 self.assertEqual(revise(*git.tr[2][1:]),
342 (modfile, 18, 'eggs', [' q = y / 0\n'], 0))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000343
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000344 def test_frame(self):
345 args, varargs, varkw, locals = inspect.getargvalues(mod.fr)
346 self.assertEqual(args, ['x', 'y'])
347 self.assertEqual(varargs, None)
348 self.assertEqual(varkw, None)
349 self.assertEqual(locals, {'x': 11, 'p': 11, 'y': 14})
350 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
351 '(x=11, y=14)')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000352
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000353 def test_previous_frame(self):
354 args, varargs, varkw, locals = inspect.getargvalues(mod.fr.f_back)
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000355 self.assertEqual(args, ['a', 'b', 'c', 'd', 'e', 'f'])
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000356 self.assertEqual(varargs, 'g')
357 self.assertEqual(varkw, 'h')
358 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000359 '(a=7, b=8, c=9, d=3, e=4, f=5, *g=(), **h={})')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000360
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000361class GetSourceBase(unittest.TestCase):
362 # Subclasses must override.
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000363 fodderModule = None
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000364
Yury Selivanov6738b112015-05-16 10:10:21 -0400365 def setUp(self):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000366 with open(inspect.getsourcefile(self.fodderModule)) as fp:
Philip Jenveya27c5bd2009-05-28 06:09:08 +0000367 self.source = fp.read()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000368
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000369 def sourcerange(self, top, bottom):
370 lines = self.source.split("\n")
Vladimir Matveev91cb2982018-08-24 07:18:00 -0700371 return "\n".join(lines[top-1:bottom]) + ("\n" if bottom else "")
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000372
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000373 def assertSourceEqual(self, obj, top, bottom):
374 self.assertEqual(inspect.getsource(obj),
375 self.sourcerange(top, bottom))
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000376
Raymond Hettingerd1e768a2019-03-25 13:01:13 -0700377class SlotUser:
378 'Docstrings for __slots__'
379 __slots__ = {'power': 'measured in kilowatts',
380 'distance': 'measured in kilometers'}
381
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000382class TestRetrievingSourceCode(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000383 fodderModule = mod
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000384
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000385 def test_getclasses(self):
386 classes = inspect.getmembers(mod, inspect.isclass)
387 self.assertEqual(classes,
388 [('FesteringGob', mod.FesteringGob),
389 ('MalodorousPervert', mod.MalodorousPervert),
390 ('ParrotDroppings', mod.ParrotDroppings),
Serhiy Storchaka362c1b52013-09-05 17:14:32 +0300391 ('StupidGit', mod.StupidGit),
392 ('Tit', mod.MalodorousPervert),
393 ])
394 tree = inspect.getclasstree([cls[1] for cls in classes])
395 self.assertEqual(tree,
396 [(object, ()),
397 [(mod.ParrotDroppings, (object,)),
398 [(mod.FesteringGob, (mod.MalodorousPervert,
399 mod.ParrotDroppings))
400 ],
401 (mod.StupidGit, (object,)),
402 [(mod.MalodorousPervert, (mod.StupidGit,)),
403 [(mod.FesteringGob, (mod.MalodorousPervert,
404 mod.ParrotDroppings))
405 ]
406 ]
407 ]
408 ])
409 tree = inspect.getclasstree([cls[1] for cls in classes], True)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000410 self.assertEqual(tree,
Thomas Wouters725af872006-04-15 09:13:19 +0000411 [(object, ()),
412 [(mod.ParrotDroppings, (object,)),
413 (mod.StupidGit, (object,)),
414 [(mod.MalodorousPervert, (mod.StupidGit,)),
415 [(mod.FesteringGob, (mod.MalodorousPervert,
416 mod.ParrotDroppings))
417 ]
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000418 ]
419 ]
420 ])
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000421
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000422 def test_getfunctions(self):
423 functions = inspect.getmembers(mod, inspect.isfunction)
424 self.assertEqual(functions, [('eggs', mod.eggs),
Yury Selivanove4e811d2015-07-21 19:01:52 +0300425 ('lobbest', mod.lobbest),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000426 ('spam', mod.spam)])
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000427
R. David Murray378c0cf2010-02-24 01:46:21 +0000428 @unittest.skipIf(sys.flags.optimize >= 2,
429 "Docstrings are omitted with -O2 and above")
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000430 def test_getdoc(self):
431 self.assertEqual(inspect.getdoc(mod), 'A module docstring.')
432 self.assertEqual(inspect.getdoc(mod.StupidGit),
433 'A longer,\n\nindented\n\ndocstring.')
434 self.assertEqual(inspect.getdoc(git.abuse),
435 'Another\n\ndocstring\n\ncontaining\n\ntabs')
Raymond Hettingerd1e768a2019-03-25 13:01:13 -0700436 self.assertEqual(inspect.getdoc(SlotUser.power),
437 'measured in kilowatts')
438 self.assertEqual(inspect.getdoc(SlotUser.distance),
439 'measured in kilometers')
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000440
Serhiy Storchaka5cf2b722015-04-03 22:38:53 +0300441 @unittest.skipIf(sys.flags.optimize >= 2,
442 "Docstrings are omitted with -O2 and above")
443 def test_getdoc_inherited(self):
Serhiy Storchaka08b47c32020-05-18 20:25:07 +0300444 self.assertEqual(inspect.getdoc(mod.FesteringGob),
445 'A longer,\n\nindented\n\ndocstring.')
Serhiy Storchaka5cf2b722015-04-03 22:38:53 +0300446 self.assertEqual(inspect.getdoc(mod.FesteringGob.abuse),
447 'Another\n\ndocstring\n\ncontaining\n\ntabs')
448 self.assertEqual(inspect.getdoc(mod.FesteringGob().abuse),
449 'Another\n\ndocstring\n\ncontaining\n\ntabs')
450 self.assertEqual(inspect.getdoc(mod.FesteringGob.contradiction),
451 'The automatic gainsaying.')
452
453 @unittest.skipIf(MISSING_C_DOCSTRINGS, "test requires docstrings")
454 def test_finddoc(self):
455 finddoc = inspect._finddoc
Serhiy Storchaka08b47c32020-05-18 20:25:07 +0300456 self.assertEqual(finddoc(int), int.__doc__)
Serhiy Storchaka5cf2b722015-04-03 22:38:53 +0300457 self.assertEqual(finddoc(int.to_bytes), int.to_bytes.__doc__)
458 self.assertEqual(finddoc(int().to_bytes), int.to_bytes.__doc__)
459 self.assertEqual(finddoc(int.from_bytes), int.from_bytes.__doc__)
460 self.assertEqual(finddoc(int.real), int.real.__doc__)
461
Georg Brandl0c77a822008-06-10 16:37:50 +0000462 def test_cleandoc(self):
463 self.assertEqual(inspect.cleandoc('An\n indented\n docstring.'),
464 'An\nindented\ndocstring.')
465
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000466 def test_getcomments(self):
467 self.assertEqual(inspect.getcomments(mod), '# line 1\n')
468 self.assertEqual(inspect.getcomments(mod.StupidGit), '# line 20\n')
Karthikeyan Singaravelan696136b2020-04-18 21:49:32 +0530469 self.assertEqual(inspect.getcomments(mod2.cls160), '# line 159\n')
Marco Buttu3f2155f2017-03-17 09:50:23 +0100470 # If the object source file is not available, return None.
471 co = compile('x=1', '_non_existing_filename.py', 'exec')
472 self.assertIsNone(inspect.getcomments(co))
473 # If the object has been defined in C, return None.
474 self.assertIsNone(inspect.getcomments(list))
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000475
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000476 def test_getmodule(self):
Thomas Wouters89f507f2006-12-13 04:49:30 +0000477 # Check actual module
478 self.assertEqual(inspect.getmodule(mod), mod)
479 # Check class (uses __module__ attribute)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000480 self.assertEqual(inspect.getmodule(mod.StupidGit), mod)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000481 # Check a method (no __module__ attribute, falls back to filename)
482 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
483 # Do it again (check the caching isn't broken)
484 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
485 # Check a builtin
Georg Brandl1a3284e2007-12-02 09:40:06 +0000486 self.assertEqual(inspect.getmodule(str), sys.modules["builtins"])
Thomas Wouters89f507f2006-12-13 04:49:30 +0000487 # Check filename override
488 self.assertEqual(inspect.getmodule(None, modfile), mod)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000489
Berker Peksagff0e3b72017-01-02 06:57:43 +0300490 def test_getframeinfo_get_first_line(self):
491 frame_info = inspect.getframeinfo(self.fodderModule.fr, 50)
492 self.assertEqual(frame_info.code_context[0], "# line 1\n")
493 self.assertEqual(frame_info.code_context[1], "'A module docstring.'\n")
494
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000495 def test_getsource(self):
496 self.assertSourceEqual(git.abuse, 29, 39)
Serhiy Storchakaac4bdcc2015-10-29 08:15:50 +0200497 self.assertSourceEqual(mod.StupidGit, 21, 51)
498 self.assertSourceEqual(mod.lobbest, 75, 76)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000499
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000500 def test_getsourcefile(self):
Christian Heimesa3538eb2007-11-06 11:44:48 +0000501 self.assertEqual(normcase(inspect.getsourcefile(mod.spam)), modfile)
502 self.assertEqual(normcase(inspect.getsourcefile(git.abuse)), modfile)
R. David Murraya1b37402010-06-17 02:04:29 +0000503 fn = "_non_existing_filename_used_for_sourcefile_test.py"
Victor Stinner51d8c522016-02-08 17:57:02 +0100504 co = compile("x=1", fn, "exec")
R. David Murray4155f972010-06-17 13:23:18 +0000505 self.assertEqual(inspect.getsourcefile(co), None)
R. David Murraya1b37402010-06-17 02:04:29 +0000506 linecache.cache[co.co_filename] = (1, None, "None", co.co_filename)
Antoine Pitrou5d62a612012-07-08 13:48:46 +0200507 try:
508 self.assertEqual(normcase(inspect.getsourcefile(co)), fn)
509 finally:
510 del linecache.cache[co.co_filename]
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000511
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000512 def test_getfile(self):
513 self.assertEqual(inspect.getfile(mod.StupidGit), mod.__file__)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000514
Philipp Ad407d2a2019-06-08 14:05:46 +0200515 def test_getfile_builtin_module(self):
516 with self.assertRaises(TypeError) as e:
517 inspect.getfile(sys)
518 self.assertTrue(str(e.exception).startswith('<module'))
519
520 def test_getfile_builtin_class(self):
521 with self.assertRaises(TypeError) as e:
522 inspect.getfile(int)
523 self.assertTrue(str(e.exception).startswith('<class'))
524
525 def test_getfile_builtin_function_or_method(self):
526 with self.assertRaises(TypeError) as e_abs:
527 inspect.getfile(abs)
528 self.assertIn('expected, got', str(e_abs.exception))
529 with self.assertRaises(TypeError) as e_append:
530 inspect.getfile(list.append)
531 self.assertIn('expected, got', str(e_append.exception))
532
Yury Selivanov2eed8b72014-01-27 13:24:56 -0500533 def test_getfile_class_without_module(self):
534 class CM(type):
535 @property
536 def __module__(cls):
537 raise AttributeError
538 class C(metaclass=CM):
539 pass
540 with self.assertRaises(TypeError):
541 inspect.getfile(C)
542
Thomas Kluyvere968bc732017-10-24 13:42:36 +0100543 def test_getfile_broken_repr(self):
544 class ErrorRepr:
545 def __repr__(self):
546 raise Exception('xyz')
547 er = ErrorRepr()
548 with self.assertRaises(TypeError):
549 inspect.getfile(er)
550
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000551 def test_getmodule_recursion(self):
Christian Heimes45f9af32007-11-27 21:50:00 +0000552 from types import ModuleType
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000553 name = '__inspect_dummy'
Christian Heimes45f9af32007-11-27 21:50:00 +0000554 m = sys.modules[name] = ModuleType(name)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000555 m.__file__ = "<string>" # hopefully not a real filename...
556 m.__loader__ = "dummy" # pretend the filename is understood by a loader
Georg Brandl7cae87c2006-09-06 06:51:57 +0000557 exec("def x(): pass", m.__dict__)
Neal Norwitz221085d2007-02-25 20:55:47 +0000558 self.assertEqual(inspect.getsourcefile(m.x.__code__), '<string>')
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000559 del sys.modules[name]
560 inspect.getmodule(compile('a=10','','single'))
561
Benjamin Peterson9620cc02011-06-11 15:53:11 -0500562 def test_proceed_with_fake_filename(self):
563 '''doctest monkeypatches linecache to enable inspection'''
564 fn, source = '<test>', 'def x(): pass\n'
565 getlines = linecache.getlines
566 def monkey(filename, module_globals=None):
567 if filename == fn:
Ezio Melottid8b509b2011-09-28 17:37:55 +0300568 return source.splitlines(keepends=True)
Benjamin Peterson9620cc02011-06-11 15:53:11 -0500569 else:
570 return getlines(filename, module_globals)
571 linecache.getlines = monkey
572 try:
573 ns = {}
574 exec(compile(source, fn, 'single'), ns)
575 inspect.getsource(ns["x"])
576 finally:
577 linecache.getlines = getlines
578
Antoine Pitroua8723a02015-04-15 00:41:29 +0200579 def test_getsource_on_code_object(self):
580 self.assertSourceEqual(mod.eggs.__code__, 12, 18)
581
Vladimir Matveev91cb2982018-08-24 07:18:00 -0700582class TestGettingSourceOfToplevelFrames(GetSourceBase):
583 fodderModule = mod
584
585 def test_range_toplevel_frame(self):
586 self.maxDiff = None
587 self.assertSourceEqual(mod.currentframe, 1, None)
588
589 def test_range_traceback_toplevel_frame(self):
590 self.assertSourceEqual(mod.tb, 1, None)
591
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000592class TestDecorators(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000593 fodderModule = mod2
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000594
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000595 def test_wrapped_decorator(self):
Christian Heimes09aaa882008-02-23 15:01:06 +0000596 self.assertSourceEqual(mod2.wrapped, 14, 17)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000597
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000598 def test_replacing_decorator(self):
599 self.assertSourceEqual(mod2.gone, 9, 10)
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000600
Yury Selivanov081bbf62014-09-26 17:34:54 -0400601 def test_getsource_unwrap(self):
Antoine Pitroua8723a02015-04-15 00:41:29 +0200602 self.assertSourceEqual(mod2.real, 130, 132)
603
604 def test_decorator_with_lambda(self):
605 self.assertSourceEqual(mod2.func114, 113, 115)
Yury Selivanov081bbf62014-09-26 17:34:54 -0400606
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000607class TestOneliners(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000608 fodderModule = mod2
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000609 def test_oneline_lambda(self):
610 # Test inspect.getsource with a one-line lambda function.
611 self.assertSourceEqual(mod2.oll, 25, 25)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000612
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000613 def test_threeline_lambda(self):
614 # Test inspect.getsource with a three-line lambda function,
615 # where the second and third lines are _not_ indented.
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000616 self.assertSourceEqual(mod2.tll, 28, 30)
617
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000618 def test_twoline_indented_lambda(self):
619 # Test inspect.getsource with a two-line lambda function,
620 # where the second line _is_ indented.
621 self.assertSourceEqual(mod2.tlli, 33, 34)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000622
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000623 def test_onelinefunc(self):
624 # Test inspect.getsource with a regular one-line function.
625 self.assertSourceEqual(mod2.onelinefunc, 37, 37)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000626
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000627 def test_manyargs(self):
628 # Test inspect.getsource with a regular function where
629 # the arguments are on two lines and _not_ indented and
630 # the body on the second line with the last arguments.
631 self.assertSourceEqual(mod2.manyargs, 40, 41)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000632
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000633 def test_twolinefunc(self):
634 # Test inspect.getsource with a regular function where
635 # the body is on two lines, following the argument list and
636 # continued on the next line by a \\.
637 self.assertSourceEqual(mod2.twolinefunc, 44, 45)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000638
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000639 def test_lambda_in_list(self):
640 # Test inspect.getsource with a one-line lambda function
641 # defined in a list, indented.
642 self.assertSourceEqual(mod2.a[1], 49, 49)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000643
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000644 def test_anonymous(self):
645 # Test inspect.getsource with a lambda function defined
646 # as argument to another function.
647 self.assertSourceEqual(mod2.anonymous, 55, 55)
648
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000649class TestBuggyCases(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000650 fodderModule = mod2
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000651
652 def test_with_comment(self):
653 self.assertSourceEqual(mod2.with_comment, 58, 59)
654
655 def test_multiline_sig(self):
656 self.assertSourceEqual(mod2.multiline_sig[0], 63, 64)
657
Armin Rigodd5c0232005-09-25 11:45:45 +0000658 def test_nested_class(self):
659 self.assertSourceEqual(mod2.func69().func71, 71, 72)
660
661 def test_one_liner_followed_by_non_name(self):
662 self.assertSourceEqual(mod2.func77, 77, 77)
663
664 def test_one_liner_dedent_non_name(self):
665 self.assertSourceEqual(mod2.cls82.func83, 83, 83)
666
667 def test_with_comment_instead_of_docstring(self):
668 self.assertSourceEqual(mod2.func88, 88, 90)
669
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000670 def test_method_in_dynamic_class(self):
671 self.assertSourceEqual(mod2.method_in_dynamic_class, 95, 97)
672
R David Murray32562d72014-10-03 11:15:38 -0400673 # This should not skip for CPython, but might on a repackaged python where
674 # unicodedata is not an external module, or on pypy.
675 @unittest.skipIf(not hasattr(unicodedata, '__file__') or
676 unicodedata.__file__.endswith('.py'),
677 "unicodedata is not an external binary module")
R. David Murray74b89242009-05-13 17:33:03 +0000678 def test_findsource_binary(self):
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200679 self.assertRaises(OSError, inspect.getsource, unicodedata)
680 self.assertRaises(OSError, inspect.findsource, unicodedata)
R. David Murray74b89242009-05-13 17:33:03 +0000681
R. David Murraya1b37402010-06-17 02:04:29 +0000682 def test_findsource_code_in_linecache(self):
683 lines = ["x=1"]
684 co = compile(lines[0], "_dynamically_created_file", "exec")
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200685 self.assertRaises(OSError, inspect.findsource, co)
686 self.assertRaises(OSError, inspect.getsource, co)
R. David Murraya1b37402010-06-17 02:04:29 +0000687 linecache.cache[co.co_filename] = (1, None, lines, co.co_filename)
Antoine Pitrou5d62a612012-07-08 13:48:46 +0200688 try:
689 self.assertEqual(inspect.findsource(co), (lines,0))
690 self.assertEqual(inspect.getsource(co), lines[0])
691 finally:
692 del linecache.cache[co.co_filename]
R. David Murraya1b37402010-06-17 02:04:29 +0000693
Ezio Melotti1b145922013-03-30 05:17:24 +0200694 def test_findsource_without_filename(self):
695 for fname in ['', '<string>']:
696 co = compile('x=1', fname, "exec")
697 self.assertRaises(IOError, inspect.findsource, co)
698 self.assertRaises(IOError, inspect.getsource, co)
699
Antoine Pitroua8723a02015-04-15 00:41:29 +0200700 def test_getsource_on_method(self):
701 self.assertSourceEqual(mod2.ClassWithMethod.method, 118, 119)
702
Yury Selivanov4f4913b2015-07-23 17:10:00 +0300703 def test_nested_func(self):
704 self.assertSourceEqual(mod2.cls135.func136, 136, 139)
705
Karthikeyan Singaravelan696136b2020-04-18 21:49:32 +0530706 def test_class_definition_in_multiline_string_definition(self):
707 self.assertSourceEqual(mod2.cls149, 149, 152)
708
709 def test_class_definition_in_multiline_comment(self):
710 self.assertSourceEqual(mod2.cls160, 160, 163)
711
712 def test_nested_class_definition_indented_string(self):
713 self.assertSourceEqual(mod2.cls173.cls175, 175, 176)
714
715 def test_nested_class_definition(self):
716 self.assertSourceEqual(mod2.cls183, 183, 188)
717 self.assertSourceEqual(mod2.cls183.cls185, 185, 188)
718
719 def test_class_decorator(self):
720 self.assertSourceEqual(mod2.cls196, 194, 201)
721 self.assertSourceEqual(mod2.cls196.cls200, 198, 201)
722
723 def test_class_inside_conditional(self):
724 self.assertSourceEqual(mod2.cls238, 238, 240)
725 self.assertSourceEqual(mod2.cls238.cls239, 239, 240)
726
727 def test_multiple_children_classes(self):
728 self.assertSourceEqual(mod2.cls203, 203, 209)
729 self.assertSourceEqual(mod2.cls203.cls204, 204, 206)
730 self.assertSourceEqual(mod2.cls203.cls204.cls205, 205, 206)
731 self.assertSourceEqual(mod2.cls203.cls207, 207, 209)
732 self.assertSourceEqual(mod2.cls203.cls207.cls205, 208, 209)
733
734 def test_nested_class_definition_inside_function(self):
735 self.assertSourceEqual(mod2.func212(), 213, 214)
736 self.assertSourceEqual(mod2.cls213, 218, 222)
737 self.assertSourceEqual(mod2.cls213().func219(), 220, 221)
738
739 def test_nested_class_definition_inside_async_function(self):
740 import asyncio
741 self.addCleanup(asyncio.set_event_loop_policy, None)
742 self.assertSourceEqual(asyncio.run(mod2.func225()), 226, 227)
743 self.assertSourceEqual(mod2.cls226, 231, 235)
744 self.assertSourceEqual(asyncio.run(mod2.cls226().func232()), 233, 234)
Yury Selivanov4f4913b2015-07-23 17:10:00 +0300745
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000746class TestNoEOL(GetSourceBase):
Yury Selivanov6738b112015-05-16 10:10:21 -0400747 def setUp(self):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000748 self.tempdir = TESTFN + '_dir'
749 os.mkdir(self.tempdir)
750 with open(os.path.join(self.tempdir,
751 'inspect_fodder3%spy' % os.extsep), 'w') as f:
752 f.write("class X:\n pass # No EOL")
753 with DirsOnSysPath(self.tempdir):
754 import inspect_fodder3 as mod3
755 self.fodderModule = mod3
Yury Selivanov6738b112015-05-16 10:10:21 -0400756 super().setUp()
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000757
758 def tearDown(self):
759 shutil.rmtree(self.tempdir)
760
761 def test_class(self):
762 self.assertSourceEqual(self.fodderModule.X, 1, 2)
763
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100764
765class _BrokenDataDescriptor(object):
766 """
767 A broken data descriptor. See bug #1785.
768 """
769 def __get__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700770 raise AttributeError("broken data descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100771
772 def __set__(*args):
773 raise RuntimeError
774
775 def __getattr__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700776 raise AttributeError("broken data descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100777
778
779class _BrokenMethodDescriptor(object):
780 """
781 A broken method descriptor. See bug #1785.
782 """
783 def __get__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700784 raise AttributeError("broken method descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100785
786 def __getattr__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700787 raise AttributeError("broken method descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100788
789
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000790# Helper for testing classify_class_attrs.
Tim Peters13b49d32001-09-23 02:00:29 +0000791def attrs_wo_objs(cls):
792 return [t[:3] for t in inspect.classify_class_attrs(cls)]
793
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100794
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000795class TestClassesAndFunctions(unittest.TestCase):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000796 def test_newstyle_mro(self):
797 # The same w/ new-class MRO.
798 class A(object): pass
799 class B(A): pass
800 class C(A): pass
801 class D(B, C): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000802
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000803 expected = (D, B, C, A, object)
804 got = inspect.getmro(D)
805 self.assertEqual(expected, got)
Tim Peters13b49d32001-09-23 02:00:29 +0000806
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500807 def assertArgSpecEquals(self, routine, args_e, varargs_e=None,
808 varkw_e=None, defaults_e=None, formatted=None):
Xtreak6d0b7472019-05-30 17:31:39 +0530809 with self.assertWarns(DeprecationWarning):
810 args, varargs, varkw, defaults = inspect.getargspec(routine)
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500811 self.assertEqual(args, args_e)
812 self.assertEqual(varargs, varargs_e)
813 self.assertEqual(varkw, varkw_e)
814 self.assertEqual(defaults, defaults_e)
815 if formatted is not None:
Xtreak6d0b7472019-05-30 17:31:39 +0530816 with self.assertWarns(DeprecationWarning):
817 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults),
818 formatted)
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500819
Christian Heimes3795b532007-11-08 13:48:53 +0000820 def assertFullArgSpecEquals(self, routine, args_e, varargs_e=None,
821 varkw_e=None, defaults_e=None,
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100822 posonlyargs_e=[], kwonlyargs_e=[],
823 kwonlydefaults_e=None,
Christian Heimes3795b532007-11-08 13:48:53 +0000824 ann_e={}, formatted=None):
Pablo Galindoaee19f52019-05-16 21:08:15 +0100825 args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \
826 inspect.getfullargspec(routine)
Christian Heimes3795b532007-11-08 13:48:53 +0000827 self.assertEqual(args, args_e)
828 self.assertEqual(varargs, varargs_e)
829 self.assertEqual(varkw, varkw_e)
830 self.assertEqual(defaults, defaults_e)
831 self.assertEqual(kwonlyargs, kwonlyargs_e)
832 self.assertEqual(kwonlydefaults, kwonlydefaults_e)
833 self.assertEqual(ann, ann_e)
834 if formatted is not None:
Xtreak6d0b7472019-05-30 17:31:39 +0530835 with self.assertWarns(DeprecationWarning):
836 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults,
837 kwonlyargs, kwonlydefaults, ann),
838 formatted)
Christian Heimes3795b532007-11-08 13:48:53 +0000839
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500840 def test_getargspec(self):
841 self.assertArgSpecEquals(mod.eggs, ['x', 'y'], formatted='(x, y)')
842
Pablo Galindod5d2b452019-04-30 02:01:14 +0100843 self.assertArgSpecEquals(mod.spam,
844 ['a', 'b', 'c', 'd', 'e', 'f'],
845 'g', 'h', (3, 4, 5),
846 '(a, b, c, d=3, e=4, f=5, *g, **h)')
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500847
848 self.assertRaises(ValueError, self.assertArgSpecEquals,
849 mod2.keyworded, [])
850
851 self.assertRaises(ValueError, self.assertArgSpecEquals,
852 mod2.annotated, [])
853 self.assertRaises(ValueError, self.assertArgSpecEquals,
854 mod2.keyword_only_arg, [])
855
856
Christian Heimes3795b532007-11-08 13:48:53 +0000857 def test_getfullargspec(self):
858 self.assertFullArgSpecEquals(mod2.keyworded, [], varargs_e='arg1',
859 kwonlyargs_e=['arg2'],
860 kwonlydefaults_e={'arg2':1},
861 formatted='(*arg1, arg2=1)')
862
863 self.assertFullArgSpecEquals(mod2.annotated, ['arg1'],
Christian Heimesc9543e42007-11-28 08:28:28 +0000864 ann_e={'arg1' : list},
Batuhan Taskaya044a1042020-10-06 23:03:02 +0300865 formatted="(arg1: list)")
Benjamin Peterson9953a8d2009-01-17 04:15:01 +0000866 self.assertFullArgSpecEquals(mod2.keyword_only_arg, [],
867 kwonlyargs_e=['arg'],
868 formatted='(*, arg)')
869
Pablo Galindod5d2b452019-04-30 02:01:14 +0100870 self.assertFullArgSpecEquals(mod2.all_markers, ['a', 'b', 'c', 'd'],
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100871 kwonlyargs_e=['e', 'f'],
Pablo Galindod5d2b452019-04-30 02:01:14 +0100872 formatted='(a, b, c, d, *, e, f)')
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100873
874 self.assertFullArgSpecEquals(mod2.all_markers_with_args_and_kwargs,
Pablo Galindod5d2b452019-04-30 02:01:14 +0100875 ['a', 'b', 'c', 'd'],
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100876 varargs_e='args',
877 varkw_e='kwargs',
878 kwonlyargs_e=['e', 'f'],
Pablo Galindod5d2b452019-04-30 02:01:14 +0100879 formatted='(a, b, c, d, *args, e, f, **kwargs)')
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100880
Pablo Galindod5d2b452019-04-30 02:01:14 +0100881 self.assertFullArgSpecEquals(mod2.all_markers_with_defaults, ['a', 'b', 'c', 'd'],
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100882 defaults_e=(1,2,3),
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100883 kwonlyargs_e=['e', 'f'],
884 kwonlydefaults_e={'e': 4, 'f': 5},
Pablo Galindod5d2b452019-04-30 02:01:14 +0100885 formatted='(a, b=1, c=2, d=3, *, e=4, f=5)')
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100886
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500887 def test_argspec_api_ignores_wrapped(self):
Yury Selivanov57d240e2014-02-19 16:27:23 -0500888 # Issue 20684: low level introspection API must ignore __wrapped__
889 @functools.wraps(mod.spam)
890 def ham(x, y):
891 pass
892 # Basic check
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500893 self.assertArgSpecEquals(ham, ['x', 'y'], formatted='(x, y)')
Yury Selivanov57d240e2014-02-19 16:27:23 -0500894 self.assertFullArgSpecEquals(ham, ['x', 'y'], formatted='(x, y)')
895 self.assertFullArgSpecEquals(functools.partial(ham),
896 ['x', 'y'], formatted='(x, y)')
897 # Other variants
898 def check_method(f):
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500899 self.assertArgSpecEquals(f, ['self', 'x', 'y'],
900 formatted='(self, x, y)')
Yury Selivanov57d240e2014-02-19 16:27:23 -0500901 class C:
902 @functools.wraps(mod.spam)
903 def ham(self, x, y):
904 pass
905 pham = functools.partialmethod(ham)
906 @functools.wraps(mod.spam)
907 def __call__(self, x, y):
908 pass
909 check_method(C())
910 check_method(C.ham)
911 check_method(C().ham)
912 check_method(C.pham)
913 check_method(C().pham)
914
915 class C_new:
916 @functools.wraps(mod.spam)
917 def __new__(self, x, y):
918 pass
919 check_method(C_new)
920
921 class C_init:
922 @functools.wraps(mod.spam)
923 def __init__(self, x, y):
924 pass
925 check_method(C_init)
926
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500927 def test_getfullargspec_signature_attr(self):
928 def test():
929 pass
930 spam_param = inspect.Parameter('spam', inspect.Parameter.POSITIONAL_ONLY)
931 test.__signature__ = inspect.Signature(parameters=(spam_param,))
932
Pablo Galindod5d2b452019-04-30 02:01:14 +0100933 self.assertFullArgSpecEquals(test, ['spam'], formatted='(spam)')
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500934
Yury Selivanov4cb93912014-01-29 11:54:12 -0500935 def test_getfullargspec_signature_annos(self):
936 def test(a:'spam') -> 'ham': pass
Pablo Galindoaee19f52019-05-16 21:08:15 +0100937 spec = inspect.getfullargspec(test)
Yury Selivanov4cb93912014-01-29 11:54:12 -0500938 self.assertEqual(test.__annotations__, spec.annotations)
939
940 def test(): pass
Pablo Galindoaee19f52019-05-16 21:08:15 +0100941 spec = inspect.getfullargspec(test)
Yury Selivanov4cb93912014-01-29 11:54:12 -0500942 self.assertEqual(test.__annotations__, spec.annotations)
943
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500944 @unittest.skipIf(MISSING_C_DOCSTRINGS,
945 "Signature information for builtins requires docstrings")
946 def test_getfullargspec_builtin_methods(self):
Pablo Galindod5d2b452019-04-30 02:01:14 +0100947 self.assertFullArgSpecEquals(_pickle.Pickler.dump, ['self', 'obj'],
948 formatted='(self, obj)')
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500949
Pablo Galindod5d2b452019-04-30 02:01:14 +0100950 self.assertFullArgSpecEquals(_pickle.Pickler(io.BytesIO()).dump, ['self', 'obj'],
951 formatted='(self, obj)')
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500952
Yury Selivanov8c185ee2014-02-21 01:32:42 -0500953 self.assertFullArgSpecEquals(
954 os.stat,
955 args_e=['path'],
956 kwonlyargs_e=['dir_fd', 'follow_symlinks'],
957 kwonlydefaults_e={'dir_fd': None, 'follow_symlinks': True},
958 formatted='(path, *, dir_fd=None, follow_symlinks=True)')
959
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200960 @cpython_only
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500961 @unittest.skipIf(MISSING_C_DOCSTRINGS,
962 "Signature information for builtins requires docstrings")
Chih-Hsuan Yenc57eb9a2018-10-04 21:15:00 +0800963 def test_getfullargspec_builtin_func(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200964 import _testcapi
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500965 builtin = _testcapi.docstring_with_signature_with_defaults
Pablo Galindoaee19f52019-05-16 21:08:15 +0100966 spec = inspect.getfullargspec(builtin)
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500967 self.assertEqual(spec.defaults[0], 'avocado')
968
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200969 @cpython_only
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500970 @unittest.skipIf(MISSING_C_DOCSTRINGS,
971 "Signature information for builtins requires docstrings")
Chih-Hsuan Yenc57eb9a2018-10-04 21:15:00 +0800972 def test_getfullargspec_builtin_func_no_signature(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200973 import _testcapi
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500974 builtin = _testcapi.docstring_no_signature
Pablo Galindoaee19f52019-05-16 21:08:15 +0100975 with self.assertRaises(TypeError):
976 inspect.getfullargspec(builtin)
Christian Heimes3795b532007-11-08 13:48:53 +0000977
larryhastingsf36ba122018-01-28 11:13:09 -0800978 def test_getfullargspec_definition_order_preserved_on_kwonly(self):
979 for fn in signatures_with_lexicographic_keyword_only_parameters():
Pablo Galindoaee19f52019-05-16 21:08:15 +0100980 signature = inspect.getfullargspec(fn)
larryhastingsf36ba122018-01-28 11:13:09 -0800981 l = list(signature.kwonlyargs)
982 sorted_l = sorted(l)
983 self.assertTrue(l)
984 self.assertEqual(l, sorted_l)
Pablo Galindoaee19f52019-05-16 21:08:15 +0100985 signature = inspect.getfullargspec(unsorted_keyword_only_parameters_fn)
larryhastingsf36ba122018-01-28 11:13:09 -0800986 l = list(signature.kwonlyargs)
987 self.assertEqual(l, unsorted_keyword_only_parameters)
988
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500989 def test_getargspec_method(self):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000990 class A(object):
991 def m(self):
992 pass
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500993 self.assertArgSpecEquals(A.m, ['self'])
Tim Peters13b49d32001-09-23 02:00:29 +0000994
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000995 def test_classify_newstyle(self):
996 class A(object):
Tim Peters13b49d32001-09-23 02:00:29 +0000997
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000998 def s(): pass
999 s = staticmethod(s)
Tim Peters13b49d32001-09-23 02:00:29 +00001000
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001001 def c(cls): pass
1002 c = classmethod(c)
Tim Peters13b49d32001-09-23 02:00:29 +00001003
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001004 def getp(self): pass
1005 p = property(getp)
Tim Peters13b49d32001-09-23 02:00:29 +00001006
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001007 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +00001008
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001009 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +00001010
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001011 datablob = '1'
Tim Peters13b49d32001-09-23 02:00:29 +00001012
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +01001013 dd = _BrokenDataDescriptor()
1014 md = _BrokenMethodDescriptor()
1015
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001016 attrs = attrs_wo_objs(A)
Yury Selivanov0860a0b2014-01-31 14:28:44 -05001017
Serhiy Storchaka3327a2d2017-12-15 14:13:41 +02001018 self.assertIn(('__new__', 'static method', object), attrs,
1019 'missing __new__')
Yury Selivanov0860a0b2014-01-31 14:28:44 -05001020 self.assertIn(('__init__', 'method', object), attrs, 'missing __init__')
1021
Benjamin Peterson577473f2010-01-19 00:09:57 +00001022 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
1023 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
1024 self.assertIn(('p', 'property', A), attrs, 'missing property')
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001025 self.assertIn(('m', 'method', A), attrs,
1026 'missing plain method: %r' % attrs)
Benjamin Peterson577473f2010-01-19 00:09:57 +00001027 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
1028 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +01001029 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
1030 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +00001031
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001032 class B(A):
Tim Peters13b49d32001-09-23 02:00:29 +00001033
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001034 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +00001035
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001036 attrs = attrs_wo_objs(B)
Benjamin Peterson577473f2010-01-19 00:09:57 +00001037 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
1038 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
1039 self.assertIn(('p', 'property', A), attrs, 'missing property')
1040 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
1041 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
1042 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +01001043 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
1044 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +00001045
1046
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001047 class C(A):
Tim Peters13b49d32001-09-23 02:00:29 +00001048
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001049 def m(self): pass
1050 def c(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +00001051
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001052 attrs = attrs_wo_objs(C)
Benjamin Peterson577473f2010-01-19 00:09:57 +00001053 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
1054 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
1055 self.assertIn(('p', 'property', A), attrs, 'missing property')
1056 self.assertIn(('m', 'method', C), attrs, 'missing plain method')
1057 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
1058 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +01001059 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
1060 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +00001061
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001062 class D(B, C):
Tim Peters13b49d32001-09-23 02:00:29 +00001063
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001064 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +00001065
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001066 attrs = attrs_wo_objs(D)
Benjamin Peterson577473f2010-01-19 00:09:57 +00001067 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
1068 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
1069 self.assertIn(('p', 'property', A), attrs, 'missing property')
1070 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
1071 self.assertIn(('m1', 'method', D), attrs, 'missing plain method')
1072 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +01001073 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
1074 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
1075
1076 def test_classify_builtin_types(self):
1077 # Simple sanity check that all built-in types can have their
1078 # attributes classified.
1079 for name in dir(__builtins__):
1080 builtin = getattr(__builtins__, name)
1081 if isinstance(builtin, type):
1082 inspect.classify_class_attrs(builtin)
1083
Serhiy Storchaka3327a2d2017-12-15 14:13:41 +02001084 attrs = attrs_wo_objs(bool)
1085 self.assertIn(('__new__', 'static method', bool), attrs,
1086 'missing __new__')
1087 self.assertIn(('from_bytes', 'class method', int), attrs,
1088 'missing class method')
1089 self.assertIn(('to_bytes', 'method', int), attrs,
1090 'missing plain method')
1091 self.assertIn(('__add__', 'method', int), attrs,
1092 'missing plain method')
1093 self.assertIn(('__and__', 'method', bool), attrs,
1094 'missing plain method')
1095
Ethan Furman63c141c2013-10-18 00:27:39 -07001096 def test_classify_DynamicClassAttribute(self):
1097 class Meta(type):
1098 def __getattr__(self, name):
1099 if name == 'ham':
1100 return 'spam'
1101 return super().__getattr__(name)
1102 class VA(metaclass=Meta):
Ethan Furmane03ea372013-09-25 07:14:41 -07001103 @types.DynamicClassAttribute
1104 def ham(self):
1105 return 'eggs'
Ethan Furman63c141c2013-10-18 00:27:39 -07001106 should_find_dca = inspect.Attribute('ham', 'data', VA, VA.__dict__['ham'])
1107 self.assertIn(should_find_dca, inspect.classify_class_attrs(VA))
Ethan Furmanb0c84cd2013-10-20 22:37:39 -07001108 should_find_ga = inspect.Attribute('ham', 'data', Meta, 'spam')
Ethan Furman63c141c2013-10-18 00:27:39 -07001109 self.assertIn(should_find_ga, inspect.classify_class_attrs(VA))
1110
Yury Selivanovbf341fb2015-05-21 15:41:57 -04001111 def test_classify_overrides_bool(self):
1112 class NoBool(object):
1113 def __eq__(self, other):
1114 return NoBool()
1115
1116 def __bool__(self):
1117 raise NotImplementedError(
1118 "This object does not specify a boolean value")
1119
1120 class HasNB(object):
1121 dd = NoBool()
1122
1123 should_find_attr = inspect.Attribute('dd', 'data', HasNB, HasNB.dd)
1124 self.assertIn(should_find_attr, inspect.classify_class_attrs(HasNB))
1125
Ethan Furmanb0c84cd2013-10-20 22:37:39 -07001126 def test_classify_metaclass_class_attribute(self):
1127 class Meta(type):
1128 fish = 'slap'
1129 def __dir__(self):
Serhiy Storchakaa60c2fe2015-03-12 21:56:08 +02001130 return ['__class__', '__module__', '__name__', 'fish']
Ethan Furmanb0c84cd2013-10-20 22:37:39 -07001131 class Class(metaclass=Meta):
1132 pass
1133 should_find = inspect.Attribute('fish', 'data', Meta, 'slap')
1134 self.assertIn(should_find, inspect.classify_class_attrs(Class))
1135
Ethan Furman63c141c2013-10-18 00:27:39 -07001136 def test_classify_VirtualAttribute(self):
1137 class Meta(type):
1138 def __dir__(cls):
1139 return ['__class__', '__module__', '__name__', 'BOOM']
1140 def __getattr__(self, name):
1141 if name =='BOOM':
1142 return 42
1143 return super().__getattr(name)
1144 class Class(metaclass=Meta):
1145 pass
Ethan Furmanb0c84cd2013-10-20 22:37:39 -07001146 should_find = inspect.Attribute('BOOM', 'data', Meta, 42)
Ethan Furman63c141c2013-10-18 00:27:39 -07001147 self.assertIn(should_find, inspect.classify_class_attrs(Class))
1148
1149 def test_classify_VirtualAttribute_multi_classes(self):
1150 class Meta1(type):
1151 def __dir__(cls):
1152 return ['__class__', '__module__', '__name__', 'one']
1153 def __getattr__(self, name):
1154 if name =='one':
1155 return 1
1156 return super().__getattr__(name)
1157 class Meta2(type):
1158 def __dir__(cls):
1159 return ['__class__', '__module__', '__name__', 'two']
1160 def __getattr__(self, name):
1161 if name =='two':
1162 return 2
1163 return super().__getattr__(name)
1164 class Meta3(Meta1, Meta2):
1165 def __dir__(cls):
1166 return list(sorted(set(['__class__', '__module__', '__name__', 'three'] +
1167 Meta1.__dir__(cls) + Meta2.__dir__(cls))))
1168 def __getattr__(self, name):
1169 if name =='three':
1170 return 3
1171 return super().__getattr__(name)
1172 class Class1(metaclass=Meta1):
1173 pass
1174 class Class2(Class1, metaclass=Meta3):
1175 pass
1176
Ethan Furmanb0c84cd2013-10-20 22:37:39 -07001177 should_find1 = inspect.Attribute('one', 'data', Meta1, 1)
1178 should_find2 = inspect.Attribute('two', 'data', Meta2, 2)
1179 should_find3 = inspect.Attribute('three', 'data', Meta3, 3)
Ethan Furman63c141c2013-10-18 00:27:39 -07001180 cca = inspect.classify_class_attrs(Class2)
1181 for sf in (should_find1, should_find2, should_find3):
1182 self.assertIn(sf, cca)
1183
1184 def test_classify_class_attrs_with_buggy_dir(self):
1185 class M(type):
1186 def __dir__(cls):
1187 return ['__class__', '__name__', 'missing']
1188 class C(metaclass=M):
1189 pass
1190 attrs = [a[0] for a in inspect.classify_class_attrs(C)]
1191 self.assertNotIn('missing', attrs)
Ethan Furmane03ea372013-09-25 07:14:41 -07001192
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +01001193 def test_getmembers_descriptors(self):
1194 class A(object):
1195 dd = _BrokenDataDescriptor()
1196 md = _BrokenMethodDescriptor()
1197
1198 def pred_wrapper(pred):
1199 # A quick'n'dirty way to discard standard attributes of new-style
1200 # classes.
1201 class Empty(object):
1202 pass
1203 def wrapped(x):
1204 if '__name__' in dir(x) and hasattr(Empty, x.__name__):
1205 return False
1206 return pred(x)
1207 return wrapped
1208
1209 ismethoddescriptor = pred_wrapper(inspect.ismethoddescriptor)
1210 isdatadescriptor = pred_wrapper(inspect.isdatadescriptor)
1211
1212 self.assertEqual(inspect.getmembers(A, ismethoddescriptor),
1213 [('md', A.__dict__['md'])])
1214 self.assertEqual(inspect.getmembers(A, isdatadescriptor),
1215 [('dd', A.__dict__['dd'])])
1216
1217 class B(A):
1218 pass
1219
1220 self.assertEqual(inspect.getmembers(B, ismethoddescriptor),
1221 [('md', A.__dict__['md'])])
1222 self.assertEqual(inspect.getmembers(B, isdatadescriptor),
1223 [('dd', A.__dict__['dd'])])
1224
Antoine Pitrou0c603812012-01-18 17:40:18 +01001225 def test_getmembers_method(self):
1226 class B:
1227 def f(self):
1228 pass
1229
1230 self.assertIn(('f', B.f), inspect.getmembers(B))
1231 self.assertNotIn(('f', B.f), inspect.getmembers(B, inspect.ismethod))
1232 b = B()
1233 self.assertIn(('f', b.f), inspect.getmembers(b))
1234 self.assertIn(('f', b.f), inspect.getmembers(b, inspect.ismethod))
1235
Ethan Furmane03ea372013-09-25 07:14:41 -07001236 def test_getmembers_VirtualAttribute(self):
Ethan Furman63c141c2013-10-18 00:27:39 -07001237 class M(type):
1238 def __getattr__(cls, name):
1239 if name == 'eggs':
1240 return 'scrambled'
1241 return super().__getattr__(name)
1242 class A(metaclass=M):
Ethan Furmane03ea372013-09-25 07:14:41 -07001243 @types.DynamicClassAttribute
1244 def eggs(self):
1245 return 'spam'
Ethan Furman63c141c2013-10-18 00:27:39 -07001246 self.assertIn(('eggs', 'scrambled'), inspect.getmembers(A))
1247 self.assertIn(('eggs', 'spam'), inspect.getmembers(A()))
1248
1249 def test_getmembers_with_buggy_dir(self):
1250 class M(type):
1251 def __dir__(cls):
1252 return ['__class__', '__name__', 'missing']
1253 class C(metaclass=M):
1254 pass
1255 attrs = [a[0] for a in inspect.getmembers(C)]
1256 self.assertNotIn('missing', attrs)
Ethan Furmane03ea372013-09-25 07:14:41 -07001257
Aaron Hall, MBA4054b172018-05-20 19:46:42 -04001258class TestIsDataDescriptor(unittest.TestCase):
1259
1260 def test_custom_descriptors(self):
1261 class NonDataDescriptor:
1262 def __get__(self, value, type=None): pass
1263 class DataDescriptor0:
1264 def __set__(self, name, value): pass
1265 class DataDescriptor1:
1266 def __delete__(self, name): pass
1267 class DataDescriptor2:
1268 __set__ = None
1269 self.assertFalse(inspect.isdatadescriptor(NonDataDescriptor()),
1270 'class with only __get__ not a data descriptor')
1271 self.assertTrue(inspect.isdatadescriptor(DataDescriptor0()),
1272 'class with __set__ is a data descriptor')
1273 self.assertTrue(inspect.isdatadescriptor(DataDescriptor1()),
1274 'class with __delete__ is a data descriptor')
1275 self.assertTrue(inspect.isdatadescriptor(DataDescriptor2()),
1276 'class with __set__ = None is a data descriptor')
1277
1278 def test_slot(self):
1279 class Slotted:
1280 __slots__ = 'foo',
1281 self.assertTrue(inspect.isdatadescriptor(Slotted.foo),
1282 'a slot is a data descriptor')
1283
1284 def test_property(self):
1285 class Propertied:
1286 @property
1287 def a_property(self):
1288 pass
1289 self.assertTrue(inspect.isdatadescriptor(Propertied.a_property),
1290 'a property is a data descriptor')
1291
1292 def test_functions(self):
1293 class Test(object):
1294 def instance_method(self): pass
1295 @classmethod
1296 def class_method(cls): pass
1297 @staticmethod
1298 def static_method(): pass
1299 def function():
1300 pass
1301 a_lambda = lambda: None
1302 self.assertFalse(inspect.isdatadescriptor(Test().instance_method),
1303 'a instance method is not a data descriptor')
1304 self.assertFalse(inspect.isdatadescriptor(Test().class_method),
1305 'a class method is not a data descriptor')
1306 self.assertFalse(inspect.isdatadescriptor(Test().static_method),
1307 'a static method is not a data descriptor')
1308 self.assertFalse(inspect.isdatadescriptor(function),
1309 'a function is not a data descriptor')
1310 self.assertFalse(inspect.isdatadescriptor(a_lambda),
1311 'a lambda is not a data descriptor')
1312
Jeremy Hyltonc4bf5ed2003-06-27 18:43:12 +00001313
Nick Coghlan2f92e542012-06-23 19:39:55 +10001314_global_ref = object()
1315class TestGetClosureVars(unittest.TestCase):
1316
1317 def test_name_resolution(self):
1318 # Basic test of the 4 different resolution mechanisms
1319 def f(nonlocal_ref):
1320 def g(local_ref):
1321 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
1322 return g
1323 _arg = object()
1324 nonlocal_vars = {"nonlocal_ref": _arg}
1325 global_vars = {"_global_ref": _global_ref}
1326 builtin_vars = {"print": print}
1327 unbound_names = {"unbound_ref"}
1328 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
1329 builtin_vars, unbound_names)
1330 self.assertEqual(inspect.getclosurevars(f(_arg)), expected)
1331
1332 def test_generator_closure(self):
1333 def f(nonlocal_ref):
1334 def g(local_ref):
1335 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
1336 yield
1337 return g
1338 _arg = object()
1339 nonlocal_vars = {"nonlocal_ref": _arg}
1340 global_vars = {"_global_ref": _global_ref}
1341 builtin_vars = {"print": print}
1342 unbound_names = {"unbound_ref"}
1343 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
1344 builtin_vars, unbound_names)
1345 self.assertEqual(inspect.getclosurevars(f(_arg)), expected)
1346
1347 def test_method_closure(self):
1348 class C:
1349 def f(self, nonlocal_ref):
1350 def g(local_ref):
1351 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
1352 return g
1353 _arg = object()
1354 nonlocal_vars = {"nonlocal_ref": _arg}
1355 global_vars = {"_global_ref": _global_ref}
1356 builtin_vars = {"print": print}
1357 unbound_names = {"unbound_ref"}
1358 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
1359 builtin_vars, unbound_names)
1360 self.assertEqual(inspect.getclosurevars(C().f(_arg)), expected)
1361
1362 def test_nonlocal_vars(self):
1363 # More complex tests of nonlocal resolution
1364 def _nonlocal_vars(f):
1365 return inspect.getclosurevars(f).nonlocals
1366
1367 def make_adder(x):
1368 def add(y):
1369 return x + y
1370 return add
1371
1372 def curry(func, arg1):
1373 return lambda arg2: func(arg1, arg2)
1374
1375 def less_than(a, b):
1376 return a < b
1377
1378 # The infamous Y combinator.
1379 def Y(le):
1380 def g(f):
1381 return le(lambda x: f(f)(x))
1382 Y.g_ref = g
1383 return g(g)
1384
1385 def check_y_combinator(func):
1386 self.assertEqual(_nonlocal_vars(func), {'f': Y.g_ref})
1387
1388 inc = make_adder(1)
1389 add_two = make_adder(2)
1390 greater_than_five = curry(less_than, 5)
1391
1392 self.assertEqual(_nonlocal_vars(inc), {'x': 1})
1393 self.assertEqual(_nonlocal_vars(add_two), {'x': 2})
1394 self.assertEqual(_nonlocal_vars(greater_than_five),
1395 {'arg1': 5, 'func': less_than})
1396 self.assertEqual(_nonlocal_vars((lambda x: lambda y: x + y)(3)),
1397 {'x': 3})
1398 Y(check_y_combinator)
1399
1400 def test_getclosurevars_empty(self):
1401 def foo(): pass
1402 _empty = inspect.ClosureVars({}, {}, {}, set())
1403 self.assertEqual(inspect.getclosurevars(lambda: True), _empty)
1404 self.assertEqual(inspect.getclosurevars(foo), _empty)
1405
1406 def test_getclosurevars_error(self):
1407 class T: pass
1408 self.assertRaises(TypeError, inspect.getclosurevars, 1)
1409 self.assertRaises(TypeError, inspect.getclosurevars, list)
1410 self.assertRaises(TypeError, inspect.getclosurevars, {})
1411
Nick Coghlan6c6e2542012-06-23 20:07:39 +10001412 def _private_globals(self):
1413 code = """def f(): print(path)"""
1414 ns = {}
1415 exec(code, ns)
1416 return ns["f"], ns
1417
1418 def test_builtins_fallback(self):
1419 f, ns = self._private_globals()
1420 ns.pop("__builtins__", None)
1421 expected = inspect.ClosureVars({}, {}, {"print":print}, {"path"})
1422 self.assertEqual(inspect.getclosurevars(f), expected)
1423
1424 def test_builtins_as_dict(self):
1425 f, ns = self._private_globals()
1426 ns["__builtins__"] = {"path":1}
1427 expected = inspect.ClosureVars({}, {}, {"path":1}, {"print"})
1428 self.assertEqual(inspect.getclosurevars(f), expected)
1429
1430 def test_builtins_as_module(self):
1431 f, ns = self._private_globals()
1432 ns["__builtins__"] = os
1433 expected = inspect.ClosureVars({}, {}, {"path":os.path}, {"print"})
1434 self.assertEqual(inspect.getclosurevars(f), expected)
1435
Nick Coghlan2f92e542012-06-23 19:39:55 +10001436
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001437class TestGetcallargsFunctions(unittest.TestCase):
1438
1439 def assertEqualCallArgs(self, func, call_params_string, locs=None):
1440 locs = dict(locs or {}, func=func)
1441 r1 = eval('func(%s)' % call_params_string, None, locs)
Pablo Galindoaee19f52019-05-16 21:08:15 +01001442 r2 = eval('inspect.getcallargs(func, %s)' % call_params_string, None,
1443 locs)
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001444 self.assertEqual(r1, r2)
1445
1446 def assertEqualException(self, func, call_param_string, locs=None):
1447 locs = dict(locs or {}, func=func)
1448 try:
1449 eval('func(%s)' % call_param_string, None, locs)
1450 except Exception as e:
1451 ex1 = e
1452 else:
1453 self.fail('Exception not raised')
1454 try:
Pablo Galindoaee19f52019-05-16 21:08:15 +01001455 eval('inspect.getcallargs(func, %s)' % call_param_string, None,
1456 locs)
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001457 except Exception as e:
1458 ex2 = e
1459 else:
1460 self.fail('Exception not raised')
1461 self.assertIs(type(ex1), type(ex2))
1462 self.assertEqual(str(ex1), str(ex2))
1463 del ex1, ex2
1464
1465 def makeCallable(self, signature):
1466 """Create a function that returns its locals()"""
1467 code = "lambda %s: locals()"
1468 return eval(code % signature)
1469
1470 def test_plain(self):
1471 f = self.makeCallable('a, b=1')
1472 self.assertEqualCallArgs(f, '2')
1473 self.assertEqualCallArgs(f, '2, 3')
1474 self.assertEqualCallArgs(f, 'a=2')
1475 self.assertEqualCallArgs(f, 'b=3, a=2')
1476 self.assertEqualCallArgs(f, '2, b=3')
1477 # expand *iterable / **mapping
1478 self.assertEqualCallArgs(f, '*(2,)')
1479 self.assertEqualCallArgs(f, '*[2]')
1480 self.assertEqualCallArgs(f, '*(2, 3)')
1481 self.assertEqualCallArgs(f, '*[2, 3]')
1482 self.assertEqualCallArgs(f, '**{"a":2}')
1483 self.assertEqualCallArgs(f, 'b=3, **{"a":2}')
1484 self.assertEqualCallArgs(f, '2, **{"b":3}')
1485 self.assertEqualCallArgs(f, '**{"b":3, "a":2}')
1486 # expand UserList / UserDict
1487 self.assertEqualCallArgs(f, '*collections.UserList([2])')
1488 self.assertEqualCallArgs(f, '*collections.UserList([2, 3])')
1489 self.assertEqualCallArgs(f, '**collections.UserDict(a=2)')
1490 self.assertEqualCallArgs(f, '2, **collections.UserDict(b=3)')
1491 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3)')
1492
1493 def test_varargs(self):
1494 f = self.makeCallable('a, b=1, *c')
1495 self.assertEqualCallArgs(f, '2')
1496 self.assertEqualCallArgs(f, '2, 3')
1497 self.assertEqualCallArgs(f, '2, 3, 4')
1498 self.assertEqualCallArgs(f, '*(2,3,4)')
1499 self.assertEqualCallArgs(f, '2, *[3,4]')
1500 self.assertEqualCallArgs(f, '2, 3, *collections.UserList([4])')
1501
1502 def test_varkw(self):
1503 f = self.makeCallable('a, b=1, **c')
1504 self.assertEqualCallArgs(f, 'a=2')
1505 self.assertEqualCallArgs(f, '2, b=3, c=4')
1506 self.assertEqualCallArgs(f, 'b=3, a=2, c=4')
1507 self.assertEqualCallArgs(f, 'c=4, **{"a":2, "b":3}')
1508 self.assertEqualCallArgs(f, '2, c=4, **{"b":3}')
1509 self.assertEqualCallArgs(f, 'b=2, **{"a":3, "c":4}')
1510 self.assertEqualCallArgs(f, '**collections.UserDict(a=2, b=3, c=4)')
1511 self.assertEqualCallArgs(f, '2, c=4, **collections.UserDict(b=3)')
1512 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3, c=4)')
1513
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001514 def test_varkw_only(self):
1515 # issue11256:
1516 f = self.makeCallable('**c')
1517 self.assertEqualCallArgs(f, '')
1518 self.assertEqualCallArgs(f, 'a=1')
1519 self.assertEqualCallArgs(f, 'a=1, b=2')
1520 self.assertEqualCallArgs(f, 'c=3, **{"a": 1, "b": 2}')
1521 self.assertEqualCallArgs(f, '**collections.UserDict(a=1, b=2)')
1522 self.assertEqualCallArgs(f, 'c=3, **collections.UserDict(a=1, b=2)')
1523
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001524 def test_keyword_only(self):
1525 f = self.makeCallable('a=3, *, c, d=2')
1526 self.assertEqualCallArgs(f, 'c=3')
1527 self.assertEqualCallArgs(f, 'c=3, a=3')
1528 self.assertEqualCallArgs(f, 'a=2, c=4')
1529 self.assertEqualCallArgs(f, '4, c=4')
1530 self.assertEqualException(f, '')
1531 self.assertEqualException(f, '3')
1532 self.assertEqualException(f, 'a=3')
1533 self.assertEqualException(f, 'd=4')
1534
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001535 f = self.makeCallable('*, c, d=2')
1536 self.assertEqualCallArgs(f, 'c=3')
1537 self.assertEqualCallArgs(f, 'c=3, d=4')
1538 self.assertEqualCallArgs(f, 'd=4, c=3')
1539
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001540 def test_multiple_features(self):
1541 f = self.makeCallable('a, b=2, *f, **g')
1542 self.assertEqualCallArgs(f, '2, 3, 7')
1543 self.assertEqualCallArgs(f, '2, 3, x=8')
1544 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
1545 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9')
1546 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9')
1547 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
1548 '[2, 3, (4,[5,6])]), **{"y":9, "z":10}')
1549 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
1550 '(4,[5,6])]), **collections.UserDict('
1551 'y=9, z=10)')
1552
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001553 f = self.makeCallable('a, b=2, *f, x, y=99, **g')
1554 self.assertEqualCallArgs(f, '2, 3, x=8')
1555 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
1556 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9, z=10')
1557 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9, z=10')
1558 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
1559 '[2, 3, (4,[5,6])]), q=0, **{"y":9, "z":10}')
1560 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
1561 '(4,[5,6])]), q=0, **collections.UserDict('
1562 'y=9, z=10)')
1563
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001564 def test_errors(self):
1565 f0 = self.makeCallable('')
1566 f1 = self.makeCallable('a, b')
1567 f2 = self.makeCallable('a, b=1')
1568 # f0 takes no arguments
1569 self.assertEqualException(f0, '1')
1570 self.assertEqualException(f0, 'x=1')
1571 self.assertEqualException(f0, '1,x=1')
1572 # f1 takes exactly 2 arguments
1573 self.assertEqualException(f1, '')
1574 self.assertEqualException(f1, '1')
1575 self.assertEqualException(f1, 'a=2')
1576 self.assertEqualException(f1, 'b=3')
1577 # f2 takes at least 1 argument
1578 self.assertEqualException(f2, '')
1579 self.assertEqualException(f2, 'b=3')
1580 for f in f1, f2:
1581 # f1/f2 takes exactly/at most 2 arguments
1582 self.assertEqualException(f, '2, 3, 4')
1583 self.assertEqualException(f, '1, 2, 3, a=1')
1584 self.assertEqualException(f, '2, 3, 4, c=5')
Georg Brandl178e5ea2012-02-21 00:32:36 +01001585 # XXX: success of this one depends on dict order
1586 ## self.assertEqualException(f, '2, 3, 4, a=1, c=5')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001587 # f got an unexpected keyword argument
1588 self.assertEqualException(f, 'c=2')
1589 self.assertEqualException(f, '2, c=3')
1590 self.assertEqualException(f, '2, 3, c=4')
1591 self.assertEqualException(f, '2, c=4, b=3')
1592 self.assertEqualException(f, '**{u"\u03c0\u03b9": 4}')
1593 # f got multiple values for keyword argument
1594 self.assertEqualException(f, '1, a=2')
1595 self.assertEqualException(f, '1, **{"a":2}')
1596 self.assertEqualException(f, '1, 2, b=3')
1597 # XXX: Python inconsistency
1598 # - for functions and bound methods: unexpected keyword 'c'
1599 # - for unbound methods: multiple values for keyword 'a'
1600 #self.assertEqualException(f, '1, c=3, a=2')
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001601 # issue11256:
1602 f3 = self.makeCallable('**c')
1603 self.assertEqualException(f3, '1, 2')
1604 self.assertEqualException(f3, '1, 2, a=1, b=2')
1605 f4 = self.makeCallable('*, a, b=0')
1606 self.assertEqualException(f3, '1, 2')
1607 self.assertEqualException(f3, '1, 2, a=1, b=2')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001608
Yury Selivanov875df202014-03-27 18:23:03 -04001609 # issue #20816: getcallargs() fails to iterate over non-existent
1610 # kwonlydefaults and raises a wrong TypeError
1611 def f5(*, a): pass
1612 with self.assertRaisesRegex(TypeError,
1613 'missing 1 required keyword-only'):
Pablo Galindoaee19f52019-05-16 21:08:15 +01001614 inspect.getcallargs(f5)
Yury Selivanov875df202014-03-27 18:23:03 -04001615
1616
Yury Selivanovdccfa132014-03-27 18:42:52 -04001617 # issue20817:
1618 def f6(a, b, c):
1619 pass
1620 with self.assertRaisesRegex(TypeError, "'a', 'b' and 'c'"):
Pablo Galindoaee19f52019-05-16 21:08:15 +01001621 inspect.getcallargs(f6)
Yury Selivanovdccfa132014-03-27 18:42:52 -04001622
Dong-hee Naa9cab432018-05-30 00:04:08 +09001623 # bpo-33197
1624 with self.assertRaisesRegex(ValueError,
1625 'variadic keyword parameters cannot'
1626 ' have default values'):
1627 inspect.Parameter("foo", kind=inspect.Parameter.VAR_KEYWORD,
1628 default=42)
1629 with self.assertRaisesRegex(ValueError,
1630 "value 5 is not a valid Parameter.kind"):
1631 inspect.Parameter("bar", kind=5, default=42)
1632
1633 with self.assertRaisesRegex(TypeError,
1634 'name must be a str, not a int'):
1635 inspect.Parameter(123, kind=4)
1636
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001637class TestGetcallargsMethods(TestGetcallargsFunctions):
1638
1639 def setUp(self):
1640 class Foo(object):
1641 pass
1642 self.cls = Foo
1643 self.inst = Foo()
1644
1645 def makeCallable(self, signature):
1646 assert 'self' not in signature
1647 mk = super(TestGetcallargsMethods, self).makeCallable
1648 self.cls.method = mk('self, ' + signature)
1649 return self.inst.method
1650
1651class TestGetcallargsUnboundMethods(TestGetcallargsMethods):
1652
1653 def makeCallable(self, signature):
1654 super(TestGetcallargsUnboundMethods, self).makeCallable(signature)
1655 return self.cls.method
1656
1657 def assertEqualCallArgs(self, func, call_params_string, locs=None):
1658 return super(TestGetcallargsUnboundMethods, self).assertEqualCallArgs(
1659 *self._getAssertEqualParams(func, call_params_string, locs))
1660
1661 def assertEqualException(self, func, call_params_string, locs=None):
1662 return super(TestGetcallargsUnboundMethods, self).assertEqualException(
1663 *self._getAssertEqualParams(func, call_params_string, locs))
1664
1665 def _getAssertEqualParams(self, func, call_params_string, locs=None):
1666 assert 'inst' not in call_params_string
1667 locs = dict(locs or {}, inst=self.inst)
1668 return (func, 'inst,' + call_params_string, locs)
1669
Michael Foord95fc51d2010-11-20 15:07:30 +00001670
1671class TestGetattrStatic(unittest.TestCase):
1672
1673 def test_basic(self):
1674 class Thing(object):
1675 x = object()
1676
1677 thing = Thing()
1678 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1679 self.assertEqual(inspect.getattr_static(thing, 'x', None), Thing.x)
1680 with self.assertRaises(AttributeError):
1681 inspect.getattr_static(thing, 'y')
1682
1683 self.assertEqual(inspect.getattr_static(thing, 'y', 3), 3)
1684
1685 def test_inherited(self):
1686 class Thing(object):
1687 x = object()
1688 class OtherThing(Thing):
1689 pass
1690
1691 something = OtherThing()
1692 self.assertEqual(inspect.getattr_static(something, 'x'), Thing.x)
1693
1694 def test_instance_attr(self):
1695 class Thing(object):
1696 x = 2
1697 def __init__(self, x):
1698 self.x = x
1699 thing = Thing(3)
1700 self.assertEqual(inspect.getattr_static(thing, 'x'), 3)
1701 del thing.x
1702 self.assertEqual(inspect.getattr_static(thing, 'x'), 2)
1703
1704 def test_property(self):
1705 class Thing(object):
1706 @property
1707 def x(self):
1708 raise AttributeError("I'm pretending not to exist")
1709 thing = Thing()
1710 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1711
Ezio Melotti75cbd732011-04-28 00:59:29 +03001712 def test_descriptor_raises_AttributeError(self):
Michael Foord95fc51d2010-11-20 15:07:30 +00001713 class descriptor(object):
1714 def __get__(*_):
1715 raise AttributeError("I'm pretending not to exist")
1716 desc = descriptor()
1717 class Thing(object):
1718 x = desc
1719 thing = Thing()
1720 self.assertEqual(inspect.getattr_static(thing, 'x'), desc)
1721
1722 def test_classAttribute(self):
1723 class Thing(object):
1724 x = object()
1725
1726 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.x)
1727
Ethan Furmane03ea372013-09-25 07:14:41 -07001728 def test_classVirtualAttribute(self):
1729 class Thing(object):
1730 @types.DynamicClassAttribute
1731 def x(self):
1732 return self._x
1733 _x = object()
1734
1735 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.__dict__['x'])
1736
Michael Foord95fc51d2010-11-20 15:07:30 +00001737 def test_inherited_classattribute(self):
1738 class Thing(object):
1739 x = object()
1740 class OtherThing(Thing):
1741 pass
1742
1743 self.assertEqual(inspect.getattr_static(OtherThing, 'x'), Thing.x)
1744
1745 def test_slots(self):
1746 class Thing(object):
1747 y = 'bar'
1748 __slots__ = ['x']
1749 def __init__(self):
1750 self.x = 'foo'
1751 thing = Thing()
1752 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1753 self.assertEqual(inspect.getattr_static(thing, 'y'), 'bar')
1754
1755 del thing.x
1756 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1757
1758 def test_metaclass(self):
1759 class meta(type):
1760 attr = 'foo'
1761 class Thing(object, metaclass=meta):
1762 pass
1763 self.assertEqual(inspect.getattr_static(Thing, 'attr'), 'foo')
1764
1765 class sub(meta):
1766 pass
1767 class OtherThing(object, metaclass=sub):
1768 x = 3
1769 self.assertEqual(inspect.getattr_static(OtherThing, 'attr'), 'foo')
1770
1771 class OtherOtherThing(OtherThing):
1772 pass
1773 # this test is odd, but it was added as it exposed a bug
1774 self.assertEqual(inspect.getattr_static(OtherOtherThing, 'x'), 3)
1775
1776 def test_no_dict_no_slots(self):
1777 self.assertEqual(inspect.getattr_static(1, 'foo', None), None)
1778 self.assertNotEqual(inspect.getattr_static('foo', 'lower'), None)
1779
1780 def test_no_dict_no_slots_instance_member(self):
1781 # returns descriptor
1782 with open(__file__) as handle:
1783 self.assertEqual(inspect.getattr_static(handle, 'name'), type(handle).name)
1784
1785 def test_inherited_slots(self):
1786 # returns descriptor
1787 class Thing(object):
1788 __slots__ = ['x']
1789 def __init__(self):
1790 self.x = 'foo'
1791
1792 class OtherThing(Thing):
1793 pass
1794 # it would be nice if this worked...
1795 # we get the descriptor instead of the instance attribute
1796 self.assertEqual(inspect.getattr_static(OtherThing(), 'x'), Thing.x)
1797
1798 def test_descriptor(self):
1799 class descriptor(object):
1800 def __get__(self, instance, owner):
1801 return 3
1802 class Foo(object):
1803 d = descriptor()
1804
1805 foo = Foo()
1806
1807 # for a non data descriptor we return the instance attribute
1808 foo.__dict__['d'] = 1
1809 self.assertEqual(inspect.getattr_static(foo, 'd'), 1)
1810
Mike53f7a7c2017-12-14 14:04:53 +03001811 # if the descriptor is a data-descriptor we should return the
Michael Foord95fc51d2010-11-20 15:07:30 +00001812 # descriptor
1813 descriptor.__set__ = lambda s, i, v: None
1814 self.assertEqual(inspect.getattr_static(foo, 'd'), Foo.__dict__['d'])
1815
1816
1817 def test_metaclass_with_descriptor(self):
1818 class descriptor(object):
1819 def __get__(self, instance, owner):
1820 return 3
1821 class meta(type):
1822 d = descriptor()
1823 class Thing(object, metaclass=meta):
1824 pass
1825 self.assertEqual(inspect.getattr_static(Thing, 'd'), meta.__dict__['d'])
1826
1827
Michael Foordcc7ebb82010-11-20 16:20:16 +00001828 def test_class_as_property(self):
1829 class Base(object):
1830 foo = 3
1831
1832 class Something(Base):
Michael Foord35184ed2010-11-20 16:58:30 +00001833 executed = False
Michael Foordcc7ebb82010-11-20 16:20:16 +00001834 @property
1835 def __class__(self):
Michael Foord35184ed2010-11-20 16:58:30 +00001836 self.executed = True
Michael Foordcc7ebb82010-11-20 16:20:16 +00001837 return object
1838
Michael Foord35184ed2010-11-20 16:58:30 +00001839 instance = Something()
1840 self.assertEqual(inspect.getattr_static(instance, 'foo'), 3)
1841 self.assertFalse(instance.executed)
Michael Foordcc7ebb82010-11-20 16:20:16 +00001842 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1843
Michael Foorde5162652010-11-20 16:40:44 +00001844 def test_mro_as_property(self):
1845 class Meta(type):
1846 @property
1847 def __mro__(self):
1848 return (object,)
1849
1850 class Base(object):
1851 foo = 3
1852
1853 class Something(Base, metaclass=Meta):
1854 pass
1855
1856 self.assertEqual(inspect.getattr_static(Something(), 'foo'), 3)
1857 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1858
Michael Foorddcebe0f2011-03-15 19:20:44 -04001859 def test_dict_as_property(self):
1860 test = self
1861 test.called = False
1862
1863 class Foo(dict):
1864 a = 3
1865 @property
1866 def __dict__(self):
1867 test.called = True
1868 return {}
1869
1870 foo = Foo()
1871 foo.a = 4
1872 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1873 self.assertFalse(test.called)
1874
1875 def test_custom_object_dict(self):
1876 test = self
1877 test.called = False
1878
1879 class Custom(dict):
1880 def get(self, key, default=None):
1881 test.called = True
1882 super().get(key, default)
1883
1884 class Foo(object):
1885 a = 3
1886 foo = Foo()
1887 foo.__dict__ = Custom()
1888 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1889 self.assertFalse(test.called)
1890
1891 def test_metaclass_dict_as_property(self):
1892 class Meta(type):
1893 @property
1894 def __dict__(self):
1895 self.executed = True
1896
1897 class Thing(metaclass=Meta):
1898 executed = False
1899
1900 def __init__(self):
1901 self.spam = 42
1902
1903 instance = Thing()
1904 self.assertEqual(inspect.getattr_static(instance, "spam"), 42)
1905 self.assertFalse(Thing.executed)
Michael Foorde5162652010-11-20 16:40:44 +00001906
Michael Foorda51623b2011-12-18 22:01:40 +00001907 def test_module(self):
1908 sentinel = object()
1909 self.assertIsNot(inspect.getattr_static(sys, "version", sentinel),
1910 sentinel)
1911
Michael Foord3ba95f82011-12-22 01:13:37 +00001912 def test_metaclass_with_metaclass_with_dict_as_property(self):
1913 class MetaMeta(type):
1914 @property
1915 def __dict__(self):
1916 self.executed = True
1917 return dict(spam=42)
1918
1919 class Meta(type, metaclass=MetaMeta):
1920 executed = False
1921
1922 class Thing(metaclass=Meta):
1923 pass
1924
1925 with self.assertRaises(AttributeError):
1926 inspect.getattr_static(Thing, "spam")
1927 self.assertFalse(Thing.executed)
1928
Nick Coghlane0f04652010-11-21 03:44:04 +00001929class TestGetGeneratorState(unittest.TestCase):
1930
1931 def setUp(self):
1932 def number_generator():
1933 for number in range(5):
1934 yield number
1935 self.generator = number_generator()
1936
1937 def _generatorstate(self):
1938 return inspect.getgeneratorstate(self.generator)
1939
1940 def test_created(self):
1941 self.assertEqual(self._generatorstate(), inspect.GEN_CREATED)
1942
1943 def test_suspended(self):
1944 next(self.generator)
1945 self.assertEqual(self._generatorstate(), inspect.GEN_SUSPENDED)
1946
1947 def test_closed_after_exhaustion(self):
1948 for i in self.generator:
1949 pass
1950 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1951
1952 def test_closed_after_immediate_exception(self):
1953 with self.assertRaises(RuntimeError):
1954 self.generator.throw(RuntimeError)
1955 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1956
1957 def test_running(self):
1958 # As mentioned on issue #10220, checking for the RUNNING state only
1959 # makes sense inside the generator itself.
1960 # The following generator checks for this by using the closure's
1961 # reference to self and the generator state checking helper method
1962 def running_check_generator():
1963 for number in range(5):
1964 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1965 yield number
1966 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1967 self.generator = running_check_generator()
1968 # Running up to the first yield
1969 next(self.generator)
1970 # Running after the first yield
1971 next(self.generator)
1972
Nick Coghlan7921b9f2010-11-30 06:36:04 +00001973 def test_easy_debugging(self):
1974 # repr() and str() of a generator state should contain the state name
1975 names = 'GEN_CREATED GEN_RUNNING GEN_SUSPENDED GEN_CLOSED'.split()
1976 for name in names:
1977 state = getattr(inspect, name)
1978 self.assertIn(name, repr(state))
1979 self.assertIn(name, str(state))
1980
Nick Coghlan04e2e3f2012-06-23 19:52:05 +10001981 def test_getgeneratorlocals(self):
1982 def each(lst, a=None):
1983 b=(1, 2, 3)
1984 for v in lst:
1985 if v == 3:
1986 c = 12
1987 yield v
1988
1989 numbers = each([1, 2, 3])
1990 self.assertEqual(inspect.getgeneratorlocals(numbers),
1991 {'a': None, 'lst': [1, 2, 3]})
1992 next(numbers)
1993 self.assertEqual(inspect.getgeneratorlocals(numbers),
1994 {'a': None, 'lst': [1, 2, 3], 'v': 1,
1995 'b': (1, 2, 3)})
1996 next(numbers)
1997 self.assertEqual(inspect.getgeneratorlocals(numbers),
1998 {'a': None, 'lst': [1, 2, 3], 'v': 2,
1999 'b': (1, 2, 3)})
2000 next(numbers)
2001 self.assertEqual(inspect.getgeneratorlocals(numbers),
2002 {'a': None, 'lst': [1, 2, 3], 'v': 3,
2003 'b': (1, 2, 3), 'c': 12})
2004 try:
2005 next(numbers)
2006 except StopIteration:
2007 pass
2008 self.assertEqual(inspect.getgeneratorlocals(numbers), {})
2009
2010 def test_getgeneratorlocals_empty(self):
2011 def yield_one():
2012 yield 1
2013 one = yield_one()
2014 self.assertEqual(inspect.getgeneratorlocals(one), {})
2015 try:
2016 next(one)
2017 except StopIteration:
2018 pass
2019 self.assertEqual(inspect.getgeneratorlocals(one), {})
2020
2021 def test_getgeneratorlocals_error(self):
2022 self.assertRaises(TypeError, inspect.getgeneratorlocals, 1)
2023 self.assertRaises(TypeError, inspect.getgeneratorlocals, lambda x: True)
2024 self.assertRaises(TypeError, inspect.getgeneratorlocals, set)
2025 self.assertRaises(TypeError, inspect.getgeneratorlocals, (2,3))
2026
Nick Coghlane0f04652010-11-21 03:44:04 +00002027
Yury Selivanov5376ba92015-06-22 12:19:30 -04002028class TestGetCoroutineState(unittest.TestCase):
2029
2030 def setUp(self):
2031 @types.coroutine
2032 def number_coroutine():
2033 for number in range(5):
2034 yield number
2035 async def coroutine():
2036 await number_coroutine()
2037 self.coroutine = coroutine()
2038
2039 def tearDown(self):
2040 self.coroutine.close()
2041
2042 def _coroutinestate(self):
2043 return inspect.getcoroutinestate(self.coroutine)
2044
2045 def test_created(self):
2046 self.assertEqual(self._coroutinestate(), inspect.CORO_CREATED)
2047
2048 def test_suspended(self):
2049 self.coroutine.send(None)
2050 self.assertEqual(self._coroutinestate(), inspect.CORO_SUSPENDED)
2051
2052 def test_closed_after_exhaustion(self):
2053 while True:
2054 try:
2055 self.coroutine.send(None)
2056 except StopIteration:
2057 break
2058
2059 self.assertEqual(self._coroutinestate(), inspect.CORO_CLOSED)
2060
2061 def test_closed_after_immediate_exception(self):
2062 with self.assertRaises(RuntimeError):
2063 self.coroutine.throw(RuntimeError)
2064 self.assertEqual(self._coroutinestate(), inspect.CORO_CLOSED)
2065
2066 def test_easy_debugging(self):
2067 # repr() and str() of a coroutine state should contain the state name
2068 names = 'CORO_CREATED CORO_RUNNING CORO_SUSPENDED CORO_CLOSED'.split()
2069 for name in names:
2070 state = getattr(inspect, name)
2071 self.assertIn(name, repr(state))
2072 self.assertIn(name, str(state))
2073
2074 def test_getcoroutinelocals(self):
2075 @types.coroutine
2076 def gencoro():
2077 yield
2078
2079 gencoro = gencoro()
2080 async def func(a=None):
2081 b = 'spam'
2082 await gencoro
2083
2084 coro = func()
2085 self.assertEqual(inspect.getcoroutinelocals(coro),
2086 {'a': None, 'gencoro': gencoro})
2087 coro.send(None)
2088 self.assertEqual(inspect.getcoroutinelocals(coro),
2089 {'a': None, 'gencoro': gencoro, 'b': 'spam'})
2090
2091
Yury Selivanova5d63dd2014-03-27 11:31:43 -04002092class MySignature(inspect.Signature):
2093 # Top-level to make it picklable;
2094 # used in test_signature_object_pickle
2095 pass
2096
2097class MyParameter(inspect.Parameter):
2098 # Top-level to make it picklable;
2099 # used in test_signature_object_pickle
2100 pass
2101
Nick Coghlanf9e227e2014-08-17 14:01:19 +10002102
Yury Selivanova5d63dd2014-03-27 11:31:43 -04002103
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002104class TestSignatureObject(unittest.TestCase):
2105 @staticmethod
Yury Selivanovbcd4fc12015-05-20 14:30:08 -04002106 def signature(func, **kw):
2107 sig = inspect.signature(func, **kw)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002108 return (tuple((param.name,
2109 (... if param.default is param.empty else param.default),
2110 (... if param.annotation is param.empty
2111 else param.annotation),
2112 str(param.kind).lower())
2113 for param in sig.parameters.values()),
2114 (... if sig.return_annotation is sig.empty
2115 else sig.return_annotation))
2116
2117 def test_signature_object(self):
2118 S = inspect.Signature
2119 P = inspect.Parameter
2120
2121 self.assertEqual(str(S()), '()')
Jens Reidel611836a2020-03-18 03:22:46 +01002122 self.assertEqual(repr(S().parameters), 'mappingproxy(OrderedDict())')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002123
Yury Selivanov07a9e452014-01-29 10:58:16 -05002124 def test(po, pk, pod=42, pkd=100, *args, ko, **kwargs):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002125 pass
2126 sig = inspect.signature(test)
2127 po = sig.parameters['po'].replace(kind=P.POSITIONAL_ONLY)
Yury Selivanov07a9e452014-01-29 10:58:16 -05002128 pod = sig.parameters['pod'].replace(kind=P.POSITIONAL_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002129 pk = sig.parameters['pk']
Yury Selivanov07a9e452014-01-29 10:58:16 -05002130 pkd = sig.parameters['pkd']
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002131 args = sig.parameters['args']
2132 ko = sig.parameters['ko']
2133 kwargs = sig.parameters['kwargs']
2134
2135 S((po, pk, args, ko, kwargs))
2136
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002137 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002138 S((pk, po, args, ko, kwargs))
2139
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002140 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002141 S((po, args, pk, ko, kwargs))
2142
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002143 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002144 S((args, po, pk, ko, kwargs))
2145
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002146 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002147 S((po, pk, args, kwargs, ko))
2148
2149 kwargs2 = kwargs.replace(name='args')
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002150 with self.assertRaisesRegex(ValueError, 'duplicate parameter name'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002151 S((po, pk, args, kwargs2, ko))
2152
Yury Selivanov07a9e452014-01-29 10:58:16 -05002153 with self.assertRaisesRegex(ValueError, 'follows default argument'):
2154 S((pod, po))
2155
2156 with self.assertRaisesRegex(ValueError, 'follows default argument'):
2157 S((po, pkd, pk))
2158
2159 with self.assertRaisesRegex(ValueError, 'follows default argument'):
2160 S((pkd, pk))
2161
Yury Selivanov374375d2014-03-27 12:41:53 -04002162 self.assertTrue(repr(sig).startswith('<Signature'))
Yury Selivanov0cd2bf42015-05-15 12:55:20 -04002163 self.assertTrue('(po, pk' in repr(sig))
Yury Selivanov374375d2014-03-27 12:41:53 -04002164
Yury Selivanova5d63dd2014-03-27 11:31:43 -04002165 def test_signature_object_pickle(self):
2166 def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
2167 foo_partial = functools.partial(foo, a=1)
2168
2169 sig = inspect.signature(foo_partial)
Yury Selivanova5d63dd2014-03-27 11:31:43 -04002170
2171 for ver in range(pickle.HIGHEST_PROTOCOL + 1):
2172 with self.subTest(pickle_ver=ver, subclass=False):
2173 sig_pickled = pickle.loads(pickle.dumps(sig, ver))
2174 self.assertEqual(sig, sig_pickled)
Yury Selivanova5d63dd2014-03-27 11:31:43 -04002175
2176 # Test that basic sub-classing works
2177 sig = inspect.signature(foo)
2178 myparam = MyParameter(name='z', kind=inspect.Parameter.POSITIONAL_ONLY)
2179 myparams = collections.OrderedDict(sig.parameters, a=myparam)
2180 mysig = MySignature().replace(parameters=myparams.values(),
2181 return_annotation=sig.return_annotation)
2182 self.assertTrue(isinstance(mysig, MySignature))
2183 self.assertTrue(isinstance(mysig.parameters['z'], MyParameter))
2184
2185 for ver in range(pickle.HIGHEST_PROTOCOL + 1):
2186 with self.subTest(pickle_ver=ver, subclass=True):
2187 sig_pickled = pickle.loads(pickle.dumps(mysig, ver))
2188 self.assertEqual(mysig, sig_pickled)
2189 self.assertTrue(isinstance(sig_pickled, MySignature))
2190 self.assertTrue(isinstance(sig_pickled.parameters['z'],
2191 MyParameter))
2192
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002193 def test_signature_immutability(self):
2194 def test(a):
2195 pass
2196 sig = inspect.signature(test)
2197
2198 with self.assertRaises(AttributeError):
2199 sig.foo = 'bar'
2200
2201 with self.assertRaises(TypeError):
2202 sig.parameters['a'] = None
2203
2204 def test_signature_on_noarg(self):
2205 def test():
2206 pass
2207 self.assertEqual(self.signature(test), ((), ...))
2208
2209 def test_signature_on_wargs(self):
2210 def test(a, b:'foo') -> 123:
2211 pass
2212 self.assertEqual(self.signature(test),
2213 ((('a', ..., ..., "positional_or_keyword"),
Batuhan Taskaya044a1042020-10-06 23:03:02 +03002214 ('b', ..., repr('foo'), "positional_or_keyword")),
2215 '123'))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002216
2217 def test_signature_on_wkwonly(self):
2218 def test(*, a:float, b:str) -> int:
2219 pass
2220 self.assertEqual(self.signature(test),
2221 ((('a', ..., float, "keyword_only"),
2222 ('b', ..., str, "keyword_only")),
2223 int))
2224
2225 def test_signature_on_complex_args(self):
2226 def test(a, b:'foo'=10, *args:'bar', spam:'baz', ham=123, **kwargs:int):
2227 pass
2228 self.assertEqual(self.signature(test),
2229 ((('a', ..., ..., "positional_or_keyword"),
Batuhan Taskaya044a1042020-10-06 23:03:02 +03002230 ('b', 10, repr('foo'), "positional_or_keyword"),
2231 ('args', ..., repr('bar'), "var_positional"),
2232 ('spam', ..., repr('baz'), "keyword_only"),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002233 ('ham', 123, ..., "keyword_only"),
Batuhan Taskaya044a1042020-10-06 23:03:02 +03002234 ('kwargs', ..., 'int', "var_keyword")),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002235 ...))
2236
Dong-hee Na378d7062017-05-18 04:00:51 +09002237 def test_signature_without_self(self):
2238 def test_args_only(*args): # NOQA
2239 pass
2240
2241 def test_args_kwargs_only(*args, **kwargs): # NOQA
2242 pass
2243
2244 class A:
2245 @classmethod
2246 def test_classmethod(*args): # NOQA
2247 pass
2248
2249 @staticmethod
2250 def test_staticmethod(*args): # NOQA
2251 pass
2252
2253 f1 = functools.partialmethod((test_classmethod), 1)
2254 f2 = functools.partialmethod((test_args_only), 1)
2255 f3 = functools.partialmethod((test_staticmethod), 1)
2256 f4 = functools.partialmethod((test_args_kwargs_only),1)
2257
2258 self.assertEqual(self.signature(test_args_only),
2259 ((('args', ..., ..., 'var_positional'),), ...))
2260 self.assertEqual(self.signature(test_args_kwargs_only),
2261 ((('args', ..., ..., 'var_positional'),
2262 ('kwargs', ..., ..., 'var_keyword')), ...))
2263 self.assertEqual(self.signature(A.f1),
2264 ((('args', ..., ..., 'var_positional'),), ...))
2265 self.assertEqual(self.signature(A.f2),
2266 ((('args', ..., ..., 'var_positional'),), ...))
2267 self.assertEqual(self.signature(A.f3),
2268 ((('args', ..., ..., 'var_positional'),), ...))
Serhiy Storchaka13ad3b72017-09-14 09:38:36 +03002269 self.assertEqual(self.signature(A.f4),
Dong-hee Na378d7062017-05-18 04:00:51 +09002270 ((('args', ..., ..., 'var_positional'),
2271 ('kwargs', ..., ..., 'var_keyword')), ...))
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002272 @cpython_only
Larry Hastingsfcafe432013-11-23 17:35:48 -08002273 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2274 "Signature information for builtins requires docstrings")
2275 def test_signature_on_builtins(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002276 import _testcapi
Larry Hastings16c51912014-01-07 11:53:01 -08002277
Larry Hastings5c661892014-01-24 06:17:25 -08002278 def test_unbound_method(o):
2279 """Use this to test unbound methods (things that should have a self)"""
2280 signature = inspect.signature(o)
2281 self.assertTrue(isinstance(signature, inspect.Signature))
2282 self.assertEqual(list(signature.parameters.values())[0].name, 'self')
2283 return signature
2284
2285 def test_callable(o):
2286 """Use this to test bound methods or normal callables (things that don't expect self)"""
2287 signature = inspect.signature(o)
2288 self.assertTrue(isinstance(signature, inspect.Signature))
2289 if signature.parameters:
2290 self.assertNotEqual(list(signature.parameters.values())[0].name, 'self')
2291 return signature
2292
2293 signature = test_callable(_testcapi.docstring_with_signature_with_defaults)
Larry Hastings16c51912014-01-07 11:53:01 -08002294 def p(name): return signature.parameters[name].default
2295 self.assertEqual(p('s'), 'avocado')
Larry Hastings2a727912014-01-16 11:32:01 -08002296 self.assertEqual(p('b'), b'bytes')
Larry Hastings16c51912014-01-07 11:53:01 -08002297 self.assertEqual(p('d'), 3.14)
2298 self.assertEqual(p('i'), 35)
Larry Hastings16c51912014-01-07 11:53:01 -08002299 self.assertEqual(p('n'), None)
2300 self.assertEqual(p('t'), True)
2301 self.assertEqual(p('f'), False)
Larry Hastings2a727912014-01-16 11:32:01 -08002302 self.assertEqual(p('local'), 3)
2303 self.assertEqual(p('sys'), sys.maxsize)
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +02002304 self.assertNotIn('exp', signature.parameters)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002305
Larry Hastings5c661892014-01-24 06:17:25 -08002306 test_callable(object)
2307
2308 # normal method
2309 # (PyMethodDescr_Type, "method_descriptor")
2310 test_unbound_method(_pickle.Pickler.dump)
2311 d = _pickle.Pickler(io.StringIO())
2312 test_callable(d.dump)
2313
2314 # static method
Serhiy Storchaka279f4462019-09-14 12:24:05 +03002315 test_callable(bytes.maketrans)
2316 test_callable(b'abc'.maketrans)
Larry Hastings5c661892014-01-24 06:17:25 -08002317
2318 # class method
2319 test_callable(dict.fromkeys)
2320 test_callable({}.fromkeys)
2321
2322 # wrapper around slot (PyWrapperDescr_Type, "wrapper_descriptor")
2323 test_unbound_method(type.__call__)
2324 test_unbound_method(int.__add__)
2325 test_callable((3).__add__)
2326
2327 # _PyMethodWrapper_Type
2328 # support for 'method-wrapper'
2329 test_callable(min.__call__)
2330
Larry Hastings2623c8c2014-02-08 22:15:29 -08002331 # This doesn't work now.
2332 # (We don't have a valid signature for "type" in 3.4)
2333 with self.assertRaisesRegex(ValueError, "no signature found"):
2334 class ThisWorksNow:
2335 __call__ = type
2336 test_callable(ThisWorksNow())
Larry Hastings5c661892014-01-24 06:17:25 -08002337
Yury Selivanov056e2652014-03-02 12:25:27 -05002338 # Regression test for issue #20786
2339 test_unbound_method(dict.__delitem__)
2340 test_unbound_method(property.__delete__)
2341
Zachary Ware8ef887c2015-04-13 18:22:35 -05002342 # Regression test for issue #20586
2343 test_callable(_testcapi.docstring_with_signature_but_no_doc)
2344
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002345 @cpython_only
Yury Selivanov76c6c592014-01-29 10:52:57 -05002346 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2347 "Signature information for builtins requires docstrings")
2348 def test_signature_on_decorated_builtins(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002349 import _testcapi
Yury Selivanov76c6c592014-01-29 10:52:57 -05002350 func = _testcapi.docstring_with_signature_with_defaults
2351
2352 def decorator(func):
2353 @functools.wraps(func)
2354 def wrapper(*args, **kwargs) -> int:
2355 return func(*args, **kwargs)
2356 return wrapper
2357
2358 decorated_func = decorator(func)
2359
2360 self.assertEqual(inspect.signature(func),
2361 inspect.signature(decorated_func))
Larry Hastings5c661892014-01-24 06:17:25 -08002362
Yury Selivanovbcd4fc12015-05-20 14:30:08 -04002363 def wrapper_like(*args, **kwargs) -> int: pass
2364 self.assertEqual(inspect.signature(decorated_func,
2365 follow_wrapped=False),
2366 inspect.signature(wrapper_like))
2367
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002368 @cpython_only
Larry Hastings5c661892014-01-24 06:17:25 -08002369 def test_signature_on_builtins_no_signature(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002370 import _testcapi
Yury Selivanovbf304fc2015-05-30 17:08:36 -04002371 with self.assertRaisesRegex(ValueError,
2372 'no signature found for builtin'):
Larry Hastings5c661892014-01-24 06:17:25 -08002373 inspect.signature(_testcapi.docstring_no_signature)
2374
Yury Selivanovbf304fc2015-05-30 17:08:36 -04002375 with self.assertRaisesRegex(ValueError,
2376 'no signature found for builtin'):
2377 inspect.signature(str)
2378
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002379 def test_signature_on_non_function(self):
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002380 with self.assertRaisesRegex(TypeError, 'is not a callable object'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002381 inspect.signature(42)
2382
Yury Selivanov63da7c72014-01-31 14:48:37 -05002383 def test_signature_from_functionlike_object(self):
2384 def func(a,b, *args, kwonly=True, kwonlyreq, **kwargs):
2385 pass
2386
2387 class funclike:
2388 # Has to be callable, and have correct
2389 # __code__, __annotations__, __defaults__, __name__,
2390 # and __kwdefaults__ attributes
2391
2392 def __init__(self, func):
2393 self.__name__ = func.__name__
2394 self.__code__ = func.__code__
2395 self.__annotations__ = func.__annotations__
2396 self.__defaults__ = func.__defaults__
2397 self.__kwdefaults__ = func.__kwdefaults__
2398 self.func = func
2399
2400 def __call__(self, *args, **kwargs):
2401 return self.func(*args, **kwargs)
2402
Yury Selivanov57c74fc2015-05-20 23:07:02 -04002403 sig_func = inspect.Signature.from_callable(func)
Yury Selivanov63da7c72014-01-31 14:48:37 -05002404
Yury Selivanov57c74fc2015-05-20 23:07:02 -04002405 sig_funclike = inspect.Signature.from_callable(funclike(func))
Yury Selivanov63da7c72014-01-31 14:48:37 -05002406 self.assertEqual(sig_funclike, sig_func)
2407
2408 sig_funclike = inspect.signature(funclike(func))
2409 self.assertEqual(sig_funclike, sig_func)
2410
2411 # If object is not a duck type of function, then
2412 # signature will try to get a signature for its '__call__'
2413 # method
2414 fl = funclike(func)
2415 del fl.__defaults__
2416 self.assertEqual(self.signature(fl),
2417 ((('args', ..., ..., "var_positional"),
2418 ('kwargs', ..., ..., "var_keyword")),
2419 ...))
2420
Yury Selivanova773de02014-02-21 18:30:53 -05002421 # Test with cython-like builtins:
2422 _orig_isdesc = inspect.ismethoddescriptor
2423 def _isdesc(obj):
2424 if hasattr(obj, '_builtinmock'):
2425 return True
2426 return _orig_isdesc(obj)
2427
2428 with unittest.mock.patch('inspect.ismethoddescriptor', _isdesc):
2429 builtin_func = funclike(func)
2430 # Make sure that our mock setup is working
2431 self.assertFalse(inspect.ismethoddescriptor(builtin_func))
2432 builtin_func._builtinmock = True
2433 self.assertTrue(inspect.ismethoddescriptor(builtin_func))
2434 self.assertEqual(inspect.signature(builtin_func), sig_func)
2435
Yury Selivanov63da7c72014-01-31 14:48:37 -05002436 def test_signature_functionlike_class(self):
2437 # We only want to duck type function-like objects,
2438 # not classes.
2439
2440 def func(a,b, *args, kwonly=True, kwonlyreq, **kwargs):
2441 pass
2442
2443 class funclike:
2444 def __init__(self, marker):
2445 pass
2446
2447 __name__ = func.__name__
2448 __code__ = func.__code__
2449 __annotations__ = func.__annotations__
2450 __defaults__ = func.__defaults__
2451 __kwdefaults__ = func.__kwdefaults__
2452
Yury Selivanov63da7c72014-01-31 14:48:37 -05002453 self.assertEqual(str(inspect.signature(funclike)), '(marker)')
2454
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002455 def test_signature_on_method(self):
2456 class Test:
Yury Selivanov62560fb2014-01-28 12:26:24 -05002457 def __init__(*args):
2458 pass
2459 def m1(self, arg1, arg2=1) -> int:
2460 pass
2461 def m2(*args):
2462 pass
2463 def __call__(*, a):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002464 pass
2465
Yury Selivanov62560fb2014-01-28 12:26:24 -05002466 self.assertEqual(self.signature(Test().m1),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002467 ((('arg1', ..., ..., "positional_or_keyword"),
2468 ('arg2', 1, ..., "positional_or_keyword")),
2469 int))
2470
Yury Selivanov62560fb2014-01-28 12:26:24 -05002471 self.assertEqual(self.signature(Test().m2),
2472 ((('args', ..., ..., "var_positional"),),
2473 ...))
2474
2475 self.assertEqual(self.signature(Test),
2476 ((('args', ..., ..., "var_positional"),),
2477 ...))
2478
2479 with self.assertRaisesRegex(ValueError, 'invalid method signature'):
2480 self.signature(Test())
2481
Yury Selivanov46c759d2015-05-27 21:56:53 -04002482 def test_signature_wrapped_bound_method(self):
2483 # Issue 24298
2484 class Test:
2485 def m1(self, arg1, arg2=1) -> int:
2486 pass
2487 @functools.wraps(Test().m1)
2488 def m1d(*args, **kwargs):
2489 pass
2490 self.assertEqual(self.signature(m1d),
2491 ((('arg1', ..., ..., "positional_or_keyword"),
2492 ('arg2', 1, ..., "positional_or_keyword")),
2493 int))
2494
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002495 def test_signature_on_classmethod(self):
2496 class Test:
2497 @classmethod
2498 def foo(cls, arg1, *, arg2=1):
2499 pass
2500
2501 meth = Test().foo
2502 self.assertEqual(self.signature(meth),
2503 ((('arg1', ..., ..., "positional_or_keyword"),
2504 ('arg2', 1, ..., "keyword_only")),
2505 ...))
2506
2507 meth = Test.foo
2508 self.assertEqual(self.signature(meth),
2509 ((('arg1', ..., ..., "positional_or_keyword"),
2510 ('arg2', 1, ..., "keyword_only")),
2511 ...))
2512
2513 def test_signature_on_staticmethod(self):
2514 class Test:
2515 @staticmethod
2516 def foo(cls, *, arg):
2517 pass
2518
2519 meth = Test().foo
2520 self.assertEqual(self.signature(meth),
2521 ((('cls', ..., ..., "positional_or_keyword"),
2522 ('arg', ..., ..., "keyword_only")),
2523 ...))
2524
2525 meth = Test.foo
2526 self.assertEqual(self.signature(meth),
2527 ((('cls', ..., ..., "positional_or_keyword"),
2528 ('arg', ..., ..., "keyword_only")),
2529 ...))
2530
2531 def test_signature_on_partial(self):
2532 from functools import partial
2533
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002534 Parameter = inspect.Parameter
2535
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002536 def test():
2537 pass
2538
2539 self.assertEqual(self.signature(partial(test)), ((), ...))
2540
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002541 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002542 inspect.signature(partial(test, 1))
2543
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002544 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002545 inspect.signature(partial(test, a=1))
2546
2547 def test(a, b, *, c, d):
2548 pass
2549
2550 self.assertEqual(self.signature(partial(test)),
2551 ((('a', ..., ..., "positional_or_keyword"),
2552 ('b', ..., ..., "positional_or_keyword"),
2553 ('c', ..., ..., "keyword_only"),
2554 ('d', ..., ..., "keyword_only")),
2555 ...))
2556
2557 self.assertEqual(self.signature(partial(test, 1)),
2558 ((('b', ..., ..., "positional_or_keyword"),
2559 ('c', ..., ..., "keyword_only"),
2560 ('d', ..., ..., "keyword_only")),
2561 ...))
2562
2563 self.assertEqual(self.signature(partial(test, 1, c=2)),
2564 ((('b', ..., ..., "positional_or_keyword"),
2565 ('c', 2, ..., "keyword_only"),
2566 ('d', ..., ..., "keyword_only")),
2567 ...))
2568
2569 self.assertEqual(self.signature(partial(test, b=1, c=2)),
2570 ((('a', ..., ..., "positional_or_keyword"),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002571 ('b', 1, ..., "keyword_only"),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002572 ('c', 2, ..., "keyword_only"),
2573 ('d', ..., ..., "keyword_only")),
2574 ...))
2575
2576 self.assertEqual(self.signature(partial(test, 0, b=1, c=2)),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002577 ((('b', 1, ..., "keyword_only"),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002578 ('c', 2, ..., "keyword_only"),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002579 ('d', ..., ..., "keyword_only")),
2580 ...))
2581
2582 self.assertEqual(self.signature(partial(test, a=1)),
2583 ((('a', 1, ..., "keyword_only"),
2584 ('b', ..., ..., "keyword_only"),
2585 ('c', ..., ..., "keyword_only"),
2586 ('d', ..., ..., "keyword_only")),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002587 ...))
2588
2589 def test(a, *args, b, **kwargs):
2590 pass
2591
2592 self.assertEqual(self.signature(partial(test, 1)),
2593 ((('args', ..., ..., "var_positional"),
2594 ('b', ..., ..., "keyword_only"),
2595 ('kwargs', ..., ..., "var_keyword")),
2596 ...))
2597
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002598 self.assertEqual(self.signature(partial(test, a=1)),
2599 ((('a', 1, ..., "keyword_only"),
2600 ('b', ..., ..., "keyword_only"),
2601 ('kwargs', ..., ..., "var_keyword")),
2602 ...))
2603
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002604 self.assertEqual(self.signature(partial(test, 1, 2, 3)),
2605 ((('args', ..., ..., "var_positional"),
2606 ('b', ..., ..., "keyword_only"),
2607 ('kwargs', ..., ..., "var_keyword")),
2608 ...))
2609
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002610 self.assertEqual(self.signature(partial(test, 1, 2, 3, test=True)),
2611 ((('args', ..., ..., "var_positional"),
2612 ('b', ..., ..., "keyword_only"),
2613 ('kwargs', ..., ..., "var_keyword")),
2614 ...))
2615
2616 self.assertEqual(self.signature(partial(test, 1, 2, 3, test=1, b=0)),
2617 ((('args', ..., ..., "var_positional"),
2618 ('b', 0, ..., "keyword_only"),
2619 ('kwargs', ..., ..., "var_keyword")),
2620 ...))
2621
2622 self.assertEqual(self.signature(partial(test, b=0)),
2623 ((('a', ..., ..., "positional_or_keyword"),
2624 ('args', ..., ..., "var_positional"),
2625 ('b', 0, ..., "keyword_only"),
2626 ('kwargs', ..., ..., "var_keyword")),
2627 ...))
2628
2629 self.assertEqual(self.signature(partial(test, b=0, test=1)),
2630 ((('a', ..., ..., "positional_or_keyword"),
2631 ('args', ..., ..., "var_positional"),
2632 ('b', 0, ..., "keyword_only"),
2633 ('kwargs', ..., ..., "var_keyword")),
2634 ...))
2635
2636 def test(a, b, c:int) -> 42:
2637 pass
2638
2639 sig = test.__signature__ = inspect.signature(test)
2640
2641 self.assertEqual(self.signature(partial(partial(test, 1))),
2642 ((('b', ..., ..., "positional_or_keyword"),
Batuhan Taskaya044a1042020-10-06 23:03:02 +03002643 ('c', ..., 'int', "positional_or_keyword")),
2644 '42'))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002645
2646 self.assertEqual(self.signature(partial(partial(test, 1), 2)),
Batuhan Taskaya044a1042020-10-06 23:03:02 +03002647 ((('c', ..., 'int', "positional_or_keyword"),),
2648 '42'))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002649
2650 psig = inspect.signature(partial(partial(test, 1), 2))
2651
2652 def foo(a):
2653 return a
2654 _foo = partial(partial(foo, a=10), a=20)
2655 self.assertEqual(self.signature(_foo),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002656 ((('a', 20, ..., "keyword_only"),),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002657 ...))
2658 # check that we don't have any side-effects in signature(),
2659 # and the partial object is still functioning
2660 self.assertEqual(_foo(), 20)
2661
2662 def foo(a, b, c):
2663 return a, b, c
2664 _foo = partial(partial(foo, 1, b=20), b=30)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002665
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002666 self.assertEqual(self.signature(_foo),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002667 ((('b', 30, ..., "keyword_only"),
2668 ('c', ..., ..., "keyword_only")),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002669 ...))
2670 self.assertEqual(_foo(c=10), (1, 30, 10))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002671
2672 def foo(a, b, c, *, d):
2673 return a, b, c, d
2674 _foo = partial(partial(foo, d=20, c=20), b=10, d=30)
2675 self.assertEqual(self.signature(_foo),
2676 ((('a', ..., ..., "positional_or_keyword"),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002677 ('b', 10, ..., "keyword_only"),
2678 ('c', 20, ..., "keyword_only"),
2679 ('d', 30, ..., "keyword_only"),
2680 ),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002681 ...))
2682 ba = inspect.signature(_foo).bind(a=200, b=11)
2683 self.assertEqual(_foo(*ba.args, **ba.kwargs), (200, 11, 20, 30))
2684
2685 def foo(a=1, b=2, c=3):
2686 return a, b, c
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002687 _foo = partial(foo, c=13) # (a=1, b=2, *, c=13)
2688
2689 ba = inspect.signature(_foo).bind(a=11)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002690 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 2, 13))
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002691
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002692 ba = inspect.signature(_foo).bind(11, 12)
2693 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002694
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002695 ba = inspect.signature(_foo).bind(11, b=12)
2696 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002697
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002698 ba = inspect.signature(_foo).bind(b=12)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002699 self.assertEqual(_foo(*ba.args, **ba.kwargs), (1, 12, 13))
2700
2701 _foo = partial(_foo, b=10, c=20)
2702 ba = inspect.signature(_foo).bind(12)
2703 self.assertEqual(_foo(*ba.args, **ba.kwargs), (12, 10, 20))
2704
2705
2706 def foo(a, b, c, d, **kwargs):
2707 pass
2708 sig = inspect.signature(foo)
2709 params = sig.parameters.copy()
2710 params['a'] = params['a'].replace(kind=Parameter.POSITIONAL_ONLY)
2711 params['b'] = params['b'].replace(kind=Parameter.POSITIONAL_ONLY)
2712 foo.__signature__ = inspect.Signature(params.values())
2713 sig = inspect.signature(foo)
2714 self.assertEqual(str(sig), '(a, b, /, c, d, **kwargs)')
2715
2716 self.assertEqual(self.signature(partial(foo, 1)),
2717 ((('b', ..., ..., 'positional_only'),
2718 ('c', ..., ..., 'positional_or_keyword'),
2719 ('d', ..., ..., 'positional_or_keyword'),
2720 ('kwargs', ..., ..., 'var_keyword')),
2721 ...))
2722
2723 self.assertEqual(self.signature(partial(foo, 1, 2)),
2724 ((('c', ..., ..., 'positional_or_keyword'),
2725 ('d', ..., ..., 'positional_or_keyword'),
2726 ('kwargs', ..., ..., 'var_keyword')),
2727 ...))
2728
2729 self.assertEqual(self.signature(partial(foo, 1, 2, 3)),
2730 ((('d', ..., ..., 'positional_or_keyword'),
2731 ('kwargs', ..., ..., 'var_keyword')),
2732 ...))
2733
2734 self.assertEqual(self.signature(partial(foo, 1, 2, c=3)),
2735 ((('c', 3, ..., 'keyword_only'),
2736 ('d', ..., ..., 'keyword_only'),
2737 ('kwargs', ..., ..., 'var_keyword')),
2738 ...))
2739
2740 self.assertEqual(self.signature(partial(foo, 1, c=3)),
2741 ((('b', ..., ..., 'positional_only'),
2742 ('c', 3, ..., 'keyword_only'),
2743 ('d', ..., ..., 'keyword_only'),
2744 ('kwargs', ..., ..., 'var_keyword')),
2745 ...))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002746
Yury Selivanovda5fe4f2014-01-27 17:28:37 -05002747 def test_signature_on_partialmethod(self):
2748 from functools import partialmethod
2749
2750 class Spam:
2751 def test():
2752 pass
2753 ham = partialmethod(test)
2754
2755 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
2756 inspect.signature(Spam.ham)
2757
2758 class Spam:
2759 def test(it, a, *, c) -> 'spam':
2760 pass
2761 ham = partialmethod(test, c=1)
2762
2763 self.assertEqual(self.signature(Spam.ham),
2764 ((('it', ..., ..., 'positional_or_keyword'),
2765 ('a', ..., ..., 'positional_or_keyword'),
2766 ('c', 1, ..., 'keyword_only')),
Batuhan Taskaya044a1042020-10-06 23:03:02 +03002767 repr('spam')))
Yury Selivanovda5fe4f2014-01-27 17:28:37 -05002768
2769 self.assertEqual(self.signature(Spam().ham),
2770 ((('a', ..., ..., 'positional_or_keyword'),
2771 ('c', 1, ..., 'keyword_only')),
Batuhan Taskaya044a1042020-10-06 23:03:02 +03002772 repr('spam')))
Yury Selivanovda5fe4f2014-01-27 17:28:37 -05002773
Yury Selivanov8a387212018-03-06 12:59:45 -05002774 class Spam:
2775 def test(self: 'anno', x):
2776 pass
2777
2778 g = partialmethod(test, 1)
2779
2780 self.assertEqual(self.signature(Spam.g),
Batuhan Taskaya044a1042020-10-06 23:03:02 +03002781 ((('self', ..., repr('anno'), 'positional_or_keyword'),),
Yury Selivanov8a387212018-03-06 12:59:45 -05002782 ...))
2783
Yury Selivanov0486f812014-01-29 12:18:59 -05002784 def test_signature_on_fake_partialmethod(self):
2785 def foo(a): pass
2786 foo._partialmethod = 'spam'
2787 self.assertEqual(str(inspect.signature(foo)), '(a)')
2788
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002789 def test_signature_on_decorated(self):
2790 import functools
2791
2792 def decorator(func):
2793 @functools.wraps(func)
2794 def wrapper(*args, **kwargs) -> int:
2795 return func(*args, **kwargs)
2796 return wrapper
2797
2798 class Foo:
2799 @decorator
2800 def bar(self, a, b):
2801 pass
2802
2803 self.assertEqual(self.signature(Foo.bar),
2804 ((('self', ..., ..., "positional_or_keyword"),
2805 ('a', ..., ..., "positional_or_keyword"),
2806 ('b', ..., ..., "positional_or_keyword")),
2807 ...))
2808
2809 self.assertEqual(self.signature(Foo().bar),
2810 ((('a', ..., ..., "positional_or_keyword"),
2811 ('b', ..., ..., "positional_or_keyword")),
2812 ...))
2813
Yury Selivanovbcd4fc12015-05-20 14:30:08 -04002814 self.assertEqual(self.signature(Foo.bar, follow_wrapped=False),
2815 ((('args', ..., ..., "var_positional"),
2816 ('kwargs', ..., ..., "var_keyword")),
2817 ...)) # functools.wraps will copy __annotations__
2818 # from "func" to "wrapper", hence no
2819 # return_annotation
2820
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002821 # Test that we handle method wrappers correctly
2822 def decorator(func):
2823 @functools.wraps(func)
2824 def wrapper(*args, **kwargs) -> int:
2825 return func(42, *args, **kwargs)
2826 sig = inspect.signature(func)
2827 new_params = tuple(sig.parameters.values())[1:]
2828 wrapper.__signature__ = sig.replace(parameters=new_params)
2829 return wrapper
2830
2831 class Foo:
2832 @decorator
2833 def __call__(self, a, b):
2834 pass
2835
2836 self.assertEqual(self.signature(Foo.__call__),
2837 ((('a', ..., ..., "positional_or_keyword"),
2838 ('b', ..., ..., "positional_or_keyword")),
2839 ...))
2840
2841 self.assertEqual(self.signature(Foo().__call__),
2842 ((('b', ..., ..., "positional_or_keyword"),),
2843 ...))
2844
Nick Coghlane8c45d62013-07-28 20:00:01 +10002845 # Test we handle __signature__ partway down the wrapper stack
2846 def wrapped_foo_call():
2847 pass
2848 wrapped_foo_call.__wrapped__ = Foo.__call__
2849
2850 self.assertEqual(self.signature(wrapped_foo_call),
2851 ((('a', ..., ..., "positional_or_keyword"),
2852 ('b', ..., ..., "positional_or_keyword")),
2853 ...))
2854
2855
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002856 def test_signature_on_class(self):
2857 class C:
2858 def __init__(self, a):
2859 pass
2860
2861 self.assertEqual(self.signature(C),
2862 ((('a', ..., ..., "positional_or_keyword"),),
2863 ...))
2864
2865 class CM(type):
2866 def __call__(cls, a):
2867 pass
2868 class C(metaclass=CM):
2869 def __init__(self, b):
2870 pass
2871
2872 self.assertEqual(self.signature(C),
2873 ((('a', ..., ..., "positional_or_keyword"),),
2874 ...))
2875
2876 class CM(type):
2877 def __new__(mcls, name, bases, dct, *, foo=1):
2878 return super().__new__(mcls, name, bases, dct)
2879 class C(metaclass=CM):
2880 def __init__(self, b):
2881 pass
2882
2883 self.assertEqual(self.signature(C),
2884 ((('b', ..., ..., "positional_or_keyword"),),
2885 ...))
2886
2887 self.assertEqual(self.signature(CM),
2888 ((('name', ..., ..., "positional_or_keyword"),
2889 ('bases', ..., ..., "positional_or_keyword"),
2890 ('dct', ..., ..., "positional_or_keyword"),
2891 ('foo', 1, ..., "keyword_only")),
2892 ...))
2893
2894 class CMM(type):
2895 def __new__(mcls, name, bases, dct, *, foo=1):
2896 return super().__new__(mcls, name, bases, dct)
2897 def __call__(cls, nm, bs, dt):
2898 return type(nm, bs, dt)
2899 class CM(type, metaclass=CMM):
2900 def __new__(mcls, name, bases, dct, *, bar=2):
2901 return super().__new__(mcls, name, bases, dct)
2902 class C(metaclass=CM):
2903 def __init__(self, b):
2904 pass
2905
2906 self.assertEqual(self.signature(CMM),
2907 ((('name', ..., ..., "positional_or_keyword"),
2908 ('bases', ..., ..., "positional_or_keyword"),
2909 ('dct', ..., ..., "positional_or_keyword"),
2910 ('foo', 1, ..., "keyword_only")),
2911 ...))
2912
2913 self.assertEqual(self.signature(CM),
2914 ((('nm', ..., ..., "positional_or_keyword"),
2915 ('bs', ..., ..., "positional_or_keyword"),
2916 ('dt', ..., ..., "positional_or_keyword")),
2917 ...))
2918
2919 self.assertEqual(self.signature(C),
2920 ((('b', ..., ..., "positional_or_keyword"),),
2921 ...))
2922
2923 class CM(type):
2924 def __init__(cls, name, bases, dct, *, bar=2):
2925 return super().__init__(name, bases, dct)
2926 class C(metaclass=CM):
2927 def __init__(self, b):
2928 pass
2929
2930 self.assertEqual(self.signature(CM),
2931 ((('name', ..., ..., "positional_or_keyword"),
2932 ('bases', ..., ..., "positional_or_keyword"),
2933 ('dct', ..., ..., "positional_or_keyword"),
2934 ('bar', 2, ..., "keyword_only")),
2935 ...))
2936
Yury Selivanov145dff82014-02-01 13:49:29 -05002937 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2938 "Signature information for builtins requires docstrings")
2939 def test_signature_on_class_without_init(self):
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002940 # Test classes without user-defined __init__ or __new__
2941 class C: pass
2942 self.assertEqual(str(inspect.signature(C)), '()')
2943 class D(C): pass
2944 self.assertEqual(str(inspect.signature(D)), '()')
2945
2946 # Test meta-classes without user-defined __init__ or __new__
2947 class C(type): pass
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002948 class D(C): pass
Larry Hastings2623c8c2014-02-08 22:15:29 -08002949 with self.assertRaisesRegex(ValueError, "callable.*is not supported"):
2950 self.assertEqual(inspect.signature(C), None)
2951 with self.assertRaisesRegex(ValueError, "callable.*is not supported"):
2952 self.assertEqual(inspect.signature(D), None)
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002953
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002954 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2955 "Signature information for builtins requires docstrings")
2956 def test_signature_on_builtin_class(self):
Antoine Pitrou91f43802019-05-26 17:10:09 +02002957 expected = ('(file, protocol=None, fix_imports=True, '
2958 'buffer_callback=None)')
2959 self.assertEqual(str(inspect.signature(_pickle.Pickler)), expected)
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002960
2961 class P(_pickle.Pickler): pass
2962 class EmptyTrait: pass
2963 class P2(EmptyTrait, P): pass
Antoine Pitrou91f43802019-05-26 17:10:09 +02002964 self.assertEqual(str(inspect.signature(P)), expected)
2965 self.assertEqual(str(inspect.signature(P2)), expected)
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002966
2967 class P3(P2):
2968 def __init__(self, spam):
2969 pass
2970 self.assertEqual(str(inspect.signature(P3)), '(spam)')
2971
2972 class MetaP(type):
2973 def __call__(cls, foo, bar):
2974 pass
2975 class P4(P2, metaclass=MetaP):
2976 pass
2977 self.assertEqual(str(inspect.signature(P4)), '(foo, bar)')
2978
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002979 def test_signature_on_callable_objects(self):
2980 class Foo:
2981 def __call__(self, a):
2982 pass
2983
2984 self.assertEqual(self.signature(Foo()),
2985 ((('a', ..., ..., "positional_or_keyword"),),
2986 ...))
2987
2988 class Spam:
2989 pass
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002990 with self.assertRaisesRegex(TypeError, "is not a callable object"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002991 inspect.signature(Spam())
2992
2993 class Bar(Spam, Foo):
2994 pass
2995
2996 self.assertEqual(self.signature(Bar()),
2997 ((('a', ..., ..., "positional_or_keyword"),),
2998 ...))
2999
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003000 class Wrapped:
3001 pass
3002 Wrapped.__wrapped__ = lambda a: None
3003 self.assertEqual(self.signature(Wrapped),
3004 ((('a', ..., ..., "positional_or_keyword"),),
3005 ...))
Nick Coghlane8c45d62013-07-28 20:00:01 +10003006 # wrapper loop:
3007 Wrapped.__wrapped__ = Wrapped
3008 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3009 self.signature(Wrapped)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003010
3011 def test_signature_on_lambdas(self):
3012 self.assertEqual(self.signature((lambda a=10: a)),
3013 ((('a', 10, ..., "positional_or_keyword"),),
3014 ...))
3015
3016 def test_signature_equality(self):
3017 def foo(a, *, b:int) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003018 self.assertFalse(inspect.signature(foo) == 42)
3019 self.assertTrue(inspect.signature(foo) != 42)
Serhiy Storchaka7d44e7a2019-08-08 08:43:18 +03003020 self.assertTrue(inspect.signature(foo) == ALWAYS_EQ)
3021 self.assertFalse(inspect.signature(foo) != ALWAYS_EQ)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003022
3023 def bar(a, *, b:int) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003024 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
3025 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003026 self.assertEqual(
3027 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003028
3029 def bar(a, *, b:int) -> int: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003030 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
3031 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003032 self.assertNotEqual(
3033 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003034
3035 def bar(a, *, b:int): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003036 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
3037 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003038 self.assertNotEqual(
3039 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003040
3041 def bar(a, *, b:int=42) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003042 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
3043 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003044 self.assertNotEqual(
3045 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003046
3047 def bar(a, *, c) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003048 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
3049 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003050 self.assertNotEqual(
3051 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003052
3053 def bar(a, b:int) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003054 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
3055 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003056 self.assertNotEqual(
3057 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003058 def spam(b:int, a) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003059 self.assertFalse(inspect.signature(spam) == inspect.signature(bar))
3060 self.assertTrue(inspect.signature(spam) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003061 self.assertNotEqual(
3062 hash(inspect.signature(spam)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003063
3064 def foo(*, a, b, c): pass
3065 def bar(*, c, b, a): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003066 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
3067 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003068 self.assertEqual(
3069 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003070
3071 def foo(*, a=1, b, c): pass
3072 def bar(*, c, b, a=1): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003073 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
3074 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003075 self.assertEqual(
3076 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003077
3078 def foo(pos, *, a=1, b, c): pass
3079 def bar(pos, *, c, b, a=1): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003080 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
3081 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003082 self.assertEqual(
3083 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003084
3085 def foo(pos, *, a, b, c): pass
3086 def bar(pos, *, c, b, a=1): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003087 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
3088 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003089 self.assertNotEqual(
3090 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003091
3092 def foo(pos, *args, a=42, b, c, **kwargs:int): pass
3093 def bar(pos, *args, c, b, a=42, **kwargs:int): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003094 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
3095 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003096 self.assertEqual(
3097 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003098
Yury Selivanov67ae50e2014-04-08 11:46:50 -04003099 def test_signature_hashable(self):
3100 S = inspect.Signature
3101 P = inspect.Parameter
3102
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003103 def foo(a): pass
Yury Selivanov67ae50e2014-04-08 11:46:50 -04003104 foo_sig = inspect.signature(foo)
3105
3106 manual_sig = S(parameters=[P('a', P.POSITIONAL_OR_KEYWORD)])
3107
3108 self.assertEqual(hash(foo_sig), hash(manual_sig))
3109 self.assertNotEqual(hash(foo_sig),
3110 hash(manual_sig.replace(return_annotation='spam')))
3111
3112 def bar(a) -> 1: pass
3113 self.assertNotEqual(hash(foo_sig), hash(inspect.signature(bar)))
3114
3115 def foo(a={}): pass
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003116 with self.assertRaisesRegex(TypeError, 'unhashable type'):
Yury Selivanov67ae50e2014-04-08 11:46:50 -04003117 hash(inspect.signature(foo))
3118
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003119 def test_signature_str(self):
3120 def foo(a:int=1, *, b, c=None, **kwargs) -> 42:
3121 pass
3122 self.assertEqual(str(inspect.signature(foo)),
Batuhan Taskaya044a1042020-10-06 23:03:02 +03003123 '(a: \'int\' = 1, *, b, c=None, **kwargs) -> \'42\'')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003124
3125 def foo(a:int=1, *args, b, c=None, **kwargs) -> 42:
3126 pass
3127 self.assertEqual(str(inspect.signature(foo)),
Batuhan Taskaya044a1042020-10-06 23:03:02 +03003128 '(a: \'int\' = 1, *args, b, c=None, **kwargs) -> \'42\'')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003129
3130 def foo():
3131 pass
3132 self.assertEqual(str(inspect.signature(foo)), '()')
3133
3134 def test_signature_str_positional_only(self):
3135 P = inspect.Parameter
Yury Selivanov2393dca2014-01-27 15:07:58 -05003136 S = inspect.Signature
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003137
3138 def test(a_po, *, b, **kwargs):
3139 return a_po, kwargs
3140
3141 sig = inspect.signature(test)
3142 new_params = list(sig.parameters.values())
3143 new_params[0] = new_params[0].replace(kind=P.POSITIONAL_ONLY)
3144 test.__signature__ = sig.replace(parameters=new_params)
3145
3146 self.assertEqual(str(inspect.signature(test)),
Yury Selivanov2393dca2014-01-27 15:07:58 -05003147 '(a_po, /, *, b, **kwargs)')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003148
Yury Selivanov2393dca2014-01-27 15:07:58 -05003149 self.assertEqual(str(S(parameters=[P('foo', P.POSITIONAL_ONLY)])),
3150 '(foo, /)')
3151
3152 self.assertEqual(str(S(parameters=[
3153 P('foo', P.POSITIONAL_ONLY),
3154 P('bar', P.VAR_KEYWORD)])),
3155 '(foo, /, **bar)')
3156
3157 self.assertEqual(str(S(parameters=[
3158 P('foo', P.POSITIONAL_ONLY),
3159 P('bar', P.VAR_POSITIONAL)])),
3160 '(foo, /, *bar)')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003161
3162 def test_signature_replace_anno(self):
3163 def test() -> 42:
3164 pass
3165
3166 sig = inspect.signature(test)
3167 sig = sig.replace(return_annotation=None)
3168 self.assertIs(sig.return_annotation, None)
3169 sig = sig.replace(return_annotation=sig.empty)
3170 self.assertIs(sig.return_annotation, sig.empty)
Batuhan Taskaya044a1042020-10-06 23:03:02 +03003171 sig = sig.replace(return_annotation='42')
3172 self.assertEqual(sig.return_annotation, '42')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003173 self.assertEqual(sig, inspect.signature(test))
3174
Yury Selivanov34ce99f2014-02-18 12:49:41 -05003175 def test_signature_on_mangled_parameters(self):
3176 class Spam:
3177 def foo(self, __p1:1=2, *, __p2:2=3):
3178 pass
3179 class Ham(Spam):
3180 pass
3181
3182 self.assertEqual(self.signature(Spam.foo),
3183 ((('self', ..., ..., "positional_or_keyword"),
Batuhan Taskaya044a1042020-10-06 23:03:02 +03003184 ('_Spam__p1', 2, '1', "positional_or_keyword"),
3185 ('_Spam__p2', 3, '2', "keyword_only")),
Yury Selivanov34ce99f2014-02-18 12:49:41 -05003186 ...))
3187
3188 self.assertEqual(self.signature(Spam.foo),
3189 self.signature(Ham.foo))
3190
Yury Selivanovda396452014-03-27 12:09:24 -04003191 def test_signature_from_callable_python_obj(self):
3192 class MySignature(inspect.Signature): pass
3193 def foo(a, *, b:1): pass
3194 foo_sig = MySignature.from_callable(foo)
Gregory P. Smith5b9ff7a2019-09-13 17:13:51 +01003195 self.assertIsInstance(foo_sig, MySignature)
3196
3197 def test_signature_from_callable_class(self):
3198 # A regression test for a class inheriting its signature from `object`.
3199 class MySignature(inspect.Signature): pass
3200 class foo: pass
3201 foo_sig = MySignature.from_callable(foo)
3202 self.assertIsInstance(foo_sig, MySignature)
Yury Selivanovda396452014-03-27 12:09:24 -04003203
3204 @unittest.skipIf(MISSING_C_DOCSTRINGS,
3205 "Signature information for builtins requires docstrings")
3206 def test_signature_from_callable_builtin_obj(self):
3207 class MySignature(inspect.Signature): pass
3208 sig = MySignature.from_callable(_pickle.Pickler)
Gregory P. Smith5b9ff7a2019-09-13 17:13:51 +01003209 self.assertIsInstance(sig, MySignature)
Yury Selivanovda396452014-03-27 12:09:24 -04003210
larryhastingsf36ba122018-01-28 11:13:09 -08003211 def test_signature_definition_order_preserved_on_kwonly(self):
3212 for fn in signatures_with_lexicographic_keyword_only_parameters():
3213 signature = inspect.signature(fn)
3214 l = list(signature.parameters)
3215 sorted_l = sorted(l)
3216 self.assertTrue(l)
3217 self.assertEqual(l, sorted_l)
3218 signature = inspect.signature(unsorted_keyword_only_parameters_fn)
3219 l = list(signature.parameters)
3220 self.assertEqual(l, unsorted_keyword_only_parameters)
3221
Jens Reidel611836a2020-03-18 03:22:46 +01003222 def test_signater_parameters_is_ordered(self):
3223 p1 = inspect.signature(lambda x, y: None).parameters
3224 p2 = inspect.signature(lambda y, x: None).parameters
3225 self.assertNotEqual(p1, p2)
3226
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003227
3228class TestParameterObject(unittest.TestCase):
3229 def test_signature_parameter_kinds(self):
3230 P = inspect.Parameter
3231 self.assertTrue(P.POSITIONAL_ONLY < P.POSITIONAL_OR_KEYWORD < \
3232 P.VAR_POSITIONAL < P.KEYWORD_ONLY < P.VAR_KEYWORD)
3233
3234 self.assertEqual(str(P.POSITIONAL_ONLY), 'POSITIONAL_ONLY')
3235 self.assertTrue('POSITIONAL_ONLY' in repr(P.POSITIONAL_ONLY))
3236
3237 def test_signature_parameter_object(self):
3238 p = inspect.Parameter('foo', default=10,
3239 kind=inspect.Parameter.POSITIONAL_ONLY)
3240 self.assertEqual(p.name, 'foo')
3241 self.assertEqual(p.default, 10)
3242 self.assertIs(p.annotation, p.empty)
3243 self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY)
3244
Dong-hee Naa9cab432018-05-30 00:04:08 +09003245 with self.assertRaisesRegex(ValueError, "value '123' is "
3246 "not a valid Parameter.kind"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003247 inspect.Parameter('foo', default=10, kind='123')
3248
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003249 with self.assertRaisesRegex(ValueError, 'not a valid parameter name'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003250 inspect.Parameter('1', kind=inspect.Parameter.VAR_KEYWORD)
3251
Yury Selivanov2393dca2014-01-27 15:07:58 -05003252 with self.assertRaisesRegex(TypeError, 'name must be a str'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003253 inspect.Parameter(None, kind=inspect.Parameter.VAR_KEYWORD)
3254
Yury Selivanov2393dca2014-01-27 15:07:58 -05003255 with self.assertRaisesRegex(ValueError,
3256 'is not a valid parameter name'):
3257 inspect.Parameter('$', kind=inspect.Parameter.VAR_KEYWORD)
3258
Nick Coghlanb4b966e2016-06-04 14:40:03 -07003259 with self.assertRaisesRegex(ValueError,
3260 'is not a valid parameter name'):
3261 inspect.Parameter('.a', kind=inspect.Parameter.VAR_KEYWORD)
3262
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003263 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003264 inspect.Parameter('a', default=42,
3265 kind=inspect.Parameter.VAR_KEYWORD)
3266
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003267 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003268 inspect.Parameter('a', default=42,
3269 kind=inspect.Parameter.VAR_POSITIONAL)
3270
3271 p = inspect.Parameter('a', default=42,
3272 kind=inspect.Parameter.POSITIONAL_OR_KEYWORD)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003273 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003274 p.replace(kind=inspect.Parameter.VAR_POSITIONAL)
3275
3276 self.assertTrue(repr(p).startswith('<Parameter'))
Yury Selivanov374375d2014-03-27 12:41:53 -04003277 self.assertTrue('"a=42"' in repr(p))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003278
Yury Selivanov67ae50e2014-04-08 11:46:50 -04003279 def test_signature_parameter_hashable(self):
3280 P = inspect.Parameter
3281 foo = P('foo', kind=P.POSITIONAL_ONLY)
3282 self.assertEqual(hash(foo), hash(P('foo', kind=P.POSITIONAL_ONLY)))
3283 self.assertNotEqual(hash(foo), hash(P('foo', kind=P.POSITIONAL_ONLY,
3284 default=42)))
3285 self.assertNotEqual(hash(foo),
3286 hash(foo.replace(kind=P.VAR_POSITIONAL)))
3287
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003288 def test_signature_parameter_equality(self):
3289 P = inspect.Parameter
3290 p = P('foo', default=42, kind=inspect.Parameter.KEYWORD_ONLY)
3291
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003292 self.assertTrue(p == p)
3293 self.assertFalse(p != p)
3294 self.assertFalse(p == 42)
3295 self.assertTrue(p != 42)
Serhiy Storchaka7d44e7a2019-08-08 08:43:18 +03003296 self.assertTrue(p == ALWAYS_EQ)
3297 self.assertFalse(p != ALWAYS_EQ)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003298
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003299 self.assertTrue(p == P('foo', default=42,
3300 kind=inspect.Parameter.KEYWORD_ONLY))
3301 self.assertFalse(p != P('foo', default=42,
3302 kind=inspect.Parameter.KEYWORD_ONLY))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003303
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003304 def test_signature_parameter_replace(self):
3305 p = inspect.Parameter('foo', default=42,
3306 kind=inspect.Parameter.KEYWORD_ONLY)
3307
3308 self.assertIsNot(p, p.replace())
3309 self.assertEqual(p, p.replace())
3310
3311 p2 = p.replace(annotation=1)
3312 self.assertEqual(p2.annotation, 1)
3313 p2 = p2.replace(annotation=p2.empty)
3314 self.assertEqual(p, p2)
3315
3316 p2 = p2.replace(name='bar')
3317 self.assertEqual(p2.name, 'bar')
3318 self.assertNotEqual(p2, p)
3319
Yury Selivanov2393dca2014-01-27 15:07:58 -05003320 with self.assertRaisesRegex(ValueError,
3321 'name is a required attribute'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003322 p2 = p2.replace(name=p2.empty)
3323
3324 p2 = p2.replace(name='foo', default=None)
3325 self.assertIs(p2.default, None)
3326 self.assertNotEqual(p2, p)
3327
3328 p2 = p2.replace(name='foo', default=p2.empty)
3329 self.assertIs(p2.default, p2.empty)
3330
3331
3332 p2 = p2.replace(default=42, kind=p2.POSITIONAL_OR_KEYWORD)
3333 self.assertEqual(p2.kind, p2.POSITIONAL_OR_KEYWORD)
3334 self.assertNotEqual(p2, p)
3335
Dong-hee Naa9cab432018-05-30 00:04:08 +09003336 with self.assertRaisesRegex(ValueError,
3337 "value <class 'inspect._empty'> "
3338 "is not a valid Parameter.kind"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003339 p2 = p2.replace(kind=p2.empty)
3340
3341 p2 = p2.replace(kind=p2.KEYWORD_ONLY)
3342 self.assertEqual(p2, p)
3343
3344 def test_signature_parameter_positional_only(self):
Yury Selivanov2393dca2014-01-27 15:07:58 -05003345 with self.assertRaisesRegex(TypeError, 'name must be a str'):
3346 inspect.Parameter(None, kind=inspect.Parameter.POSITIONAL_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003347
Nick Coghlanb4b966e2016-06-04 14:40:03 -07003348 @cpython_only
3349 def test_signature_parameter_implicit(self):
3350 with self.assertRaisesRegex(ValueError,
Dong-hee Naa9cab432018-05-30 00:04:08 +09003351 'implicit arguments must be passed as '
3352 'positional or keyword arguments, '
3353 'not positional-only'):
Nick Coghlanb4b966e2016-06-04 14:40:03 -07003354 inspect.Parameter('.0', kind=inspect.Parameter.POSITIONAL_ONLY)
3355
3356 param = inspect.Parameter(
3357 '.0', kind=inspect.Parameter.POSITIONAL_OR_KEYWORD)
3358 self.assertEqual(param.kind, inspect.Parameter.POSITIONAL_ONLY)
3359 self.assertEqual(param.name, 'implicit0')
3360
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003361 def test_signature_parameter_immutability(self):
Yury Selivanov2393dca2014-01-27 15:07:58 -05003362 p = inspect.Parameter('spam', kind=inspect.Parameter.KEYWORD_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003363
3364 with self.assertRaises(AttributeError):
3365 p.foo = 'bar'
3366
3367 with self.assertRaises(AttributeError):
3368 p.kind = 123
3369
3370
3371class TestSignatureBind(unittest.TestCase):
3372 @staticmethod
3373 def call(func, *args, **kwargs):
3374 sig = inspect.signature(func)
3375 ba = sig.bind(*args, **kwargs)
3376 return func(*ba.args, **ba.kwargs)
3377
3378 def test_signature_bind_empty(self):
3379 def test():
3380 return 42
3381
3382 self.assertEqual(self.call(test), 42)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003383 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003384 self.call(test, 1)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003385 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003386 self.call(test, 1, spam=10)
Yury Selivanov86872752015-05-19 00:27:49 -04003387 with self.assertRaisesRegex(
3388 TypeError, "got an unexpected keyword argument 'spam'"):
3389
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003390 self.call(test, spam=1)
3391
3392 def test_signature_bind_var(self):
3393 def test(*args, **kwargs):
3394 return args, kwargs
3395
3396 self.assertEqual(self.call(test), ((), {}))
3397 self.assertEqual(self.call(test, 1), ((1,), {}))
3398 self.assertEqual(self.call(test, 1, 2), ((1, 2), {}))
3399 self.assertEqual(self.call(test, foo='bar'), ((), {'foo': 'bar'}))
3400 self.assertEqual(self.call(test, 1, foo='bar'), ((1,), {'foo': 'bar'}))
3401 self.assertEqual(self.call(test, args=10), ((), {'args': 10}))
3402 self.assertEqual(self.call(test, 1, 2, foo='bar'),
3403 ((1, 2), {'foo': 'bar'}))
3404
3405 def test_signature_bind_just_args(self):
3406 def test(a, b, c):
3407 return a, b, c
3408
3409 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
3410
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003411 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003412 self.call(test, 1, 2, 3, 4)
3413
Yury Selivanov86872752015-05-19 00:27:49 -04003414 with self.assertRaisesRegex(TypeError,
3415 "missing a required argument: 'b'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003416 self.call(test, 1)
3417
Yury Selivanov86872752015-05-19 00:27:49 -04003418 with self.assertRaisesRegex(TypeError,
3419 "missing a required argument: 'a'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003420 self.call(test)
3421
3422 def test(a, b, c=10):
3423 return a, b, c
3424 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
3425 self.assertEqual(self.call(test, 1, 2), (1, 2, 10))
3426
3427 def test(a=1, b=2, c=3):
3428 return a, b, c
3429 self.assertEqual(self.call(test, a=10, c=13), (10, 2, 13))
3430 self.assertEqual(self.call(test, a=10), (10, 2, 3))
3431 self.assertEqual(self.call(test, b=10), (1, 10, 3))
3432
3433 def test_signature_bind_varargs_order(self):
3434 def test(*args):
3435 return args
3436
3437 self.assertEqual(self.call(test), ())
3438 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
3439
3440 def test_signature_bind_args_and_varargs(self):
3441 def test(a, b, c=3, *args):
3442 return a, b, c, args
3443
3444 self.assertEqual(self.call(test, 1, 2, 3, 4, 5), (1, 2, 3, (4, 5)))
3445 self.assertEqual(self.call(test, 1, 2), (1, 2, 3, ()))
3446 self.assertEqual(self.call(test, b=1, a=2), (2, 1, 3, ()))
3447 self.assertEqual(self.call(test, 1, b=2), (1, 2, 3, ()))
3448
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003449 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003450 "multiple values for argument 'c'"):
3451 self.call(test, 1, 2, 3, c=4)
3452
3453 def test_signature_bind_just_kwargs(self):
3454 def test(**kwargs):
3455 return kwargs
3456
3457 self.assertEqual(self.call(test), {})
3458 self.assertEqual(self.call(test, foo='bar', spam='ham'),
3459 {'foo': 'bar', 'spam': 'ham'})
3460
3461 def test_signature_bind_args_and_kwargs(self):
3462 def test(a, b, c=3, **kwargs):
3463 return a, b, c, kwargs
3464
3465 self.assertEqual(self.call(test, 1, 2), (1, 2, 3, {}))
3466 self.assertEqual(self.call(test, 1, 2, foo='bar', spam='ham'),
3467 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3468 self.assertEqual(self.call(test, b=2, a=1, foo='bar', spam='ham'),
3469 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3470 self.assertEqual(self.call(test, a=1, b=2, foo='bar', spam='ham'),
3471 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3472 self.assertEqual(self.call(test, 1, b=2, foo='bar', spam='ham'),
3473 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3474 self.assertEqual(self.call(test, 1, b=2, c=4, foo='bar', spam='ham'),
3475 (1, 2, 4, {'foo': 'bar', 'spam': 'ham'}))
3476 self.assertEqual(self.call(test, 1, 2, 4, foo='bar'),
3477 (1, 2, 4, {'foo': 'bar'}))
3478 self.assertEqual(self.call(test, c=5, a=4, b=3),
3479 (4, 3, 5, {}))
3480
3481 def test_signature_bind_kwonly(self):
3482 def test(*, foo):
3483 return foo
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003484 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003485 'too many positional arguments'):
3486 self.call(test, 1)
3487 self.assertEqual(self.call(test, foo=1), 1)
3488
3489 def test(a, *, foo=1, bar):
3490 return foo
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003491 with self.assertRaisesRegex(TypeError,
Yury Selivanov86872752015-05-19 00:27:49 -04003492 "missing a required argument: 'bar'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003493 self.call(test, 1)
3494
3495 def test(foo, *, bar):
3496 return foo, bar
3497 self.assertEqual(self.call(test, 1, bar=2), (1, 2))
3498 self.assertEqual(self.call(test, bar=2, foo=1), (1, 2))
3499
Yury Selivanov86872752015-05-19 00:27:49 -04003500 with self.assertRaisesRegex(
3501 TypeError, "got an unexpected keyword argument 'spam'"):
3502
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003503 self.call(test, bar=2, foo=1, spam=10)
3504
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003505 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003506 'too many positional arguments'):
3507 self.call(test, 1, 2)
3508
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003509 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003510 'too many positional arguments'):
3511 self.call(test, 1, 2, bar=2)
3512
Yury Selivanov86872752015-05-19 00:27:49 -04003513 with self.assertRaisesRegex(
3514 TypeError, "got an unexpected keyword argument 'spam'"):
3515
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003516 self.call(test, 1, bar=2, spam='ham')
3517
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003518 with self.assertRaisesRegex(TypeError,
Yury Selivanov86872752015-05-19 00:27:49 -04003519 "missing a required argument: 'bar'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003520 self.call(test, 1)
3521
3522 def test(foo, *, bar, **bin):
3523 return foo, bar, bin
3524 self.assertEqual(self.call(test, 1, bar=2), (1, 2, {}))
3525 self.assertEqual(self.call(test, foo=1, bar=2), (1, 2, {}))
3526 self.assertEqual(self.call(test, 1, bar=2, spam='ham'),
3527 (1, 2, {'spam': 'ham'}))
3528 self.assertEqual(self.call(test, spam='ham', foo=1, bar=2),
3529 (1, 2, {'spam': 'ham'}))
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003530 with self.assertRaisesRegex(TypeError,
Yury Selivanov86872752015-05-19 00:27:49 -04003531 "missing a required argument: 'foo'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003532 self.call(test, spam='ham', bar=2)
3533 self.assertEqual(self.call(test, 1, bar=2, bin=1, spam=10),
3534 (1, 2, {'bin': 1, 'spam': 10}))
3535
3536 def test_signature_bind_arguments(self):
3537 def test(a, *args, b, z=100, **kwargs):
3538 pass
3539 sig = inspect.signature(test)
3540 ba = sig.bind(10, 20, b=30, c=40, args=50, kwargs=60)
3541 # we won't have 'z' argument in the bound arguments object, as we didn't
3542 # pass it to the 'bind'
3543 self.assertEqual(tuple(ba.arguments.items()),
3544 (('a', 10), ('args', (20,)), ('b', 30),
3545 ('kwargs', {'c': 40, 'args': 50, 'kwargs': 60})))
3546 self.assertEqual(ba.kwargs,
3547 {'b': 30, 'c': 40, 'args': 50, 'kwargs': 60})
3548 self.assertEqual(ba.args, (10, 20))
3549
3550 def test_signature_bind_positional_only(self):
3551 P = inspect.Parameter
3552
3553 def test(a_po, b_po, c_po=3, foo=42, *, bar=50, **kwargs):
3554 return a_po, b_po, c_po, foo, bar, kwargs
3555
3556 sig = inspect.signature(test)
3557 new_params = collections.OrderedDict(tuple(sig.parameters.items()))
3558 for name in ('a_po', 'b_po', 'c_po'):
3559 new_params[name] = new_params[name].replace(kind=P.POSITIONAL_ONLY)
3560 new_sig = sig.replace(parameters=new_params.values())
3561 test.__signature__ = new_sig
3562
3563 self.assertEqual(self.call(test, 1, 2, 4, 5, bar=6),
3564 (1, 2, 4, 5, 6, {}))
3565
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05003566 self.assertEqual(self.call(test, 1, 2),
3567 (1, 2, 3, 42, 50, {}))
3568
3569 self.assertEqual(self.call(test, 1, 2, foo=4, bar=5),
3570 (1, 2, 3, 4, 5, {}))
3571
3572 with self.assertRaisesRegex(TypeError, "but was passed as a keyword"):
3573 self.call(test, 1, 2, foo=4, bar=5, c_po=10)
3574
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003575 with self.assertRaisesRegex(TypeError, "parameter is positional only"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003576 self.call(test, 1, 2, c_po=4)
3577
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003578 with self.assertRaisesRegex(TypeError, "parameter is positional only"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003579 self.call(test, a_po=1, b_po=2)
3580
Antoine Pitroubd41d1b2013-01-29 21:20:57 +01003581 def test_signature_bind_with_self_arg(self):
3582 # Issue #17071: one of the parameters is named "self
3583 def test(a, self, b):
3584 pass
3585 sig = inspect.signature(test)
3586 ba = sig.bind(1, 2, 3)
3587 self.assertEqual(ba.args, (1, 2, 3))
3588 ba = sig.bind(1, self=2, b=3)
3589 self.assertEqual(ba.args, (1, 2, 3))
3590
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05003591 def test_signature_bind_vararg_name(self):
3592 def test(a, *args):
3593 return a, args
3594 sig = inspect.signature(test)
3595
Yury Selivanov86872752015-05-19 00:27:49 -04003596 with self.assertRaisesRegex(
3597 TypeError, "got an unexpected keyword argument 'args'"):
3598
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05003599 sig.bind(a=0, args=1)
3600
3601 def test(*args, **kwargs):
3602 return args, kwargs
3603 self.assertEqual(self.call(test, args=1), ((), {'args': 1}))
3604
3605 sig = inspect.signature(test)
3606 ba = sig.bind(args=1)
3607 self.assertEqual(ba.arguments, {'kwargs': {'args': 1}})
3608
Nick Coghlanb4b966e2016-06-04 14:40:03 -07003609 @cpython_only
3610 def test_signature_bind_implicit_arg(self):
3611 # Issue #19611: getcallargs should work with set comprehensions
3612 def make_set():
3613 return {z * z for z in range(5)}
3614 setcomp_code = make_set.__code__.co_consts[1]
3615 setcomp_func = types.FunctionType(setcomp_code, {})
3616
3617 iterator = iter(range(5))
3618 self.assertEqual(self.call(setcomp_func, iterator), {0, 1, 4, 9, 16})
3619
Pablo Galindof3ef06a2019-10-15 12:40:02 +01003620 def test_signature_bind_posonly_kwargs(self):
3621 def foo(bar, /, **kwargs):
3622 return bar, kwargs.get(bar)
3623
3624 sig = inspect.signature(foo)
3625 result = sig.bind("pos-only", bar="keyword")
3626
3627 self.assertEqual(result.kwargs, {"bar": "keyword"})
3628 self.assertIn(("bar", "pos-only"), result.arguments.items())
3629
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003630
3631class TestBoundArguments(unittest.TestCase):
3632 def test_signature_bound_arguments_unhashable(self):
3633 def foo(a): pass
3634 ba = inspect.signature(foo).bind(1)
3635
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003636 with self.assertRaisesRegex(TypeError, 'unhashable type'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003637 hash(ba)
3638
3639 def test_signature_bound_arguments_equality(self):
3640 def foo(a): pass
3641 ba = inspect.signature(foo).bind(1)
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003642 self.assertTrue(ba == ba)
3643 self.assertFalse(ba != ba)
Serhiy Storchaka7d44e7a2019-08-08 08:43:18 +03003644 self.assertTrue(ba == ALWAYS_EQ)
3645 self.assertFalse(ba != ALWAYS_EQ)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003646
3647 ba2 = inspect.signature(foo).bind(1)
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003648 self.assertTrue(ba == ba2)
3649 self.assertFalse(ba != ba2)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003650
3651 ba3 = inspect.signature(foo).bind(2)
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003652 self.assertFalse(ba == ba3)
3653 self.assertTrue(ba != ba3)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003654 ba3.arguments['a'] = 1
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003655 self.assertTrue(ba == ba3)
3656 self.assertFalse(ba != ba3)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003657
3658 def bar(b): pass
3659 ba4 = inspect.signature(bar).bind(1)
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003660 self.assertFalse(ba == ba4)
3661 self.assertTrue(ba != ba4)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003662
Yury Selivanov4cfd4ea2015-05-14 18:30:27 -04003663 def foo(*, a, b): pass
3664 sig = inspect.signature(foo)
3665 ba1 = sig.bind(a=1, b=2)
3666 ba2 = sig.bind(b=2, a=1)
Serhiy Storchaka2489bd52015-07-18 23:20:50 +03003667 self.assertTrue(ba1 == ba2)
3668 self.assertFalse(ba1 != ba2)
Yury Selivanov4cfd4ea2015-05-14 18:30:27 -04003669
Yury Selivanova5d63dd2014-03-27 11:31:43 -04003670 def test_signature_bound_arguments_pickle(self):
3671 def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
3672 sig = inspect.signature(foo)
3673 ba = sig.bind(20, 30, z={})
3674
3675 for ver in range(pickle.HIGHEST_PROTOCOL + 1):
3676 with self.subTest(pickle_ver=ver):
3677 ba_pickled = pickle.loads(pickle.dumps(ba, ver))
3678 self.assertEqual(ba, ba_pickled)
3679
Yury Selivanov3f6538f2015-05-14 18:47:17 -04003680 def test_signature_bound_arguments_repr(self):
3681 def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
3682 sig = inspect.signature(foo)
3683 ba = sig.bind(20, 30, z={})
Yury Selivanovf229bc52015-05-15 12:53:56 -04003684 self.assertRegex(repr(ba), r'<BoundArguments \(a=20,.*\}\}\)>')
Yury Selivanov3f6538f2015-05-14 18:47:17 -04003685
Yury Selivanovb907a512015-05-16 13:45:09 -04003686 def test_signature_bound_arguments_apply_defaults(self):
3687 def foo(a, b=1, *args, c:1={}, **kw): pass
3688 sig = inspect.signature(foo)
3689
3690 ba = sig.bind(20)
3691 ba.apply_defaults()
3692 self.assertEqual(
3693 list(ba.arguments.items()),
3694 [('a', 20), ('b', 1), ('args', ()), ('c', {}), ('kw', {})])
3695
3696 # Make sure that we preserve the order:
3697 # i.e. 'c' should be *before* 'kw'.
3698 ba = sig.bind(10, 20, 30, d=1)
3699 ba.apply_defaults()
3700 self.assertEqual(
3701 list(ba.arguments.items()),
3702 [('a', 10), ('b', 20), ('args', (30,)), ('c', {}), ('kw', {'d':1})])
3703
3704 # Make sure that BoundArguments produced by bind_partial()
3705 # are supported.
3706 def foo(a, b): pass
3707 sig = inspect.signature(foo)
3708 ba = sig.bind_partial(20)
3709 ba.apply_defaults()
3710 self.assertEqual(
3711 list(ba.arguments.items()),
3712 [('a', 20)])
3713
3714 # Test no args
3715 def foo(): pass
3716 sig = inspect.signature(foo)
3717 ba = sig.bind()
3718 ba.apply_defaults()
3719 self.assertEqual(list(ba.arguments.items()), [])
3720
Yury Selivanovf9e1f2b2016-03-02 11:07:47 -05003721 # Make sure a no-args binding still acquires proper defaults.
3722 def foo(a='spam'): pass
3723 sig = inspect.signature(foo)
3724 ba = sig.bind()
3725 ba.apply_defaults()
3726 self.assertEqual(list(ba.arguments.items()), [('a', 'spam')])
3727
Rémi Lapeyre2cca8ef2020-01-28 13:47:03 +01003728 def test_signature_bound_arguments_arguments_type(self):
3729 def foo(a): pass
3730 ba = inspect.signature(foo).bind(1)
3731 self.assertIs(type(ba.arguments), dict)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003732
Yury Selivanovd82eddc2014-01-29 11:24:39 -05003733class TestSignaturePrivateHelpers(unittest.TestCase):
3734 def test_signature_get_bound_param(self):
3735 getter = inspect._signature_get_bound_param
3736
3737 self.assertEqual(getter('($self)'), 'self')
3738 self.assertEqual(getter('($self, obj)'), 'self')
3739 self.assertEqual(getter('($cls, /, obj)'), 'cls')
3740
Larry Hastings2623c8c2014-02-08 22:15:29 -08003741 def _strip_non_python_syntax(self, input,
3742 clean_signature, self_parameter, last_positional_only):
3743 computed_clean_signature, \
3744 computed_self_parameter, \
3745 computed_last_positional_only = \
3746 inspect._signature_strip_non_python_syntax(input)
3747 self.assertEqual(computed_clean_signature, clean_signature)
3748 self.assertEqual(computed_self_parameter, self_parameter)
3749 self.assertEqual(computed_last_positional_only, last_positional_only)
3750
3751 def test_signature_strip_non_python_syntax(self):
3752 self._strip_non_python_syntax(
3753 "($module, /, path, mode, *, dir_fd=None, " +
3754 "effective_ids=False,\n follow_symlinks=True)",
3755 "(module, path, mode, *, dir_fd=None, " +
3756 "effective_ids=False, follow_symlinks=True)",
3757 0,
3758 0)
3759
3760 self._strip_non_python_syntax(
3761 "($module, word, salt, /)",
3762 "(module, word, salt)",
3763 0,
3764 2)
3765
3766 self._strip_non_python_syntax(
3767 "(x, y=None, z=None, /)",
3768 "(x, y=None, z=None)",
3769 None,
3770 2)
3771
3772 self._strip_non_python_syntax(
3773 "(x, y=None, z=None)",
3774 "(x, y=None, z=None)",
3775 None,
3776 None)
3777
3778 self._strip_non_python_syntax(
3779 "(x,\n y=None,\n z = None )",
3780 "(x, y=None, z=None)",
3781 None,
3782 None)
3783
3784 self._strip_non_python_syntax(
3785 "",
3786 "",
3787 None,
3788 None)
3789
3790 self._strip_non_python_syntax(
3791 None,
3792 None,
3793 None,
3794 None)
3795
Nick Coghlan9c680b02015-04-13 12:54:54 -04003796class TestSignatureDefinitions(unittest.TestCase):
3797 # This test case provides a home for checking that particular APIs
3798 # have signatures available for introspection
3799
3800 @cpython_only
3801 @unittest.skipIf(MISSING_C_DOCSTRINGS,
3802 "Signature information for builtins requires docstrings")
3803 def test_builtins_have_signatures(self):
3804 # This checks all builtin callables in CPython have signatures
3805 # A few have signatures Signature can't yet handle, so we skip those
3806 # since they will have to wait until PEP 457 adds the required
3807 # introspection support to the inspect module
3808 # Some others also haven't been converted yet for various other
3809 # reasons, so we also skip those for the time being, but design
3810 # the test to fail in order to indicate when it needs to be
3811 # updated.
3812 no_signature = set()
3813 # These need PEP 457 groups
3814 needs_groups = {"range", "slice", "dir", "getattr",
3815 "next", "iter", "vars"}
3816 no_signature |= needs_groups
3817 # These need PEP 457 groups or a signature change to accept None
3818 needs_semantic_update = {"round"}
3819 no_signature |= needs_semantic_update
3820 # These need *args support in Argument Clinic
Barry Warsaw36c1d1f2017-10-05 12:11:18 -04003821 needs_varargs = {"breakpoint", "min", "max", "print",
3822 "__build_class__"}
Nick Coghlan9c680b02015-04-13 12:54:54 -04003823 no_signature |= needs_varargs
3824 # These simply weren't covered in the initial AC conversion
3825 # for builtin callables
3826 not_converted_yet = {"open", "__import__"}
3827 no_signature |= not_converted_yet
3828 # These builtin types are expected to provide introspection info
3829 types_with_signatures = set()
3830 # Check the signatures we expect to be there
3831 ns = vars(builtins)
3832 for name, obj in sorted(ns.items()):
3833 if not callable(obj):
3834 continue
3835 # The builtin types haven't been converted to AC yet
3836 if isinstance(obj, type) and (name not in types_with_signatures):
3837 # Note that this also skips all the exception types
3838 no_signature.add(name)
3839 if (name in no_signature):
3840 # Not yet converted
3841 continue
3842 with self.subTest(builtin=name):
3843 self.assertIsNotNone(inspect.signature(obj))
3844 # Check callables that haven't been converted don't claim a signature
3845 # This ensures this test will start failing as more signatures are
3846 # added, so the affected items can be moved into the scope of the
3847 # regression test above
3848 for name in no_signature:
3849 with self.subTest(builtin=name):
3850 self.assertIsNone(obj.__text_signature__)
3851
Serhiy Storchakad53cf992019-05-06 22:40:27 +03003852 def test_python_function_override_signature(self):
3853 def func(*args, **kwargs):
3854 pass
3855 func.__text_signature__ = '($self, a, b=1, *args, c, d=2, **kwargs)'
3856 sig = inspect.signature(func)
3857 self.assertIsNotNone(sig)
3858 self.assertEqual(str(sig), '(self, /, a, b=1, *args, c, d=2, **kwargs)')
3859 func.__text_signature__ = '($self, a, b=1, /, *args, c, d=2, **kwargs)'
3860 sig = inspect.signature(func)
3861 self.assertEqual(str(sig), '(self, a, b=1, /, *args, c, d=2, **kwargs)')
3862
Yury Selivanovd82eddc2014-01-29 11:24:39 -05003863
Thomas Kluyverf9169ce2017-05-23 04:27:52 +01003864class NTimesUnwrappable:
3865 def __init__(self, n):
3866 self.n = n
3867 self._next = None
3868
3869 @property
3870 def __wrapped__(self):
3871 if self.n <= 0:
3872 raise Exception("Unwrapped too many times")
3873 if self._next is None:
3874 self._next = NTimesUnwrappable(self.n - 1)
3875 return self._next
3876
Nick Coghlane8c45d62013-07-28 20:00:01 +10003877class TestUnwrap(unittest.TestCase):
3878
3879 def test_unwrap_one(self):
3880 def func(a, b):
3881 return a + b
3882 wrapper = functools.lru_cache(maxsize=20)(func)
3883 self.assertIs(inspect.unwrap(wrapper), func)
3884
3885 def test_unwrap_several(self):
3886 def func(a, b):
3887 return a + b
3888 wrapper = func
3889 for __ in range(10):
3890 @functools.wraps(wrapper)
3891 def wrapper():
3892 pass
3893 self.assertIsNot(wrapper.__wrapped__, func)
3894 self.assertIs(inspect.unwrap(wrapper), func)
3895
3896 def test_stop(self):
3897 def func1(a, b):
3898 return a + b
3899 @functools.wraps(func1)
3900 def func2():
3901 pass
3902 @functools.wraps(func2)
3903 def wrapper():
3904 pass
3905 func2.stop_here = 1
3906 unwrapped = inspect.unwrap(wrapper,
3907 stop=(lambda f: hasattr(f, "stop_here")))
3908 self.assertIs(unwrapped, func2)
3909
3910 def test_cycle(self):
3911 def func1(): pass
3912 func1.__wrapped__ = func1
3913 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3914 inspect.unwrap(func1)
3915
3916 def func2(): pass
3917 func2.__wrapped__ = func1
3918 func1.__wrapped__ = func2
3919 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3920 inspect.unwrap(func1)
3921 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3922 inspect.unwrap(func2)
3923
3924 def test_unhashable(self):
3925 def func(): pass
3926 func.__wrapped__ = None
3927 class C:
3928 __hash__ = None
3929 __wrapped__ = func
3930 self.assertIsNone(inspect.unwrap(C()))
3931
Thomas Kluyverf9169ce2017-05-23 04:27:52 +01003932 def test_recursion_limit(self):
3933 obj = NTimesUnwrappable(sys.getrecursionlimit() + 1)
3934 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3935 inspect.unwrap(obj)
3936
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003937class TestMain(unittest.TestCase):
3938 def test_only_source(self):
3939 module = importlib.import_module('unittest')
3940 rc, out, err = assert_python_ok('-m', 'inspect',
3941 'unittest')
3942 lines = out.decode().splitlines()
3943 # ignore the final newline
3944 self.assertEqual(lines[:-1], inspect.getsource(module).splitlines())
3945 self.assertEqual(err, b'')
3946
Yury Selivanov42407ab2014-06-23 10:23:50 -07003947 def test_custom_getattr(self):
3948 def foo():
3949 pass
3950 foo.__signature__ = 42
3951 with self.assertRaises(TypeError):
3952 inspect.signature(foo)
3953
Brett Cannon634a8fc2013-10-02 10:25:42 -04003954 @unittest.skipIf(ThreadPoolExecutor is None,
Brett Cannon0de3f012013-10-02 10:58:58 -04003955 'threads required to test __qualname__ for source files')
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003956 def test_qualname_source(self):
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003957 rc, out, err = assert_python_ok('-m', 'inspect',
3958 'concurrent.futures:ThreadPoolExecutor')
3959 lines = out.decode().splitlines()
3960 # ignore the final newline
3961 self.assertEqual(lines[:-1],
Brett Cannon634a8fc2013-10-02 10:25:42 -04003962 inspect.getsource(ThreadPoolExecutor).splitlines())
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003963 self.assertEqual(err, b'')
3964
3965 def test_builtins(self):
3966 module = importlib.import_module('unittest')
3967 _, out, err = assert_python_failure('-m', 'inspect',
3968 'sys')
3969 lines = err.decode().splitlines()
3970 self.assertEqual(lines, ["Can't get info for builtin modules."])
3971
3972 def test_details(self):
3973 module = importlib.import_module('unittest')
Victor Stinner9def2842016-01-18 12:15:08 +01003974 args = support.optim_args_from_interpreter_flags()
3975 rc, out, err = assert_python_ok(*args, '-m', 'inspect',
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003976 'unittest', '--details')
3977 output = out.decode()
3978 # Just a quick sanity check on the output
3979 self.assertIn(module.__name__, output)
3980 self.assertIn(module.__file__, output)
Victor Stinner9def2842016-01-18 12:15:08 +01003981 self.assertIn(module.__cached__, output)
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003982 self.assertEqual(err, b'')
3983
3984
Yury Selivanovef1e7502014-12-08 16:05:34 -05003985class TestReload(unittest.TestCase):
3986
3987 src_before = textwrap.dedent("""\
3988def foo():
3989 print("Bla")
3990 """)
3991
3992 src_after = textwrap.dedent("""\
3993def foo():
3994 print("Oh no!")
3995 """)
3996
3997 def assertInspectEqual(self, path, source):
3998 inspected_src = inspect.getsource(source)
3999 with open(path) as src:
4000 self.assertEqual(
4001 src.read().splitlines(True),
4002 inspected_src.splitlines(True)
4003 )
4004
4005 def test_getsource_reload(self):
4006 # see issue 1218234
4007 with _ready_to_import('reload_bug', self.src_before) as (name, path):
4008 module = importlib.import_module(name)
4009 self.assertInspectEqual(path, module)
4010 with open(path, 'w') as src:
4011 src.write(self.src_after)
4012 self.assertInspectEqual(path, module)
Nick Coghlanf94a16b2013-09-22 22:46:49 +10004013
Nick Coghlane8c45d62013-07-28 20:00:01 +10004014
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00004015def test_main():
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00004016 run_unittest(
4017 TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBuggyCases,
4018 TestInterpreterStack, TestClassesAndFunctions, TestPredicates,
4019 TestGetcallargsFunctions, TestGetcallargsMethods,
Alexander Belopolskyf546e702010-12-02 00:10:11 +00004020 TestGetcallargsUnboundMethods, TestGetattrStatic, TestGetGeneratorState,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07004021 TestNoEOL, TestSignatureObject, TestSignatureBind, TestParameterObject,
Nick Coghlan9c680b02015-04-13 12:54:54 -04004022 TestBoundArguments, TestSignaturePrivateHelpers,
Aaron Hall, MBA4054b172018-05-20 19:46:42 -04004023 TestSignatureDefinitions, TestIsDataDescriptor,
Yury Selivanov5376ba92015-06-22 12:19:30 -04004024 TestGetClosureVars, TestUnwrap, TestMain, TestReload,
Vladimir Matveev91cb2982018-08-24 07:18:00 -07004025 TestGetCoroutineState, TestGettingSourceOfToplevelFrames
Michael Foord95fc51d2010-11-20 15:07:30 +00004026 )
Martin v. Löwis893ffa42003-10-31 15:35:53 +00004027
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00004028if __name__ == "__main__":
4029 test_main()