blob: 172e6bf6cd8a637443e91ce835f0baddc80a08ea [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),
Irit Katriel6e1eec72020-12-04 16:45:38 +0000393 ('WhichComments', mod.WhichComments),
Serhiy Storchaka362c1b52013-09-05 17:14:32 +0300394 ])
395 tree = inspect.getclasstree([cls[1] for cls in classes])
396 self.assertEqual(tree,
397 [(object, ()),
398 [(mod.ParrotDroppings, (object,)),
399 [(mod.FesteringGob, (mod.MalodorousPervert,
400 mod.ParrotDroppings))
401 ],
402 (mod.StupidGit, (object,)),
403 [(mod.MalodorousPervert, (mod.StupidGit,)),
404 [(mod.FesteringGob, (mod.MalodorousPervert,
405 mod.ParrotDroppings))
406 ]
Irit Katriel6e1eec72020-12-04 16:45:38 +0000407 ],
408 (mod.WhichComments, (object,),)
Serhiy Storchaka362c1b52013-09-05 17:14:32 +0300409 ]
410 ])
411 tree = inspect.getclasstree([cls[1] for cls in classes], True)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000412 self.assertEqual(tree,
Thomas Wouters725af872006-04-15 09:13:19 +0000413 [(object, ()),
414 [(mod.ParrotDroppings, (object,)),
415 (mod.StupidGit, (object,)),
416 [(mod.MalodorousPervert, (mod.StupidGit,)),
417 [(mod.FesteringGob, (mod.MalodorousPervert,
418 mod.ParrotDroppings))
419 ]
Irit Katriel6e1eec72020-12-04 16:45:38 +0000420 ],
421 (mod.WhichComments, (object,),)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000422 ]
423 ])
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000424
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000425 def test_getfunctions(self):
426 functions = inspect.getmembers(mod, inspect.isfunction)
427 self.assertEqual(functions, [('eggs', mod.eggs),
Yury Selivanove4e811d2015-07-21 19:01:52 +0300428 ('lobbest', mod.lobbest),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000429 ('spam', mod.spam)])
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000430
R. David Murray378c0cf2010-02-24 01:46:21 +0000431 @unittest.skipIf(sys.flags.optimize >= 2,
432 "Docstrings are omitted with -O2 and above")
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000433 def test_getdoc(self):
434 self.assertEqual(inspect.getdoc(mod), 'A module docstring.')
435 self.assertEqual(inspect.getdoc(mod.StupidGit),
436 'A longer,\n\nindented\n\ndocstring.')
437 self.assertEqual(inspect.getdoc(git.abuse),
438 'Another\n\ndocstring\n\ncontaining\n\ntabs')
Raymond Hettingerd1e768a2019-03-25 13:01:13 -0700439 self.assertEqual(inspect.getdoc(SlotUser.power),
440 'measured in kilowatts')
441 self.assertEqual(inspect.getdoc(SlotUser.distance),
442 'measured in kilometers')
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000443
Serhiy Storchaka5cf2b722015-04-03 22:38:53 +0300444 @unittest.skipIf(sys.flags.optimize >= 2,
445 "Docstrings are omitted with -O2 and above")
446 def test_getdoc_inherited(self):
Serhiy Storchaka08b47c32020-05-18 20:25:07 +0300447 self.assertEqual(inspect.getdoc(mod.FesteringGob),
448 'A longer,\n\nindented\n\ndocstring.')
Serhiy Storchaka5cf2b722015-04-03 22:38:53 +0300449 self.assertEqual(inspect.getdoc(mod.FesteringGob.abuse),
450 'Another\n\ndocstring\n\ncontaining\n\ntabs')
451 self.assertEqual(inspect.getdoc(mod.FesteringGob().abuse),
452 'Another\n\ndocstring\n\ncontaining\n\ntabs')
453 self.assertEqual(inspect.getdoc(mod.FesteringGob.contradiction),
454 'The automatic gainsaying.')
455
456 @unittest.skipIf(MISSING_C_DOCSTRINGS, "test requires docstrings")
457 def test_finddoc(self):
458 finddoc = inspect._finddoc
Serhiy Storchaka08b47c32020-05-18 20:25:07 +0300459 self.assertEqual(finddoc(int), int.__doc__)
Serhiy Storchaka5cf2b722015-04-03 22:38:53 +0300460 self.assertEqual(finddoc(int.to_bytes), int.to_bytes.__doc__)
461 self.assertEqual(finddoc(int().to_bytes), int.to_bytes.__doc__)
462 self.assertEqual(finddoc(int.from_bytes), int.from_bytes.__doc__)
463 self.assertEqual(finddoc(int.real), int.real.__doc__)
464
Georg Brandl0c77a822008-06-10 16:37:50 +0000465 def test_cleandoc(self):
466 self.assertEqual(inspect.cleandoc('An\n indented\n docstring.'),
467 'An\nindented\ndocstring.')
468
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000469 def test_getcomments(self):
470 self.assertEqual(inspect.getcomments(mod), '# line 1\n')
471 self.assertEqual(inspect.getcomments(mod.StupidGit), '# line 20\n')
Karthikeyan Singaravelan696136b2020-04-18 21:49:32 +0530472 self.assertEqual(inspect.getcomments(mod2.cls160), '# line 159\n')
Marco Buttu3f2155f2017-03-17 09:50:23 +0100473 # If the object source file is not available, return None.
474 co = compile('x=1', '_non_existing_filename.py', 'exec')
475 self.assertIsNone(inspect.getcomments(co))
476 # If the object has been defined in C, return None.
477 self.assertIsNone(inspect.getcomments(list))
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000478
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000479 def test_getmodule(self):
Thomas Wouters89f507f2006-12-13 04:49:30 +0000480 # Check actual module
481 self.assertEqual(inspect.getmodule(mod), mod)
482 # Check class (uses __module__ attribute)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000483 self.assertEqual(inspect.getmodule(mod.StupidGit), mod)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000484 # Check a method (no __module__ attribute, falls back to filename)
485 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
486 # Do it again (check the caching isn't broken)
487 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
488 # Check a builtin
Georg Brandl1a3284e2007-12-02 09:40:06 +0000489 self.assertEqual(inspect.getmodule(str), sys.modules["builtins"])
Thomas Wouters89f507f2006-12-13 04:49:30 +0000490 # Check filename override
491 self.assertEqual(inspect.getmodule(None, modfile), mod)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000492
Berker Peksagff0e3b72017-01-02 06:57:43 +0300493 def test_getframeinfo_get_first_line(self):
494 frame_info = inspect.getframeinfo(self.fodderModule.fr, 50)
495 self.assertEqual(frame_info.code_context[0], "# line 1\n")
496 self.assertEqual(frame_info.code_context[1], "'A module docstring.'\n")
497
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000498 def test_getsource(self):
499 self.assertSourceEqual(git.abuse, 29, 39)
Serhiy Storchakaac4bdcc2015-10-29 08:15:50 +0200500 self.assertSourceEqual(mod.StupidGit, 21, 51)
501 self.assertSourceEqual(mod.lobbest, 75, 76)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000502
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000503 def test_getsourcefile(self):
Christian Heimesa3538eb2007-11-06 11:44:48 +0000504 self.assertEqual(normcase(inspect.getsourcefile(mod.spam)), modfile)
505 self.assertEqual(normcase(inspect.getsourcefile(git.abuse)), modfile)
R. David Murraya1b37402010-06-17 02:04:29 +0000506 fn = "_non_existing_filename_used_for_sourcefile_test.py"
Victor Stinner51d8c522016-02-08 17:57:02 +0100507 co = compile("x=1", fn, "exec")
R. David Murray4155f972010-06-17 13:23:18 +0000508 self.assertEqual(inspect.getsourcefile(co), None)
R. David Murraya1b37402010-06-17 02:04:29 +0000509 linecache.cache[co.co_filename] = (1, None, "None", co.co_filename)
Antoine Pitrou5d62a612012-07-08 13:48:46 +0200510 try:
511 self.assertEqual(normcase(inspect.getsourcefile(co)), fn)
512 finally:
513 del linecache.cache[co.co_filename]
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000514
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000515 def test_getfile(self):
516 self.assertEqual(inspect.getfile(mod.StupidGit), mod.__file__)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000517
Philipp Ad407d2a2019-06-08 14:05:46 +0200518 def test_getfile_builtin_module(self):
519 with self.assertRaises(TypeError) as e:
520 inspect.getfile(sys)
521 self.assertTrue(str(e.exception).startswith('<module'))
522
523 def test_getfile_builtin_class(self):
524 with self.assertRaises(TypeError) as e:
525 inspect.getfile(int)
526 self.assertTrue(str(e.exception).startswith('<class'))
527
528 def test_getfile_builtin_function_or_method(self):
529 with self.assertRaises(TypeError) as e_abs:
530 inspect.getfile(abs)
531 self.assertIn('expected, got', str(e_abs.exception))
532 with self.assertRaises(TypeError) as e_append:
533 inspect.getfile(list.append)
534 self.assertIn('expected, got', str(e_append.exception))
535
Yury Selivanov2eed8b72014-01-27 13:24:56 -0500536 def test_getfile_class_without_module(self):
537 class CM(type):
538 @property
539 def __module__(cls):
540 raise AttributeError
541 class C(metaclass=CM):
542 pass
543 with self.assertRaises(TypeError):
544 inspect.getfile(C)
545
Thomas Kluyvere968bc732017-10-24 13:42:36 +0100546 def test_getfile_broken_repr(self):
547 class ErrorRepr:
548 def __repr__(self):
549 raise Exception('xyz')
550 er = ErrorRepr()
551 with self.assertRaises(TypeError):
552 inspect.getfile(er)
553
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000554 def test_getmodule_recursion(self):
Christian Heimes45f9af32007-11-27 21:50:00 +0000555 from types import ModuleType
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000556 name = '__inspect_dummy'
Christian Heimes45f9af32007-11-27 21:50:00 +0000557 m = sys.modules[name] = ModuleType(name)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000558 m.__file__ = "<string>" # hopefully not a real filename...
559 m.__loader__ = "dummy" # pretend the filename is understood by a loader
Georg Brandl7cae87c2006-09-06 06:51:57 +0000560 exec("def x(): pass", m.__dict__)
Neal Norwitz221085d2007-02-25 20:55:47 +0000561 self.assertEqual(inspect.getsourcefile(m.x.__code__), '<string>')
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000562 del sys.modules[name]
563 inspect.getmodule(compile('a=10','','single'))
564
Benjamin Peterson9620cc02011-06-11 15:53:11 -0500565 def test_proceed_with_fake_filename(self):
566 '''doctest monkeypatches linecache to enable inspection'''
567 fn, source = '<test>', 'def x(): pass\n'
568 getlines = linecache.getlines
569 def monkey(filename, module_globals=None):
570 if filename == fn:
Ezio Melottid8b509b2011-09-28 17:37:55 +0300571 return source.splitlines(keepends=True)
Benjamin Peterson9620cc02011-06-11 15:53:11 -0500572 else:
573 return getlines(filename, module_globals)
574 linecache.getlines = monkey
575 try:
576 ns = {}
577 exec(compile(source, fn, 'single'), ns)
578 inspect.getsource(ns["x"])
579 finally:
580 linecache.getlines = getlines
581
Antoine Pitroua8723a02015-04-15 00:41:29 +0200582 def test_getsource_on_code_object(self):
583 self.assertSourceEqual(mod.eggs.__code__, 12, 18)
584
Vladimir Matveev91cb2982018-08-24 07:18:00 -0700585class TestGettingSourceOfToplevelFrames(GetSourceBase):
586 fodderModule = mod
587
588 def test_range_toplevel_frame(self):
589 self.maxDiff = None
590 self.assertSourceEqual(mod.currentframe, 1, None)
591
592 def test_range_traceback_toplevel_frame(self):
593 self.assertSourceEqual(mod.tb, 1, None)
594
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000595class TestDecorators(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000596 fodderModule = mod2
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000597
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000598 def test_wrapped_decorator(self):
Christian Heimes09aaa882008-02-23 15:01:06 +0000599 self.assertSourceEqual(mod2.wrapped, 14, 17)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000600
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000601 def test_replacing_decorator(self):
602 self.assertSourceEqual(mod2.gone, 9, 10)
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000603
Yury Selivanov081bbf62014-09-26 17:34:54 -0400604 def test_getsource_unwrap(self):
Antoine Pitroua8723a02015-04-15 00:41:29 +0200605 self.assertSourceEqual(mod2.real, 130, 132)
606
607 def test_decorator_with_lambda(self):
608 self.assertSourceEqual(mod2.func114, 113, 115)
Yury Selivanov081bbf62014-09-26 17:34:54 -0400609
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000610class TestOneliners(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000611 fodderModule = mod2
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000612 def test_oneline_lambda(self):
613 # Test inspect.getsource with a one-line lambda function.
614 self.assertSourceEqual(mod2.oll, 25, 25)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000615
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000616 def test_threeline_lambda(self):
617 # Test inspect.getsource with a three-line lambda function,
618 # where the second and third lines are _not_ indented.
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000619 self.assertSourceEqual(mod2.tll, 28, 30)
620
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000621 def test_twoline_indented_lambda(self):
622 # Test inspect.getsource with a two-line lambda function,
623 # where the second line _is_ indented.
624 self.assertSourceEqual(mod2.tlli, 33, 34)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000625
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000626 def test_onelinefunc(self):
627 # Test inspect.getsource with a regular one-line function.
628 self.assertSourceEqual(mod2.onelinefunc, 37, 37)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000629
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000630 def test_manyargs(self):
631 # Test inspect.getsource with a regular function where
632 # the arguments are on two lines and _not_ indented and
633 # the body on the second line with the last arguments.
634 self.assertSourceEqual(mod2.manyargs, 40, 41)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000635
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000636 def test_twolinefunc(self):
637 # Test inspect.getsource with a regular function where
638 # the body is on two lines, following the argument list and
639 # continued on the next line by a \\.
640 self.assertSourceEqual(mod2.twolinefunc, 44, 45)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000641
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000642 def test_lambda_in_list(self):
643 # Test inspect.getsource with a one-line lambda function
644 # defined in a list, indented.
645 self.assertSourceEqual(mod2.a[1], 49, 49)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000646
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000647 def test_anonymous(self):
648 # Test inspect.getsource with a lambda function defined
649 # as argument to another function.
650 self.assertSourceEqual(mod2.anonymous, 55, 55)
651
Irit Katriel6e1eec72020-12-04 16:45:38 +0000652class TestBlockComments(GetSourceBase):
653 fodderModule = mod
654
655 def test_toplevel_class(self):
656 self.assertSourceEqual(mod.WhichComments, 96, 114)
657
658 def test_class_method(self):
659 self.assertSourceEqual(mod.WhichComments.f, 99, 104)
660
661 def test_class_async_method(self):
662 self.assertSourceEqual(mod.WhichComments.asyncf, 109, 112)
663
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000664class TestBuggyCases(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000665 fodderModule = mod2
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000666
667 def test_with_comment(self):
668 self.assertSourceEqual(mod2.with_comment, 58, 59)
669
670 def test_multiline_sig(self):
671 self.assertSourceEqual(mod2.multiline_sig[0], 63, 64)
672
Armin Rigodd5c0232005-09-25 11:45:45 +0000673 def test_nested_class(self):
674 self.assertSourceEqual(mod2.func69().func71, 71, 72)
675
676 def test_one_liner_followed_by_non_name(self):
677 self.assertSourceEqual(mod2.func77, 77, 77)
678
679 def test_one_liner_dedent_non_name(self):
680 self.assertSourceEqual(mod2.cls82.func83, 83, 83)
681
682 def test_with_comment_instead_of_docstring(self):
683 self.assertSourceEqual(mod2.func88, 88, 90)
684
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000685 def test_method_in_dynamic_class(self):
686 self.assertSourceEqual(mod2.method_in_dynamic_class, 95, 97)
687
R David Murray32562d72014-10-03 11:15:38 -0400688 # This should not skip for CPython, but might on a repackaged python where
689 # unicodedata is not an external module, or on pypy.
690 @unittest.skipIf(not hasattr(unicodedata, '__file__') or
691 unicodedata.__file__.endswith('.py'),
692 "unicodedata is not an external binary module")
R. David Murray74b89242009-05-13 17:33:03 +0000693 def test_findsource_binary(self):
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200694 self.assertRaises(OSError, inspect.getsource, unicodedata)
695 self.assertRaises(OSError, inspect.findsource, unicodedata)
R. David Murray74b89242009-05-13 17:33:03 +0000696
R. David Murraya1b37402010-06-17 02:04:29 +0000697 def test_findsource_code_in_linecache(self):
698 lines = ["x=1"]
699 co = compile(lines[0], "_dynamically_created_file", "exec")
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200700 self.assertRaises(OSError, inspect.findsource, co)
701 self.assertRaises(OSError, inspect.getsource, co)
R. David Murraya1b37402010-06-17 02:04:29 +0000702 linecache.cache[co.co_filename] = (1, None, lines, co.co_filename)
Antoine Pitrou5d62a612012-07-08 13:48:46 +0200703 try:
704 self.assertEqual(inspect.findsource(co), (lines,0))
705 self.assertEqual(inspect.getsource(co), lines[0])
706 finally:
707 del linecache.cache[co.co_filename]
R. David Murraya1b37402010-06-17 02:04:29 +0000708
Ezio Melotti1b145922013-03-30 05:17:24 +0200709 def test_findsource_without_filename(self):
710 for fname in ['', '<string>']:
711 co = compile('x=1', fname, "exec")
712 self.assertRaises(IOError, inspect.findsource, co)
713 self.assertRaises(IOError, inspect.getsource, co)
714
Antoine Pitroua8723a02015-04-15 00:41:29 +0200715 def test_getsource_on_method(self):
716 self.assertSourceEqual(mod2.ClassWithMethod.method, 118, 119)
717
Yury Selivanov4f4913b2015-07-23 17:10:00 +0300718 def test_nested_func(self):
719 self.assertSourceEqual(mod2.cls135.func136, 136, 139)
720
Karthikeyan Singaravelan696136b2020-04-18 21:49:32 +0530721 def test_class_definition_in_multiline_string_definition(self):
722 self.assertSourceEqual(mod2.cls149, 149, 152)
723
724 def test_class_definition_in_multiline_comment(self):
725 self.assertSourceEqual(mod2.cls160, 160, 163)
726
727 def test_nested_class_definition_indented_string(self):
728 self.assertSourceEqual(mod2.cls173.cls175, 175, 176)
729
730 def test_nested_class_definition(self):
731 self.assertSourceEqual(mod2.cls183, 183, 188)
732 self.assertSourceEqual(mod2.cls183.cls185, 185, 188)
733
734 def test_class_decorator(self):
735 self.assertSourceEqual(mod2.cls196, 194, 201)
736 self.assertSourceEqual(mod2.cls196.cls200, 198, 201)
737
738 def test_class_inside_conditional(self):
739 self.assertSourceEqual(mod2.cls238, 238, 240)
740 self.assertSourceEqual(mod2.cls238.cls239, 239, 240)
741
742 def test_multiple_children_classes(self):
743 self.assertSourceEqual(mod2.cls203, 203, 209)
744 self.assertSourceEqual(mod2.cls203.cls204, 204, 206)
745 self.assertSourceEqual(mod2.cls203.cls204.cls205, 205, 206)
746 self.assertSourceEqual(mod2.cls203.cls207, 207, 209)
747 self.assertSourceEqual(mod2.cls203.cls207.cls205, 208, 209)
748
749 def test_nested_class_definition_inside_function(self):
750 self.assertSourceEqual(mod2.func212(), 213, 214)
751 self.assertSourceEqual(mod2.cls213, 218, 222)
752 self.assertSourceEqual(mod2.cls213().func219(), 220, 221)
753
754 def test_nested_class_definition_inside_async_function(self):
755 import asyncio
756 self.addCleanup(asyncio.set_event_loop_policy, None)
757 self.assertSourceEqual(asyncio.run(mod2.func225()), 226, 227)
758 self.assertSourceEqual(mod2.cls226, 231, 235)
759 self.assertSourceEqual(asyncio.run(mod2.cls226().func232()), 233, 234)
Yury Selivanov4f4913b2015-07-23 17:10:00 +0300760
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000761class TestNoEOL(GetSourceBase):
Yury Selivanov6738b112015-05-16 10:10:21 -0400762 def setUp(self):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000763 self.tempdir = TESTFN + '_dir'
764 os.mkdir(self.tempdir)
765 with open(os.path.join(self.tempdir,
766 'inspect_fodder3%spy' % os.extsep), 'w') as f:
767 f.write("class X:\n pass # No EOL")
768 with DirsOnSysPath(self.tempdir):
769 import inspect_fodder3 as mod3
770 self.fodderModule = mod3
Yury Selivanov6738b112015-05-16 10:10:21 -0400771 super().setUp()
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000772
773 def tearDown(self):
774 shutil.rmtree(self.tempdir)
775
776 def test_class(self):
777 self.assertSourceEqual(self.fodderModule.X, 1, 2)
778
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100779
780class _BrokenDataDescriptor(object):
781 """
782 A broken data descriptor. See bug #1785.
783 """
784 def __get__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700785 raise AttributeError("broken data descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100786
787 def __set__(*args):
788 raise RuntimeError
789
790 def __getattr__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700791 raise AttributeError("broken data descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100792
793
794class _BrokenMethodDescriptor(object):
795 """
796 A broken method descriptor. See bug #1785.
797 """
798 def __get__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700799 raise AttributeError("broken method descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100800
801 def __getattr__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700802 raise AttributeError("broken method descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100803
804
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000805# Helper for testing classify_class_attrs.
Tim Peters13b49d32001-09-23 02:00:29 +0000806def attrs_wo_objs(cls):
807 return [t[:3] for t in inspect.classify_class_attrs(cls)]
808
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100809
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000810class TestClassesAndFunctions(unittest.TestCase):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000811 def test_newstyle_mro(self):
812 # The same w/ new-class MRO.
813 class A(object): pass
814 class B(A): pass
815 class C(A): pass
816 class D(B, C): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000817
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000818 expected = (D, B, C, A, object)
819 got = inspect.getmro(D)
820 self.assertEqual(expected, got)
Tim Peters13b49d32001-09-23 02:00:29 +0000821
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500822 def assertArgSpecEquals(self, routine, args_e, varargs_e=None,
823 varkw_e=None, defaults_e=None, formatted=None):
Xtreak6d0b7472019-05-30 17:31:39 +0530824 with self.assertWarns(DeprecationWarning):
825 args, varargs, varkw, defaults = inspect.getargspec(routine)
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500826 self.assertEqual(args, args_e)
827 self.assertEqual(varargs, varargs_e)
828 self.assertEqual(varkw, varkw_e)
829 self.assertEqual(defaults, defaults_e)
830 if formatted is not None:
Xtreak6d0b7472019-05-30 17:31:39 +0530831 with self.assertWarns(DeprecationWarning):
832 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults),
833 formatted)
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500834
Christian Heimes3795b532007-11-08 13:48:53 +0000835 def assertFullArgSpecEquals(self, routine, args_e, varargs_e=None,
836 varkw_e=None, defaults_e=None,
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100837 posonlyargs_e=[], kwonlyargs_e=[],
838 kwonlydefaults_e=None,
Christian Heimes3795b532007-11-08 13:48:53 +0000839 ann_e={}, formatted=None):
Pablo Galindoaee19f52019-05-16 21:08:15 +0100840 args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \
841 inspect.getfullargspec(routine)
Christian Heimes3795b532007-11-08 13:48:53 +0000842 self.assertEqual(args, args_e)
843 self.assertEqual(varargs, varargs_e)
844 self.assertEqual(varkw, varkw_e)
845 self.assertEqual(defaults, defaults_e)
846 self.assertEqual(kwonlyargs, kwonlyargs_e)
847 self.assertEqual(kwonlydefaults, kwonlydefaults_e)
848 self.assertEqual(ann, ann_e)
849 if formatted is not None:
Xtreak6d0b7472019-05-30 17:31:39 +0530850 with self.assertWarns(DeprecationWarning):
851 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults,
852 kwonlyargs, kwonlydefaults, ann),
853 formatted)
Christian Heimes3795b532007-11-08 13:48:53 +0000854
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500855 def test_getargspec(self):
856 self.assertArgSpecEquals(mod.eggs, ['x', 'y'], formatted='(x, y)')
857
Pablo Galindod5d2b452019-04-30 02:01:14 +0100858 self.assertArgSpecEquals(mod.spam,
859 ['a', 'b', 'c', 'd', 'e', 'f'],
860 'g', 'h', (3, 4, 5),
861 '(a, b, c, d=3, e=4, f=5, *g, **h)')
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500862
863 self.assertRaises(ValueError, self.assertArgSpecEquals,
864 mod2.keyworded, [])
865
866 self.assertRaises(ValueError, self.assertArgSpecEquals,
867 mod2.annotated, [])
868 self.assertRaises(ValueError, self.assertArgSpecEquals,
869 mod2.keyword_only_arg, [])
870
871
Christian Heimes3795b532007-11-08 13:48:53 +0000872 def test_getfullargspec(self):
873 self.assertFullArgSpecEquals(mod2.keyworded, [], varargs_e='arg1',
874 kwonlyargs_e=['arg2'],
875 kwonlydefaults_e={'arg2':1},
876 formatted='(*arg1, arg2=1)')
877
878 self.assertFullArgSpecEquals(mod2.annotated, ['arg1'],
Christian Heimesc9543e42007-11-28 08:28:28 +0000879 ann_e={'arg1' : list},
Batuhan Taskaya044a1042020-10-06 23:03:02 +0300880 formatted="(arg1: list)")
Benjamin Peterson9953a8d2009-01-17 04:15:01 +0000881 self.assertFullArgSpecEquals(mod2.keyword_only_arg, [],
882 kwonlyargs_e=['arg'],
883 formatted='(*, arg)')
884
Pablo Galindod5d2b452019-04-30 02:01:14 +0100885 self.assertFullArgSpecEquals(mod2.all_markers, ['a', 'b', 'c', 'd'],
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100886 kwonlyargs_e=['e', 'f'],
Pablo Galindod5d2b452019-04-30 02:01:14 +0100887 formatted='(a, b, c, d, *, e, f)')
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100888
889 self.assertFullArgSpecEquals(mod2.all_markers_with_args_and_kwargs,
Pablo Galindod5d2b452019-04-30 02:01:14 +0100890 ['a', 'b', 'c', 'd'],
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100891 varargs_e='args',
892 varkw_e='kwargs',
893 kwonlyargs_e=['e', 'f'],
Pablo Galindod5d2b452019-04-30 02:01:14 +0100894 formatted='(a, b, c, d, *args, e, f, **kwargs)')
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100895
Pablo Galindod5d2b452019-04-30 02:01:14 +0100896 self.assertFullArgSpecEquals(mod2.all_markers_with_defaults, ['a', 'b', 'c', 'd'],
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100897 defaults_e=(1,2,3),
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100898 kwonlyargs_e=['e', 'f'],
899 kwonlydefaults_e={'e': 4, 'f': 5},
Pablo Galindod5d2b452019-04-30 02:01:14 +0100900 formatted='(a, b=1, c=2, d=3, *, e=4, f=5)')
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100901
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500902 def test_argspec_api_ignores_wrapped(self):
Yury Selivanov57d240e2014-02-19 16:27:23 -0500903 # Issue 20684: low level introspection API must ignore __wrapped__
904 @functools.wraps(mod.spam)
905 def ham(x, y):
906 pass
907 # Basic check
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500908 self.assertArgSpecEquals(ham, ['x', 'y'], formatted='(x, y)')
Yury Selivanov57d240e2014-02-19 16:27:23 -0500909 self.assertFullArgSpecEquals(ham, ['x', 'y'], formatted='(x, y)')
910 self.assertFullArgSpecEquals(functools.partial(ham),
911 ['x', 'y'], formatted='(x, y)')
912 # Other variants
913 def check_method(f):
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500914 self.assertArgSpecEquals(f, ['self', 'x', 'y'],
915 formatted='(self, x, y)')
Yury Selivanov57d240e2014-02-19 16:27:23 -0500916 class C:
917 @functools.wraps(mod.spam)
918 def ham(self, x, y):
919 pass
920 pham = functools.partialmethod(ham)
921 @functools.wraps(mod.spam)
922 def __call__(self, x, y):
923 pass
924 check_method(C())
925 check_method(C.ham)
926 check_method(C().ham)
927 check_method(C.pham)
928 check_method(C().pham)
929
930 class C_new:
931 @functools.wraps(mod.spam)
932 def __new__(self, x, y):
933 pass
934 check_method(C_new)
935
936 class C_init:
937 @functools.wraps(mod.spam)
938 def __init__(self, x, y):
939 pass
940 check_method(C_init)
941
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500942 def test_getfullargspec_signature_attr(self):
943 def test():
944 pass
945 spam_param = inspect.Parameter('spam', inspect.Parameter.POSITIONAL_ONLY)
946 test.__signature__ = inspect.Signature(parameters=(spam_param,))
947
Pablo Galindod5d2b452019-04-30 02:01:14 +0100948 self.assertFullArgSpecEquals(test, ['spam'], formatted='(spam)')
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500949
Yury Selivanov4cb93912014-01-29 11:54:12 -0500950 def test_getfullargspec_signature_annos(self):
951 def test(a:'spam') -> 'ham': pass
Pablo Galindoaee19f52019-05-16 21:08:15 +0100952 spec = inspect.getfullargspec(test)
Yury Selivanov4cb93912014-01-29 11:54:12 -0500953 self.assertEqual(test.__annotations__, spec.annotations)
954
955 def test(): pass
Pablo Galindoaee19f52019-05-16 21:08:15 +0100956 spec = inspect.getfullargspec(test)
Yury Selivanov4cb93912014-01-29 11:54:12 -0500957 self.assertEqual(test.__annotations__, spec.annotations)
958
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500959 @unittest.skipIf(MISSING_C_DOCSTRINGS,
960 "Signature information for builtins requires docstrings")
961 def test_getfullargspec_builtin_methods(self):
Pablo Galindod5d2b452019-04-30 02:01:14 +0100962 self.assertFullArgSpecEquals(_pickle.Pickler.dump, ['self', 'obj'],
963 formatted='(self, obj)')
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500964
Pablo Galindod5d2b452019-04-30 02:01:14 +0100965 self.assertFullArgSpecEquals(_pickle.Pickler(io.BytesIO()).dump, ['self', 'obj'],
966 formatted='(self, obj)')
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500967
Yury Selivanov8c185ee2014-02-21 01:32:42 -0500968 self.assertFullArgSpecEquals(
969 os.stat,
970 args_e=['path'],
971 kwonlyargs_e=['dir_fd', 'follow_symlinks'],
972 kwonlydefaults_e={'dir_fd': None, 'follow_symlinks': True},
973 formatted='(path, *, dir_fd=None, follow_symlinks=True)')
974
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200975 @cpython_only
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500976 @unittest.skipIf(MISSING_C_DOCSTRINGS,
977 "Signature information for builtins requires docstrings")
Chih-Hsuan Yenc57eb9a2018-10-04 21:15:00 +0800978 def test_getfullargspec_builtin_func(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200979 import _testcapi
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500980 builtin = _testcapi.docstring_with_signature_with_defaults
Pablo Galindoaee19f52019-05-16 21:08:15 +0100981 spec = inspect.getfullargspec(builtin)
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500982 self.assertEqual(spec.defaults[0], 'avocado')
983
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200984 @cpython_only
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500985 @unittest.skipIf(MISSING_C_DOCSTRINGS,
986 "Signature information for builtins requires docstrings")
Chih-Hsuan Yenc57eb9a2018-10-04 21:15:00 +0800987 def test_getfullargspec_builtin_func_no_signature(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200988 import _testcapi
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500989 builtin = _testcapi.docstring_no_signature
Pablo Galindoaee19f52019-05-16 21:08:15 +0100990 with self.assertRaises(TypeError):
991 inspect.getfullargspec(builtin)
Christian Heimes3795b532007-11-08 13:48:53 +0000992
larryhastingsf36ba122018-01-28 11:13:09 -0800993 def test_getfullargspec_definition_order_preserved_on_kwonly(self):
994 for fn in signatures_with_lexicographic_keyword_only_parameters():
Pablo Galindoaee19f52019-05-16 21:08:15 +0100995 signature = inspect.getfullargspec(fn)
larryhastingsf36ba122018-01-28 11:13:09 -0800996 l = list(signature.kwonlyargs)
997 sorted_l = sorted(l)
998 self.assertTrue(l)
999 self.assertEqual(l, sorted_l)
Pablo Galindoaee19f52019-05-16 21:08:15 +01001000 signature = inspect.getfullargspec(unsorted_keyword_only_parameters_fn)
larryhastingsf36ba122018-01-28 11:13:09 -08001001 l = list(signature.kwonlyargs)
1002 self.assertEqual(l, unsorted_keyword_only_parameters)
1003
Yury Selivanov37dc2b22016-01-11 15:15:01 -05001004 def test_getargspec_method(self):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001005 class A(object):
1006 def m(self):
1007 pass
Yury Selivanov37dc2b22016-01-11 15:15:01 -05001008 self.assertArgSpecEquals(A.m, ['self'])
Tim Peters13b49d32001-09-23 02:00:29 +00001009
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001010 def test_classify_newstyle(self):
1011 class A(object):
Tim Peters13b49d32001-09-23 02:00:29 +00001012
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001013 def s(): pass
1014 s = staticmethod(s)
Tim Peters13b49d32001-09-23 02:00:29 +00001015
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001016 def c(cls): pass
1017 c = classmethod(c)
Tim Peters13b49d32001-09-23 02:00:29 +00001018
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001019 def getp(self): pass
1020 p = property(getp)
Tim Peters13b49d32001-09-23 02:00:29 +00001021
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001022 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +00001023
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001024 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +00001025
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001026 datablob = '1'
Tim Peters13b49d32001-09-23 02:00:29 +00001027
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +01001028 dd = _BrokenDataDescriptor()
1029 md = _BrokenMethodDescriptor()
1030
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001031 attrs = attrs_wo_objs(A)
Yury Selivanov0860a0b2014-01-31 14:28:44 -05001032
Serhiy Storchaka3327a2d2017-12-15 14:13:41 +02001033 self.assertIn(('__new__', 'static method', object), attrs,
1034 'missing __new__')
Yury Selivanov0860a0b2014-01-31 14:28:44 -05001035 self.assertIn(('__init__', 'method', object), attrs, 'missing __init__')
1036
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')
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001040 self.assertIn(('m', 'method', A), attrs,
1041 'missing plain method: %r' % attrs)
Benjamin Peterson577473f2010-01-19 00:09:57 +00001042 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
1043 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +01001044 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
1045 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +00001046
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001047 class B(A):
Tim Peters13b49d32001-09-23 02:00:29 +00001048
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001049 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +00001050
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001051 attrs = attrs_wo_objs(B)
Benjamin Peterson577473f2010-01-19 00:09:57 +00001052 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
1053 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
1054 self.assertIn(('p', 'property', A), attrs, 'missing property')
1055 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
1056 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
1057 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +01001058 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
1059 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +00001060
1061
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001062 class C(A):
Tim Peters13b49d32001-09-23 02:00:29 +00001063
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001064 def m(self): pass
1065 def c(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +00001066
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001067 attrs = attrs_wo_objs(C)
Benjamin Peterson577473f2010-01-19 00:09:57 +00001068 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
1069 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
1070 self.assertIn(('p', 'property', A), attrs, 'missing property')
1071 self.assertIn(('m', 'method', C), attrs, 'missing plain method')
1072 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
1073 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +01001074 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
1075 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +00001076
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001077 class D(B, C):
Tim Peters13b49d32001-09-23 02:00:29 +00001078
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001079 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +00001080
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001081 attrs = attrs_wo_objs(D)
Benjamin Peterson577473f2010-01-19 00:09:57 +00001082 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
1083 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
1084 self.assertIn(('p', 'property', A), attrs, 'missing property')
1085 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
1086 self.assertIn(('m1', 'method', D), attrs, 'missing plain method')
1087 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +01001088 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
1089 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
1090
1091 def test_classify_builtin_types(self):
1092 # Simple sanity check that all built-in types can have their
1093 # attributes classified.
1094 for name in dir(__builtins__):
1095 builtin = getattr(__builtins__, name)
1096 if isinstance(builtin, type):
1097 inspect.classify_class_attrs(builtin)
1098
Serhiy Storchaka3327a2d2017-12-15 14:13:41 +02001099 attrs = attrs_wo_objs(bool)
1100 self.assertIn(('__new__', 'static method', bool), attrs,
1101 'missing __new__')
1102 self.assertIn(('from_bytes', 'class method', int), attrs,
1103 'missing class method')
1104 self.assertIn(('to_bytes', 'method', int), attrs,
1105 'missing plain method')
1106 self.assertIn(('__add__', 'method', int), attrs,
1107 'missing plain method')
1108 self.assertIn(('__and__', 'method', bool), attrs,
1109 'missing plain method')
1110
Ethan Furman63c141c2013-10-18 00:27:39 -07001111 def test_classify_DynamicClassAttribute(self):
1112 class Meta(type):
1113 def __getattr__(self, name):
1114 if name == 'ham':
1115 return 'spam'
1116 return super().__getattr__(name)
1117 class VA(metaclass=Meta):
Ethan Furmane03ea372013-09-25 07:14:41 -07001118 @types.DynamicClassAttribute
1119 def ham(self):
1120 return 'eggs'
Ethan Furman63c141c2013-10-18 00:27:39 -07001121 should_find_dca = inspect.Attribute('ham', 'data', VA, VA.__dict__['ham'])
1122 self.assertIn(should_find_dca, inspect.classify_class_attrs(VA))
Ethan Furmanb0c84cd2013-10-20 22:37:39 -07001123 should_find_ga = inspect.Attribute('ham', 'data', Meta, 'spam')
Ethan Furman63c141c2013-10-18 00:27:39 -07001124 self.assertIn(should_find_ga, inspect.classify_class_attrs(VA))
1125
Yury Selivanovbf341fb2015-05-21 15:41:57 -04001126 def test_classify_overrides_bool(self):
1127 class NoBool(object):
1128 def __eq__(self, other):
1129 return NoBool()
1130
1131 def __bool__(self):
1132 raise NotImplementedError(
1133 "This object does not specify a boolean value")
1134
1135 class HasNB(object):
1136 dd = NoBool()
1137
1138 should_find_attr = inspect.Attribute('dd', 'data', HasNB, HasNB.dd)
1139 self.assertIn(should_find_attr, inspect.classify_class_attrs(HasNB))
1140
Ethan Furmanb0c84cd2013-10-20 22:37:39 -07001141 def test_classify_metaclass_class_attribute(self):
1142 class Meta(type):
1143 fish = 'slap'
1144 def __dir__(self):
Serhiy Storchakaa60c2fe2015-03-12 21:56:08 +02001145 return ['__class__', '__module__', '__name__', 'fish']
Ethan Furmanb0c84cd2013-10-20 22:37:39 -07001146 class Class(metaclass=Meta):
1147 pass
1148 should_find = inspect.Attribute('fish', 'data', Meta, 'slap')
1149 self.assertIn(should_find, inspect.classify_class_attrs(Class))
1150
Ethan Furman63c141c2013-10-18 00:27:39 -07001151 def test_classify_VirtualAttribute(self):
1152 class Meta(type):
1153 def __dir__(cls):
1154 return ['__class__', '__module__', '__name__', 'BOOM']
1155 def __getattr__(self, name):
1156 if name =='BOOM':
1157 return 42
1158 return super().__getattr(name)
1159 class Class(metaclass=Meta):
1160 pass
Ethan Furmanb0c84cd2013-10-20 22:37:39 -07001161 should_find = inspect.Attribute('BOOM', 'data', Meta, 42)
Ethan Furman63c141c2013-10-18 00:27:39 -07001162 self.assertIn(should_find, inspect.classify_class_attrs(Class))
1163
1164 def test_classify_VirtualAttribute_multi_classes(self):
1165 class Meta1(type):
1166 def __dir__(cls):
1167 return ['__class__', '__module__', '__name__', 'one']
1168 def __getattr__(self, name):
1169 if name =='one':
1170 return 1
1171 return super().__getattr__(name)
1172 class Meta2(type):
1173 def __dir__(cls):
1174 return ['__class__', '__module__', '__name__', 'two']
1175 def __getattr__(self, name):
1176 if name =='two':
1177 return 2
1178 return super().__getattr__(name)
1179 class Meta3(Meta1, Meta2):
1180 def __dir__(cls):
1181 return list(sorted(set(['__class__', '__module__', '__name__', 'three'] +
1182 Meta1.__dir__(cls) + Meta2.__dir__(cls))))
1183 def __getattr__(self, name):
1184 if name =='three':
1185 return 3
1186 return super().__getattr__(name)
1187 class Class1(metaclass=Meta1):
1188 pass
1189 class Class2(Class1, metaclass=Meta3):
1190 pass
1191
Ethan Furmanb0c84cd2013-10-20 22:37:39 -07001192 should_find1 = inspect.Attribute('one', 'data', Meta1, 1)
1193 should_find2 = inspect.Attribute('two', 'data', Meta2, 2)
1194 should_find3 = inspect.Attribute('three', 'data', Meta3, 3)
Ethan Furman63c141c2013-10-18 00:27:39 -07001195 cca = inspect.classify_class_attrs(Class2)
1196 for sf in (should_find1, should_find2, should_find3):
1197 self.assertIn(sf, cca)
1198
1199 def test_classify_class_attrs_with_buggy_dir(self):
1200 class M(type):
1201 def __dir__(cls):
1202 return ['__class__', '__name__', 'missing']
1203 class C(metaclass=M):
1204 pass
1205 attrs = [a[0] for a in inspect.classify_class_attrs(C)]
1206 self.assertNotIn('missing', attrs)
Ethan Furmane03ea372013-09-25 07:14:41 -07001207
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +01001208 def test_getmembers_descriptors(self):
1209 class A(object):
1210 dd = _BrokenDataDescriptor()
1211 md = _BrokenMethodDescriptor()
1212
1213 def pred_wrapper(pred):
1214 # A quick'n'dirty way to discard standard attributes of new-style
1215 # classes.
1216 class Empty(object):
1217 pass
1218 def wrapped(x):
1219 if '__name__' in dir(x) and hasattr(Empty, x.__name__):
1220 return False
1221 return pred(x)
1222 return wrapped
1223
1224 ismethoddescriptor = pred_wrapper(inspect.ismethoddescriptor)
1225 isdatadescriptor = pred_wrapper(inspect.isdatadescriptor)
1226
1227 self.assertEqual(inspect.getmembers(A, ismethoddescriptor),
1228 [('md', A.__dict__['md'])])
1229 self.assertEqual(inspect.getmembers(A, isdatadescriptor),
1230 [('dd', A.__dict__['dd'])])
1231
1232 class B(A):
1233 pass
1234
1235 self.assertEqual(inspect.getmembers(B, ismethoddescriptor),
1236 [('md', A.__dict__['md'])])
1237 self.assertEqual(inspect.getmembers(B, isdatadescriptor),
1238 [('dd', A.__dict__['dd'])])
1239
Antoine Pitrou0c603812012-01-18 17:40:18 +01001240 def test_getmembers_method(self):
1241 class B:
1242 def f(self):
1243 pass
1244
1245 self.assertIn(('f', B.f), inspect.getmembers(B))
1246 self.assertNotIn(('f', B.f), inspect.getmembers(B, inspect.ismethod))
1247 b = B()
1248 self.assertIn(('f', b.f), inspect.getmembers(b))
1249 self.assertIn(('f', b.f), inspect.getmembers(b, inspect.ismethod))
1250
Ethan Furmane03ea372013-09-25 07:14:41 -07001251 def test_getmembers_VirtualAttribute(self):
Ethan Furman63c141c2013-10-18 00:27:39 -07001252 class M(type):
1253 def __getattr__(cls, name):
1254 if name == 'eggs':
1255 return 'scrambled'
1256 return super().__getattr__(name)
1257 class A(metaclass=M):
Ethan Furmane03ea372013-09-25 07:14:41 -07001258 @types.DynamicClassAttribute
1259 def eggs(self):
1260 return 'spam'
Ethan Furman63c141c2013-10-18 00:27:39 -07001261 self.assertIn(('eggs', 'scrambled'), inspect.getmembers(A))
1262 self.assertIn(('eggs', 'spam'), inspect.getmembers(A()))
1263
1264 def test_getmembers_with_buggy_dir(self):
1265 class M(type):
1266 def __dir__(cls):
1267 return ['__class__', '__name__', 'missing']
1268 class C(metaclass=M):
1269 pass
1270 attrs = [a[0] for a in inspect.getmembers(C)]
1271 self.assertNotIn('missing', attrs)
Ethan Furmane03ea372013-09-25 07:14:41 -07001272
Aaron Hall, MBA4054b172018-05-20 19:46:42 -04001273class TestIsDataDescriptor(unittest.TestCase):
1274
1275 def test_custom_descriptors(self):
1276 class NonDataDescriptor:
1277 def __get__(self, value, type=None): pass
1278 class DataDescriptor0:
1279 def __set__(self, name, value): pass
1280 class DataDescriptor1:
1281 def __delete__(self, name): pass
1282 class DataDescriptor2:
1283 __set__ = None
1284 self.assertFalse(inspect.isdatadescriptor(NonDataDescriptor()),
1285 'class with only __get__ not a data descriptor')
1286 self.assertTrue(inspect.isdatadescriptor(DataDescriptor0()),
1287 'class with __set__ is a data descriptor')
1288 self.assertTrue(inspect.isdatadescriptor(DataDescriptor1()),
1289 'class with __delete__ is a data descriptor')
1290 self.assertTrue(inspect.isdatadescriptor(DataDescriptor2()),
1291 'class with __set__ = None is a data descriptor')
1292
1293 def test_slot(self):
1294 class Slotted:
1295 __slots__ = 'foo',
1296 self.assertTrue(inspect.isdatadescriptor(Slotted.foo),
1297 'a slot is a data descriptor')
1298
1299 def test_property(self):
1300 class Propertied:
1301 @property
1302 def a_property(self):
1303 pass
1304 self.assertTrue(inspect.isdatadescriptor(Propertied.a_property),
1305 'a property is a data descriptor')
1306
1307 def test_functions(self):
1308 class Test(object):
1309 def instance_method(self): pass
1310 @classmethod
1311 def class_method(cls): pass
1312 @staticmethod
1313 def static_method(): pass
1314 def function():
1315 pass
1316 a_lambda = lambda: None
1317 self.assertFalse(inspect.isdatadescriptor(Test().instance_method),
1318 'a instance method is not a data descriptor')
1319 self.assertFalse(inspect.isdatadescriptor(Test().class_method),
1320 'a class method is not a data descriptor')
1321 self.assertFalse(inspect.isdatadescriptor(Test().static_method),
1322 'a static method is not a data descriptor')
1323 self.assertFalse(inspect.isdatadescriptor(function),
1324 'a function is not a data descriptor')
1325 self.assertFalse(inspect.isdatadescriptor(a_lambda),
1326 'a lambda is not a data descriptor')
1327
Jeremy Hyltonc4bf5ed2003-06-27 18:43:12 +00001328
Nick Coghlan2f92e542012-06-23 19:39:55 +10001329_global_ref = object()
1330class TestGetClosureVars(unittest.TestCase):
1331
1332 def test_name_resolution(self):
1333 # Basic test of the 4 different resolution mechanisms
1334 def f(nonlocal_ref):
1335 def g(local_ref):
1336 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
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_generator_closure(self):
1348 def f(nonlocal_ref):
1349 def g(local_ref):
1350 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
1351 yield
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(f(_arg)), expected)
1361
1362 def test_method_closure(self):
1363 class C:
1364 def f(self, nonlocal_ref):
1365 def g(local_ref):
1366 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
1367 return g
1368 _arg = object()
1369 nonlocal_vars = {"nonlocal_ref": _arg}
1370 global_vars = {"_global_ref": _global_ref}
1371 builtin_vars = {"print": print}
1372 unbound_names = {"unbound_ref"}
1373 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
1374 builtin_vars, unbound_names)
1375 self.assertEqual(inspect.getclosurevars(C().f(_arg)), expected)
1376
1377 def test_nonlocal_vars(self):
1378 # More complex tests of nonlocal resolution
1379 def _nonlocal_vars(f):
1380 return inspect.getclosurevars(f).nonlocals
1381
1382 def make_adder(x):
1383 def add(y):
1384 return x + y
1385 return add
1386
1387 def curry(func, arg1):
1388 return lambda arg2: func(arg1, arg2)
1389
1390 def less_than(a, b):
1391 return a < b
1392
1393 # The infamous Y combinator.
1394 def Y(le):
1395 def g(f):
1396 return le(lambda x: f(f)(x))
1397 Y.g_ref = g
1398 return g(g)
1399
1400 def check_y_combinator(func):
1401 self.assertEqual(_nonlocal_vars(func), {'f': Y.g_ref})
1402
1403 inc = make_adder(1)
1404 add_two = make_adder(2)
1405 greater_than_five = curry(less_than, 5)
1406
1407 self.assertEqual(_nonlocal_vars(inc), {'x': 1})
1408 self.assertEqual(_nonlocal_vars(add_two), {'x': 2})
1409 self.assertEqual(_nonlocal_vars(greater_than_five),
1410 {'arg1': 5, 'func': less_than})
1411 self.assertEqual(_nonlocal_vars((lambda x: lambda y: x + y)(3)),
1412 {'x': 3})
1413 Y(check_y_combinator)
1414
1415 def test_getclosurevars_empty(self):
1416 def foo(): pass
1417 _empty = inspect.ClosureVars({}, {}, {}, set())
1418 self.assertEqual(inspect.getclosurevars(lambda: True), _empty)
1419 self.assertEqual(inspect.getclosurevars(foo), _empty)
1420
1421 def test_getclosurevars_error(self):
1422 class T: pass
1423 self.assertRaises(TypeError, inspect.getclosurevars, 1)
1424 self.assertRaises(TypeError, inspect.getclosurevars, list)
1425 self.assertRaises(TypeError, inspect.getclosurevars, {})
1426
Nick Coghlan6c6e2542012-06-23 20:07:39 +10001427 def _private_globals(self):
1428 code = """def f(): print(path)"""
1429 ns = {}
1430 exec(code, ns)
1431 return ns["f"], ns
1432
1433 def test_builtins_fallback(self):
1434 f, ns = self._private_globals()
1435 ns.pop("__builtins__", None)
1436 expected = inspect.ClosureVars({}, {}, {"print":print}, {"path"})
1437 self.assertEqual(inspect.getclosurevars(f), expected)
1438
1439 def test_builtins_as_dict(self):
1440 f, ns = self._private_globals()
1441 ns["__builtins__"] = {"path":1}
1442 expected = inspect.ClosureVars({}, {}, {"path":1}, {"print"})
1443 self.assertEqual(inspect.getclosurevars(f), expected)
1444
1445 def test_builtins_as_module(self):
1446 f, ns = self._private_globals()
1447 ns["__builtins__"] = os
1448 expected = inspect.ClosureVars({}, {}, {"path":os.path}, {"print"})
1449 self.assertEqual(inspect.getclosurevars(f), expected)
1450
Nick Coghlan2f92e542012-06-23 19:39:55 +10001451
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001452class TestGetcallargsFunctions(unittest.TestCase):
1453
1454 def assertEqualCallArgs(self, func, call_params_string, locs=None):
1455 locs = dict(locs or {}, func=func)
1456 r1 = eval('func(%s)' % call_params_string, None, locs)
Pablo Galindoaee19f52019-05-16 21:08:15 +01001457 r2 = eval('inspect.getcallargs(func, %s)' % call_params_string, None,
1458 locs)
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001459 self.assertEqual(r1, r2)
1460
1461 def assertEqualException(self, func, call_param_string, locs=None):
1462 locs = dict(locs or {}, func=func)
1463 try:
1464 eval('func(%s)' % call_param_string, None, locs)
1465 except Exception as e:
1466 ex1 = e
1467 else:
1468 self.fail('Exception not raised')
1469 try:
Pablo Galindoaee19f52019-05-16 21:08:15 +01001470 eval('inspect.getcallargs(func, %s)' % call_param_string, None,
1471 locs)
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001472 except Exception as e:
1473 ex2 = e
1474 else:
1475 self.fail('Exception not raised')
1476 self.assertIs(type(ex1), type(ex2))
1477 self.assertEqual(str(ex1), str(ex2))
1478 del ex1, ex2
1479
1480 def makeCallable(self, signature):
1481 """Create a function that returns its locals()"""
1482 code = "lambda %s: locals()"
1483 return eval(code % signature)
1484
1485 def test_plain(self):
1486 f = self.makeCallable('a, b=1')
1487 self.assertEqualCallArgs(f, '2')
1488 self.assertEqualCallArgs(f, '2, 3')
1489 self.assertEqualCallArgs(f, 'a=2')
1490 self.assertEqualCallArgs(f, 'b=3, a=2')
1491 self.assertEqualCallArgs(f, '2, b=3')
1492 # expand *iterable / **mapping
1493 self.assertEqualCallArgs(f, '*(2,)')
1494 self.assertEqualCallArgs(f, '*[2]')
1495 self.assertEqualCallArgs(f, '*(2, 3)')
1496 self.assertEqualCallArgs(f, '*[2, 3]')
1497 self.assertEqualCallArgs(f, '**{"a":2}')
1498 self.assertEqualCallArgs(f, 'b=3, **{"a":2}')
1499 self.assertEqualCallArgs(f, '2, **{"b":3}')
1500 self.assertEqualCallArgs(f, '**{"b":3, "a":2}')
1501 # expand UserList / UserDict
1502 self.assertEqualCallArgs(f, '*collections.UserList([2])')
1503 self.assertEqualCallArgs(f, '*collections.UserList([2, 3])')
1504 self.assertEqualCallArgs(f, '**collections.UserDict(a=2)')
1505 self.assertEqualCallArgs(f, '2, **collections.UserDict(b=3)')
1506 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3)')
1507
1508 def test_varargs(self):
1509 f = self.makeCallable('a, b=1, *c')
1510 self.assertEqualCallArgs(f, '2')
1511 self.assertEqualCallArgs(f, '2, 3')
1512 self.assertEqualCallArgs(f, '2, 3, 4')
1513 self.assertEqualCallArgs(f, '*(2,3,4)')
1514 self.assertEqualCallArgs(f, '2, *[3,4]')
1515 self.assertEqualCallArgs(f, '2, 3, *collections.UserList([4])')
1516
1517 def test_varkw(self):
1518 f = self.makeCallable('a, b=1, **c')
1519 self.assertEqualCallArgs(f, 'a=2')
1520 self.assertEqualCallArgs(f, '2, b=3, c=4')
1521 self.assertEqualCallArgs(f, 'b=3, a=2, c=4')
1522 self.assertEqualCallArgs(f, 'c=4, **{"a":2, "b":3}')
1523 self.assertEqualCallArgs(f, '2, c=4, **{"b":3}')
1524 self.assertEqualCallArgs(f, 'b=2, **{"a":3, "c":4}')
1525 self.assertEqualCallArgs(f, '**collections.UserDict(a=2, b=3, c=4)')
1526 self.assertEqualCallArgs(f, '2, c=4, **collections.UserDict(b=3)')
1527 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3, c=4)')
1528
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001529 def test_varkw_only(self):
1530 # issue11256:
1531 f = self.makeCallable('**c')
1532 self.assertEqualCallArgs(f, '')
1533 self.assertEqualCallArgs(f, 'a=1')
1534 self.assertEqualCallArgs(f, 'a=1, b=2')
1535 self.assertEqualCallArgs(f, 'c=3, **{"a": 1, "b": 2}')
1536 self.assertEqualCallArgs(f, '**collections.UserDict(a=1, b=2)')
1537 self.assertEqualCallArgs(f, 'c=3, **collections.UserDict(a=1, b=2)')
1538
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001539 def test_keyword_only(self):
1540 f = self.makeCallable('a=3, *, c, d=2')
1541 self.assertEqualCallArgs(f, 'c=3')
1542 self.assertEqualCallArgs(f, 'c=3, a=3')
1543 self.assertEqualCallArgs(f, 'a=2, c=4')
1544 self.assertEqualCallArgs(f, '4, c=4')
1545 self.assertEqualException(f, '')
1546 self.assertEqualException(f, '3')
1547 self.assertEqualException(f, 'a=3')
1548 self.assertEqualException(f, 'd=4')
1549
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001550 f = self.makeCallable('*, c, d=2')
1551 self.assertEqualCallArgs(f, 'c=3')
1552 self.assertEqualCallArgs(f, 'c=3, d=4')
1553 self.assertEqualCallArgs(f, 'd=4, c=3')
1554
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001555 def test_multiple_features(self):
1556 f = self.makeCallable('a, b=2, *f, **g')
1557 self.assertEqualCallArgs(f, '2, 3, 7')
1558 self.assertEqualCallArgs(f, '2, 3, x=8')
1559 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
1560 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9')
1561 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9')
1562 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
1563 '[2, 3, (4,[5,6])]), **{"y":9, "z":10}')
1564 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
1565 '(4,[5,6])]), **collections.UserDict('
1566 'y=9, z=10)')
1567
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001568 f = self.makeCallable('a, b=2, *f, x, y=99, **g')
1569 self.assertEqualCallArgs(f, '2, 3, x=8')
1570 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
1571 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9, z=10')
1572 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9, z=10')
1573 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
1574 '[2, 3, (4,[5,6])]), q=0, **{"y":9, "z":10}')
1575 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
1576 '(4,[5,6])]), q=0, **collections.UserDict('
1577 'y=9, z=10)')
1578
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001579 def test_errors(self):
1580 f0 = self.makeCallable('')
1581 f1 = self.makeCallable('a, b')
1582 f2 = self.makeCallable('a, b=1')
1583 # f0 takes no arguments
1584 self.assertEqualException(f0, '1')
1585 self.assertEqualException(f0, 'x=1')
1586 self.assertEqualException(f0, '1,x=1')
1587 # f1 takes exactly 2 arguments
1588 self.assertEqualException(f1, '')
1589 self.assertEqualException(f1, '1')
1590 self.assertEqualException(f1, 'a=2')
1591 self.assertEqualException(f1, 'b=3')
1592 # f2 takes at least 1 argument
1593 self.assertEqualException(f2, '')
1594 self.assertEqualException(f2, 'b=3')
1595 for f in f1, f2:
1596 # f1/f2 takes exactly/at most 2 arguments
1597 self.assertEqualException(f, '2, 3, 4')
1598 self.assertEqualException(f, '1, 2, 3, a=1')
1599 self.assertEqualException(f, '2, 3, 4, c=5')
Georg Brandl178e5ea2012-02-21 00:32:36 +01001600 # XXX: success of this one depends on dict order
1601 ## self.assertEqualException(f, '2, 3, 4, a=1, c=5')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001602 # f got an unexpected keyword argument
1603 self.assertEqualException(f, 'c=2')
1604 self.assertEqualException(f, '2, c=3')
1605 self.assertEqualException(f, '2, 3, c=4')
1606 self.assertEqualException(f, '2, c=4, b=3')
1607 self.assertEqualException(f, '**{u"\u03c0\u03b9": 4}')
1608 # f got multiple values for keyword argument
1609 self.assertEqualException(f, '1, a=2')
1610 self.assertEqualException(f, '1, **{"a":2}')
1611 self.assertEqualException(f, '1, 2, b=3')
1612 # XXX: Python inconsistency
1613 # - for functions and bound methods: unexpected keyword 'c'
1614 # - for unbound methods: multiple values for keyword 'a'
1615 #self.assertEqualException(f, '1, c=3, a=2')
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001616 # issue11256:
1617 f3 = self.makeCallable('**c')
1618 self.assertEqualException(f3, '1, 2')
1619 self.assertEqualException(f3, '1, 2, a=1, b=2')
1620 f4 = self.makeCallable('*, a, b=0')
1621 self.assertEqualException(f3, '1, 2')
1622 self.assertEqualException(f3, '1, 2, a=1, b=2')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001623
Yury Selivanov875df202014-03-27 18:23:03 -04001624 # issue #20816: getcallargs() fails to iterate over non-existent
1625 # kwonlydefaults and raises a wrong TypeError
1626 def f5(*, a): pass
1627 with self.assertRaisesRegex(TypeError,
1628 'missing 1 required keyword-only'):
Pablo Galindoaee19f52019-05-16 21:08:15 +01001629 inspect.getcallargs(f5)
Yury Selivanov875df202014-03-27 18:23:03 -04001630
1631
Yury Selivanovdccfa132014-03-27 18:42:52 -04001632 # issue20817:
1633 def f6(a, b, c):
1634 pass
1635 with self.assertRaisesRegex(TypeError, "'a', 'b' and 'c'"):
Pablo Galindoaee19f52019-05-16 21:08:15 +01001636 inspect.getcallargs(f6)
Yury Selivanovdccfa132014-03-27 18:42:52 -04001637
Dong-hee Naa9cab432018-05-30 00:04:08 +09001638 # bpo-33197
1639 with self.assertRaisesRegex(ValueError,
1640 'variadic keyword parameters cannot'
1641 ' have default values'):
1642 inspect.Parameter("foo", kind=inspect.Parameter.VAR_KEYWORD,
1643 default=42)
1644 with self.assertRaisesRegex(ValueError,
1645 "value 5 is not a valid Parameter.kind"):
1646 inspect.Parameter("bar", kind=5, default=42)
1647
1648 with self.assertRaisesRegex(TypeError,
1649 'name must be a str, not a int'):
1650 inspect.Parameter(123, kind=4)
1651
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001652class TestGetcallargsMethods(TestGetcallargsFunctions):
1653
1654 def setUp(self):
1655 class Foo(object):
1656 pass
1657 self.cls = Foo
1658 self.inst = Foo()
1659
1660 def makeCallable(self, signature):
1661 assert 'self' not in signature
1662 mk = super(TestGetcallargsMethods, self).makeCallable
1663 self.cls.method = mk('self, ' + signature)
1664 return self.inst.method
1665
1666class TestGetcallargsUnboundMethods(TestGetcallargsMethods):
1667
1668 def makeCallable(self, signature):
1669 super(TestGetcallargsUnboundMethods, self).makeCallable(signature)
1670 return self.cls.method
1671
1672 def assertEqualCallArgs(self, func, call_params_string, locs=None):
1673 return super(TestGetcallargsUnboundMethods, self).assertEqualCallArgs(
1674 *self._getAssertEqualParams(func, call_params_string, locs))
1675
1676 def assertEqualException(self, func, call_params_string, locs=None):
1677 return super(TestGetcallargsUnboundMethods, self).assertEqualException(
1678 *self._getAssertEqualParams(func, call_params_string, locs))
1679
1680 def _getAssertEqualParams(self, func, call_params_string, locs=None):
1681 assert 'inst' not in call_params_string
1682 locs = dict(locs or {}, inst=self.inst)
1683 return (func, 'inst,' + call_params_string, locs)
1684
Michael Foord95fc51d2010-11-20 15:07:30 +00001685
1686class TestGetattrStatic(unittest.TestCase):
1687
1688 def test_basic(self):
1689 class Thing(object):
1690 x = object()
1691
1692 thing = Thing()
1693 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1694 self.assertEqual(inspect.getattr_static(thing, 'x', None), Thing.x)
1695 with self.assertRaises(AttributeError):
1696 inspect.getattr_static(thing, 'y')
1697
1698 self.assertEqual(inspect.getattr_static(thing, 'y', 3), 3)
1699
1700 def test_inherited(self):
1701 class Thing(object):
1702 x = object()
1703 class OtherThing(Thing):
1704 pass
1705
1706 something = OtherThing()
1707 self.assertEqual(inspect.getattr_static(something, 'x'), Thing.x)
1708
1709 def test_instance_attr(self):
1710 class Thing(object):
1711 x = 2
1712 def __init__(self, x):
1713 self.x = x
1714 thing = Thing(3)
1715 self.assertEqual(inspect.getattr_static(thing, 'x'), 3)
1716 del thing.x
1717 self.assertEqual(inspect.getattr_static(thing, 'x'), 2)
1718
1719 def test_property(self):
1720 class Thing(object):
1721 @property
1722 def x(self):
1723 raise AttributeError("I'm pretending not to exist")
1724 thing = Thing()
1725 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1726
Ezio Melotti75cbd732011-04-28 00:59:29 +03001727 def test_descriptor_raises_AttributeError(self):
Michael Foord95fc51d2010-11-20 15:07:30 +00001728 class descriptor(object):
1729 def __get__(*_):
1730 raise AttributeError("I'm pretending not to exist")
1731 desc = descriptor()
1732 class Thing(object):
1733 x = desc
1734 thing = Thing()
1735 self.assertEqual(inspect.getattr_static(thing, 'x'), desc)
1736
1737 def test_classAttribute(self):
1738 class Thing(object):
1739 x = object()
1740
1741 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.x)
1742
Ethan Furmane03ea372013-09-25 07:14:41 -07001743 def test_classVirtualAttribute(self):
1744 class Thing(object):
1745 @types.DynamicClassAttribute
1746 def x(self):
1747 return self._x
1748 _x = object()
1749
1750 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.__dict__['x'])
1751
Michael Foord95fc51d2010-11-20 15:07:30 +00001752 def test_inherited_classattribute(self):
1753 class Thing(object):
1754 x = object()
1755 class OtherThing(Thing):
1756 pass
1757
1758 self.assertEqual(inspect.getattr_static(OtherThing, 'x'), Thing.x)
1759
1760 def test_slots(self):
1761 class Thing(object):
1762 y = 'bar'
1763 __slots__ = ['x']
1764 def __init__(self):
1765 self.x = 'foo'
1766 thing = Thing()
1767 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1768 self.assertEqual(inspect.getattr_static(thing, 'y'), 'bar')
1769
1770 del thing.x
1771 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1772
1773 def test_metaclass(self):
1774 class meta(type):
1775 attr = 'foo'
1776 class Thing(object, metaclass=meta):
1777 pass
1778 self.assertEqual(inspect.getattr_static(Thing, 'attr'), 'foo')
1779
1780 class sub(meta):
1781 pass
1782 class OtherThing(object, metaclass=sub):
1783 x = 3
1784 self.assertEqual(inspect.getattr_static(OtherThing, 'attr'), 'foo')
1785
1786 class OtherOtherThing(OtherThing):
1787 pass
1788 # this test is odd, but it was added as it exposed a bug
1789 self.assertEqual(inspect.getattr_static(OtherOtherThing, 'x'), 3)
1790
1791 def test_no_dict_no_slots(self):
1792 self.assertEqual(inspect.getattr_static(1, 'foo', None), None)
1793 self.assertNotEqual(inspect.getattr_static('foo', 'lower'), None)
1794
1795 def test_no_dict_no_slots_instance_member(self):
1796 # returns descriptor
1797 with open(__file__) as handle:
1798 self.assertEqual(inspect.getattr_static(handle, 'name'), type(handle).name)
1799
1800 def test_inherited_slots(self):
1801 # returns descriptor
1802 class Thing(object):
1803 __slots__ = ['x']
1804 def __init__(self):
1805 self.x = 'foo'
1806
1807 class OtherThing(Thing):
1808 pass
1809 # it would be nice if this worked...
1810 # we get the descriptor instead of the instance attribute
1811 self.assertEqual(inspect.getattr_static(OtherThing(), 'x'), Thing.x)
1812
1813 def test_descriptor(self):
1814 class descriptor(object):
1815 def __get__(self, instance, owner):
1816 return 3
1817 class Foo(object):
1818 d = descriptor()
1819
1820 foo = Foo()
1821
1822 # for a non data descriptor we return the instance attribute
1823 foo.__dict__['d'] = 1
1824 self.assertEqual(inspect.getattr_static(foo, 'd'), 1)
1825
Mike53f7a7c2017-12-14 14:04:53 +03001826 # if the descriptor is a data-descriptor we should return the
Michael Foord95fc51d2010-11-20 15:07:30 +00001827 # descriptor
1828 descriptor.__set__ = lambda s, i, v: None
1829 self.assertEqual(inspect.getattr_static(foo, 'd'), Foo.__dict__['d'])
1830
1831
1832 def test_metaclass_with_descriptor(self):
1833 class descriptor(object):
1834 def __get__(self, instance, owner):
1835 return 3
1836 class meta(type):
1837 d = descriptor()
1838 class Thing(object, metaclass=meta):
1839 pass
1840 self.assertEqual(inspect.getattr_static(Thing, 'd'), meta.__dict__['d'])
1841
1842
Michael Foordcc7ebb82010-11-20 16:20:16 +00001843 def test_class_as_property(self):
1844 class Base(object):
1845 foo = 3
1846
1847 class Something(Base):
Michael Foord35184ed2010-11-20 16:58:30 +00001848 executed = False
Michael Foordcc7ebb82010-11-20 16:20:16 +00001849 @property
1850 def __class__(self):
Michael Foord35184ed2010-11-20 16:58:30 +00001851 self.executed = True
Michael Foordcc7ebb82010-11-20 16:20:16 +00001852 return object
1853
Michael Foord35184ed2010-11-20 16:58:30 +00001854 instance = Something()
1855 self.assertEqual(inspect.getattr_static(instance, 'foo'), 3)
1856 self.assertFalse(instance.executed)
Michael Foordcc7ebb82010-11-20 16:20:16 +00001857 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1858
Michael Foorde5162652010-11-20 16:40:44 +00001859 def test_mro_as_property(self):
1860 class Meta(type):
1861 @property
1862 def __mro__(self):
1863 return (object,)
1864
1865 class Base(object):
1866 foo = 3
1867
1868 class Something(Base, metaclass=Meta):
1869 pass
1870
1871 self.assertEqual(inspect.getattr_static(Something(), 'foo'), 3)
1872 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1873
Michael Foorddcebe0f2011-03-15 19:20:44 -04001874 def test_dict_as_property(self):
1875 test = self
1876 test.called = False
1877
1878 class Foo(dict):
1879 a = 3
1880 @property
1881 def __dict__(self):
1882 test.called = True
1883 return {}
1884
1885 foo = Foo()
1886 foo.a = 4
1887 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1888 self.assertFalse(test.called)
1889
1890 def test_custom_object_dict(self):
1891 test = self
1892 test.called = False
1893
1894 class Custom(dict):
1895 def get(self, key, default=None):
1896 test.called = True
1897 super().get(key, default)
1898
1899 class Foo(object):
1900 a = 3
1901 foo = Foo()
1902 foo.__dict__ = Custom()
1903 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1904 self.assertFalse(test.called)
1905
1906 def test_metaclass_dict_as_property(self):
1907 class Meta(type):
1908 @property
1909 def __dict__(self):
1910 self.executed = True
1911
1912 class Thing(metaclass=Meta):
1913 executed = False
1914
1915 def __init__(self):
1916 self.spam = 42
1917
1918 instance = Thing()
1919 self.assertEqual(inspect.getattr_static(instance, "spam"), 42)
1920 self.assertFalse(Thing.executed)
Michael Foorde5162652010-11-20 16:40:44 +00001921
Michael Foorda51623b2011-12-18 22:01:40 +00001922 def test_module(self):
1923 sentinel = object()
1924 self.assertIsNot(inspect.getattr_static(sys, "version", sentinel),
1925 sentinel)
1926
Michael Foord3ba95f82011-12-22 01:13:37 +00001927 def test_metaclass_with_metaclass_with_dict_as_property(self):
1928 class MetaMeta(type):
1929 @property
1930 def __dict__(self):
1931 self.executed = True
1932 return dict(spam=42)
1933
1934 class Meta(type, metaclass=MetaMeta):
1935 executed = False
1936
1937 class Thing(metaclass=Meta):
1938 pass
1939
1940 with self.assertRaises(AttributeError):
1941 inspect.getattr_static(Thing, "spam")
1942 self.assertFalse(Thing.executed)
1943
Nick Coghlane0f04652010-11-21 03:44:04 +00001944class TestGetGeneratorState(unittest.TestCase):
1945
1946 def setUp(self):
1947 def number_generator():
1948 for number in range(5):
1949 yield number
1950 self.generator = number_generator()
1951
1952 def _generatorstate(self):
1953 return inspect.getgeneratorstate(self.generator)
1954
1955 def test_created(self):
1956 self.assertEqual(self._generatorstate(), inspect.GEN_CREATED)
1957
1958 def test_suspended(self):
1959 next(self.generator)
1960 self.assertEqual(self._generatorstate(), inspect.GEN_SUSPENDED)
1961
1962 def test_closed_after_exhaustion(self):
1963 for i in self.generator:
1964 pass
1965 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1966
1967 def test_closed_after_immediate_exception(self):
1968 with self.assertRaises(RuntimeError):
1969 self.generator.throw(RuntimeError)
1970 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1971
1972 def test_running(self):
1973 # As mentioned on issue #10220, checking for the RUNNING state only
1974 # makes sense inside the generator itself.
1975 # The following generator checks for this by using the closure's
1976 # reference to self and the generator state checking helper method
1977 def running_check_generator():
1978 for number in range(5):
1979 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1980 yield number
1981 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1982 self.generator = running_check_generator()
1983 # Running up to the first yield
1984 next(self.generator)
1985 # Running after the first yield
1986 next(self.generator)
1987
Nick Coghlan7921b9f2010-11-30 06:36:04 +00001988 def test_easy_debugging(self):
1989 # repr() and str() of a generator state should contain the state name
1990 names = 'GEN_CREATED GEN_RUNNING GEN_SUSPENDED GEN_CLOSED'.split()
1991 for name in names:
1992 state = getattr(inspect, name)
1993 self.assertIn(name, repr(state))
1994 self.assertIn(name, str(state))
1995
Nick Coghlan04e2e3f2012-06-23 19:52:05 +10001996 def test_getgeneratorlocals(self):
1997 def each(lst, a=None):
1998 b=(1, 2, 3)
1999 for v in lst:
2000 if v == 3:
2001 c = 12
2002 yield v
2003
2004 numbers = each([1, 2, 3])
2005 self.assertEqual(inspect.getgeneratorlocals(numbers),
2006 {'a': None, 'lst': [1, 2, 3]})
2007 next(numbers)
2008 self.assertEqual(inspect.getgeneratorlocals(numbers),
2009 {'a': None, 'lst': [1, 2, 3], 'v': 1,
2010 'b': (1, 2, 3)})
2011 next(numbers)
2012 self.assertEqual(inspect.getgeneratorlocals(numbers),
2013 {'a': None, 'lst': [1, 2, 3], 'v': 2,
2014 'b': (1, 2, 3)})
2015 next(numbers)
2016 self.assertEqual(inspect.getgeneratorlocals(numbers),
2017 {'a': None, 'lst': [1, 2, 3], 'v': 3,
2018 'b': (1, 2, 3), 'c': 12})
2019 try:
2020 next(numbers)
2021 except StopIteration:
2022 pass
2023 self.assertEqual(inspect.getgeneratorlocals(numbers), {})
2024
2025 def test_getgeneratorlocals_empty(self):
2026 def yield_one():
2027 yield 1
2028 one = yield_one()
2029 self.assertEqual(inspect.getgeneratorlocals(one), {})
2030 try:
2031 next(one)
2032 except StopIteration:
2033 pass
2034 self.assertEqual(inspect.getgeneratorlocals(one), {})
2035
2036 def test_getgeneratorlocals_error(self):
2037 self.assertRaises(TypeError, inspect.getgeneratorlocals, 1)
2038 self.assertRaises(TypeError, inspect.getgeneratorlocals, lambda x: True)
2039 self.assertRaises(TypeError, inspect.getgeneratorlocals, set)
2040 self.assertRaises(TypeError, inspect.getgeneratorlocals, (2,3))
2041
Nick Coghlane0f04652010-11-21 03:44:04 +00002042
Yury Selivanov5376ba92015-06-22 12:19:30 -04002043class TestGetCoroutineState(unittest.TestCase):
2044
2045 def setUp(self):
2046 @types.coroutine
2047 def number_coroutine():
2048 for number in range(5):
2049 yield number
2050 async def coroutine():
2051 await number_coroutine()
2052 self.coroutine = coroutine()
2053
2054 def tearDown(self):
2055 self.coroutine.close()
2056
2057 def _coroutinestate(self):
2058 return inspect.getcoroutinestate(self.coroutine)
2059
2060 def test_created(self):
2061 self.assertEqual(self._coroutinestate(), inspect.CORO_CREATED)
2062
2063 def test_suspended(self):
2064 self.coroutine.send(None)
2065 self.assertEqual(self._coroutinestate(), inspect.CORO_SUSPENDED)
2066
2067 def test_closed_after_exhaustion(self):
2068 while True:
2069 try:
2070 self.coroutine.send(None)
2071 except StopIteration:
2072 break
2073
2074 self.assertEqual(self._coroutinestate(), inspect.CORO_CLOSED)
2075
2076 def test_closed_after_immediate_exception(self):
2077 with self.assertRaises(RuntimeError):
2078 self.coroutine.throw(RuntimeError)
2079 self.assertEqual(self._coroutinestate(), inspect.CORO_CLOSED)
2080
2081 def test_easy_debugging(self):
2082 # repr() and str() of a coroutine state should contain the state name
2083 names = 'CORO_CREATED CORO_RUNNING CORO_SUSPENDED CORO_CLOSED'.split()
2084 for name in names:
2085 state = getattr(inspect, name)
2086 self.assertIn(name, repr(state))
2087 self.assertIn(name, str(state))
2088
2089 def test_getcoroutinelocals(self):
2090 @types.coroutine
2091 def gencoro():
2092 yield
2093
2094 gencoro = gencoro()
2095 async def func(a=None):
2096 b = 'spam'
2097 await gencoro
2098
2099 coro = func()
2100 self.assertEqual(inspect.getcoroutinelocals(coro),
2101 {'a': None, 'gencoro': gencoro})
2102 coro.send(None)
2103 self.assertEqual(inspect.getcoroutinelocals(coro),
2104 {'a': None, 'gencoro': gencoro, 'b': 'spam'})
2105
2106
Yury Selivanova5d63dd2014-03-27 11:31:43 -04002107class MySignature(inspect.Signature):
2108 # Top-level to make it picklable;
2109 # used in test_signature_object_pickle
2110 pass
2111
2112class MyParameter(inspect.Parameter):
2113 # Top-level to make it picklable;
2114 # used in test_signature_object_pickle
2115 pass
2116
Nick Coghlanf9e227e2014-08-17 14:01:19 +10002117
Yury Selivanova5d63dd2014-03-27 11:31:43 -04002118
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002119class TestSignatureObject(unittest.TestCase):
2120 @staticmethod
Yury Selivanovbcd4fc12015-05-20 14:30:08 -04002121 def signature(func, **kw):
2122 sig = inspect.signature(func, **kw)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002123 return (tuple((param.name,
2124 (... if param.default is param.empty else param.default),
2125 (... if param.annotation is param.empty
2126 else param.annotation),
2127 str(param.kind).lower())
2128 for param in sig.parameters.values()),
2129 (... if sig.return_annotation is sig.empty
2130 else sig.return_annotation))
2131
2132 def test_signature_object(self):
2133 S = inspect.Signature
2134 P = inspect.Parameter
2135
2136 self.assertEqual(str(S()), '()')
Jens Reidel611836a2020-03-18 03:22:46 +01002137 self.assertEqual(repr(S().parameters), 'mappingproxy(OrderedDict())')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002138
Yury Selivanov07a9e452014-01-29 10:58:16 -05002139 def test(po, pk, pod=42, pkd=100, *args, ko, **kwargs):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002140 pass
2141 sig = inspect.signature(test)
2142 po = sig.parameters['po'].replace(kind=P.POSITIONAL_ONLY)
Yury Selivanov07a9e452014-01-29 10:58:16 -05002143 pod = sig.parameters['pod'].replace(kind=P.POSITIONAL_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002144 pk = sig.parameters['pk']
Yury Selivanov07a9e452014-01-29 10:58:16 -05002145 pkd = sig.parameters['pkd']
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002146 args = sig.parameters['args']
2147 ko = sig.parameters['ko']
2148 kwargs = sig.parameters['kwargs']
2149
2150 S((po, pk, args, ko, kwargs))
2151
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002152 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002153 S((pk, po, args, ko, kwargs))
2154
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002155 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002156 S((po, args, pk, ko, kwargs))
2157
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002158 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002159 S((args, po, pk, ko, kwargs))
2160
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002161 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002162 S((po, pk, args, kwargs, ko))
2163
2164 kwargs2 = kwargs.replace(name='args')
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002165 with self.assertRaisesRegex(ValueError, 'duplicate parameter name'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002166 S((po, pk, args, kwargs2, ko))
2167
Yury Selivanov07a9e452014-01-29 10:58:16 -05002168 with self.assertRaisesRegex(ValueError, 'follows default argument'):
2169 S((pod, po))
2170
2171 with self.assertRaisesRegex(ValueError, 'follows default argument'):
2172 S((po, pkd, pk))
2173
2174 with self.assertRaisesRegex(ValueError, 'follows default argument'):
2175 S((pkd, pk))
2176
Yury Selivanov374375d2014-03-27 12:41:53 -04002177 self.assertTrue(repr(sig).startswith('<Signature'))
Yury Selivanov0cd2bf42015-05-15 12:55:20 -04002178 self.assertTrue('(po, pk' in repr(sig))
Yury Selivanov374375d2014-03-27 12:41:53 -04002179
Yury Selivanova5d63dd2014-03-27 11:31:43 -04002180 def test_signature_object_pickle(self):
2181 def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
2182 foo_partial = functools.partial(foo, a=1)
2183
2184 sig = inspect.signature(foo_partial)
Yury Selivanova5d63dd2014-03-27 11:31:43 -04002185
2186 for ver in range(pickle.HIGHEST_PROTOCOL + 1):
2187 with self.subTest(pickle_ver=ver, subclass=False):
2188 sig_pickled = pickle.loads(pickle.dumps(sig, ver))
2189 self.assertEqual(sig, sig_pickled)
Yury Selivanova5d63dd2014-03-27 11:31:43 -04002190
2191 # Test that basic sub-classing works
2192 sig = inspect.signature(foo)
2193 myparam = MyParameter(name='z', kind=inspect.Parameter.POSITIONAL_ONLY)
2194 myparams = collections.OrderedDict(sig.parameters, a=myparam)
2195 mysig = MySignature().replace(parameters=myparams.values(),
2196 return_annotation=sig.return_annotation)
2197 self.assertTrue(isinstance(mysig, MySignature))
2198 self.assertTrue(isinstance(mysig.parameters['z'], MyParameter))
2199
2200 for ver in range(pickle.HIGHEST_PROTOCOL + 1):
2201 with self.subTest(pickle_ver=ver, subclass=True):
2202 sig_pickled = pickle.loads(pickle.dumps(mysig, ver))
2203 self.assertEqual(mysig, sig_pickled)
2204 self.assertTrue(isinstance(sig_pickled, MySignature))
2205 self.assertTrue(isinstance(sig_pickled.parameters['z'],
2206 MyParameter))
2207
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002208 def test_signature_immutability(self):
2209 def test(a):
2210 pass
2211 sig = inspect.signature(test)
2212
2213 with self.assertRaises(AttributeError):
2214 sig.foo = 'bar'
2215
2216 with self.assertRaises(TypeError):
2217 sig.parameters['a'] = None
2218
2219 def test_signature_on_noarg(self):
2220 def test():
2221 pass
2222 self.assertEqual(self.signature(test), ((), ...))
2223
2224 def test_signature_on_wargs(self):
2225 def test(a, b:'foo') -> 123:
2226 pass
2227 self.assertEqual(self.signature(test),
2228 ((('a', ..., ..., "positional_or_keyword"),
Batuhan Taskaya044a1042020-10-06 23:03:02 +03002229 ('b', ..., repr('foo'), "positional_or_keyword")),
2230 '123'))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002231
2232 def test_signature_on_wkwonly(self):
2233 def test(*, a:float, b:str) -> int:
2234 pass
2235 self.assertEqual(self.signature(test),
2236 ((('a', ..., float, "keyword_only"),
2237 ('b', ..., str, "keyword_only")),
2238 int))
2239
2240 def test_signature_on_complex_args(self):
2241 def test(a, b:'foo'=10, *args:'bar', spam:'baz', ham=123, **kwargs:int):
2242 pass
2243 self.assertEqual(self.signature(test),
2244 ((('a', ..., ..., "positional_or_keyword"),
Batuhan Taskaya044a1042020-10-06 23:03:02 +03002245 ('b', 10, repr('foo'), "positional_or_keyword"),
2246 ('args', ..., repr('bar'), "var_positional"),
2247 ('spam', ..., repr('baz'), "keyword_only"),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002248 ('ham', 123, ..., "keyword_only"),
Batuhan Taskaya044a1042020-10-06 23:03:02 +03002249 ('kwargs', ..., 'int', "var_keyword")),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002250 ...))
2251
Dong-hee Na378d7062017-05-18 04:00:51 +09002252 def test_signature_without_self(self):
2253 def test_args_only(*args): # NOQA
2254 pass
2255
2256 def test_args_kwargs_only(*args, **kwargs): # NOQA
2257 pass
2258
2259 class A:
2260 @classmethod
2261 def test_classmethod(*args): # NOQA
2262 pass
2263
2264 @staticmethod
2265 def test_staticmethod(*args): # NOQA
2266 pass
2267
2268 f1 = functools.partialmethod((test_classmethod), 1)
2269 f2 = functools.partialmethod((test_args_only), 1)
2270 f3 = functools.partialmethod((test_staticmethod), 1)
2271 f4 = functools.partialmethod((test_args_kwargs_only),1)
2272
2273 self.assertEqual(self.signature(test_args_only),
2274 ((('args', ..., ..., 'var_positional'),), ...))
2275 self.assertEqual(self.signature(test_args_kwargs_only),
2276 ((('args', ..., ..., 'var_positional'),
2277 ('kwargs', ..., ..., 'var_keyword')), ...))
2278 self.assertEqual(self.signature(A.f1),
2279 ((('args', ..., ..., 'var_positional'),), ...))
2280 self.assertEqual(self.signature(A.f2),
2281 ((('args', ..., ..., 'var_positional'),), ...))
2282 self.assertEqual(self.signature(A.f3),
2283 ((('args', ..., ..., 'var_positional'),), ...))
Serhiy Storchaka13ad3b72017-09-14 09:38:36 +03002284 self.assertEqual(self.signature(A.f4),
Dong-hee Na378d7062017-05-18 04:00:51 +09002285 ((('args', ..., ..., 'var_positional'),
2286 ('kwargs', ..., ..., 'var_keyword')), ...))
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002287 @cpython_only
Larry Hastingsfcafe432013-11-23 17:35:48 -08002288 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2289 "Signature information for builtins requires docstrings")
2290 def test_signature_on_builtins(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002291 import _testcapi
Larry Hastings16c51912014-01-07 11:53:01 -08002292
Larry Hastings5c661892014-01-24 06:17:25 -08002293 def test_unbound_method(o):
2294 """Use this to test unbound methods (things that should have a self)"""
2295 signature = inspect.signature(o)
2296 self.assertTrue(isinstance(signature, inspect.Signature))
2297 self.assertEqual(list(signature.parameters.values())[0].name, 'self')
2298 return signature
2299
2300 def test_callable(o):
2301 """Use this to test bound methods or normal callables (things that don't expect self)"""
2302 signature = inspect.signature(o)
2303 self.assertTrue(isinstance(signature, inspect.Signature))
2304 if signature.parameters:
2305 self.assertNotEqual(list(signature.parameters.values())[0].name, 'self')
2306 return signature
2307
2308 signature = test_callable(_testcapi.docstring_with_signature_with_defaults)
Larry Hastings16c51912014-01-07 11:53:01 -08002309 def p(name): return signature.parameters[name].default
2310 self.assertEqual(p('s'), 'avocado')
Larry Hastings2a727912014-01-16 11:32:01 -08002311 self.assertEqual(p('b'), b'bytes')
Larry Hastings16c51912014-01-07 11:53:01 -08002312 self.assertEqual(p('d'), 3.14)
2313 self.assertEqual(p('i'), 35)
Larry Hastings16c51912014-01-07 11:53:01 -08002314 self.assertEqual(p('n'), None)
2315 self.assertEqual(p('t'), True)
2316 self.assertEqual(p('f'), False)
Larry Hastings2a727912014-01-16 11:32:01 -08002317 self.assertEqual(p('local'), 3)
2318 self.assertEqual(p('sys'), sys.maxsize)
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +02002319 self.assertNotIn('exp', signature.parameters)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002320
Larry Hastings5c661892014-01-24 06:17:25 -08002321 test_callable(object)
2322
2323 # normal method
2324 # (PyMethodDescr_Type, "method_descriptor")
2325 test_unbound_method(_pickle.Pickler.dump)
2326 d = _pickle.Pickler(io.StringIO())
2327 test_callable(d.dump)
2328
2329 # static method
Serhiy Storchaka279f4462019-09-14 12:24:05 +03002330 test_callable(bytes.maketrans)
2331 test_callable(b'abc'.maketrans)
Larry Hastings5c661892014-01-24 06:17:25 -08002332
2333 # class method
2334 test_callable(dict.fromkeys)
2335 test_callable({}.fromkeys)
2336
2337 # wrapper around slot (PyWrapperDescr_Type, "wrapper_descriptor")
2338 test_unbound_method(type.__call__)
2339 test_unbound_method(int.__add__)
2340 test_callable((3).__add__)
2341
2342 # _PyMethodWrapper_Type
2343 # support for 'method-wrapper'
2344 test_callable(min.__call__)
2345
Larry Hastings2623c8c2014-02-08 22:15:29 -08002346 # This doesn't work now.
2347 # (We don't have a valid signature for "type" in 3.4)
2348 with self.assertRaisesRegex(ValueError, "no signature found"):
2349 class ThisWorksNow:
2350 __call__ = type
2351 test_callable(ThisWorksNow())
Larry Hastings5c661892014-01-24 06:17:25 -08002352
Yury Selivanov056e2652014-03-02 12:25:27 -05002353 # Regression test for issue #20786
2354 test_unbound_method(dict.__delitem__)
2355 test_unbound_method(property.__delete__)
2356
Zachary Ware8ef887c2015-04-13 18:22:35 -05002357 # Regression test for issue #20586
2358 test_callable(_testcapi.docstring_with_signature_but_no_doc)
2359
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002360 @cpython_only
Yury Selivanov76c6c592014-01-29 10:52:57 -05002361 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2362 "Signature information for builtins requires docstrings")
2363 def test_signature_on_decorated_builtins(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002364 import _testcapi
Yury Selivanov76c6c592014-01-29 10:52:57 -05002365 func = _testcapi.docstring_with_signature_with_defaults
2366
2367 def decorator(func):
2368 @functools.wraps(func)
2369 def wrapper(*args, **kwargs) -> int:
2370 return func(*args, **kwargs)
2371 return wrapper
2372
2373 decorated_func = decorator(func)
2374
2375 self.assertEqual(inspect.signature(func),
2376 inspect.signature(decorated_func))
Larry Hastings5c661892014-01-24 06:17:25 -08002377
Yury Selivanovbcd4fc12015-05-20 14:30:08 -04002378 def wrapper_like(*args, **kwargs) -> int: pass
2379 self.assertEqual(inspect.signature(decorated_func,
2380 follow_wrapped=False),
2381 inspect.signature(wrapper_like))
2382
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002383 @cpython_only
Larry Hastings5c661892014-01-24 06:17:25 -08002384 def test_signature_on_builtins_no_signature(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002385 import _testcapi
Yury Selivanovbf304fc2015-05-30 17:08:36 -04002386 with self.assertRaisesRegex(ValueError,
2387 'no signature found for builtin'):
Larry Hastings5c661892014-01-24 06:17:25 -08002388 inspect.signature(_testcapi.docstring_no_signature)
2389
Yury Selivanovbf304fc2015-05-30 17:08:36 -04002390 with self.assertRaisesRegex(ValueError,
2391 'no signature found for builtin'):
2392 inspect.signature(str)
2393
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002394 def test_signature_on_non_function(self):
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002395 with self.assertRaisesRegex(TypeError, 'is not a callable object'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002396 inspect.signature(42)
2397
Yury Selivanov63da7c72014-01-31 14:48:37 -05002398 def test_signature_from_functionlike_object(self):
2399 def func(a,b, *args, kwonly=True, kwonlyreq, **kwargs):
2400 pass
2401
2402 class funclike:
2403 # Has to be callable, and have correct
2404 # __code__, __annotations__, __defaults__, __name__,
2405 # and __kwdefaults__ attributes
2406
2407 def __init__(self, func):
2408 self.__name__ = func.__name__
2409 self.__code__ = func.__code__
2410 self.__annotations__ = func.__annotations__
2411 self.__defaults__ = func.__defaults__
2412 self.__kwdefaults__ = func.__kwdefaults__
2413 self.func = func
2414
2415 def __call__(self, *args, **kwargs):
2416 return self.func(*args, **kwargs)
2417
Yury Selivanov57c74fc2015-05-20 23:07:02 -04002418 sig_func = inspect.Signature.from_callable(func)
Yury Selivanov63da7c72014-01-31 14:48:37 -05002419
Yury Selivanov57c74fc2015-05-20 23:07:02 -04002420 sig_funclike = inspect.Signature.from_callable(funclike(func))
Yury Selivanov63da7c72014-01-31 14:48:37 -05002421 self.assertEqual(sig_funclike, sig_func)
2422
2423 sig_funclike = inspect.signature(funclike(func))
2424 self.assertEqual(sig_funclike, sig_func)
2425
2426 # If object is not a duck type of function, then
2427 # signature will try to get a signature for its '__call__'
2428 # method
2429 fl = funclike(func)
2430 del fl.__defaults__
2431 self.assertEqual(self.signature(fl),
2432 ((('args', ..., ..., "var_positional"),
2433 ('kwargs', ..., ..., "var_keyword")),
2434 ...))
2435
Yury Selivanova773de02014-02-21 18:30:53 -05002436 # Test with cython-like builtins:
2437 _orig_isdesc = inspect.ismethoddescriptor
2438 def _isdesc(obj):
2439 if hasattr(obj, '_builtinmock'):
2440 return True
2441 return _orig_isdesc(obj)
2442
2443 with unittest.mock.patch('inspect.ismethoddescriptor', _isdesc):
2444 builtin_func = funclike(func)
2445 # Make sure that our mock setup is working
2446 self.assertFalse(inspect.ismethoddescriptor(builtin_func))
2447 builtin_func._builtinmock = True
2448 self.assertTrue(inspect.ismethoddescriptor(builtin_func))
2449 self.assertEqual(inspect.signature(builtin_func), sig_func)
2450
Yury Selivanov63da7c72014-01-31 14:48:37 -05002451 def test_signature_functionlike_class(self):
2452 # We only want to duck type function-like objects,
2453 # not classes.
2454
2455 def func(a,b, *args, kwonly=True, kwonlyreq, **kwargs):
2456 pass
2457
2458 class funclike:
2459 def __init__(self, marker):
2460 pass
2461
2462 __name__ = func.__name__
2463 __code__ = func.__code__
2464 __annotations__ = func.__annotations__
2465 __defaults__ = func.__defaults__
2466 __kwdefaults__ = func.__kwdefaults__
2467
Yury Selivanov63da7c72014-01-31 14:48:37 -05002468 self.assertEqual(str(inspect.signature(funclike)), '(marker)')
2469
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002470 def test_signature_on_method(self):
2471 class Test:
Yury Selivanov62560fb2014-01-28 12:26:24 -05002472 def __init__(*args):
2473 pass
2474 def m1(self, arg1, arg2=1) -> int:
2475 pass
2476 def m2(*args):
2477 pass
2478 def __call__(*, a):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002479 pass
2480
Yury Selivanov62560fb2014-01-28 12:26:24 -05002481 self.assertEqual(self.signature(Test().m1),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002482 ((('arg1', ..., ..., "positional_or_keyword"),
2483 ('arg2', 1, ..., "positional_or_keyword")),
2484 int))
2485
Yury Selivanov62560fb2014-01-28 12:26:24 -05002486 self.assertEqual(self.signature(Test().m2),
2487 ((('args', ..., ..., "var_positional"),),
2488 ...))
2489
2490 self.assertEqual(self.signature(Test),
2491 ((('args', ..., ..., "var_positional"),),
2492 ...))
2493
2494 with self.assertRaisesRegex(ValueError, 'invalid method signature'):
2495 self.signature(Test())
2496
Yury Selivanov46c759d2015-05-27 21:56:53 -04002497 def test_signature_wrapped_bound_method(self):
2498 # Issue 24298
2499 class Test:
2500 def m1(self, arg1, arg2=1) -> int:
2501 pass
2502 @functools.wraps(Test().m1)
2503 def m1d(*args, **kwargs):
2504 pass
2505 self.assertEqual(self.signature(m1d),
2506 ((('arg1', ..., ..., "positional_or_keyword"),
2507 ('arg2', 1, ..., "positional_or_keyword")),
2508 int))
2509
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002510 def test_signature_on_classmethod(self):
2511 class Test:
2512 @classmethod
2513 def foo(cls, arg1, *, arg2=1):
2514 pass
2515
2516 meth = Test().foo
2517 self.assertEqual(self.signature(meth),
2518 ((('arg1', ..., ..., "positional_or_keyword"),
2519 ('arg2', 1, ..., "keyword_only")),
2520 ...))
2521
2522 meth = Test.foo
2523 self.assertEqual(self.signature(meth),
2524 ((('arg1', ..., ..., "positional_or_keyword"),
2525 ('arg2', 1, ..., "keyword_only")),
2526 ...))
2527
2528 def test_signature_on_staticmethod(self):
2529 class Test:
2530 @staticmethod
2531 def foo(cls, *, arg):
2532 pass
2533
2534 meth = Test().foo
2535 self.assertEqual(self.signature(meth),
2536 ((('cls', ..., ..., "positional_or_keyword"),
2537 ('arg', ..., ..., "keyword_only")),
2538 ...))
2539
2540 meth = Test.foo
2541 self.assertEqual(self.signature(meth),
2542 ((('cls', ..., ..., "positional_or_keyword"),
2543 ('arg', ..., ..., "keyword_only")),
2544 ...))
2545
2546 def test_signature_on_partial(self):
2547 from functools import partial
2548
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002549 Parameter = inspect.Parameter
2550
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002551 def test():
2552 pass
2553
2554 self.assertEqual(self.signature(partial(test)), ((), ...))
2555
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002556 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002557 inspect.signature(partial(test, 1))
2558
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002559 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002560 inspect.signature(partial(test, a=1))
2561
2562 def test(a, b, *, c, d):
2563 pass
2564
2565 self.assertEqual(self.signature(partial(test)),
2566 ((('a', ..., ..., "positional_or_keyword"),
2567 ('b', ..., ..., "positional_or_keyword"),
2568 ('c', ..., ..., "keyword_only"),
2569 ('d', ..., ..., "keyword_only")),
2570 ...))
2571
2572 self.assertEqual(self.signature(partial(test, 1)),
2573 ((('b', ..., ..., "positional_or_keyword"),
2574 ('c', ..., ..., "keyword_only"),
2575 ('d', ..., ..., "keyword_only")),
2576 ...))
2577
2578 self.assertEqual(self.signature(partial(test, 1, c=2)),
2579 ((('b', ..., ..., "positional_or_keyword"),
2580 ('c', 2, ..., "keyword_only"),
2581 ('d', ..., ..., "keyword_only")),
2582 ...))
2583
2584 self.assertEqual(self.signature(partial(test, b=1, c=2)),
2585 ((('a', ..., ..., "positional_or_keyword"),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002586 ('b', 1, ..., "keyword_only"),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002587 ('c', 2, ..., "keyword_only"),
2588 ('d', ..., ..., "keyword_only")),
2589 ...))
2590
2591 self.assertEqual(self.signature(partial(test, 0, b=1, c=2)),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002592 ((('b', 1, ..., "keyword_only"),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002593 ('c', 2, ..., "keyword_only"),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002594 ('d', ..., ..., "keyword_only")),
2595 ...))
2596
2597 self.assertEqual(self.signature(partial(test, a=1)),
2598 ((('a', 1, ..., "keyword_only"),
2599 ('b', ..., ..., "keyword_only"),
2600 ('c', ..., ..., "keyword_only"),
2601 ('d', ..., ..., "keyword_only")),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002602 ...))
2603
2604 def test(a, *args, b, **kwargs):
2605 pass
2606
2607 self.assertEqual(self.signature(partial(test, 1)),
2608 ((('args', ..., ..., "var_positional"),
2609 ('b', ..., ..., "keyword_only"),
2610 ('kwargs', ..., ..., "var_keyword")),
2611 ...))
2612
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002613 self.assertEqual(self.signature(partial(test, a=1)),
2614 ((('a', 1, ..., "keyword_only"),
2615 ('b', ..., ..., "keyword_only"),
2616 ('kwargs', ..., ..., "var_keyword")),
2617 ...))
2618
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002619 self.assertEqual(self.signature(partial(test, 1, 2, 3)),
2620 ((('args', ..., ..., "var_positional"),
2621 ('b', ..., ..., "keyword_only"),
2622 ('kwargs', ..., ..., "var_keyword")),
2623 ...))
2624
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002625 self.assertEqual(self.signature(partial(test, 1, 2, 3, test=True)),
2626 ((('args', ..., ..., "var_positional"),
2627 ('b', ..., ..., "keyword_only"),
2628 ('kwargs', ..., ..., "var_keyword")),
2629 ...))
2630
2631 self.assertEqual(self.signature(partial(test, 1, 2, 3, test=1, b=0)),
2632 ((('args', ..., ..., "var_positional"),
2633 ('b', 0, ..., "keyword_only"),
2634 ('kwargs', ..., ..., "var_keyword")),
2635 ...))
2636
2637 self.assertEqual(self.signature(partial(test, b=0)),
2638 ((('a', ..., ..., "positional_or_keyword"),
2639 ('args', ..., ..., "var_positional"),
2640 ('b', 0, ..., "keyword_only"),
2641 ('kwargs', ..., ..., "var_keyword")),
2642 ...))
2643
2644 self.assertEqual(self.signature(partial(test, b=0, test=1)),
2645 ((('a', ..., ..., "positional_or_keyword"),
2646 ('args', ..., ..., "var_positional"),
2647 ('b', 0, ..., "keyword_only"),
2648 ('kwargs', ..., ..., "var_keyword")),
2649 ...))
2650
2651 def test(a, b, c:int) -> 42:
2652 pass
2653
2654 sig = test.__signature__ = inspect.signature(test)
2655
2656 self.assertEqual(self.signature(partial(partial(test, 1))),
2657 ((('b', ..., ..., "positional_or_keyword"),
Batuhan Taskaya044a1042020-10-06 23:03:02 +03002658 ('c', ..., 'int', "positional_or_keyword")),
2659 '42'))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002660
2661 self.assertEqual(self.signature(partial(partial(test, 1), 2)),
Batuhan Taskaya044a1042020-10-06 23:03:02 +03002662 ((('c', ..., 'int', "positional_or_keyword"),),
2663 '42'))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002664
2665 psig = inspect.signature(partial(partial(test, 1), 2))
2666
2667 def foo(a):
2668 return a
2669 _foo = partial(partial(foo, a=10), a=20)
2670 self.assertEqual(self.signature(_foo),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002671 ((('a', 20, ..., "keyword_only"),),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002672 ...))
2673 # check that we don't have any side-effects in signature(),
2674 # and the partial object is still functioning
2675 self.assertEqual(_foo(), 20)
2676
2677 def foo(a, b, c):
2678 return a, b, c
2679 _foo = partial(partial(foo, 1, b=20), b=30)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002680
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002681 self.assertEqual(self.signature(_foo),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002682 ((('b', 30, ..., "keyword_only"),
2683 ('c', ..., ..., "keyword_only")),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002684 ...))
2685 self.assertEqual(_foo(c=10), (1, 30, 10))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002686
2687 def foo(a, b, c, *, d):
2688 return a, b, c, d
2689 _foo = partial(partial(foo, d=20, c=20), b=10, d=30)
2690 self.assertEqual(self.signature(_foo),
2691 ((('a', ..., ..., "positional_or_keyword"),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002692 ('b', 10, ..., "keyword_only"),
2693 ('c', 20, ..., "keyword_only"),
2694 ('d', 30, ..., "keyword_only"),
2695 ),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002696 ...))
2697 ba = inspect.signature(_foo).bind(a=200, b=11)
2698 self.assertEqual(_foo(*ba.args, **ba.kwargs), (200, 11, 20, 30))
2699
2700 def foo(a=1, b=2, c=3):
2701 return a, b, c
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002702 _foo = partial(foo, c=13) # (a=1, b=2, *, c=13)
2703
2704 ba = inspect.signature(_foo).bind(a=11)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002705 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 2, 13))
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002706
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002707 ba = inspect.signature(_foo).bind(11, 12)
2708 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002709
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002710 ba = inspect.signature(_foo).bind(11, b=12)
2711 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002712
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002713 ba = inspect.signature(_foo).bind(b=12)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002714 self.assertEqual(_foo(*ba.args, **ba.kwargs), (1, 12, 13))
2715
2716 _foo = partial(_foo, b=10, c=20)
2717 ba = inspect.signature(_foo).bind(12)
2718 self.assertEqual(_foo(*ba.args, **ba.kwargs), (12, 10, 20))
2719
2720
2721 def foo(a, b, c, d, **kwargs):
2722 pass
2723 sig = inspect.signature(foo)
2724 params = sig.parameters.copy()
2725 params['a'] = params['a'].replace(kind=Parameter.POSITIONAL_ONLY)
2726 params['b'] = params['b'].replace(kind=Parameter.POSITIONAL_ONLY)
2727 foo.__signature__ = inspect.Signature(params.values())
2728 sig = inspect.signature(foo)
2729 self.assertEqual(str(sig), '(a, b, /, c, d, **kwargs)')
2730
2731 self.assertEqual(self.signature(partial(foo, 1)),
2732 ((('b', ..., ..., 'positional_only'),
2733 ('c', ..., ..., 'positional_or_keyword'),
2734 ('d', ..., ..., 'positional_or_keyword'),
2735 ('kwargs', ..., ..., 'var_keyword')),
2736 ...))
2737
2738 self.assertEqual(self.signature(partial(foo, 1, 2)),
2739 ((('c', ..., ..., 'positional_or_keyword'),
2740 ('d', ..., ..., 'positional_or_keyword'),
2741 ('kwargs', ..., ..., 'var_keyword')),
2742 ...))
2743
2744 self.assertEqual(self.signature(partial(foo, 1, 2, 3)),
2745 ((('d', ..., ..., 'positional_or_keyword'),
2746 ('kwargs', ..., ..., 'var_keyword')),
2747 ...))
2748
2749 self.assertEqual(self.signature(partial(foo, 1, 2, c=3)),
2750 ((('c', 3, ..., 'keyword_only'),
2751 ('d', ..., ..., 'keyword_only'),
2752 ('kwargs', ..., ..., 'var_keyword')),
2753 ...))
2754
2755 self.assertEqual(self.signature(partial(foo, 1, c=3)),
2756 ((('b', ..., ..., 'positional_only'),
2757 ('c', 3, ..., 'keyword_only'),
2758 ('d', ..., ..., 'keyword_only'),
2759 ('kwargs', ..., ..., 'var_keyword')),
2760 ...))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002761
Yury Selivanovda5fe4f2014-01-27 17:28:37 -05002762 def test_signature_on_partialmethod(self):
2763 from functools import partialmethod
2764
2765 class Spam:
2766 def test():
2767 pass
2768 ham = partialmethod(test)
2769
2770 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
2771 inspect.signature(Spam.ham)
2772
2773 class Spam:
2774 def test(it, a, *, c) -> 'spam':
2775 pass
2776 ham = partialmethod(test, c=1)
2777
2778 self.assertEqual(self.signature(Spam.ham),
2779 ((('it', ..., ..., 'positional_or_keyword'),
2780 ('a', ..., ..., 'positional_or_keyword'),
2781 ('c', 1, ..., 'keyword_only')),
Batuhan Taskaya044a1042020-10-06 23:03:02 +03002782 repr('spam')))
Yury Selivanovda5fe4f2014-01-27 17:28:37 -05002783
2784 self.assertEqual(self.signature(Spam().ham),
2785 ((('a', ..., ..., 'positional_or_keyword'),
2786 ('c', 1, ..., 'keyword_only')),
Batuhan Taskaya044a1042020-10-06 23:03:02 +03002787 repr('spam')))
Yury Selivanovda5fe4f2014-01-27 17:28:37 -05002788
Yury Selivanov8a387212018-03-06 12:59:45 -05002789 class Spam:
2790 def test(self: 'anno', x):
2791 pass
2792
2793 g = partialmethod(test, 1)
2794
2795 self.assertEqual(self.signature(Spam.g),
Batuhan Taskaya044a1042020-10-06 23:03:02 +03002796 ((('self', ..., repr('anno'), 'positional_or_keyword'),),
Yury Selivanov8a387212018-03-06 12:59:45 -05002797 ...))
2798
Yury Selivanov0486f812014-01-29 12:18:59 -05002799 def test_signature_on_fake_partialmethod(self):
2800 def foo(a): pass
2801 foo._partialmethod = 'spam'
2802 self.assertEqual(str(inspect.signature(foo)), '(a)')
2803
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002804 def test_signature_on_decorated(self):
2805 import functools
2806
2807 def decorator(func):
2808 @functools.wraps(func)
2809 def wrapper(*args, **kwargs) -> int:
2810 return func(*args, **kwargs)
2811 return wrapper
2812
2813 class Foo:
2814 @decorator
2815 def bar(self, a, b):
2816 pass
2817
2818 self.assertEqual(self.signature(Foo.bar),
2819 ((('self', ..., ..., "positional_or_keyword"),
2820 ('a', ..., ..., "positional_or_keyword"),
2821 ('b', ..., ..., "positional_or_keyword")),
2822 ...))
2823
2824 self.assertEqual(self.signature(Foo().bar),
2825 ((('a', ..., ..., "positional_or_keyword"),
2826 ('b', ..., ..., "positional_or_keyword")),
2827 ...))
2828
Yury Selivanovbcd4fc12015-05-20 14:30:08 -04002829 self.assertEqual(self.signature(Foo.bar, follow_wrapped=False),
2830 ((('args', ..., ..., "var_positional"),
2831 ('kwargs', ..., ..., "var_keyword")),
2832 ...)) # functools.wraps will copy __annotations__
2833 # from "func" to "wrapper", hence no
2834 # return_annotation
2835
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002836 # Test that we handle method wrappers correctly
2837 def decorator(func):
2838 @functools.wraps(func)
2839 def wrapper(*args, **kwargs) -> int:
2840 return func(42, *args, **kwargs)
2841 sig = inspect.signature(func)
2842 new_params = tuple(sig.parameters.values())[1:]
2843 wrapper.__signature__ = sig.replace(parameters=new_params)
2844 return wrapper
2845
2846 class Foo:
2847 @decorator
2848 def __call__(self, a, b):
2849 pass
2850
2851 self.assertEqual(self.signature(Foo.__call__),
2852 ((('a', ..., ..., "positional_or_keyword"),
2853 ('b', ..., ..., "positional_or_keyword")),
2854 ...))
2855
2856 self.assertEqual(self.signature(Foo().__call__),
2857 ((('b', ..., ..., "positional_or_keyword"),),
2858 ...))
2859
Nick Coghlane8c45d62013-07-28 20:00:01 +10002860 # Test we handle __signature__ partway down the wrapper stack
2861 def wrapped_foo_call():
2862 pass
2863 wrapped_foo_call.__wrapped__ = Foo.__call__
2864
2865 self.assertEqual(self.signature(wrapped_foo_call),
2866 ((('a', ..., ..., "positional_or_keyword"),
2867 ('b', ..., ..., "positional_or_keyword")),
2868 ...))
2869
2870
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002871 def test_signature_on_class(self):
2872 class C:
2873 def __init__(self, a):
2874 pass
2875
2876 self.assertEqual(self.signature(C),
2877 ((('a', ..., ..., "positional_or_keyword"),),
2878 ...))
2879
2880 class CM(type):
2881 def __call__(cls, a):
2882 pass
2883 class C(metaclass=CM):
2884 def __init__(self, b):
2885 pass
2886
2887 self.assertEqual(self.signature(C),
2888 ((('a', ..., ..., "positional_or_keyword"),),
2889 ...))
2890
2891 class CM(type):
2892 def __new__(mcls, name, bases, dct, *, foo=1):
2893 return super().__new__(mcls, name, bases, dct)
2894 class C(metaclass=CM):
2895 def __init__(self, b):
2896 pass
2897
2898 self.assertEqual(self.signature(C),
2899 ((('b', ..., ..., "positional_or_keyword"),),
2900 ...))
2901
2902 self.assertEqual(self.signature(CM),
2903 ((('name', ..., ..., "positional_or_keyword"),
2904 ('bases', ..., ..., "positional_or_keyword"),
2905 ('dct', ..., ..., "positional_or_keyword"),
2906 ('foo', 1, ..., "keyword_only")),
2907 ...))
2908
2909 class CMM(type):
2910 def __new__(mcls, name, bases, dct, *, foo=1):
2911 return super().__new__(mcls, name, bases, dct)
2912 def __call__(cls, nm, bs, dt):
2913 return type(nm, bs, dt)
2914 class CM(type, metaclass=CMM):
2915 def __new__(mcls, name, bases, dct, *, bar=2):
2916 return super().__new__(mcls, name, bases, dct)
2917 class C(metaclass=CM):
2918 def __init__(self, b):
2919 pass
2920
2921 self.assertEqual(self.signature(CMM),
2922 ((('name', ..., ..., "positional_or_keyword"),
2923 ('bases', ..., ..., "positional_or_keyword"),
2924 ('dct', ..., ..., "positional_or_keyword"),
2925 ('foo', 1, ..., "keyword_only")),
2926 ...))
2927
2928 self.assertEqual(self.signature(CM),
2929 ((('nm', ..., ..., "positional_or_keyword"),
2930 ('bs', ..., ..., "positional_or_keyword"),
2931 ('dt', ..., ..., "positional_or_keyword")),
2932 ...))
2933
2934 self.assertEqual(self.signature(C),
2935 ((('b', ..., ..., "positional_or_keyword"),),
2936 ...))
2937
2938 class CM(type):
2939 def __init__(cls, name, bases, dct, *, bar=2):
2940 return super().__init__(name, bases, dct)
2941 class C(metaclass=CM):
2942 def __init__(self, b):
2943 pass
2944
2945 self.assertEqual(self.signature(CM),
2946 ((('name', ..., ..., "positional_or_keyword"),
2947 ('bases', ..., ..., "positional_or_keyword"),
2948 ('dct', ..., ..., "positional_or_keyword"),
2949 ('bar', 2, ..., "keyword_only")),
2950 ...))
2951
Yury Selivanov145dff82014-02-01 13:49:29 -05002952 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2953 "Signature information for builtins requires docstrings")
2954 def test_signature_on_class_without_init(self):
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002955 # Test classes without user-defined __init__ or __new__
2956 class C: pass
2957 self.assertEqual(str(inspect.signature(C)), '()')
2958 class D(C): pass
2959 self.assertEqual(str(inspect.signature(D)), '()')
2960
2961 # Test meta-classes without user-defined __init__ or __new__
2962 class C(type): pass
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002963 class D(C): pass
Larry Hastings2623c8c2014-02-08 22:15:29 -08002964 with self.assertRaisesRegex(ValueError, "callable.*is not supported"):
2965 self.assertEqual(inspect.signature(C), None)
2966 with self.assertRaisesRegex(ValueError, "callable.*is not supported"):
2967 self.assertEqual(inspect.signature(D), None)
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002968
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002969 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2970 "Signature information for builtins requires docstrings")
2971 def test_signature_on_builtin_class(self):
Antoine Pitrou91f43802019-05-26 17:10:09 +02002972 expected = ('(file, protocol=None, fix_imports=True, '
2973 'buffer_callback=None)')
2974 self.assertEqual(str(inspect.signature(_pickle.Pickler)), expected)
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002975
2976 class P(_pickle.Pickler): pass
2977 class EmptyTrait: pass
2978 class P2(EmptyTrait, P): pass
Antoine Pitrou91f43802019-05-26 17:10:09 +02002979 self.assertEqual(str(inspect.signature(P)), expected)
2980 self.assertEqual(str(inspect.signature(P2)), expected)
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002981
2982 class P3(P2):
2983 def __init__(self, spam):
2984 pass
2985 self.assertEqual(str(inspect.signature(P3)), '(spam)')
2986
2987 class MetaP(type):
2988 def __call__(cls, foo, bar):
2989 pass
2990 class P4(P2, metaclass=MetaP):
2991 pass
2992 self.assertEqual(str(inspect.signature(P4)), '(foo, bar)')
2993
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002994 def test_signature_on_callable_objects(self):
2995 class Foo:
2996 def __call__(self, a):
2997 pass
2998
2999 self.assertEqual(self.signature(Foo()),
3000 ((('a', ..., ..., "positional_or_keyword"),),
3001 ...))
3002
3003 class Spam:
3004 pass
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003005 with self.assertRaisesRegex(TypeError, "is not a callable object"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003006 inspect.signature(Spam())
3007
3008 class Bar(Spam, Foo):
3009 pass
3010
3011 self.assertEqual(self.signature(Bar()),
3012 ((('a', ..., ..., "positional_or_keyword"),),
3013 ...))
3014
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003015 class Wrapped:
3016 pass
3017 Wrapped.__wrapped__ = lambda a: None
3018 self.assertEqual(self.signature(Wrapped),
3019 ((('a', ..., ..., "positional_or_keyword"),),
3020 ...))
Nick Coghlane8c45d62013-07-28 20:00:01 +10003021 # wrapper loop:
3022 Wrapped.__wrapped__ = Wrapped
3023 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3024 self.signature(Wrapped)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003025
3026 def test_signature_on_lambdas(self):
3027 self.assertEqual(self.signature((lambda a=10: a)),
3028 ((('a', 10, ..., "positional_or_keyword"),),
3029 ...))
3030
3031 def test_signature_equality(self):
3032 def foo(a, *, b:int) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003033 self.assertFalse(inspect.signature(foo) == 42)
3034 self.assertTrue(inspect.signature(foo) != 42)
Serhiy Storchaka7d44e7a2019-08-08 08:43:18 +03003035 self.assertTrue(inspect.signature(foo) == ALWAYS_EQ)
3036 self.assertFalse(inspect.signature(foo) != ALWAYS_EQ)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003037
3038 def bar(a, *, b:int) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003039 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
3040 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003041 self.assertEqual(
3042 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003043
3044 def bar(a, *, b:int) -> int: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003045 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
3046 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003047 self.assertNotEqual(
3048 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003049
3050 def bar(a, *, b:int): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003051 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
3052 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003053 self.assertNotEqual(
3054 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003055
3056 def bar(a, *, b:int=42) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003057 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
3058 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003059 self.assertNotEqual(
3060 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003061
3062 def bar(a, *, c) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003063 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
3064 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003065 self.assertNotEqual(
3066 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003067
3068 def bar(a, b:int) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003069 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
3070 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003071 self.assertNotEqual(
3072 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003073 def spam(b:int, a) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003074 self.assertFalse(inspect.signature(spam) == inspect.signature(bar))
3075 self.assertTrue(inspect.signature(spam) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003076 self.assertNotEqual(
3077 hash(inspect.signature(spam)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003078
3079 def foo(*, a, b, c): pass
3080 def bar(*, c, b, a): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003081 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
3082 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003083 self.assertEqual(
3084 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003085
3086 def foo(*, a=1, b, c): pass
3087 def bar(*, c, b, a=1): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003088 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
3089 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003090 self.assertEqual(
3091 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003092
3093 def foo(pos, *, a=1, b, c): pass
3094 def bar(pos, *, c, b, a=1): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003095 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
3096 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003097 self.assertEqual(
3098 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003099
3100 def foo(pos, *, a, b, c): pass
3101 def bar(pos, *, c, b, a=1): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003102 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
3103 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003104 self.assertNotEqual(
3105 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003106
3107 def foo(pos, *args, a=42, b, c, **kwargs:int): pass
3108 def bar(pos, *args, c, b, a=42, **kwargs:int): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003109 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
3110 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003111 self.assertEqual(
3112 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003113
Yury Selivanov67ae50e2014-04-08 11:46:50 -04003114 def test_signature_hashable(self):
3115 S = inspect.Signature
3116 P = inspect.Parameter
3117
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003118 def foo(a): pass
Yury Selivanov67ae50e2014-04-08 11:46:50 -04003119 foo_sig = inspect.signature(foo)
3120
3121 manual_sig = S(parameters=[P('a', P.POSITIONAL_OR_KEYWORD)])
3122
3123 self.assertEqual(hash(foo_sig), hash(manual_sig))
3124 self.assertNotEqual(hash(foo_sig),
3125 hash(manual_sig.replace(return_annotation='spam')))
3126
3127 def bar(a) -> 1: pass
3128 self.assertNotEqual(hash(foo_sig), hash(inspect.signature(bar)))
3129
3130 def foo(a={}): pass
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003131 with self.assertRaisesRegex(TypeError, 'unhashable type'):
Yury Selivanov67ae50e2014-04-08 11:46:50 -04003132 hash(inspect.signature(foo))
3133
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003134 def test_signature_str(self):
3135 def foo(a:int=1, *, b, c=None, **kwargs) -> 42:
3136 pass
3137 self.assertEqual(str(inspect.signature(foo)),
Batuhan Taskaya044a1042020-10-06 23:03:02 +03003138 '(a: \'int\' = 1, *, b, c=None, **kwargs) -> \'42\'')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003139
3140 def foo(a:int=1, *args, b, c=None, **kwargs) -> 42:
3141 pass
3142 self.assertEqual(str(inspect.signature(foo)),
Batuhan Taskaya044a1042020-10-06 23:03:02 +03003143 '(a: \'int\' = 1, *args, b, c=None, **kwargs) -> \'42\'')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003144
3145 def foo():
3146 pass
3147 self.assertEqual(str(inspect.signature(foo)), '()')
3148
3149 def test_signature_str_positional_only(self):
3150 P = inspect.Parameter
Yury Selivanov2393dca2014-01-27 15:07:58 -05003151 S = inspect.Signature
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003152
3153 def test(a_po, *, b, **kwargs):
3154 return a_po, kwargs
3155
3156 sig = inspect.signature(test)
3157 new_params = list(sig.parameters.values())
3158 new_params[0] = new_params[0].replace(kind=P.POSITIONAL_ONLY)
3159 test.__signature__ = sig.replace(parameters=new_params)
3160
3161 self.assertEqual(str(inspect.signature(test)),
Yury Selivanov2393dca2014-01-27 15:07:58 -05003162 '(a_po, /, *, b, **kwargs)')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003163
Yury Selivanov2393dca2014-01-27 15:07:58 -05003164 self.assertEqual(str(S(parameters=[P('foo', P.POSITIONAL_ONLY)])),
3165 '(foo, /)')
3166
3167 self.assertEqual(str(S(parameters=[
3168 P('foo', P.POSITIONAL_ONLY),
3169 P('bar', P.VAR_KEYWORD)])),
3170 '(foo, /, **bar)')
3171
3172 self.assertEqual(str(S(parameters=[
3173 P('foo', P.POSITIONAL_ONLY),
3174 P('bar', P.VAR_POSITIONAL)])),
3175 '(foo, /, *bar)')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003176
3177 def test_signature_replace_anno(self):
3178 def test() -> 42:
3179 pass
3180
3181 sig = inspect.signature(test)
3182 sig = sig.replace(return_annotation=None)
3183 self.assertIs(sig.return_annotation, None)
3184 sig = sig.replace(return_annotation=sig.empty)
3185 self.assertIs(sig.return_annotation, sig.empty)
Batuhan Taskaya044a1042020-10-06 23:03:02 +03003186 sig = sig.replace(return_annotation='42')
3187 self.assertEqual(sig.return_annotation, '42')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003188 self.assertEqual(sig, inspect.signature(test))
3189
Yury Selivanov34ce99f2014-02-18 12:49:41 -05003190 def test_signature_on_mangled_parameters(self):
3191 class Spam:
3192 def foo(self, __p1:1=2, *, __p2:2=3):
3193 pass
3194 class Ham(Spam):
3195 pass
3196
3197 self.assertEqual(self.signature(Spam.foo),
3198 ((('self', ..., ..., "positional_or_keyword"),
Batuhan Taskaya044a1042020-10-06 23:03:02 +03003199 ('_Spam__p1', 2, '1', "positional_or_keyword"),
3200 ('_Spam__p2', 3, '2', "keyword_only")),
Yury Selivanov34ce99f2014-02-18 12:49:41 -05003201 ...))
3202
3203 self.assertEqual(self.signature(Spam.foo),
3204 self.signature(Ham.foo))
3205
Yury Selivanovda396452014-03-27 12:09:24 -04003206 def test_signature_from_callable_python_obj(self):
3207 class MySignature(inspect.Signature): pass
3208 def foo(a, *, b:1): pass
3209 foo_sig = MySignature.from_callable(foo)
Gregory P. Smith5b9ff7a2019-09-13 17:13:51 +01003210 self.assertIsInstance(foo_sig, MySignature)
3211
3212 def test_signature_from_callable_class(self):
3213 # A regression test for a class inheriting its signature from `object`.
3214 class MySignature(inspect.Signature): pass
3215 class foo: pass
3216 foo_sig = MySignature.from_callable(foo)
3217 self.assertIsInstance(foo_sig, MySignature)
Yury Selivanovda396452014-03-27 12:09:24 -04003218
3219 @unittest.skipIf(MISSING_C_DOCSTRINGS,
3220 "Signature information for builtins requires docstrings")
3221 def test_signature_from_callable_builtin_obj(self):
3222 class MySignature(inspect.Signature): pass
3223 sig = MySignature.from_callable(_pickle.Pickler)
Gregory P. Smith5b9ff7a2019-09-13 17:13:51 +01003224 self.assertIsInstance(sig, MySignature)
Yury Selivanovda396452014-03-27 12:09:24 -04003225
larryhastingsf36ba122018-01-28 11:13:09 -08003226 def test_signature_definition_order_preserved_on_kwonly(self):
3227 for fn in signatures_with_lexicographic_keyword_only_parameters():
3228 signature = inspect.signature(fn)
3229 l = list(signature.parameters)
3230 sorted_l = sorted(l)
3231 self.assertTrue(l)
3232 self.assertEqual(l, sorted_l)
3233 signature = inspect.signature(unsorted_keyword_only_parameters_fn)
3234 l = list(signature.parameters)
3235 self.assertEqual(l, unsorted_keyword_only_parameters)
3236
Jens Reidel611836a2020-03-18 03:22:46 +01003237 def test_signater_parameters_is_ordered(self):
3238 p1 = inspect.signature(lambda x, y: None).parameters
3239 p2 = inspect.signature(lambda y, x: None).parameters
3240 self.assertNotEqual(p1, p2)
3241
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003242
3243class TestParameterObject(unittest.TestCase):
3244 def test_signature_parameter_kinds(self):
3245 P = inspect.Parameter
3246 self.assertTrue(P.POSITIONAL_ONLY < P.POSITIONAL_OR_KEYWORD < \
3247 P.VAR_POSITIONAL < P.KEYWORD_ONLY < P.VAR_KEYWORD)
3248
3249 self.assertEqual(str(P.POSITIONAL_ONLY), 'POSITIONAL_ONLY')
3250 self.assertTrue('POSITIONAL_ONLY' in repr(P.POSITIONAL_ONLY))
3251
3252 def test_signature_parameter_object(self):
3253 p = inspect.Parameter('foo', default=10,
3254 kind=inspect.Parameter.POSITIONAL_ONLY)
3255 self.assertEqual(p.name, 'foo')
3256 self.assertEqual(p.default, 10)
3257 self.assertIs(p.annotation, p.empty)
3258 self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY)
3259
Dong-hee Naa9cab432018-05-30 00:04:08 +09003260 with self.assertRaisesRegex(ValueError, "value '123' is "
3261 "not a valid Parameter.kind"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003262 inspect.Parameter('foo', default=10, kind='123')
3263
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003264 with self.assertRaisesRegex(ValueError, 'not a valid parameter name'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003265 inspect.Parameter('1', kind=inspect.Parameter.VAR_KEYWORD)
3266
Yury Selivanov2393dca2014-01-27 15:07:58 -05003267 with self.assertRaisesRegex(TypeError, 'name must be a str'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003268 inspect.Parameter(None, kind=inspect.Parameter.VAR_KEYWORD)
3269
Yury Selivanov2393dca2014-01-27 15:07:58 -05003270 with self.assertRaisesRegex(ValueError,
3271 'is not a valid parameter name'):
3272 inspect.Parameter('$', kind=inspect.Parameter.VAR_KEYWORD)
3273
Nick Coghlanb4b966e2016-06-04 14:40:03 -07003274 with self.assertRaisesRegex(ValueError,
3275 'is not a valid parameter name'):
3276 inspect.Parameter('.a', kind=inspect.Parameter.VAR_KEYWORD)
3277
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003278 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003279 inspect.Parameter('a', default=42,
3280 kind=inspect.Parameter.VAR_KEYWORD)
3281
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003282 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003283 inspect.Parameter('a', default=42,
3284 kind=inspect.Parameter.VAR_POSITIONAL)
3285
3286 p = inspect.Parameter('a', default=42,
3287 kind=inspect.Parameter.POSITIONAL_OR_KEYWORD)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003288 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003289 p.replace(kind=inspect.Parameter.VAR_POSITIONAL)
3290
3291 self.assertTrue(repr(p).startswith('<Parameter'))
Yury Selivanov374375d2014-03-27 12:41:53 -04003292 self.assertTrue('"a=42"' in repr(p))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003293
Yury Selivanov67ae50e2014-04-08 11:46:50 -04003294 def test_signature_parameter_hashable(self):
3295 P = inspect.Parameter
3296 foo = P('foo', kind=P.POSITIONAL_ONLY)
3297 self.assertEqual(hash(foo), hash(P('foo', kind=P.POSITIONAL_ONLY)))
3298 self.assertNotEqual(hash(foo), hash(P('foo', kind=P.POSITIONAL_ONLY,
3299 default=42)))
3300 self.assertNotEqual(hash(foo),
3301 hash(foo.replace(kind=P.VAR_POSITIONAL)))
3302
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003303 def test_signature_parameter_equality(self):
3304 P = inspect.Parameter
3305 p = P('foo', default=42, kind=inspect.Parameter.KEYWORD_ONLY)
3306
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003307 self.assertTrue(p == p)
3308 self.assertFalse(p != p)
3309 self.assertFalse(p == 42)
3310 self.assertTrue(p != 42)
Serhiy Storchaka7d44e7a2019-08-08 08:43:18 +03003311 self.assertTrue(p == ALWAYS_EQ)
3312 self.assertFalse(p != ALWAYS_EQ)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003313
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003314 self.assertTrue(p == P('foo', default=42,
3315 kind=inspect.Parameter.KEYWORD_ONLY))
3316 self.assertFalse(p != P('foo', default=42,
3317 kind=inspect.Parameter.KEYWORD_ONLY))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003318
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003319 def test_signature_parameter_replace(self):
3320 p = inspect.Parameter('foo', default=42,
3321 kind=inspect.Parameter.KEYWORD_ONLY)
3322
3323 self.assertIsNot(p, p.replace())
3324 self.assertEqual(p, p.replace())
3325
3326 p2 = p.replace(annotation=1)
3327 self.assertEqual(p2.annotation, 1)
3328 p2 = p2.replace(annotation=p2.empty)
3329 self.assertEqual(p, p2)
3330
3331 p2 = p2.replace(name='bar')
3332 self.assertEqual(p2.name, 'bar')
3333 self.assertNotEqual(p2, p)
3334
Yury Selivanov2393dca2014-01-27 15:07:58 -05003335 with self.assertRaisesRegex(ValueError,
3336 'name is a required attribute'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003337 p2 = p2.replace(name=p2.empty)
3338
3339 p2 = p2.replace(name='foo', default=None)
3340 self.assertIs(p2.default, None)
3341 self.assertNotEqual(p2, p)
3342
3343 p2 = p2.replace(name='foo', default=p2.empty)
3344 self.assertIs(p2.default, p2.empty)
3345
3346
3347 p2 = p2.replace(default=42, kind=p2.POSITIONAL_OR_KEYWORD)
3348 self.assertEqual(p2.kind, p2.POSITIONAL_OR_KEYWORD)
3349 self.assertNotEqual(p2, p)
3350
Dong-hee Naa9cab432018-05-30 00:04:08 +09003351 with self.assertRaisesRegex(ValueError,
3352 "value <class 'inspect._empty'> "
3353 "is not a valid Parameter.kind"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003354 p2 = p2.replace(kind=p2.empty)
3355
3356 p2 = p2.replace(kind=p2.KEYWORD_ONLY)
3357 self.assertEqual(p2, p)
3358
3359 def test_signature_parameter_positional_only(self):
Yury Selivanov2393dca2014-01-27 15:07:58 -05003360 with self.assertRaisesRegex(TypeError, 'name must be a str'):
3361 inspect.Parameter(None, kind=inspect.Parameter.POSITIONAL_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003362
Nick Coghlanb4b966e2016-06-04 14:40:03 -07003363 @cpython_only
3364 def test_signature_parameter_implicit(self):
3365 with self.assertRaisesRegex(ValueError,
Dong-hee Naa9cab432018-05-30 00:04:08 +09003366 'implicit arguments must be passed as '
3367 'positional or keyword arguments, '
3368 'not positional-only'):
Nick Coghlanb4b966e2016-06-04 14:40:03 -07003369 inspect.Parameter('.0', kind=inspect.Parameter.POSITIONAL_ONLY)
3370
3371 param = inspect.Parameter(
3372 '.0', kind=inspect.Parameter.POSITIONAL_OR_KEYWORD)
3373 self.assertEqual(param.kind, inspect.Parameter.POSITIONAL_ONLY)
3374 self.assertEqual(param.name, 'implicit0')
3375
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003376 def test_signature_parameter_immutability(self):
Yury Selivanov2393dca2014-01-27 15:07:58 -05003377 p = inspect.Parameter('spam', kind=inspect.Parameter.KEYWORD_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003378
3379 with self.assertRaises(AttributeError):
3380 p.foo = 'bar'
3381
3382 with self.assertRaises(AttributeError):
3383 p.kind = 123
3384
3385
3386class TestSignatureBind(unittest.TestCase):
3387 @staticmethod
3388 def call(func, *args, **kwargs):
3389 sig = inspect.signature(func)
3390 ba = sig.bind(*args, **kwargs)
3391 return func(*ba.args, **ba.kwargs)
3392
3393 def test_signature_bind_empty(self):
3394 def test():
3395 return 42
3396
3397 self.assertEqual(self.call(test), 42)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003398 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003399 self.call(test, 1)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003400 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003401 self.call(test, 1, spam=10)
Yury Selivanov86872752015-05-19 00:27:49 -04003402 with self.assertRaisesRegex(
3403 TypeError, "got an unexpected keyword argument 'spam'"):
3404
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003405 self.call(test, spam=1)
3406
3407 def test_signature_bind_var(self):
3408 def test(*args, **kwargs):
3409 return args, kwargs
3410
3411 self.assertEqual(self.call(test), ((), {}))
3412 self.assertEqual(self.call(test, 1), ((1,), {}))
3413 self.assertEqual(self.call(test, 1, 2), ((1, 2), {}))
3414 self.assertEqual(self.call(test, foo='bar'), ((), {'foo': 'bar'}))
3415 self.assertEqual(self.call(test, 1, foo='bar'), ((1,), {'foo': 'bar'}))
3416 self.assertEqual(self.call(test, args=10), ((), {'args': 10}))
3417 self.assertEqual(self.call(test, 1, 2, foo='bar'),
3418 ((1, 2), {'foo': 'bar'}))
3419
3420 def test_signature_bind_just_args(self):
3421 def test(a, b, c):
3422 return a, b, c
3423
3424 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
3425
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003426 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003427 self.call(test, 1, 2, 3, 4)
3428
Yury Selivanov86872752015-05-19 00:27:49 -04003429 with self.assertRaisesRegex(TypeError,
3430 "missing a required argument: 'b'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003431 self.call(test, 1)
3432
Yury Selivanov86872752015-05-19 00:27:49 -04003433 with self.assertRaisesRegex(TypeError,
3434 "missing a required argument: 'a'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003435 self.call(test)
3436
3437 def test(a, b, c=10):
3438 return a, b, c
3439 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
3440 self.assertEqual(self.call(test, 1, 2), (1, 2, 10))
3441
3442 def test(a=1, b=2, c=3):
3443 return a, b, c
3444 self.assertEqual(self.call(test, a=10, c=13), (10, 2, 13))
3445 self.assertEqual(self.call(test, a=10), (10, 2, 3))
3446 self.assertEqual(self.call(test, b=10), (1, 10, 3))
3447
3448 def test_signature_bind_varargs_order(self):
3449 def test(*args):
3450 return args
3451
3452 self.assertEqual(self.call(test), ())
3453 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
3454
3455 def test_signature_bind_args_and_varargs(self):
3456 def test(a, b, c=3, *args):
3457 return a, b, c, args
3458
3459 self.assertEqual(self.call(test, 1, 2, 3, 4, 5), (1, 2, 3, (4, 5)))
3460 self.assertEqual(self.call(test, 1, 2), (1, 2, 3, ()))
3461 self.assertEqual(self.call(test, b=1, a=2), (2, 1, 3, ()))
3462 self.assertEqual(self.call(test, 1, b=2), (1, 2, 3, ()))
3463
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003464 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003465 "multiple values for argument 'c'"):
3466 self.call(test, 1, 2, 3, c=4)
3467
3468 def test_signature_bind_just_kwargs(self):
3469 def test(**kwargs):
3470 return kwargs
3471
3472 self.assertEqual(self.call(test), {})
3473 self.assertEqual(self.call(test, foo='bar', spam='ham'),
3474 {'foo': 'bar', 'spam': 'ham'})
3475
3476 def test_signature_bind_args_and_kwargs(self):
3477 def test(a, b, c=3, **kwargs):
3478 return a, b, c, kwargs
3479
3480 self.assertEqual(self.call(test, 1, 2), (1, 2, 3, {}))
3481 self.assertEqual(self.call(test, 1, 2, foo='bar', spam='ham'),
3482 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3483 self.assertEqual(self.call(test, b=2, a=1, foo='bar', spam='ham'),
3484 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3485 self.assertEqual(self.call(test, a=1, b=2, foo='bar', spam='ham'),
3486 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3487 self.assertEqual(self.call(test, 1, b=2, foo='bar', spam='ham'),
3488 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3489 self.assertEqual(self.call(test, 1, b=2, c=4, foo='bar', spam='ham'),
3490 (1, 2, 4, {'foo': 'bar', 'spam': 'ham'}))
3491 self.assertEqual(self.call(test, 1, 2, 4, foo='bar'),
3492 (1, 2, 4, {'foo': 'bar'}))
3493 self.assertEqual(self.call(test, c=5, a=4, b=3),
3494 (4, 3, 5, {}))
3495
3496 def test_signature_bind_kwonly(self):
3497 def test(*, foo):
3498 return foo
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003499 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003500 'too many positional arguments'):
3501 self.call(test, 1)
3502 self.assertEqual(self.call(test, foo=1), 1)
3503
3504 def test(a, *, foo=1, bar):
3505 return foo
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003506 with self.assertRaisesRegex(TypeError,
Yury Selivanov86872752015-05-19 00:27:49 -04003507 "missing a required argument: 'bar'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003508 self.call(test, 1)
3509
3510 def test(foo, *, bar):
3511 return foo, bar
3512 self.assertEqual(self.call(test, 1, bar=2), (1, 2))
3513 self.assertEqual(self.call(test, bar=2, foo=1), (1, 2))
3514
Yury Selivanov86872752015-05-19 00:27:49 -04003515 with self.assertRaisesRegex(
3516 TypeError, "got an unexpected keyword argument 'spam'"):
3517
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003518 self.call(test, bar=2, foo=1, spam=10)
3519
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003520 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003521 'too many positional arguments'):
3522 self.call(test, 1, 2)
3523
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003524 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003525 'too many positional arguments'):
3526 self.call(test, 1, 2, bar=2)
3527
Yury Selivanov86872752015-05-19 00:27:49 -04003528 with self.assertRaisesRegex(
3529 TypeError, "got an unexpected keyword argument 'spam'"):
3530
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003531 self.call(test, 1, bar=2, spam='ham')
3532
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003533 with self.assertRaisesRegex(TypeError,
Yury Selivanov86872752015-05-19 00:27:49 -04003534 "missing a required argument: 'bar'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003535 self.call(test, 1)
3536
3537 def test(foo, *, bar, **bin):
3538 return foo, bar, bin
3539 self.assertEqual(self.call(test, 1, bar=2), (1, 2, {}))
3540 self.assertEqual(self.call(test, foo=1, bar=2), (1, 2, {}))
3541 self.assertEqual(self.call(test, 1, bar=2, spam='ham'),
3542 (1, 2, {'spam': 'ham'}))
3543 self.assertEqual(self.call(test, spam='ham', foo=1, bar=2),
3544 (1, 2, {'spam': 'ham'}))
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003545 with self.assertRaisesRegex(TypeError,
Yury Selivanov86872752015-05-19 00:27:49 -04003546 "missing a required argument: 'foo'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003547 self.call(test, spam='ham', bar=2)
3548 self.assertEqual(self.call(test, 1, bar=2, bin=1, spam=10),
3549 (1, 2, {'bin': 1, 'spam': 10}))
3550
3551 def test_signature_bind_arguments(self):
3552 def test(a, *args, b, z=100, **kwargs):
3553 pass
3554 sig = inspect.signature(test)
3555 ba = sig.bind(10, 20, b=30, c=40, args=50, kwargs=60)
3556 # we won't have 'z' argument in the bound arguments object, as we didn't
3557 # pass it to the 'bind'
3558 self.assertEqual(tuple(ba.arguments.items()),
3559 (('a', 10), ('args', (20,)), ('b', 30),
3560 ('kwargs', {'c': 40, 'args': 50, 'kwargs': 60})))
3561 self.assertEqual(ba.kwargs,
3562 {'b': 30, 'c': 40, 'args': 50, 'kwargs': 60})
3563 self.assertEqual(ba.args, (10, 20))
3564
3565 def test_signature_bind_positional_only(self):
3566 P = inspect.Parameter
3567
3568 def test(a_po, b_po, c_po=3, foo=42, *, bar=50, **kwargs):
3569 return a_po, b_po, c_po, foo, bar, kwargs
3570
3571 sig = inspect.signature(test)
3572 new_params = collections.OrderedDict(tuple(sig.parameters.items()))
3573 for name in ('a_po', 'b_po', 'c_po'):
3574 new_params[name] = new_params[name].replace(kind=P.POSITIONAL_ONLY)
3575 new_sig = sig.replace(parameters=new_params.values())
3576 test.__signature__ = new_sig
3577
3578 self.assertEqual(self.call(test, 1, 2, 4, 5, bar=6),
3579 (1, 2, 4, 5, 6, {}))
3580
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05003581 self.assertEqual(self.call(test, 1, 2),
3582 (1, 2, 3, 42, 50, {}))
3583
3584 self.assertEqual(self.call(test, 1, 2, foo=4, bar=5),
3585 (1, 2, 3, 4, 5, {}))
3586
3587 with self.assertRaisesRegex(TypeError, "but was passed as a keyword"):
3588 self.call(test, 1, 2, foo=4, bar=5, c_po=10)
3589
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003590 with self.assertRaisesRegex(TypeError, "parameter is positional only"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003591 self.call(test, 1, 2, c_po=4)
3592
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003593 with self.assertRaisesRegex(TypeError, "parameter is positional only"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003594 self.call(test, a_po=1, b_po=2)
3595
Antoine Pitroubd41d1b2013-01-29 21:20:57 +01003596 def test_signature_bind_with_self_arg(self):
3597 # Issue #17071: one of the parameters is named "self
3598 def test(a, self, b):
3599 pass
3600 sig = inspect.signature(test)
3601 ba = sig.bind(1, 2, 3)
3602 self.assertEqual(ba.args, (1, 2, 3))
3603 ba = sig.bind(1, self=2, b=3)
3604 self.assertEqual(ba.args, (1, 2, 3))
3605
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05003606 def test_signature_bind_vararg_name(self):
3607 def test(a, *args):
3608 return a, args
3609 sig = inspect.signature(test)
3610
Yury Selivanov86872752015-05-19 00:27:49 -04003611 with self.assertRaisesRegex(
3612 TypeError, "got an unexpected keyword argument 'args'"):
3613
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05003614 sig.bind(a=0, args=1)
3615
3616 def test(*args, **kwargs):
3617 return args, kwargs
3618 self.assertEqual(self.call(test, args=1), ((), {'args': 1}))
3619
3620 sig = inspect.signature(test)
3621 ba = sig.bind(args=1)
3622 self.assertEqual(ba.arguments, {'kwargs': {'args': 1}})
3623
Nick Coghlanb4b966e2016-06-04 14:40:03 -07003624 @cpython_only
3625 def test_signature_bind_implicit_arg(self):
3626 # Issue #19611: getcallargs should work with set comprehensions
3627 def make_set():
3628 return {z * z for z in range(5)}
3629 setcomp_code = make_set.__code__.co_consts[1]
3630 setcomp_func = types.FunctionType(setcomp_code, {})
3631
3632 iterator = iter(range(5))
3633 self.assertEqual(self.call(setcomp_func, iterator), {0, 1, 4, 9, 16})
3634
Pablo Galindof3ef06a2019-10-15 12:40:02 +01003635 def test_signature_bind_posonly_kwargs(self):
3636 def foo(bar, /, **kwargs):
3637 return bar, kwargs.get(bar)
3638
3639 sig = inspect.signature(foo)
3640 result = sig.bind("pos-only", bar="keyword")
3641
3642 self.assertEqual(result.kwargs, {"bar": "keyword"})
3643 self.assertIn(("bar", "pos-only"), result.arguments.items())
3644
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003645
3646class TestBoundArguments(unittest.TestCase):
3647 def test_signature_bound_arguments_unhashable(self):
3648 def foo(a): pass
3649 ba = inspect.signature(foo).bind(1)
3650
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003651 with self.assertRaisesRegex(TypeError, 'unhashable type'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003652 hash(ba)
3653
3654 def test_signature_bound_arguments_equality(self):
3655 def foo(a): pass
3656 ba = inspect.signature(foo).bind(1)
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003657 self.assertTrue(ba == ba)
3658 self.assertFalse(ba != ba)
Serhiy Storchaka7d44e7a2019-08-08 08:43:18 +03003659 self.assertTrue(ba == ALWAYS_EQ)
3660 self.assertFalse(ba != ALWAYS_EQ)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003661
3662 ba2 = inspect.signature(foo).bind(1)
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003663 self.assertTrue(ba == ba2)
3664 self.assertFalse(ba != ba2)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003665
3666 ba3 = inspect.signature(foo).bind(2)
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003667 self.assertFalse(ba == ba3)
3668 self.assertTrue(ba != ba3)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003669 ba3.arguments['a'] = 1
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003670 self.assertTrue(ba == ba3)
3671 self.assertFalse(ba != ba3)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003672
3673 def bar(b): pass
3674 ba4 = inspect.signature(bar).bind(1)
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003675 self.assertFalse(ba == ba4)
3676 self.assertTrue(ba != ba4)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003677
Yury Selivanov4cfd4ea2015-05-14 18:30:27 -04003678 def foo(*, a, b): pass
3679 sig = inspect.signature(foo)
3680 ba1 = sig.bind(a=1, b=2)
3681 ba2 = sig.bind(b=2, a=1)
Serhiy Storchaka2489bd52015-07-18 23:20:50 +03003682 self.assertTrue(ba1 == ba2)
3683 self.assertFalse(ba1 != ba2)
Yury Selivanov4cfd4ea2015-05-14 18:30:27 -04003684
Yury Selivanova5d63dd2014-03-27 11:31:43 -04003685 def test_signature_bound_arguments_pickle(self):
3686 def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
3687 sig = inspect.signature(foo)
3688 ba = sig.bind(20, 30, z={})
3689
3690 for ver in range(pickle.HIGHEST_PROTOCOL + 1):
3691 with self.subTest(pickle_ver=ver):
3692 ba_pickled = pickle.loads(pickle.dumps(ba, ver))
3693 self.assertEqual(ba, ba_pickled)
3694
Yury Selivanov3f6538f2015-05-14 18:47:17 -04003695 def test_signature_bound_arguments_repr(self):
3696 def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
3697 sig = inspect.signature(foo)
3698 ba = sig.bind(20, 30, z={})
Yury Selivanovf229bc52015-05-15 12:53:56 -04003699 self.assertRegex(repr(ba), r'<BoundArguments \(a=20,.*\}\}\)>')
Yury Selivanov3f6538f2015-05-14 18:47:17 -04003700
Yury Selivanovb907a512015-05-16 13:45:09 -04003701 def test_signature_bound_arguments_apply_defaults(self):
3702 def foo(a, b=1, *args, c:1={}, **kw): pass
3703 sig = inspect.signature(foo)
3704
3705 ba = sig.bind(20)
3706 ba.apply_defaults()
3707 self.assertEqual(
3708 list(ba.arguments.items()),
3709 [('a', 20), ('b', 1), ('args', ()), ('c', {}), ('kw', {})])
3710
3711 # Make sure that we preserve the order:
3712 # i.e. 'c' should be *before* 'kw'.
3713 ba = sig.bind(10, 20, 30, d=1)
3714 ba.apply_defaults()
3715 self.assertEqual(
3716 list(ba.arguments.items()),
3717 [('a', 10), ('b', 20), ('args', (30,)), ('c', {}), ('kw', {'d':1})])
3718
3719 # Make sure that BoundArguments produced by bind_partial()
3720 # are supported.
3721 def foo(a, b): pass
3722 sig = inspect.signature(foo)
3723 ba = sig.bind_partial(20)
3724 ba.apply_defaults()
3725 self.assertEqual(
3726 list(ba.arguments.items()),
3727 [('a', 20)])
3728
3729 # Test no args
3730 def foo(): pass
3731 sig = inspect.signature(foo)
3732 ba = sig.bind()
3733 ba.apply_defaults()
3734 self.assertEqual(list(ba.arguments.items()), [])
3735
Yury Selivanovf9e1f2b2016-03-02 11:07:47 -05003736 # Make sure a no-args binding still acquires proper defaults.
3737 def foo(a='spam'): pass
3738 sig = inspect.signature(foo)
3739 ba = sig.bind()
3740 ba.apply_defaults()
3741 self.assertEqual(list(ba.arguments.items()), [('a', 'spam')])
3742
Rémi Lapeyre2cca8ef2020-01-28 13:47:03 +01003743 def test_signature_bound_arguments_arguments_type(self):
3744 def foo(a): pass
3745 ba = inspect.signature(foo).bind(1)
3746 self.assertIs(type(ba.arguments), dict)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003747
Yury Selivanovd82eddc2014-01-29 11:24:39 -05003748class TestSignaturePrivateHelpers(unittest.TestCase):
3749 def test_signature_get_bound_param(self):
3750 getter = inspect._signature_get_bound_param
3751
3752 self.assertEqual(getter('($self)'), 'self')
3753 self.assertEqual(getter('($self, obj)'), 'self')
3754 self.assertEqual(getter('($cls, /, obj)'), 'cls')
3755
Larry Hastings2623c8c2014-02-08 22:15:29 -08003756 def _strip_non_python_syntax(self, input,
3757 clean_signature, self_parameter, last_positional_only):
3758 computed_clean_signature, \
3759 computed_self_parameter, \
3760 computed_last_positional_only = \
3761 inspect._signature_strip_non_python_syntax(input)
3762 self.assertEqual(computed_clean_signature, clean_signature)
3763 self.assertEqual(computed_self_parameter, self_parameter)
3764 self.assertEqual(computed_last_positional_only, last_positional_only)
3765
3766 def test_signature_strip_non_python_syntax(self):
3767 self._strip_non_python_syntax(
3768 "($module, /, path, mode, *, dir_fd=None, " +
3769 "effective_ids=False,\n follow_symlinks=True)",
3770 "(module, path, mode, *, dir_fd=None, " +
3771 "effective_ids=False, follow_symlinks=True)",
3772 0,
3773 0)
3774
3775 self._strip_non_python_syntax(
3776 "($module, word, salt, /)",
3777 "(module, word, salt)",
3778 0,
3779 2)
3780
3781 self._strip_non_python_syntax(
3782 "(x, y=None, z=None, /)",
3783 "(x, y=None, z=None)",
3784 None,
3785 2)
3786
3787 self._strip_non_python_syntax(
3788 "(x, y=None, z=None)",
3789 "(x, y=None, z=None)",
3790 None,
3791 None)
3792
3793 self._strip_non_python_syntax(
3794 "(x,\n y=None,\n z = None )",
3795 "(x, y=None, z=None)",
3796 None,
3797 None)
3798
3799 self._strip_non_python_syntax(
3800 "",
3801 "",
3802 None,
3803 None)
3804
3805 self._strip_non_python_syntax(
3806 None,
3807 None,
3808 None,
3809 None)
3810
Nick Coghlan9c680b02015-04-13 12:54:54 -04003811class TestSignatureDefinitions(unittest.TestCase):
3812 # This test case provides a home for checking that particular APIs
3813 # have signatures available for introspection
3814
3815 @cpython_only
3816 @unittest.skipIf(MISSING_C_DOCSTRINGS,
3817 "Signature information for builtins requires docstrings")
3818 def test_builtins_have_signatures(self):
3819 # This checks all builtin callables in CPython have signatures
3820 # A few have signatures Signature can't yet handle, so we skip those
3821 # since they will have to wait until PEP 457 adds the required
3822 # introspection support to the inspect module
3823 # Some others also haven't been converted yet for various other
3824 # reasons, so we also skip those for the time being, but design
3825 # the test to fail in order to indicate when it needs to be
3826 # updated.
3827 no_signature = set()
3828 # These need PEP 457 groups
3829 needs_groups = {"range", "slice", "dir", "getattr",
3830 "next", "iter", "vars"}
3831 no_signature |= needs_groups
3832 # These need PEP 457 groups or a signature change to accept None
3833 needs_semantic_update = {"round"}
3834 no_signature |= needs_semantic_update
3835 # These need *args support in Argument Clinic
Barry Warsaw36c1d1f2017-10-05 12:11:18 -04003836 needs_varargs = {"breakpoint", "min", "max", "print",
3837 "__build_class__"}
Nick Coghlan9c680b02015-04-13 12:54:54 -04003838 no_signature |= needs_varargs
3839 # These simply weren't covered in the initial AC conversion
3840 # for builtin callables
3841 not_converted_yet = {"open", "__import__"}
3842 no_signature |= not_converted_yet
3843 # These builtin types are expected to provide introspection info
3844 types_with_signatures = set()
3845 # Check the signatures we expect to be there
3846 ns = vars(builtins)
3847 for name, obj in sorted(ns.items()):
3848 if not callable(obj):
3849 continue
3850 # The builtin types haven't been converted to AC yet
3851 if isinstance(obj, type) and (name not in types_with_signatures):
3852 # Note that this also skips all the exception types
3853 no_signature.add(name)
3854 if (name in no_signature):
3855 # Not yet converted
3856 continue
3857 with self.subTest(builtin=name):
3858 self.assertIsNotNone(inspect.signature(obj))
3859 # Check callables that haven't been converted don't claim a signature
3860 # This ensures this test will start failing as more signatures are
3861 # added, so the affected items can be moved into the scope of the
3862 # regression test above
3863 for name in no_signature:
3864 with self.subTest(builtin=name):
3865 self.assertIsNone(obj.__text_signature__)
3866
Serhiy Storchakad53cf992019-05-06 22:40:27 +03003867 def test_python_function_override_signature(self):
3868 def func(*args, **kwargs):
3869 pass
3870 func.__text_signature__ = '($self, a, b=1, *args, c, d=2, **kwargs)'
3871 sig = inspect.signature(func)
3872 self.assertIsNotNone(sig)
3873 self.assertEqual(str(sig), '(self, /, a, b=1, *args, c, d=2, **kwargs)')
3874 func.__text_signature__ = '($self, a, b=1, /, *args, c, d=2, **kwargs)'
3875 sig = inspect.signature(func)
3876 self.assertEqual(str(sig), '(self, a, b=1, /, *args, c, d=2, **kwargs)')
3877
Yury Selivanovd82eddc2014-01-29 11:24:39 -05003878
Thomas Kluyverf9169ce2017-05-23 04:27:52 +01003879class NTimesUnwrappable:
3880 def __init__(self, n):
3881 self.n = n
3882 self._next = None
3883
3884 @property
3885 def __wrapped__(self):
3886 if self.n <= 0:
3887 raise Exception("Unwrapped too many times")
3888 if self._next is None:
3889 self._next = NTimesUnwrappable(self.n - 1)
3890 return self._next
3891
Nick Coghlane8c45d62013-07-28 20:00:01 +10003892class TestUnwrap(unittest.TestCase):
3893
3894 def test_unwrap_one(self):
3895 def func(a, b):
3896 return a + b
3897 wrapper = functools.lru_cache(maxsize=20)(func)
3898 self.assertIs(inspect.unwrap(wrapper), func)
3899
3900 def test_unwrap_several(self):
3901 def func(a, b):
3902 return a + b
3903 wrapper = func
3904 for __ in range(10):
3905 @functools.wraps(wrapper)
3906 def wrapper():
3907 pass
3908 self.assertIsNot(wrapper.__wrapped__, func)
3909 self.assertIs(inspect.unwrap(wrapper), func)
3910
3911 def test_stop(self):
3912 def func1(a, b):
3913 return a + b
3914 @functools.wraps(func1)
3915 def func2():
3916 pass
3917 @functools.wraps(func2)
3918 def wrapper():
3919 pass
3920 func2.stop_here = 1
3921 unwrapped = inspect.unwrap(wrapper,
3922 stop=(lambda f: hasattr(f, "stop_here")))
3923 self.assertIs(unwrapped, func2)
3924
3925 def test_cycle(self):
3926 def func1(): pass
3927 func1.__wrapped__ = func1
3928 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3929 inspect.unwrap(func1)
3930
3931 def func2(): pass
3932 func2.__wrapped__ = func1
3933 func1.__wrapped__ = func2
3934 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3935 inspect.unwrap(func1)
3936 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3937 inspect.unwrap(func2)
3938
3939 def test_unhashable(self):
3940 def func(): pass
3941 func.__wrapped__ = None
3942 class C:
3943 __hash__ = None
3944 __wrapped__ = func
3945 self.assertIsNone(inspect.unwrap(C()))
3946
Thomas Kluyverf9169ce2017-05-23 04:27:52 +01003947 def test_recursion_limit(self):
3948 obj = NTimesUnwrappable(sys.getrecursionlimit() + 1)
3949 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3950 inspect.unwrap(obj)
3951
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003952class TestMain(unittest.TestCase):
3953 def test_only_source(self):
3954 module = importlib.import_module('unittest')
3955 rc, out, err = assert_python_ok('-m', 'inspect',
3956 'unittest')
3957 lines = out.decode().splitlines()
3958 # ignore the final newline
3959 self.assertEqual(lines[:-1], inspect.getsource(module).splitlines())
3960 self.assertEqual(err, b'')
3961
Yury Selivanov42407ab2014-06-23 10:23:50 -07003962 def test_custom_getattr(self):
3963 def foo():
3964 pass
3965 foo.__signature__ = 42
3966 with self.assertRaises(TypeError):
3967 inspect.signature(foo)
3968
Brett Cannon634a8fc2013-10-02 10:25:42 -04003969 @unittest.skipIf(ThreadPoolExecutor is None,
Brett Cannon0de3f012013-10-02 10:58:58 -04003970 'threads required to test __qualname__ for source files')
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003971 def test_qualname_source(self):
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003972 rc, out, err = assert_python_ok('-m', 'inspect',
3973 'concurrent.futures:ThreadPoolExecutor')
3974 lines = out.decode().splitlines()
3975 # ignore the final newline
3976 self.assertEqual(lines[:-1],
Brett Cannon634a8fc2013-10-02 10:25:42 -04003977 inspect.getsource(ThreadPoolExecutor).splitlines())
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003978 self.assertEqual(err, b'')
3979
3980 def test_builtins(self):
3981 module = importlib.import_module('unittest')
3982 _, out, err = assert_python_failure('-m', 'inspect',
3983 'sys')
3984 lines = err.decode().splitlines()
3985 self.assertEqual(lines, ["Can't get info for builtin modules."])
3986
3987 def test_details(self):
3988 module = importlib.import_module('unittest')
Victor Stinner9def2842016-01-18 12:15:08 +01003989 args = support.optim_args_from_interpreter_flags()
3990 rc, out, err = assert_python_ok(*args, '-m', 'inspect',
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003991 'unittest', '--details')
3992 output = out.decode()
3993 # Just a quick sanity check on the output
3994 self.assertIn(module.__name__, output)
3995 self.assertIn(module.__file__, output)
Victor Stinner9def2842016-01-18 12:15:08 +01003996 self.assertIn(module.__cached__, output)
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003997 self.assertEqual(err, b'')
3998
3999
Yury Selivanovef1e7502014-12-08 16:05:34 -05004000class TestReload(unittest.TestCase):
4001
4002 src_before = textwrap.dedent("""\
4003def foo():
4004 print("Bla")
4005 """)
4006
4007 src_after = textwrap.dedent("""\
4008def foo():
4009 print("Oh no!")
4010 """)
4011
4012 def assertInspectEqual(self, path, source):
4013 inspected_src = inspect.getsource(source)
4014 with open(path) as src:
4015 self.assertEqual(
4016 src.read().splitlines(True),
4017 inspected_src.splitlines(True)
4018 )
4019
4020 def test_getsource_reload(self):
4021 # see issue 1218234
4022 with _ready_to_import('reload_bug', self.src_before) as (name, path):
4023 module = importlib.import_module(name)
4024 self.assertInspectEqual(path, module)
4025 with open(path, 'w') as src:
4026 src.write(self.src_after)
4027 self.assertInspectEqual(path, module)
Nick Coghlanf94a16b2013-09-22 22:46:49 +10004028
Nick Coghlane8c45d62013-07-28 20:00:01 +10004029
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00004030def test_main():
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00004031 run_unittest(
Irit Katriel6e1eec72020-12-04 16:45:38 +00004032 TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBlockComments,
4033 TestBuggyCases, TestInterpreterStack, TestClassesAndFunctions, TestPredicates,
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00004034 TestGetcallargsFunctions, TestGetcallargsMethods,
Alexander Belopolskyf546e702010-12-02 00:10:11 +00004035 TestGetcallargsUnboundMethods, TestGetattrStatic, TestGetGeneratorState,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07004036 TestNoEOL, TestSignatureObject, TestSignatureBind, TestParameterObject,
Nick Coghlan9c680b02015-04-13 12:54:54 -04004037 TestBoundArguments, TestSignaturePrivateHelpers,
Aaron Hall, MBA4054b172018-05-20 19:46:42 -04004038 TestSignatureDefinitions, TestIsDataDescriptor,
Yury Selivanov5376ba92015-06-22 12:19:30 -04004039 TestGetClosureVars, TestUnwrap, TestMain, TestReload,
Vladimir Matveev91cb2982018-08-24 07:18:00 -07004040 TestGetCoroutineState, TestGettingSourceOfToplevelFrames
Michael Foord95fc51d2010-11-20 15:07:30 +00004041 )
Martin v. Löwis893ffa42003-10-31 15:35:53 +00004042
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00004043if __name__ == "__main__":
4044 test_main()