blob: 05485a0bc057540b130f5d9605ce88713ef4a6f0 [file] [log] [blame]
Nick Coghlanf9e227e2014-08-17 14:01:19 +10001import builtins
Guido van Rossum813b0e52007-05-21 18:11:34 +00002import collections
Larry Hastings5c661892014-01-24 06:17:25 -08003import datetime
Nick Coghlane8c45d62013-07-28 20:00:01 +10004import functools
Nick Coghlanf94a16b2013-09-22 22:46:49 +10005import importlib
Larry Hastings5c661892014-01-24 06:17:25 -08006import inspect
7import io
8import linecache
9import os
Christian Heimesa3538eb2007-11-06 11:44:48 +000010from os.path import normcase
Larry Hastings5c661892014-01-24 06:17:25 -080011import _pickle
Yury Selivanova5d63dd2014-03-27 11:31:43 -040012import pickle
Larry Hastings5c661892014-01-24 06:17:25 -080013import shutil
14import sys
15import types
Yury Selivanovef1e7502014-12-08 16:05:34 -050016import textwrap
Larry Hastings5c661892014-01-24 06:17:25 -080017import unicodedata
18import unittest
Yury Selivanova773de02014-02-21 18:30:53 -050019import unittest.mock
Yury Selivanov75445082015-05-11 22:57:16 -040020import warnings
Larry Hastings5c661892014-01-24 06:17:25 -080021
Brett Cannon634a8fc2013-10-02 10:25:42 -040022try:
23 from concurrent.futures import ThreadPoolExecutor
24except ImportError:
25 ThreadPoolExecutor = None
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000026
Serhiy Storchakaf28ba362014-02-07 10:10:55 +020027from test.support import run_unittest, TESTFN, DirsOnSysPath, cpython_only
Serhiy Storchaka7d44e7a2019-08-08 08:43:18 +030028from test.support import MISSING_C_DOCSTRINGS, ALWAYS_EQ
Berker Peksagce643912015-05-06 06:33:17 +030029from test.support.script_helper import assert_python_ok, assert_python_failure
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000030from test import inspect_fodder as mod
31from test import inspect_fodder2 as mod2
Victor Stinner9def2842016-01-18 12:15:08 +010032from test import support
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000033
Yury Selivanovef1e7502014-12-08 16:05:34 -050034from test.test_import import _ready_to_import
35
R. David Murray74b89242009-05-13 17:33:03 +000036
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000037# Functions tested in this suite:
38# ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode,
Christian Heimes7131fd92008-02-19 14:21:46 +000039# isbuiltin, isroutine, isgenerator, isgeneratorfunction, getmembers,
40# getdoc, getfile, getmodule, getsourcefile, getcomments, getsource,
Berker Peksagfa3922c2015-07-31 04:11:29 +030041# getclasstree, getargvalues, formatargspec, formatargvalues,
Christian Heimes7131fd92008-02-19 14:21:46 +000042# currentframe, stack, trace, isdatadescriptor
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000043
Nick Coghlanf088e5e2008-12-14 11:50:48 +000044# NOTE: There are some additional tests relating to interaction with
45# zipimport in the test_zipimport_support test module.
46
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000047modfile = mod.__file__
Thomas Wouters0e3f5912006-08-11 14:57:12 +000048if modfile.endswith(('c', 'o')):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000049 modfile = modfile[:-1]
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000050
Christian Heimesa3538eb2007-11-06 11:44:48 +000051# Normalize file names: on Windows, the case of file names of compiled
52# modules depends on the path used to start the python executable.
53modfile = normcase(modfile)
54
55def revise(filename, *args):
56 return (normcase(filename),) + args
57
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000058git = mod.StupidGit()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000059
larryhastingsf36ba122018-01-28 11:13:09 -080060
61def signatures_with_lexicographic_keyword_only_parameters():
62 """
63 Yields a whole bunch of functions with only keyword-only parameters,
64 where those parameters are always in lexicographically sorted order.
65 """
66 parameters = ['a', 'bar', 'c', 'delta', 'ephraim', 'magical', 'yoyo', 'z']
67 for i in range(1, 2**len(parameters)):
68 p = []
69 bit = 1
70 for j in range(len(parameters)):
71 if i & (bit << j):
72 p.append(parameters[j])
73 fn_text = "def foo(*, " + ", ".join(p) + "): pass"
74 symbols = {}
75 exec(fn_text, symbols, symbols)
76 yield symbols['foo']
77
78
79def unsorted_keyword_only_parameters_fn(*, throw, out, the, baby, with_,
80 the_, bathwater):
81 pass
82
83unsorted_keyword_only_parameters = 'throw out the baby with_ the_ bathwater'.split()
84
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000085class IsTestBase(unittest.TestCase):
86 predicates = set([inspect.isbuiltin, inspect.isclass, inspect.iscode,
87 inspect.isframe, inspect.isfunction, inspect.ismethod,
Christian Heimes7131fd92008-02-19 14:21:46 +000088 inspect.ismodule, inspect.istraceback,
Yury Selivanov75445082015-05-11 22:57:16 -040089 inspect.isgenerator, inspect.isgeneratorfunction,
Yury Selivanoveb636452016-09-08 22:01:51 -070090 inspect.iscoroutine, inspect.iscoroutinefunction,
91 inspect.isasyncgen, inspect.isasyncgenfunction])
Tim Peters5a9fb3c2005-01-07 16:01:32 +000092
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000093 def istest(self, predicate, exp):
94 obj = eval(exp)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000095 self.assertTrue(predicate(obj), '%s(%s)' % (predicate.__name__, exp))
Tim Peters5a9fb3c2005-01-07 16:01:32 +000096
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000097 for other in self.predicates - set([predicate]):
Yury Selivanov75445082015-05-11 22:57:16 -040098 if (predicate == inspect.isgeneratorfunction or \
Yury Selivanoveb636452016-09-08 22:01:51 -070099 predicate == inspect.isasyncgenfunction or \
Yury Selivanov75445082015-05-11 22:57:16 -0400100 predicate == inspect.iscoroutinefunction) and \
Christian Heimes7131fd92008-02-19 14:21:46 +0000101 other == inspect.isfunction:
102 continue
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000103 self.assertFalse(other(obj), 'not %s(%s)' % (other.__name__, exp))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000104
Christian Heimes7131fd92008-02-19 14:21:46 +0000105def generator_function_example(self):
106 for i in range(2):
107 yield i
108
Yury Selivanoveb636452016-09-08 22:01:51 -0700109async def async_generator_function_example(self):
110 async for i in range(2):
111 yield i
112
Yury Selivanov75445082015-05-11 22:57:16 -0400113async def coroutine_function_example(self):
114 return 'spam'
115
116@types.coroutine
117def gen_coroutine_function_example(self):
118 yield
119 return 'spam'
120
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000121class TestPredicates(IsTestBase):
Christian Heimes7131fd92008-02-19 14:21:46 +0000122
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000123 def test_excluding_predicates(self):
Antoine Pitroud5a1a212012-06-17 23:18:07 +0200124 global tb
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000125 self.istest(inspect.isbuiltin, 'sys.exit')
126 self.istest(inspect.isbuiltin, '[].append')
Neal Norwitz221085d2007-02-25 20:55:47 +0000127 self.istest(inspect.iscode, 'mod.spam.__code__')
Antoine Pitroud5a1a212012-06-17 23:18:07 +0200128 try:
129 1/0
130 except:
131 tb = sys.exc_info()[2]
132 self.istest(inspect.isframe, 'tb.tb_frame')
133 self.istest(inspect.istraceback, 'tb')
134 if hasattr(types, 'GetSetDescriptorType'):
135 self.istest(inspect.isgetsetdescriptor,
136 'type(tb.tb_frame).f_locals')
137 else:
138 self.assertFalse(inspect.isgetsetdescriptor(type(tb.tb_frame).f_locals))
139 finally:
140 # Clear traceback and all the frames and local variables hanging to it.
141 tb = None
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000142 self.istest(inspect.isfunction, 'mod.spam')
Christian Heimes4a22b5d2007-11-25 09:39:14 +0000143 self.istest(inspect.isfunction, 'mod.StupidGit.abuse')
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000144 self.istest(inspect.ismethod, 'git.argue')
Jeroen Demeyerfcef60f2019-04-02 16:03:42 +0200145 self.istest(inspect.ismethod, 'mod.custom_method')
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000146 self.istest(inspect.ismodule, 'mod')
Guido van Rossum813b0e52007-05-21 18:11:34 +0000147 self.istest(inspect.isdatadescriptor, 'collections.defaultdict.default_factory')
Christian Heimes7131fd92008-02-19 14:21:46 +0000148 self.istest(inspect.isgenerator, '(x for x in range(2))')
149 self.istest(inspect.isgeneratorfunction, 'generator_function_example')
Yury Selivanoveb636452016-09-08 22:01:51 -0700150 self.istest(inspect.isasyncgen,
151 'async_generator_function_example(1)')
152 self.istest(inspect.isasyncgenfunction,
153 'async_generator_function_example')
Yury Selivanov75445082015-05-11 22:57:16 -0400154
155 with warnings.catch_warnings():
156 warnings.simplefilter("ignore")
157 self.istest(inspect.iscoroutine, 'coroutine_function_example(1)')
158 self.istest(inspect.iscoroutinefunction, 'coroutine_function_example')
159
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000160 if hasattr(types, 'MemberDescriptorType'):
161 self.istest(inspect.ismemberdescriptor, 'datetime.timedelta.days')
162 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000163 self.assertFalse(inspect.ismemberdescriptor(datetime.timedelta.days))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000164
Yury Selivanov75445082015-05-11 22:57:16 -0400165 def test_iscoroutine(self):
Pablo Galindo7cd25432018-10-26 12:19:14 +0100166 async_gen_coro = async_generator_function_example(1)
Yury Selivanov75445082015-05-11 22:57:16 -0400167 gen_coro = gen_coroutine_function_example(1)
168 coro = coroutine_function_example(1)
169
Yury Selivanov5376ba92015-06-22 12:19:30 -0400170 self.assertFalse(
Yury Selivanov75445082015-05-11 22:57:16 -0400171 inspect.iscoroutinefunction(gen_coroutine_function_example))
Pablo Galindo7cd25432018-10-26 12:19:14 +0100172 self.assertFalse(
173 inspect.iscoroutinefunction(
174 functools.partial(functools.partial(
175 gen_coroutine_function_example))))
Yury Selivanov5376ba92015-06-22 12:19:30 -0400176 self.assertFalse(inspect.iscoroutine(gen_coro))
Yury Selivanov75445082015-05-11 22:57:16 -0400177
178 self.assertTrue(
179 inspect.isgeneratorfunction(gen_coroutine_function_example))
Pablo Galindo7cd25432018-10-26 12:19:14 +0100180 self.assertTrue(
181 inspect.isgeneratorfunction(
182 functools.partial(functools.partial(
183 gen_coroutine_function_example))))
Yury Selivanov75445082015-05-11 22:57:16 -0400184 self.assertTrue(inspect.isgenerator(gen_coro))
185
186 self.assertTrue(
187 inspect.iscoroutinefunction(coroutine_function_example))
Pablo Galindo7cd25432018-10-26 12:19:14 +0100188 self.assertTrue(
189 inspect.iscoroutinefunction(
190 functools.partial(functools.partial(
191 coroutine_function_example))))
Yury Selivanov75445082015-05-11 22:57:16 -0400192 self.assertTrue(inspect.iscoroutine(coro))
193
194 self.assertFalse(
195 inspect.isgeneratorfunction(coroutine_function_example))
Pablo Galindo7cd25432018-10-26 12:19:14 +0100196 self.assertFalse(
197 inspect.isgeneratorfunction(
198 functools.partial(functools.partial(
199 coroutine_function_example))))
Yury Selivanov75445082015-05-11 22:57:16 -0400200 self.assertFalse(inspect.isgenerator(coro))
201
Pablo Galindo7cd25432018-10-26 12:19:14 +0100202 self.assertTrue(
203 inspect.isasyncgenfunction(async_generator_function_example))
204 self.assertTrue(
205 inspect.isasyncgenfunction(
206 functools.partial(functools.partial(
207 async_generator_function_example))))
208 self.assertTrue(inspect.isasyncgen(async_gen_coro))
209
210 coro.close(); gen_coro.close(); # silence warnings
Yury Selivanov75445082015-05-11 22:57:16 -0400211
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -0400212 def test_isawaitable(self):
213 def gen(): yield
214 self.assertFalse(inspect.isawaitable(gen()))
215
216 coro = coroutine_function_example(1)
217 gen_coro = gen_coroutine_function_example(1)
218
219 self.assertTrue(inspect.isawaitable(coro))
220 self.assertTrue(inspect.isawaitable(gen_coro))
221
222 class Future:
223 def __await__():
224 pass
225 self.assertTrue(inspect.isawaitable(Future()))
226 self.assertFalse(inspect.isawaitable(Future))
227
228 class NotFuture: pass
229 not_fut = NotFuture()
230 not_fut.__await__ = lambda: None
231 self.assertFalse(inspect.isawaitable(not_fut))
232
233 coro.close(); gen_coro.close() # silence warnings
234
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000235 def test_isroutine(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000236 self.assertTrue(inspect.isroutine(mod.spam))
237 self.assertTrue(inspect.isroutine([].count))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000238
Benjamin Petersonc4656002009-01-17 22:41:18 +0000239 def test_isclass(self):
240 self.istest(inspect.isclass, 'mod.StupidGit')
241 self.assertTrue(inspect.isclass(list))
242
243 class CustomGetattr(object):
244 def __getattr__(self, attr):
245 return None
246 self.assertFalse(inspect.isclass(CustomGetattr()))
247
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000248 def test_get_slot_members(self):
249 class C(object):
250 __slots__ = ("a", "b")
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000251 x = C()
252 x.a = 42
253 members = dict(inspect.getmembers(x))
Benjamin Peterson577473f2010-01-19 00:09:57 +0000254 self.assertIn('a', members)
255 self.assertNotIn('b', members)
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000256
Benjamin Petersona0dfa822009-11-13 02:25:08 +0000257 def test_isabstract(self):
258 from abc import ABCMeta, abstractmethod
259
260 class AbstractClassExample(metaclass=ABCMeta):
261
262 @abstractmethod
263 def foo(self):
264 pass
265
266 class ClassExample(AbstractClassExample):
267 def foo(self):
268 pass
269
270 a = ClassExample()
271
272 # Test general behaviour.
273 self.assertTrue(inspect.isabstract(AbstractClassExample))
274 self.assertFalse(inspect.isabstract(ClassExample))
275 self.assertFalse(inspect.isabstract(a))
276 self.assertFalse(inspect.isabstract(int))
277 self.assertFalse(inspect.isabstract(5))
278
Natefcfe80e2017-04-24 10:06:15 -0700279 def test_isabstract_during_init_subclass(self):
280 from abc import ABCMeta, abstractmethod
281 isabstract_checks = []
282 class AbstractChecker(metaclass=ABCMeta):
283 def __init_subclass__(cls):
284 isabstract_checks.append(inspect.isabstract(cls))
285 class AbstractClassExample(AbstractChecker):
286 @abstractmethod
287 def foo(self):
288 pass
289 class ClassExample(AbstractClassExample):
290 def foo(self):
291 pass
292 self.assertEqual(isabstract_checks, [True, False])
293
294 isabstract_checks.clear()
295 class AbstractChild(AbstractClassExample):
296 pass
297 class AbstractGrandchild(AbstractChild):
298 pass
299 class ConcreteGrandchild(ClassExample):
300 pass
301 self.assertEqual(isabstract_checks, [True, True, False])
302
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000303
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000304class TestInterpreterStack(IsTestBase):
305 def __init__(self, *args, **kwargs):
306 unittest.TestCase.__init__(self, *args, **kwargs)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000307
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000308 git.abuse(7, 8, 9)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000309
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000310 def test_abuse_done(self):
311 self.istest(inspect.istraceback, 'git.ex[2]')
312 self.istest(inspect.isframe, 'mod.fr')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000313
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000314 def test_stack(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000315 self.assertTrue(len(mod.st) >= 5)
Christian Heimesa3538eb2007-11-06 11:44:48 +0000316 self.assertEqual(revise(*mod.st[0][1:]),
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000317 (modfile, 16, 'eggs', [' st = inspect.stack()\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000318 self.assertEqual(revise(*mod.st[1][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000319 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000320 self.assertEqual(revise(*mod.st[2][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000321 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000322 self.assertEqual(revise(*mod.st[3][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000323 (modfile, 39, 'abuse', [' self.argue(a, b, c)\n'], 0))
Antoine Pitroucdcafb72014-08-24 10:50:28 -0400324 # Test named tuple fields
325 record = mod.st[0]
326 self.assertIs(record.frame, mod.fr)
327 self.assertEqual(record.lineno, 16)
328 self.assertEqual(record.filename, mod.__file__)
329 self.assertEqual(record.function, 'eggs')
330 self.assertIn('inspect.stack()', record.code_context[0])
331 self.assertEqual(record.index, 0)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000332
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000333 def test_trace(self):
334 self.assertEqual(len(git.tr), 3)
Florent Xiclunac8575922010-03-24 17:37:49 +0000335 self.assertEqual(revise(*git.tr[0][1:]),
336 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
337 self.assertEqual(revise(*git.tr[1][1:]),
338 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
339 self.assertEqual(revise(*git.tr[2][1:]),
340 (modfile, 18, 'eggs', [' q = y / 0\n'], 0))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000341
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000342 def test_frame(self):
343 args, varargs, varkw, locals = inspect.getargvalues(mod.fr)
344 self.assertEqual(args, ['x', 'y'])
345 self.assertEqual(varargs, None)
346 self.assertEqual(varkw, None)
347 self.assertEqual(locals, {'x': 11, 'p': 11, 'y': 14})
348 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
349 '(x=11, y=14)')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000350
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000351 def test_previous_frame(self):
352 args, varargs, varkw, locals = inspect.getargvalues(mod.fr.f_back)
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000353 self.assertEqual(args, ['a', 'b', 'c', 'd', 'e', 'f'])
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000354 self.assertEqual(varargs, 'g')
355 self.assertEqual(varkw, 'h')
356 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000357 '(a=7, b=8, c=9, d=3, e=4, f=5, *g=(), **h={})')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000358
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000359class GetSourceBase(unittest.TestCase):
360 # Subclasses must override.
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000361 fodderModule = None
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000362
Yury Selivanov6738b112015-05-16 10:10:21 -0400363 def setUp(self):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000364 with open(inspect.getsourcefile(self.fodderModule)) as fp:
Philip Jenveya27c5bd2009-05-28 06:09:08 +0000365 self.source = fp.read()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000366
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000367 def sourcerange(self, top, bottom):
368 lines = self.source.split("\n")
Vladimir Matveev91cb2982018-08-24 07:18:00 -0700369 return "\n".join(lines[top-1:bottom]) + ("\n" if bottom else "")
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000370
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000371 def assertSourceEqual(self, obj, top, bottom):
372 self.assertEqual(inspect.getsource(obj),
373 self.sourcerange(top, bottom))
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000374
Raymond Hettingerd1e768a2019-03-25 13:01:13 -0700375class SlotUser:
376 'Docstrings for __slots__'
377 __slots__ = {'power': 'measured in kilowatts',
378 'distance': 'measured in kilometers'}
379
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000380class TestRetrievingSourceCode(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000381 fodderModule = mod
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000382
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000383 def test_getclasses(self):
384 classes = inspect.getmembers(mod, inspect.isclass)
385 self.assertEqual(classes,
386 [('FesteringGob', mod.FesteringGob),
387 ('MalodorousPervert', mod.MalodorousPervert),
388 ('ParrotDroppings', mod.ParrotDroppings),
Serhiy Storchaka362c1b52013-09-05 17:14:32 +0300389 ('StupidGit', mod.StupidGit),
390 ('Tit', mod.MalodorousPervert),
Miss Islington (bot)81ac0302020-12-04 12:20:05 -0800391 ('WhichComments', mod.WhichComments),
Serhiy Storchaka362c1b52013-09-05 17:14:32 +0300392 ])
393 tree = inspect.getclasstree([cls[1] for cls in classes])
394 self.assertEqual(tree,
395 [(object, ()),
396 [(mod.ParrotDroppings, (object,)),
397 [(mod.FesteringGob, (mod.MalodorousPervert,
398 mod.ParrotDroppings))
399 ],
400 (mod.StupidGit, (object,)),
401 [(mod.MalodorousPervert, (mod.StupidGit,)),
402 [(mod.FesteringGob, (mod.MalodorousPervert,
403 mod.ParrotDroppings))
404 ]
Miss Islington (bot)81ac0302020-12-04 12:20:05 -0800405 ],
406 (mod.WhichComments, (object,),)
Serhiy Storchaka362c1b52013-09-05 17:14:32 +0300407 ]
408 ])
409 tree = inspect.getclasstree([cls[1] for cls in classes], True)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000410 self.assertEqual(tree,
Thomas Wouters725af872006-04-15 09:13:19 +0000411 [(object, ()),
412 [(mod.ParrotDroppings, (object,)),
413 (mod.StupidGit, (object,)),
414 [(mod.MalodorousPervert, (mod.StupidGit,)),
415 [(mod.FesteringGob, (mod.MalodorousPervert,
416 mod.ParrotDroppings))
417 ]
Miss Islington (bot)81ac0302020-12-04 12:20:05 -0800418 ],
419 (mod.WhichComments, (object,),)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000420 ]
421 ])
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000422
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000423 def test_getfunctions(self):
424 functions = inspect.getmembers(mod, inspect.isfunction)
425 self.assertEqual(functions, [('eggs', mod.eggs),
Yury Selivanove4e811d2015-07-21 19:01:52 +0300426 ('lobbest', mod.lobbest),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000427 ('spam', mod.spam)])
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000428
R. David Murray378c0cf2010-02-24 01:46:21 +0000429 @unittest.skipIf(sys.flags.optimize >= 2,
430 "Docstrings are omitted with -O2 and above")
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000431 def test_getdoc(self):
432 self.assertEqual(inspect.getdoc(mod), 'A module docstring.')
433 self.assertEqual(inspect.getdoc(mod.StupidGit),
434 'A longer,\n\nindented\n\ndocstring.')
435 self.assertEqual(inspect.getdoc(git.abuse),
436 'Another\n\ndocstring\n\ncontaining\n\ntabs')
Raymond Hettingerd1e768a2019-03-25 13:01:13 -0700437 self.assertEqual(inspect.getdoc(SlotUser.power),
438 'measured in kilowatts')
439 self.assertEqual(inspect.getdoc(SlotUser.distance),
440 'measured in kilometers')
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000441
Serhiy Storchaka5cf2b7252015-04-03 22:38:53 +0300442 @unittest.skipIf(sys.flags.optimize >= 2,
443 "Docstrings are omitted with -O2 and above")
444 def test_getdoc_inherited(self):
Serhiy Storchaka08b47c32020-05-18 20:25:07 +0300445 self.assertEqual(inspect.getdoc(mod.FesteringGob),
446 'A longer,\n\nindented\n\ndocstring.')
Serhiy Storchaka5cf2b7252015-04-03 22:38:53 +0300447 self.assertEqual(inspect.getdoc(mod.FesteringGob.abuse),
448 'Another\n\ndocstring\n\ncontaining\n\ntabs')
449 self.assertEqual(inspect.getdoc(mod.FesteringGob().abuse),
450 'Another\n\ndocstring\n\ncontaining\n\ntabs')
451 self.assertEqual(inspect.getdoc(mod.FesteringGob.contradiction),
452 'The automatic gainsaying.')
453
454 @unittest.skipIf(MISSING_C_DOCSTRINGS, "test requires docstrings")
455 def test_finddoc(self):
456 finddoc = inspect._finddoc
Serhiy Storchaka08b47c32020-05-18 20:25:07 +0300457 self.assertEqual(finddoc(int), int.__doc__)
Serhiy Storchaka5cf2b7252015-04-03 22:38:53 +0300458 self.assertEqual(finddoc(int.to_bytes), int.to_bytes.__doc__)
459 self.assertEqual(finddoc(int().to_bytes), int.to_bytes.__doc__)
460 self.assertEqual(finddoc(int.from_bytes), int.from_bytes.__doc__)
461 self.assertEqual(finddoc(int.real), int.real.__doc__)
462
Georg Brandl0c77a822008-06-10 16:37:50 +0000463 def test_cleandoc(self):
464 self.assertEqual(inspect.cleandoc('An\n indented\n docstring.'),
465 'An\nindented\ndocstring.')
466
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000467 def test_getcomments(self):
468 self.assertEqual(inspect.getcomments(mod), '# line 1\n')
469 self.assertEqual(inspect.getcomments(mod.StupidGit), '# line 20\n')
Karthikeyan Singaravelan696136b2020-04-18 21:49:32 +0530470 self.assertEqual(inspect.getcomments(mod2.cls160), '# line 159\n')
Marco Buttu3f2155f2017-03-17 09:50:23 +0100471 # If the object source file is not available, return None.
472 co = compile('x=1', '_non_existing_filename.py', 'exec')
473 self.assertIsNone(inspect.getcomments(co))
474 # If the object has been defined in C, return None.
475 self.assertIsNone(inspect.getcomments(list))
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000476
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000477 def test_getmodule(self):
Thomas Wouters89f507f2006-12-13 04:49:30 +0000478 # Check actual module
479 self.assertEqual(inspect.getmodule(mod), mod)
480 # Check class (uses __module__ attribute)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000481 self.assertEqual(inspect.getmodule(mod.StupidGit), mod)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000482 # Check a method (no __module__ attribute, falls back to filename)
483 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
484 # Do it again (check the caching isn't broken)
485 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
486 # Check a builtin
Georg Brandl1a3284e2007-12-02 09:40:06 +0000487 self.assertEqual(inspect.getmodule(str), sys.modules["builtins"])
Thomas Wouters89f507f2006-12-13 04:49:30 +0000488 # Check filename override
489 self.assertEqual(inspect.getmodule(None, modfile), mod)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000490
Berker Peksagff0e3b72017-01-02 06:57:43 +0300491 def test_getframeinfo_get_first_line(self):
492 frame_info = inspect.getframeinfo(self.fodderModule.fr, 50)
493 self.assertEqual(frame_info.code_context[0], "# line 1\n")
494 self.assertEqual(frame_info.code_context[1], "'A module docstring.'\n")
495
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000496 def test_getsource(self):
497 self.assertSourceEqual(git.abuse, 29, 39)
Serhiy Storchakaac4bdcc2015-10-29 08:15:50 +0200498 self.assertSourceEqual(mod.StupidGit, 21, 51)
499 self.assertSourceEqual(mod.lobbest, 75, 76)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000500
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000501 def test_getsourcefile(self):
Christian Heimesa3538eb2007-11-06 11:44:48 +0000502 self.assertEqual(normcase(inspect.getsourcefile(mod.spam)), modfile)
503 self.assertEqual(normcase(inspect.getsourcefile(git.abuse)), modfile)
R. David Murraya1b37402010-06-17 02:04:29 +0000504 fn = "_non_existing_filename_used_for_sourcefile_test.py"
Victor Stinner51d8c522016-02-08 17:57:02 +0100505 co = compile("x=1", fn, "exec")
R. David Murray4155f972010-06-17 13:23:18 +0000506 self.assertEqual(inspect.getsourcefile(co), None)
R. David Murraya1b37402010-06-17 02:04:29 +0000507 linecache.cache[co.co_filename] = (1, None, "None", co.co_filename)
Antoine Pitrou5d62a612012-07-08 13:48:46 +0200508 try:
509 self.assertEqual(normcase(inspect.getsourcefile(co)), fn)
510 finally:
511 del linecache.cache[co.co_filename]
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000512
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000513 def test_getfile(self):
514 self.assertEqual(inspect.getfile(mod.StupidGit), mod.__file__)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000515
Philipp Ad407d2a2019-06-08 14:05:46 +0200516 def test_getfile_builtin_module(self):
517 with self.assertRaises(TypeError) as e:
518 inspect.getfile(sys)
519 self.assertTrue(str(e.exception).startswith('<module'))
520
521 def test_getfile_builtin_class(self):
522 with self.assertRaises(TypeError) as e:
523 inspect.getfile(int)
524 self.assertTrue(str(e.exception).startswith('<class'))
525
526 def test_getfile_builtin_function_or_method(self):
527 with self.assertRaises(TypeError) as e_abs:
528 inspect.getfile(abs)
529 self.assertIn('expected, got', str(e_abs.exception))
530 with self.assertRaises(TypeError) as e_append:
531 inspect.getfile(list.append)
532 self.assertIn('expected, got', str(e_append.exception))
533
Yury Selivanov2eed8b72014-01-27 13:24:56 -0500534 def test_getfile_class_without_module(self):
535 class CM(type):
536 @property
537 def __module__(cls):
538 raise AttributeError
539 class C(metaclass=CM):
540 pass
541 with self.assertRaises(TypeError):
542 inspect.getfile(C)
543
Thomas Kluyvere968bc732017-10-24 13:42:36 +0100544 def test_getfile_broken_repr(self):
545 class ErrorRepr:
546 def __repr__(self):
547 raise Exception('xyz')
548 er = ErrorRepr()
549 with self.assertRaises(TypeError):
550 inspect.getfile(er)
551
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000552 def test_getmodule_recursion(self):
Christian Heimes45f9af32007-11-27 21:50:00 +0000553 from types import ModuleType
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000554 name = '__inspect_dummy'
Christian Heimes45f9af32007-11-27 21:50:00 +0000555 m = sys.modules[name] = ModuleType(name)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000556 m.__file__ = "<string>" # hopefully not a real filename...
557 m.__loader__ = "dummy" # pretend the filename is understood by a loader
Georg Brandl7cae87c2006-09-06 06:51:57 +0000558 exec("def x(): pass", m.__dict__)
Neal Norwitz221085d2007-02-25 20:55:47 +0000559 self.assertEqual(inspect.getsourcefile(m.x.__code__), '<string>')
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000560 del sys.modules[name]
561 inspect.getmodule(compile('a=10','','single'))
562
Benjamin Peterson9620cc02011-06-11 15:53:11 -0500563 def test_proceed_with_fake_filename(self):
564 '''doctest monkeypatches linecache to enable inspection'''
565 fn, source = '<test>', 'def x(): pass\n'
566 getlines = linecache.getlines
567 def monkey(filename, module_globals=None):
568 if filename == fn:
Ezio Melottid8b509b2011-09-28 17:37:55 +0300569 return source.splitlines(keepends=True)
Benjamin Peterson9620cc02011-06-11 15:53:11 -0500570 else:
571 return getlines(filename, module_globals)
572 linecache.getlines = monkey
573 try:
574 ns = {}
575 exec(compile(source, fn, 'single'), ns)
576 inspect.getsource(ns["x"])
577 finally:
578 linecache.getlines = getlines
579
Antoine Pitroua8723a02015-04-15 00:41:29 +0200580 def test_getsource_on_code_object(self):
581 self.assertSourceEqual(mod.eggs.__code__, 12, 18)
582
Vladimir Matveev91cb2982018-08-24 07:18:00 -0700583class TestGettingSourceOfToplevelFrames(GetSourceBase):
584 fodderModule = mod
585
586 def test_range_toplevel_frame(self):
587 self.maxDiff = None
588 self.assertSourceEqual(mod.currentframe, 1, None)
589
590 def test_range_traceback_toplevel_frame(self):
591 self.assertSourceEqual(mod.tb, 1, None)
592
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000593class TestDecorators(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000594 fodderModule = mod2
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000595
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000596 def test_wrapped_decorator(self):
Christian Heimes09aaa882008-02-23 15:01:06 +0000597 self.assertSourceEqual(mod2.wrapped, 14, 17)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000598
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000599 def test_replacing_decorator(self):
600 self.assertSourceEqual(mod2.gone, 9, 10)
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000601
Yury Selivanov081bbf62014-09-26 17:34:54 -0400602 def test_getsource_unwrap(self):
Antoine Pitroua8723a02015-04-15 00:41:29 +0200603 self.assertSourceEqual(mod2.real, 130, 132)
604
605 def test_decorator_with_lambda(self):
606 self.assertSourceEqual(mod2.func114, 113, 115)
Yury Selivanov081bbf62014-09-26 17:34:54 -0400607
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000608class TestOneliners(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000609 fodderModule = mod2
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000610 def test_oneline_lambda(self):
611 # Test inspect.getsource with a one-line lambda function.
612 self.assertSourceEqual(mod2.oll, 25, 25)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000613
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000614 def test_threeline_lambda(self):
615 # Test inspect.getsource with a three-line lambda function,
616 # where the second and third lines are _not_ indented.
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000617 self.assertSourceEqual(mod2.tll, 28, 30)
618
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000619 def test_twoline_indented_lambda(self):
620 # Test inspect.getsource with a two-line lambda function,
621 # where the second line _is_ indented.
622 self.assertSourceEqual(mod2.tlli, 33, 34)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000623
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000624 def test_onelinefunc(self):
625 # Test inspect.getsource with a regular one-line function.
626 self.assertSourceEqual(mod2.onelinefunc, 37, 37)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000627
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000628 def test_manyargs(self):
629 # Test inspect.getsource with a regular function where
630 # the arguments are on two lines and _not_ indented and
631 # the body on the second line with the last arguments.
632 self.assertSourceEqual(mod2.manyargs, 40, 41)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000633
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000634 def test_twolinefunc(self):
635 # Test inspect.getsource with a regular function where
636 # the body is on two lines, following the argument list and
637 # continued on the next line by a \\.
638 self.assertSourceEqual(mod2.twolinefunc, 44, 45)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000639
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000640 def test_lambda_in_list(self):
641 # Test inspect.getsource with a one-line lambda function
642 # defined in a list, indented.
643 self.assertSourceEqual(mod2.a[1], 49, 49)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000644
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000645 def test_anonymous(self):
646 # Test inspect.getsource with a lambda function defined
647 # as argument to another function.
648 self.assertSourceEqual(mod2.anonymous, 55, 55)
649
Miss Islington (bot)81ac0302020-12-04 12:20:05 -0800650class TestBlockComments(GetSourceBase):
651 fodderModule = mod
652
653 def test_toplevel_class(self):
654 self.assertSourceEqual(mod.WhichComments, 96, 114)
655
656 def test_class_method(self):
657 self.assertSourceEqual(mod.WhichComments.f, 99, 104)
658
659 def test_class_async_method(self):
660 self.assertSourceEqual(mod.WhichComments.asyncf, 109, 112)
661
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000662class TestBuggyCases(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000663 fodderModule = mod2
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000664
665 def test_with_comment(self):
666 self.assertSourceEqual(mod2.with_comment, 58, 59)
667
668 def test_multiline_sig(self):
669 self.assertSourceEqual(mod2.multiline_sig[0], 63, 64)
670
Armin Rigodd5c0232005-09-25 11:45:45 +0000671 def test_nested_class(self):
672 self.assertSourceEqual(mod2.func69().func71, 71, 72)
673
674 def test_one_liner_followed_by_non_name(self):
675 self.assertSourceEqual(mod2.func77, 77, 77)
676
677 def test_one_liner_dedent_non_name(self):
678 self.assertSourceEqual(mod2.cls82.func83, 83, 83)
679
680 def test_with_comment_instead_of_docstring(self):
681 self.assertSourceEqual(mod2.func88, 88, 90)
682
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000683 def test_method_in_dynamic_class(self):
684 self.assertSourceEqual(mod2.method_in_dynamic_class, 95, 97)
685
R David Murray32562d72014-10-03 11:15:38 -0400686 # This should not skip for CPython, but might on a repackaged python where
687 # unicodedata is not an external module, or on pypy.
688 @unittest.skipIf(not hasattr(unicodedata, '__file__') or
689 unicodedata.__file__.endswith('.py'),
690 "unicodedata is not an external binary module")
R. David Murray74b89242009-05-13 17:33:03 +0000691 def test_findsource_binary(self):
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200692 self.assertRaises(OSError, inspect.getsource, unicodedata)
693 self.assertRaises(OSError, inspect.findsource, unicodedata)
R. David Murray74b89242009-05-13 17:33:03 +0000694
R. David Murraya1b37402010-06-17 02:04:29 +0000695 def test_findsource_code_in_linecache(self):
696 lines = ["x=1"]
697 co = compile(lines[0], "_dynamically_created_file", "exec")
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200698 self.assertRaises(OSError, inspect.findsource, co)
699 self.assertRaises(OSError, inspect.getsource, co)
R. David Murraya1b37402010-06-17 02:04:29 +0000700 linecache.cache[co.co_filename] = (1, None, lines, co.co_filename)
Antoine Pitrou5d62a612012-07-08 13:48:46 +0200701 try:
702 self.assertEqual(inspect.findsource(co), (lines,0))
703 self.assertEqual(inspect.getsource(co), lines[0])
704 finally:
705 del linecache.cache[co.co_filename]
R. David Murraya1b37402010-06-17 02:04:29 +0000706
Ezio Melotti1b145922013-03-30 05:17:24 +0200707 def test_findsource_without_filename(self):
708 for fname in ['', '<string>']:
709 co = compile('x=1', fname, "exec")
710 self.assertRaises(IOError, inspect.findsource, co)
711 self.assertRaises(IOError, inspect.getsource, co)
712
Antoine Pitroua8723a02015-04-15 00:41:29 +0200713 def test_getsource_on_method(self):
714 self.assertSourceEqual(mod2.ClassWithMethod.method, 118, 119)
715
Yury Selivanov4f4913b2015-07-23 17:10:00 +0300716 def test_nested_func(self):
717 self.assertSourceEqual(mod2.cls135.func136, 136, 139)
718
Karthikeyan Singaravelan696136b2020-04-18 21:49:32 +0530719 def test_class_definition_in_multiline_string_definition(self):
720 self.assertSourceEqual(mod2.cls149, 149, 152)
721
722 def test_class_definition_in_multiline_comment(self):
723 self.assertSourceEqual(mod2.cls160, 160, 163)
724
725 def test_nested_class_definition_indented_string(self):
726 self.assertSourceEqual(mod2.cls173.cls175, 175, 176)
727
728 def test_nested_class_definition(self):
729 self.assertSourceEqual(mod2.cls183, 183, 188)
730 self.assertSourceEqual(mod2.cls183.cls185, 185, 188)
731
732 def test_class_decorator(self):
733 self.assertSourceEqual(mod2.cls196, 194, 201)
734 self.assertSourceEqual(mod2.cls196.cls200, 198, 201)
735
736 def test_class_inside_conditional(self):
737 self.assertSourceEqual(mod2.cls238, 238, 240)
738 self.assertSourceEqual(mod2.cls238.cls239, 239, 240)
739
740 def test_multiple_children_classes(self):
741 self.assertSourceEqual(mod2.cls203, 203, 209)
742 self.assertSourceEqual(mod2.cls203.cls204, 204, 206)
743 self.assertSourceEqual(mod2.cls203.cls204.cls205, 205, 206)
744 self.assertSourceEqual(mod2.cls203.cls207, 207, 209)
745 self.assertSourceEqual(mod2.cls203.cls207.cls205, 208, 209)
746
747 def test_nested_class_definition_inside_function(self):
748 self.assertSourceEqual(mod2.func212(), 213, 214)
749 self.assertSourceEqual(mod2.cls213, 218, 222)
750 self.assertSourceEqual(mod2.cls213().func219(), 220, 221)
751
752 def test_nested_class_definition_inside_async_function(self):
753 import asyncio
754 self.addCleanup(asyncio.set_event_loop_policy, None)
755 self.assertSourceEqual(asyncio.run(mod2.func225()), 226, 227)
756 self.assertSourceEqual(mod2.cls226, 231, 235)
757 self.assertSourceEqual(asyncio.run(mod2.cls226().func232()), 233, 234)
Yury Selivanov4f4913b2015-07-23 17:10:00 +0300758
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000759class TestNoEOL(GetSourceBase):
Yury Selivanov6738b112015-05-16 10:10:21 -0400760 def setUp(self):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000761 self.tempdir = TESTFN + '_dir'
762 os.mkdir(self.tempdir)
763 with open(os.path.join(self.tempdir,
764 'inspect_fodder3%spy' % os.extsep), 'w') as f:
765 f.write("class X:\n pass # No EOL")
766 with DirsOnSysPath(self.tempdir):
767 import inspect_fodder3 as mod3
768 self.fodderModule = mod3
Yury Selivanov6738b112015-05-16 10:10:21 -0400769 super().setUp()
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000770
771 def tearDown(self):
772 shutil.rmtree(self.tempdir)
773
774 def test_class(self):
775 self.assertSourceEqual(self.fodderModule.X, 1, 2)
776
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100777
778class _BrokenDataDescriptor(object):
779 """
780 A broken data descriptor. See bug #1785.
781 """
782 def __get__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700783 raise AttributeError("broken data descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100784
785 def __set__(*args):
786 raise RuntimeError
787
788 def __getattr__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700789 raise AttributeError("broken data descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100790
791
792class _BrokenMethodDescriptor(object):
793 """
794 A broken method descriptor. See bug #1785.
795 """
796 def __get__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700797 raise AttributeError("broken method descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100798
799 def __getattr__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700800 raise AttributeError("broken method descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100801
802
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000803# Helper for testing classify_class_attrs.
Tim Peters13b49d32001-09-23 02:00:29 +0000804def attrs_wo_objs(cls):
805 return [t[:3] for t in inspect.classify_class_attrs(cls)]
806
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100807
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000808class TestClassesAndFunctions(unittest.TestCase):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000809 def test_newstyle_mro(self):
810 # The same w/ new-class MRO.
811 class A(object): pass
812 class B(A): pass
813 class C(A): pass
814 class D(B, C): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000815
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000816 expected = (D, B, C, A, object)
817 got = inspect.getmro(D)
818 self.assertEqual(expected, got)
Tim Peters13b49d32001-09-23 02:00:29 +0000819
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500820 def assertArgSpecEquals(self, routine, args_e, varargs_e=None,
821 varkw_e=None, defaults_e=None, formatted=None):
Xtreak6d0b7472019-05-30 17:31:39 +0530822 with self.assertWarns(DeprecationWarning):
823 args, varargs, varkw, defaults = inspect.getargspec(routine)
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500824 self.assertEqual(args, args_e)
825 self.assertEqual(varargs, varargs_e)
826 self.assertEqual(varkw, varkw_e)
827 self.assertEqual(defaults, defaults_e)
828 if formatted is not None:
Xtreak6d0b7472019-05-30 17:31:39 +0530829 with self.assertWarns(DeprecationWarning):
830 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults),
831 formatted)
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500832
Christian Heimes3795b532007-11-08 13:48:53 +0000833 def assertFullArgSpecEquals(self, routine, args_e, varargs_e=None,
834 varkw_e=None, defaults_e=None,
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100835 posonlyargs_e=[], kwonlyargs_e=[],
836 kwonlydefaults_e=None,
Christian Heimes3795b532007-11-08 13:48:53 +0000837 ann_e={}, formatted=None):
Pablo Galindoaee19f52019-05-16 21:08:15 +0100838 args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \
839 inspect.getfullargspec(routine)
Christian Heimes3795b532007-11-08 13:48:53 +0000840 self.assertEqual(args, args_e)
841 self.assertEqual(varargs, varargs_e)
842 self.assertEqual(varkw, varkw_e)
843 self.assertEqual(defaults, defaults_e)
844 self.assertEqual(kwonlyargs, kwonlyargs_e)
845 self.assertEqual(kwonlydefaults, kwonlydefaults_e)
846 self.assertEqual(ann, ann_e)
847 if formatted is not None:
Xtreak6d0b7472019-05-30 17:31:39 +0530848 with self.assertWarns(DeprecationWarning):
849 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults,
850 kwonlyargs, kwonlydefaults, ann),
851 formatted)
Christian Heimes3795b532007-11-08 13:48:53 +0000852
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500853 def test_getargspec(self):
854 self.assertArgSpecEquals(mod.eggs, ['x', 'y'], formatted='(x, y)')
855
Pablo Galindod5d2b452019-04-30 02:01:14 +0100856 self.assertArgSpecEquals(mod.spam,
857 ['a', 'b', 'c', 'd', 'e', 'f'],
858 'g', 'h', (3, 4, 5),
859 '(a, b, c, d=3, e=4, f=5, *g, **h)')
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500860
861 self.assertRaises(ValueError, self.assertArgSpecEquals,
862 mod2.keyworded, [])
863
864 self.assertRaises(ValueError, self.assertArgSpecEquals,
865 mod2.annotated, [])
866 self.assertRaises(ValueError, self.assertArgSpecEquals,
867 mod2.keyword_only_arg, [])
868
869
Christian Heimes3795b532007-11-08 13:48:53 +0000870 def test_getfullargspec(self):
871 self.assertFullArgSpecEquals(mod2.keyworded, [], varargs_e='arg1',
872 kwonlyargs_e=['arg2'],
873 kwonlydefaults_e={'arg2':1},
874 formatted='(*arg1, arg2=1)')
875
876 self.assertFullArgSpecEquals(mod2.annotated, ['arg1'],
Christian Heimesc9543e42007-11-28 08:28:28 +0000877 ann_e={'arg1' : list},
Christian Heimes3795b532007-11-08 13:48:53 +0000878 formatted='(arg1: list)')
Benjamin Peterson9953a8d2009-01-17 04:15:01 +0000879 self.assertFullArgSpecEquals(mod2.keyword_only_arg, [],
880 kwonlyargs_e=['arg'],
881 formatted='(*, arg)')
882
Pablo Galindod5d2b452019-04-30 02:01:14 +0100883 self.assertFullArgSpecEquals(mod2.all_markers, ['a', 'b', 'c', 'd'],
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100884 kwonlyargs_e=['e', 'f'],
Pablo Galindod5d2b452019-04-30 02:01:14 +0100885 formatted='(a, b, c, d, *, e, f)')
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100886
887 self.assertFullArgSpecEquals(mod2.all_markers_with_args_and_kwargs,
Pablo Galindod5d2b452019-04-30 02:01:14 +0100888 ['a', 'b', 'c', 'd'],
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100889 varargs_e='args',
890 varkw_e='kwargs',
891 kwonlyargs_e=['e', 'f'],
Pablo Galindod5d2b452019-04-30 02:01:14 +0100892 formatted='(a, b, c, d, *args, e, f, **kwargs)')
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100893
Pablo Galindod5d2b452019-04-30 02:01:14 +0100894 self.assertFullArgSpecEquals(mod2.all_markers_with_defaults, ['a', 'b', 'c', 'd'],
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100895 defaults_e=(1,2,3),
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100896 kwonlyargs_e=['e', 'f'],
897 kwonlydefaults_e={'e': 4, 'f': 5},
Pablo Galindod5d2b452019-04-30 02:01:14 +0100898 formatted='(a, b=1, c=2, d=3, *, e=4, f=5)')
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100899
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500900 def test_argspec_api_ignores_wrapped(self):
Yury Selivanov57d240e2014-02-19 16:27:23 -0500901 # Issue 20684: low level introspection API must ignore __wrapped__
902 @functools.wraps(mod.spam)
903 def ham(x, y):
904 pass
905 # Basic check
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500906 self.assertArgSpecEquals(ham, ['x', 'y'], formatted='(x, y)')
Yury Selivanov57d240e2014-02-19 16:27:23 -0500907 self.assertFullArgSpecEquals(ham, ['x', 'y'], formatted='(x, y)')
908 self.assertFullArgSpecEquals(functools.partial(ham),
909 ['x', 'y'], formatted='(x, y)')
910 # Other variants
911 def check_method(f):
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500912 self.assertArgSpecEquals(f, ['self', 'x', 'y'],
913 formatted='(self, x, y)')
Yury Selivanov57d240e2014-02-19 16:27:23 -0500914 class C:
915 @functools.wraps(mod.spam)
916 def ham(self, x, y):
917 pass
918 pham = functools.partialmethod(ham)
919 @functools.wraps(mod.spam)
920 def __call__(self, x, y):
921 pass
922 check_method(C())
923 check_method(C.ham)
924 check_method(C().ham)
925 check_method(C.pham)
926 check_method(C().pham)
927
928 class C_new:
929 @functools.wraps(mod.spam)
930 def __new__(self, x, y):
931 pass
932 check_method(C_new)
933
934 class C_init:
935 @functools.wraps(mod.spam)
936 def __init__(self, x, y):
937 pass
938 check_method(C_init)
939
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500940 def test_getfullargspec_signature_attr(self):
941 def test():
942 pass
943 spam_param = inspect.Parameter('spam', inspect.Parameter.POSITIONAL_ONLY)
944 test.__signature__ = inspect.Signature(parameters=(spam_param,))
945
Pablo Galindod5d2b452019-04-30 02:01:14 +0100946 self.assertFullArgSpecEquals(test, ['spam'], formatted='(spam)')
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500947
Yury Selivanov4cb93912014-01-29 11:54:12 -0500948 def test_getfullargspec_signature_annos(self):
949 def test(a:'spam') -> 'ham': pass
Pablo Galindoaee19f52019-05-16 21:08:15 +0100950 spec = inspect.getfullargspec(test)
Yury Selivanov4cb93912014-01-29 11:54:12 -0500951 self.assertEqual(test.__annotations__, spec.annotations)
952
953 def test(): pass
Pablo Galindoaee19f52019-05-16 21:08:15 +0100954 spec = inspect.getfullargspec(test)
Yury Selivanov4cb93912014-01-29 11:54:12 -0500955 self.assertEqual(test.__annotations__, spec.annotations)
956
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500957 @unittest.skipIf(MISSING_C_DOCSTRINGS,
958 "Signature information for builtins requires docstrings")
959 def test_getfullargspec_builtin_methods(self):
Pablo Galindod5d2b452019-04-30 02:01:14 +0100960 self.assertFullArgSpecEquals(_pickle.Pickler.dump, ['self', 'obj'],
961 formatted='(self, obj)')
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500962
Pablo Galindod5d2b452019-04-30 02:01:14 +0100963 self.assertFullArgSpecEquals(_pickle.Pickler(io.BytesIO()).dump, ['self', 'obj'],
964 formatted='(self, obj)')
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500965
Yury Selivanov8c185ee2014-02-21 01:32:42 -0500966 self.assertFullArgSpecEquals(
967 os.stat,
968 args_e=['path'],
969 kwonlyargs_e=['dir_fd', 'follow_symlinks'],
970 kwonlydefaults_e={'dir_fd': None, 'follow_symlinks': True},
971 formatted='(path, *, dir_fd=None, follow_symlinks=True)')
972
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200973 @cpython_only
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500974 @unittest.skipIf(MISSING_C_DOCSTRINGS,
975 "Signature information for builtins requires docstrings")
Chih-Hsuan Yenc57eb9a2018-10-04 21:15:00 +0800976 def test_getfullargspec_builtin_func(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200977 import _testcapi
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500978 builtin = _testcapi.docstring_with_signature_with_defaults
Pablo Galindoaee19f52019-05-16 21:08:15 +0100979 spec = inspect.getfullargspec(builtin)
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500980 self.assertEqual(spec.defaults[0], 'avocado')
981
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200982 @cpython_only
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500983 @unittest.skipIf(MISSING_C_DOCSTRINGS,
984 "Signature information for builtins requires docstrings")
Chih-Hsuan Yenc57eb9a2018-10-04 21:15:00 +0800985 def test_getfullargspec_builtin_func_no_signature(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200986 import _testcapi
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500987 builtin = _testcapi.docstring_no_signature
Pablo Galindoaee19f52019-05-16 21:08:15 +0100988 with self.assertRaises(TypeError):
989 inspect.getfullargspec(builtin)
Christian Heimes3795b532007-11-08 13:48:53 +0000990
larryhastingsf36ba122018-01-28 11:13:09 -0800991 def test_getfullargspec_definition_order_preserved_on_kwonly(self):
992 for fn in signatures_with_lexicographic_keyword_only_parameters():
Pablo Galindoaee19f52019-05-16 21:08:15 +0100993 signature = inspect.getfullargspec(fn)
larryhastingsf36ba122018-01-28 11:13:09 -0800994 l = list(signature.kwonlyargs)
995 sorted_l = sorted(l)
996 self.assertTrue(l)
997 self.assertEqual(l, sorted_l)
Pablo Galindoaee19f52019-05-16 21:08:15 +0100998 signature = inspect.getfullargspec(unsorted_keyword_only_parameters_fn)
larryhastingsf36ba122018-01-28 11:13:09 -0800999 l = list(signature.kwonlyargs)
1000 self.assertEqual(l, unsorted_keyword_only_parameters)
1001
Yury Selivanov37dc2b22016-01-11 15:15:01 -05001002 def test_getargspec_method(self):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001003 class A(object):
1004 def m(self):
1005 pass
Yury Selivanov37dc2b22016-01-11 15:15:01 -05001006 self.assertArgSpecEquals(A.m, ['self'])
Tim Peters13b49d32001-09-23 02:00:29 +00001007
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001008 def test_classify_newstyle(self):
1009 class A(object):
Tim Peters13b49d32001-09-23 02:00:29 +00001010
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001011 def s(): pass
1012 s = staticmethod(s)
Tim Peters13b49d32001-09-23 02:00:29 +00001013
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001014 def c(cls): pass
1015 c = classmethod(c)
Tim Peters13b49d32001-09-23 02:00:29 +00001016
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001017 def getp(self): pass
1018 p = property(getp)
Tim Peters13b49d32001-09-23 02:00:29 +00001019
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001020 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +00001021
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001022 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +00001023
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001024 datablob = '1'
Tim Peters13b49d32001-09-23 02:00:29 +00001025
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +01001026 dd = _BrokenDataDescriptor()
1027 md = _BrokenMethodDescriptor()
1028
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001029 attrs = attrs_wo_objs(A)
Yury Selivanov0860a0b2014-01-31 14:28:44 -05001030
Serhiy Storchaka3327a2d2017-12-15 14:13:41 +02001031 self.assertIn(('__new__', 'static method', object), attrs,
1032 'missing __new__')
Yury Selivanov0860a0b2014-01-31 14:28:44 -05001033 self.assertIn(('__init__', 'method', object), attrs, 'missing __init__')
1034
Benjamin Peterson577473f2010-01-19 00:09:57 +00001035 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
1036 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
1037 self.assertIn(('p', 'property', A), attrs, 'missing property')
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001038 self.assertIn(('m', 'method', A), attrs,
1039 'missing plain method: %r' % attrs)
Benjamin Peterson577473f2010-01-19 00:09:57 +00001040 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
1041 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +01001042 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
1043 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +00001044
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001045 class B(A):
Tim Peters13b49d32001-09-23 02:00:29 +00001046
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001047 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +00001048
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001049 attrs = attrs_wo_objs(B)
Benjamin Peterson577473f2010-01-19 00:09:57 +00001050 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
1051 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
1052 self.assertIn(('p', 'property', A), attrs, 'missing property')
1053 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
1054 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
1055 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +01001056 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
1057 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +00001058
1059
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001060 class C(A):
Tim Peters13b49d32001-09-23 02:00:29 +00001061
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001062 def m(self): pass
1063 def c(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +00001064
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001065 attrs = attrs_wo_objs(C)
Benjamin Peterson577473f2010-01-19 00:09:57 +00001066 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
1067 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
1068 self.assertIn(('p', 'property', A), attrs, 'missing property')
1069 self.assertIn(('m', 'method', C), attrs, 'missing plain method')
1070 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
1071 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +01001072 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
1073 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +00001074
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001075 class D(B, C):
Tim Peters13b49d32001-09-23 02:00:29 +00001076
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001077 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +00001078
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001079 attrs = attrs_wo_objs(D)
Benjamin Peterson577473f2010-01-19 00:09:57 +00001080 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
1081 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
1082 self.assertIn(('p', 'property', A), attrs, 'missing property')
1083 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
1084 self.assertIn(('m1', 'method', D), attrs, 'missing plain method')
1085 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +01001086 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
1087 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
1088
1089 def test_classify_builtin_types(self):
1090 # Simple sanity check that all built-in types can have their
1091 # attributes classified.
1092 for name in dir(__builtins__):
1093 builtin = getattr(__builtins__, name)
1094 if isinstance(builtin, type):
1095 inspect.classify_class_attrs(builtin)
1096
Serhiy Storchaka3327a2d2017-12-15 14:13:41 +02001097 attrs = attrs_wo_objs(bool)
1098 self.assertIn(('__new__', 'static method', bool), attrs,
1099 'missing __new__')
1100 self.assertIn(('from_bytes', 'class method', int), attrs,
1101 'missing class method')
1102 self.assertIn(('to_bytes', 'method', int), attrs,
1103 'missing plain method')
1104 self.assertIn(('__add__', 'method', int), attrs,
1105 'missing plain method')
1106 self.assertIn(('__and__', 'method', bool), attrs,
1107 'missing plain method')
1108
Ethan Furman63c141c2013-10-18 00:27:39 -07001109 def test_classify_DynamicClassAttribute(self):
1110 class Meta(type):
1111 def __getattr__(self, name):
1112 if name == 'ham':
1113 return 'spam'
1114 return super().__getattr__(name)
1115 class VA(metaclass=Meta):
Ethan Furmane03ea372013-09-25 07:14:41 -07001116 @types.DynamicClassAttribute
1117 def ham(self):
1118 return 'eggs'
Ethan Furman63c141c2013-10-18 00:27:39 -07001119 should_find_dca = inspect.Attribute('ham', 'data', VA, VA.__dict__['ham'])
1120 self.assertIn(should_find_dca, inspect.classify_class_attrs(VA))
Ethan Furmanb0c84cd2013-10-20 22:37:39 -07001121 should_find_ga = inspect.Attribute('ham', 'data', Meta, 'spam')
Ethan Furman63c141c2013-10-18 00:27:39 -07001122 self.assertIn(should_find_ga, inspect.classify_class_attrs(VA))
1123
Yury Selivanovbf341fb2015-05-21 15:41:57 -04001124 def test_classify_overrides_bool(self):
1125 class NoBool(object):
1126 def __eq__(self, other):
1127 return NoBool()
1128
1129 def __bool__(self):
1130 raise NotImplementedError(
1131 "This object does not specify a boolean value")
1132
1133 class HasNB(object):
1134 dd = NoBool()
1135
1136 should_find_attr = inspect.Attribute('dd', 'data', HasNB, HasNB.dd)
1137 self.assertIn(should_find_attr, inspect.classify_class_attrs(HasNB))
1138
Ethan Furmanb0c84cd2013-10-20 22:37:39 -07001139 def test_classify_metaclass_class_attribute(self):
1140 class Meta(type):
1141 fish = 'slap'
1142 def __dir__(self):
Serhiy Storchakaa60c2fe2015-03-12 21:56:08 +02001143 return ['__class__', '__module__', '__name__', 'fish']
Ethan Furmanb0c84cd2013-10-20 22:37:39 -07001144 class Class(metaclass=Meta):
1145 pass
1146 should_find = inspect.Attribute('fish', 'data', Meta, 'slap')
1147 self.assertIn(should_find, inspect.classify_class_attrs(Class))
1148
Ethan Furman63c141c2013-10-18 00:27:39 -07001149 def test_classify_VirtualAttribute(self):
1150 class Meta(type):
1151 def __dir__(cls):
1152 return ['__class__', '__module__', '__name__', 'BOOM']
1153 def __getattr__(self, name):
1154 if name =='BOOM':
1155 return 42
1156 return super().__getattr(name)
1157 class Class(metaclass=Meta):
1158 pass
Ethan Furmanb0c84cd2013-10-20 22:37:39 -07001159 should_find = inspect.Attribute('BOOM', 'data', Meta, 42)
Ethan Furman63c141c2013-10-18 00:27:39 -07001160 self.assertIn(should_find, inspect.classify_class_attrs(Class))
1161
1162 def test_classify_VirtualAttribute_multi_classes(self):
1163 class Meta1(type):
1164 def __dir__(cls):
1165 return ['__class__', '__module__', '__name__', 'one']
1166 def __getattr__(self, name):
1167 if name =='one':
1168 return 1
1169 return super().__getattr__(name)
1170 class Meta2(type):
1171 def __dir__(cls):
1172 return ['__class__', '__module__', '__name__', 'two']
1173 def __getattr__(self, name):
1174 if name =='two':
1175 return 2
1176 return super().__getattr__(name)
1177 class Meta3(Meta1, Meta2):
1178 def __dir__(cls):
1179 return list(sorted(set(['__class__', '__module__', '__name__', 'three'] +
1180 Meta1.__dir__(cls) + Meta2.__dir__(cls))))
1181 def __getattr__(self, name):
1182 if name =='three':
1183 return 3
1184 return super().__getattr__(name)
1185 class Class1(metaclass=Meta1):
1186 pass
1187 class Class2(Class1, metaclass=Meta3):
1188 pass
1189
Ethan Furmanb0c84cd2013-10-20 22:37:39 -07001190 should_find1 = inspect.Attribute('one', 'data', Meta1, 1)
1191 should_find2 = inspect.Attribute('two', 'data', Meta2, 2)
1192 should_find3 = inspect.Attribute('three', 'data', Meta3, 3)
Ethan Furman63c141c2013-10-18 00:27:39 -07001193 cca = inspect.classify_class_attrs(Class2)
1194 for sf in (should_find1, should_find2, should_find3):
1195 self.assertIn(sf, cca)
1196
1197 def test_classify_class_attrs_with_buggy_dir(self):
1198 class M(type):
1199 def __dir__(cls):
1200 return ['__class__', '__name__', 'missing']
1201 class C(metaclass=M):
1202 pass
1203 attrs = [a[0] for a in inspect.classify_class_attrs(C)]
1204 self.assertNotIn('missing', attrs)
Ethan Furmane03ea372013-09-25 07:14:41 -07001205
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +01001206 def test_getmembers_descriptors(self):
1207 class A(object):
1208 dd = _BrokenDataDescriptor()
1209 md = _BrokenMethodDescriptor()
1210
1211 def pred_wrapper(pred):
1212 # A quick'n'dirty way to discard standard attributes of new-style
1213 # classes.
1214 class Empty(object):
1215 pass
1216 def wrapped(x):
1217 if '__name__' in dir(x) and hasattr(Empty, x.__name__):
1218 return False
1219 return pred(x)
1220 return wrapped
1221
1222 ismethoddescriptor = pred_wrapper(inspect.ismethoddescriptor)
1223 isdatadescriptor = pred_wrapper(inspect.isdatadescriptor)
1224
1225 self.assertEqual(inspect.getmembers(A, ismethoddescriptor),
1226 [('md', A.__dict__['md'])])
1227 self.assertEqual(inspect.getmembers(A, isdatadescriptor),
1228 [('dd', A.__dict__['dd'])])
1229
1230 class B(A):
1231 pass
1232
1233 self.assertEqual(inspect.getmembers(B, ismethoddescriptor),
1234 [('md', A.__dict__['md'])])
1235 self.assertEqual(inspect.getmembers(B, isdatadescriptor),
1236 [('dd', A.__dict__['dd'])])
1237
Antoine Pitrou0c603812012-01-18 17:40:18 +01001238 def test_getmembers_method(self):
1239 class B:
1240 def f(self):
1241 pass
1242
1243 self.assertIn(('f', B.f), inspect.getmembers(B))
1244 self.assertNotIn(('f', B.f), inspect.getmembers(B, inspect.ismethod))
1245 b = B()
1246 self.assertIn(('f', b.f), inspect.getmembers(b))
1247 self.assertIn(('f', b.f), inspect.getmembers(b, inspect.ismethod))
1248
Ethan Furmane03ea372013-09-25 07:14:41 -07001249 def test_getmembers_VirtualAttribute(self):
Ethan Furman63c141c2013-10-18 00:27:39 -07001250 class M(type):
1251 def __getattr__(cls, name):
1252 if name == 'eggs':
1253 return 'scrambled'
1254 return super().__getattr__(name)
1255 class A(metaclass=M):
Ethan Furmane03ea372013-09-25 07:14:41 -07001256 @types.DynamicClassAttribute
1257 def eggs(self):
1258 return 'spam'
Ethan Furman63c141c2013-10-18 00:27:39 -07001259 self.assertIn(('eggs', 'scrambled'), inspect.getmembers(A))
1260 self.assertIn(('eggs', 'spam'), inspect.getmembers(A()))
1261
1262 def test_getmembers_with_buggy_dir(self):
1263 class M(type):
1264 def __dir__(cls):
1265 return ['__class__', '__name__', 'missing']
1266 class C(metaclass=M):
1267 pass
1268 attrs = [a[0] for a in inspect.getmembers(C)]
1269 self.assertNotIn('missing', attrs)
Ethan Furmane03ea372013-09-25 07:14:41 -07001270
Aaron Hall, MBA4054b172018-05-20 19:46:42 -04001271class TestIsDataDescriptor(unittest.TestCase):
1272
1273 def test_custom_descriptors(self):
1274 class NonDataDescriptor:
1275 def __get__(self, value, type=None): pass
1276 class DataDescriptor0:
1277 def __set__(self, name, value): pass
1278 class DataDescriptor1:
1279 def __delete__(self, name): pass
1280 class DataDescriptor2:
1281 __set__ = None
1282 self.assertFalse(inspect.isdatadescriptor(NonDataDescriptor()),
1283 'class with only __get__ not a data descriptor')
1284 self.assertTrue(inspect.isdatadescriptor(DataDescriptor0()),
1285 'class with __set__ is a data descriptor')
1286 self.assertTrue(inspect.isdatadescriptor(DataDescriptor1()),
1287 'class with __delete__ is a data descriptor')
1288 self.assertTrue(inspect.isdatadescriptor(DataDescriptor2()),
1289 'class with __set__ = None is a data descriptor')
1290
1291 def test_slot(self):
1292 class Slotted:
1293 __slots__ = 'foo',
1294 self.assertTrue(inspect.isdatadescriptor(Slotted.foo),
1295 'a slot is a data descriptor')
1296
1297 def test_property(self):
1298 class Propertied:
1299 @property
1300 def a_property(self):
1301 pass
1302 self.assertTrue(inspect.isdatadescriptor(Propertied.a_property),
1303 'a property is a data descriptor')
1304
1305 def test_functions(self):
1306 class Test(object):
1307 def instance_method(self): pass
1308 @classmethod
1309 def class_method(cls): pass
1310 @staticmethod
1311 def static_method(): pass
1312 def function():
1313 pass
1314 a_lambda = lambda: None
1315 self.assertFalse(inspect.isdatadescriptor(Test().instance_method),
1316 'a instance method is not a data descriptor')
1317 self.assertFalse(inspect.isdatadescriptor(Test().class_method),
1318 'a class method is not a data descriptor')
1319 self.assertFalse(inspect.isdatadescriptor(Test().static_method),
1320 'a static method is not a data descriptor')
1321 self.assertFalse(inspect.isdatadescriptor(function),
1322 'a function is not a data descriptor')
1323 self.assertFalse(inspect.isdatadescriptor(a_lambda),
1324 'a lambda is not a data descriptor')
1325
Jeremy Hyltonc4bf5ed2003-06-27 18:43:12 +00001326
Nick Coghlan2f92e542012-06-23 19:39:55 +10001327_global_ref = object()
1328class TestGetClosureVars(unittest.TestCase):
1329
1330 def test_name_resolution(self):
1331 # Basic test of the 4 different resolution mechanisms
1332 def f(nonlocal_ref):
1333 def g(local_ref):
1334 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
1335 return g
1336 _arg = object()
1337 nonlocal_vars = {"nonlocal_ref": _arg}
1338 global_vars = {"_global_ref": _global_ref}
1339 builtin_vars = {"print": print}
1340 unbound_names = {"unbound_ref"}
1341 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
1342 builtin_vars, unbound_names)
1343 self.assertEqual(inspect.getclosurevars(f(_arg)), expected)
1344
1345 def test_generator_closure(self):
1346 def f(nonlocal_ref):
1347 def g(local_ref):
1348 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
1349 yield
1350 return g
1351 _arg = object()
1352 nonlocal_vars = {"nonlocal_ref": _arg}
1353 global_vars = {"_global_ref": _global_ref}
1354 builtin_vars = {"print": print}
1355 unbound_names = {"unbound_ref"}
1356 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
1357 builtin_vars, unbound_names)
1358 self.assertEqual(inspect.getclosurevars(f(_arg)), expected)
1359
1360 def test_method_closure(self):
1361 class C:
1362 def f(self, nonlocal_ref):
1363 def g(local_ref):
1364 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
1365 return g
1366 _arg = object()
1367 nonlocal_vars = {"nonlocal_ref": _arg}
1368 global_vars = {"_global_ref": _global_ref}
1369 builtin_vars = {"print": print}
1370 unbound_names = {"unbound_ref"}
1371 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
1372 builtin_vars, unbound_names)
1373 self.assertEqual(inspect.getclosurevars(C().f(_arg)), expected)
1374
1375 def test_nonlocal_vars(self):
1376 # More complex tests of nonlocal resolution
1377 def _nonlocal_vars(f):
1378 return inspect.getclosurevars(f).nonlocals
1379
1380 def make_adder(x):
1381 def add(y):
1382 return x + y
1383 return add
1384
1385 def curry(func, arg1):
1386 return lambda arg2: func(arg1, arg2)
1387
1388 def less_than(a, b):
1389 return a < b
1390
1391 # The infamous Y combinator.
1392 def Y(le):
1393 def g(f):
1394 return le(lambda x: f(f)(x))
1395 Y.g_ref = g
1396 return g(g)
1397
1398 def check_y_combinator(func):
1399 self.assertEqual(_nonlocal_vars(func), {'f': Y.g_ref})
1400
1401 inc = make_adder(1)
1402 add_two = make_adder(2)
1403 greater_than_five = curry(less_than, 5)
1404
1405 self.assertEqual(_nonlocal_vars(inc), {'x': 1})
1406 self.assertEqual(_nonlocal_vars(add_two), {'x': 2})
1407 self.assertEqual(_nonlocal_vars(greater_than_five),
1408 {'arg1': 5, 'func': less_than})
1409 self.assertEqual(_nonlocal_vars((lambda x: lambda y: x + y)(3)),
1410 {'x': 3})
1411 Y(check_y_combinator)
1412
1413 def test_getclosurevars_empty(self):
1414 def foo(): pass
1415 _empty = inspect.ClosureVars({}, {}, {}, set())
1416 self.assertEqual(inspect.getclosurevars(lambda: True), _empty)
1417 self.assertEqual(inspect.getclosurevars(foo), _empty)
1418
1419 def test_getclosurevars_error(self):
1420 class T: pass
1421 self.assertRaises(TypeError, inspect.getclosurevars, 1)
1422 self.assertRaises(TypeError, inspect.getclosurevars, list)
1423 self.assertRaises(TypeError, inspect.getclosurevars, {})
1424
Nick Coghlan6c6e2542012-06-23 20:07:39 +10001425 def _private_globals(self):
1426 code = """def f(): print(path)"""
1427 ns = {}
1428 exec(code, ns)
1429 return ns["f"], ns
1430
1431 def test_builtins_fallback(self):
1432 f, ns = self._private_globals()
1433 ns.pop("__builtins__", None)
1434 expected = inspect.ClosureVars({}, {}, {"print":print}, {"path"})
1435 self.assertEqual(inspect.getclosurevars(f), expected)
1436
1437 def test_builtins_as_dict(self):
1438 f, ns = self._private_globals()
1439 ns["__builtins__"] = {"path":1}
1440 expected = inspect.ClosureVars({}, {}, {"path":1}, {"print"})
1441 self.assertEqual(inspect.getclosurevars(f), expected)
1442
1443 def test_builtins_as_module(self):
1444 f, ns = self._private_globals()
1445 ns["__builtins__"] = os
1446 expected = inspect.ClosureVars({}, {}, {"path":os.path}, {"print"})
1447 self.assertEqual(inspect.getclosurevars(f), expected)
1448
Nick Coghlan2f92e542012-06-23 19:39:55 +10001449
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001450class TestGetcallargsFunctions(unittest.TestCase):
1451
1452 def assertEqualCallArgs(self, func, call_params_string, locs=None):
1453 locs = dict(locs or {}, func=func)
1454 r1 = eval('func(%s)' % call_params_string, None, locs)
Pablo Galindoaee19f52019-05-16 21:08:15 +01001455 r2 = eval('inspect.getcallargs(func, %s)' % call_params_string, None,
1456 locs)
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001457 self.assertEqual(r1, r2)
1458
1459 def assertEqualException(self, func, call_param_string, locs=None):
1460 locs = dict(locs or {}, func=func)
1461 try:
1462 eval('func(%s)' % call_param_string, None, locs)
1463 except Exception as e:
1464 ex1 = e
1465 else:
1466 self.fail('Exception not raised')
1467 try:
Pablo Galindoaee19f52019-05-16 21:08:15 +01001468 eval('inspect.getcallargs(func, %s)' % call_param_string, None,
1469 locs)
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001470 except Exception as e:
1471 ex2 = e
1472 else:
1473 self.fail('Exception not raised')
1474 self.assertIs(type(ex1), type(ex2))
1475 self.assertEqual(str(ex1), str(ex2))
1476 del ex1, ex2
1477
1478 def makeCallable(self, signature):
1479 """Create a function that returns its locals()"""
1480 code = "lambda %s: locals()"
1481 return eval(code % signature)
1482
1483 def test_plain(self):
1484 f = self.makeCallable('a, b=1')
1485 self.assertEqualCallArgs(f, '2')
1486 self.assertEqualCallArgs(f, '2, 3')
1487 self.assertEqualCallArgs(f, 'a=2')
1488 self.assertEqualCallArgs(f, 'b=3, a=2')
1489 self.assertEqualCallArgs(f, '2, b=3')
1490 # expand *iterable / **mapping
1491 self.assertEqualCallArgs(f, '*(2,)')
1492 self.assertEqualCallArgs(f, '*[2]')
1493 self.assertEqualCallArgs(f, '*(2, 3)')
1494 self.assertEqualCallArgs(f, '*[2, 3]')
1495 self.assertEqualCallArgs(f, '**{"a":2}')
1496 self.assertEqualCallArgs(f, 'b=3, **{"a":2}')
1497 self.assertEqualCallArgs(f, '2, **{"b":3}')
1498 self.assertEqualCallArgs(f, '**{"b":3, "a":2}')
1499 # expand UserList / UserDict
1500 self.assertEqualCallArgs(f, '*collections.UserList([2])')
1501 self.assertEqualCallArgs(f, '*collections.UserList([2, 3])')
1502 self.assertEqualCallArgs(f, '**collections.UserDict(a=2)')
1503 self.assertEqualCallArgs(f, '2, **collections.UserDict(b=3)')
1504 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3)')
1505
1506 def test_varargs(self):
1507 f = self.makeCallable('a, b=1, *c')
1508 self.assertEqualCallArgs(f, '2')
1509 self.assertEqualCallArgs(f, '2, 3')
1510 self.assertEqualCallArgs(f, '2, 3, 4')
1511 self.assertEqualCallArgs(f, '*(2,3,4)')
1512 self.assertEqualCallArgs(f, '2, *[3,4]')
1513 self.assertEqualCallArgs(f, '2, 3, *collections.UserList([4])')
1514
1515 def test_varkw(self):
1516 f = self.makeCallable('a, b=1, **c')
1517 self.assertEqualCallArgs(f, 'a=2')
1518 self.assertEqualCallArgs(f, '2, b=3, c=4')
1519 self.assertEqualCallArgs(f, 'b=3, a=2, c=4')
1520 self.assertEqualCallArgs(f, 'c=4, **{"a":2, "b":3}')
1521 self.assertEqualCallArgs(f, '2, c=4, **{"b":3}')
1522 self.assertEqualCallArgs(f, 'b=2, **{"a":3, "c":4}')
1523 self.assertEqualCallArgs(f, '**collections.UserDict(a=2, b=3, c=4)')
1524 self.assertEqualCallArgs(f, '2, c=4, **collections.UserDict(b=3)')
1525 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3, c=4)')
1526
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001527 def test_varkw_only(self):
1528 # issue11256:
1529 f = self.makeCallable('**c')
1530 self.assertEqualCallArgs(f, '')
1531 self.assertEqualCallArgs(f, 'a=1')
1532 self.assertEqualCallArgs(f, 'a=1, b=2')
1533 self.assertEqualCallArgs(f, 'c=3, **{"a": 1, "b": 2}')
1534 self.assertEqualCallArgs(f, '**collections.UserDict(a=1, b=2)')
1535 self.assertEqualCallArgs(f, 'c=3, **collections.UserDict(a=1, b=2)')
1536
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001537 def test_keyword_only(self):
1538 f = self.makeCallable('a=3, *, c, d=2')
1539 self.assertEqualCallArgs(f, 'c=3')
1540 self.assertEqualCallArgs(f, 'c=3, a=3')
1541 self.assertEqualCallArgs(f, 'a=2, c=4')
1542 self.assertEqualCallArgs(f, '4, c=4')
1543 self.assertEqualException(f, '')
1544 self.assertEqualException(f, '3')
1545 self.assertEqualException(f, 'a=3')
1546 self.assertEqualException(f, 'd=4')
1547
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001548 f = self.makeCallable('*, c, d=2')
1549 self.assertEqualCallArgs(f, 'c=3')
1550 self.assertEqualCallArgs(f, 'c=3, d=4')
1551 self.assertEqualCallArgs(f, 'd=4, c=3')
1552
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001553 def test_multiple_features(self):
1554 f = self.makeCallable('a, b=2, *f, **g')
1555 self.assertEqualCallArgs(f, '2, 3, 7')
1556 self.assertEqualCallArgs(f, '2, 3, x=8')
1557 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
1558 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9')
1559 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9')
1560 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
1561 '[2, 3, (4,[5,6])]), **{"y":9, "z":10}')
1562 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
1563 '(4,[5,6])]), **collections.UserDict('
1564 'y=9, z=10)')
1565
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001566 f = self.makeCallable('a, b=2, *f, x, y=99, **g')
1567 self.assertEqualCallArgs(f, '2, 3, x=8')
1568 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
1569 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9, z=10')
1570 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9, z=10')
1571 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
1572 '[2, 3, (4,[5,6])]), q=0, **{"y":9, "z":10}')
1573 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
1574 '(4,[5,6])]), q=0, **collections.UserDict('
1575 'y=9, z=10)')
1576
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001577 def test_errors(self):
1578 f0 = self.makeCallable('')
1579 f1 = self.makeCallable('a, b')
1580 f2 = self.makeCallable('a, b=1')
1581 # f0 takes no arguments
1582 self.assertEqualException(f0, '1')
1583 self.assertEqualException(f0, 'x=1')
1584 self.assertEqualException(f0, '1,x=1')
1585 # f1 takes exactly 2 arguments
1586 self.assertEqualException(f1, '')
1587 self.assertEqualException(f1, '1')
1588 self.assertEqualException(f1, 'a=2')
1589 self.assertEqualException(f1, 'b=3')
1590 # f2 takes at least 1 argument
1591 self.assertEqualException(f2, '')
1592 self.assertEqualException(f2, 'b=3')
1593 for f in f1, f2:
1594 # f1/f2 takes exactly/at most 2 arguments
1595 self.assertEqualException(f, '2, 3, 4')
1596 self.assertEqualException(f, '1, 2, 3, a=1')
1597 self.assertEqualException(f, '2, 3, 4, c=5')
Georg Brandl178e5ea2012-02-21 00:32:36 +01001598 # XXX: success of this one depends on dict order
1599 ## self.assertEqualException(f, '2, 3, 4, a=1, c=5')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001600 # f got an unexpected keyword argument
1601 self.assertEqualException(f, 'c=2')
1602 self.assertEqualException(f, '2, c=3')
1603 self.assertEqualException(f, '2, 3, c=4')
1604 self.assertEqualException(f, '2, c=4, b=3')
1605 self.assertEqualException(f, '**{u"\u03c0\u03b9": 4}')
1606 # f got multiple values for keyword argument
1607 self.assertEqualException(f, '1, a=2')
1608 self.assertEqualException(f, '1, **{"a":2}')
1609 self.assertEqualException(f, '1, 2, b=3')
1610 # XXX: Python inconsistency
1611 # - for functions and bound methods: unexpected keyword 'c'
1612 # - for unbound methods: multiple values for keyword 'a'
1613 #self.assertEqualException(f, '1, c=3, a=2')
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001614 # issue11256:
1615 f3 = self.makeCallable('**c')
1616 self.assertEqualException(f3, '1, 2')
1617 self.assertEqualException(f3, '1, 2, a=1, b=2')
1618 f4 = self.makeCallable('*, a, b=0')
1619 self.assertEqualException(f3, '1, 2')
1620 self.assertEqualException(f3, '1, 2, a=1, b=2')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001621
Yury Selivanov875df202014-03-27 18:23:03 -04001622 # issue #20816: getcallargs() fails to iterate over non-existent
1623 # kwonlydefaults and raises a wrong TypeError
1624 def f5(*, a): pass
1625 with self.assertRaisesRegex(TypeError,
1626 'missing 1 required keyword-only'):
Pablo Galindoaee19f52019-05-16 21:08:15 +01001627 inspect.getcallargs(f5)
Yury Selivanov875df202014-03-27 18:23:03 -04001628
1629
Yury Selivanovdccfa132014-03-27 18:42:52 -04001630 # issue20817:
1631 def f6(a, b, c):
1632 pass
1633 with self.assertRaisesRegex(TypeError, "'a', 'b' and 'c'"):
Pablo Galindoaee19f52019-05-16 21:08:15 +01001634 inspect.getcallargs(f6)
Yury Selivanovdccfa132014-03-27 18:42:52 -04001635
Dong-hee Naa9cab432018-05-30 00:04:08 +09001636 # bpo-33197
1637 with self.assertRaisesRegex(ValueError,
1638 'variadic keyword parameters cannot'
1639 ' have default values'):
1640 inspect.Parameter("foo", kind=inspect.Parameter.VAR_KEYWORD,
1641 default=42)
1642 with self.assertRaisesRegex(ValueError,
1643 "value 5 is not a valid Parameter.kind"):
1644 inspect.Parameter("bar", kind=5, default=42)
1645
1646 with self.assertRaisesRegex(TypeError,
1647 'name must be a str, not a int'):
1648 inspect.Parameter(123, kind=4)
1649
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001650class TestGetcallargsMethods(TestGetcallargsFunctions):
1651
1652 def setUp(self):
1653 class Foo(object):
1654 pass
1655 self.cls = Foo
1656 self.inst = Foo()
1657
1658 def makeCallable(self, signature):
1659 assert 'self' not in signature
1660 mk = super(TestGetcallargsMethods, self).makeCallable
1661 self.cls.method = mk('self, ' + signature)
1662 return self.inst.method
1663
1664class TestGetcallargsUnboundMethods(TestGetcallargsMethods):
1665
1666 def makeCallable(self, signature):
1667 super(TestGetcallargsUnboundMethods, self).makeCallable(signature)
1668 return self.cls.method
1669
1670 def assertEqualCallArgs(self, func, call_params_string, locs=None):
1671 return super(TestGetcallargsUnboundMethods, self).assertEqualCallArgs(
1672 *self._getAssertEqualParams(func, call_params_string, locs))
1673
1674 def assertEqualException(self, func, call_params_string, locs=None):
1675 return super(TestGetcallargsUnboundMethods, self).assertEqualException(
1676 *self._getAssertEqualParams(func, call_params_string, locs))
1677
1678 def _getAssertEqualParams(self, func, call_params_string, locs=None):
1679 assert 'inst' not in call_params_string
1680 locs = dict(locs or {}, inst=self.inst)
1681 return (func, 'inst,' + call_params_string, locs)
1682
Michael Foord95fc51d2010-11-20 15:07:30 +00001683
1684class TestGetattrStatic(unittest.TestCase):
1685
1686 def test_basic(self):
1687 class Thing(object):
1688 x = object()
1689
1690 thing = Thing()
1691 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1692 self.assertEqual(inspect.getattr_static(thing, 'x', None), Thing.x)
1693 with self.assertRaises(AttributeError):
1694 inspect.getattr_static(thing, 'y')
1695
1696 self.assertEqual(inspect.getattr_static(thing, 'y', 3), 3)
1697
1698 def test_inherited(self):
1699 class Thing(object):
1700 x = object()
1701 class OtherThing(Thing):
1702 pass
1703
1704 something = OtherThing()
1705 self.assertEqual(inspect.getattr_static(something, 'x'), Thing.x)
1706
1707 def test_instance_attr(self):
1708 class Thing(object):
1709 x = 2
1710 def __init__(self, x):
1711 self.x = x
1712 thing = Thing(3)
1713 self.assertEqual(inspect.getattr_static(thing, 'x'), 3)
1714 del thing.x
1715 self.assertEqual(inspect.getattr_static(thing, 'x'), 2)
1716
1717 def test_property(self):
1718 class Thing(object):
1719 @property
1720 def x(self):
1721 raise AttributeError("I'm pretending not to exist")
1722 thing = Thing()
1723 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1724
Ezio Melotti75cbd732011-04-28 00:59:29 +03001725 def test_descriptor_raises_AttributeError(self):
Michael Foord95fc51d2010-11-20 15:07:30 +00001726 class descriptor(object):
1727 def __get__(*_):
1728 raise AttributeError("I'm pretending not to exist")
1729 desc = descriptor()
1730 class Thing(object):
1731 x = desc
1732 thing = Thing()
1733 self.assertEqual(inspect.getattr_static(thing, 'x'), desc)
1734
1735 def test_classAttribute(self):
1736 class Thing(object):
1737 x = object()
1738
1739 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.x)
1740
Ethan Furmane03ea372013-09-25 07:14:41 -07001741 def test_classVirtualAttribute(self):
1742 class Thing(object):
1743 @types.DynamicClassAttribute
1744 def x(self):
1745 return self._x
1746 _x = object()
1747
1748 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.__dict__['x'])
1749
Michael Foord95fc51d2010-11-20 15:07:30 +00001750 def test_inherited_classattribute(self):
1751 class Thing(object):
1752 x = object()
1753 class OtherThing(Thing):
1754 pass
1755
1756 self.assertEqual(inspect.getattr_static(OtherThing, 'x'), Thing.x)
1757
1758 def test_slots(self):
1759 class Thing(object):
1760 y = 'bar'
1761 __slots__ = ['x']
1762 def __init__(self):
1763 self.x = 'foo'
1764 thing = Thing()
1765 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1766 self.assertEqual(inspect.getattr_static(thing, 'y'), 'bar')
1767
1768 del thing.x
1769 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1770
1771 def test_metaclass(self):
1772 class meta(type):
1773 attr = 'foo'
1774 class Thing(object, metaclass=meta):
1775 pass
1776 self.assertEqual(inspect.getattr_static(Thing, 'attr'), 'foo')
1777
1778 class sub(meta):
1779 pass
1780 class OtherThing(object, metaclass=sub):
1781 x = 3
1782 self.assertEqual(inspect.getattr_static(OtherThing, 'attr'), 'foo')
1783
1784 class OtherOtherThing(OtherThing):
1785 pass
1786 # this test is odd, but it was added as it exposed a bug
1787 self.assertEqual(inspect.getattr_static(OtherOtherThing, 'x'), 3)
1788
1789 def test_no_dict_no_slots(self):
1790 self.assertEqual(inspect.getattr_static(1, 'foo', None), None)
1791 self.assertNotEqual(inspect.getattr_static('foo', 'lower'), None)
1792
1793 def test_no_dict_no_slots_instance_member(self):
1794 # returns descriptor
1795 with open(__file__) as handle:
1796 self.assertEqual(inspect.getattr_static(handle, 'name'), type(handle).name)
1797
1798 def test_inherited_slots(self):
1799 # returns descriptor
1800 class Thing(object):
1801 __slots__ = ['x']
1802 def __init__(self):
1803 self.x = 'foo'
1804
1805 class OtherThing(Thing):
1806 pass
1807 # it would be nice if this worked...
1808 # we get the descriptor instead of the instance attribute
1809 self.assertEqual(inspect.getattr_static(OtherThing(), 'x'), Thing.x)
1810
1811 def test_descriptor(self):
1812 class descriptor(object):
1813 def __get__(self, instance, owner):
1814 return 3
1815 class Foo(object):
1816 d = descriptor()
1817
1818 foo = Foo()
1819
1820 # for a non data descriptor we return the instance attribute
1821 foo.__dict__['d'] = 1
1822 self.assertEqual(inspect.getattr_static(foo, 'd'), 1)
1823
Mike53f7a7c2017-12-14 14:04:53 +03001824 # if the descriptor is a data-descriptor we should return the
Michael Foord95fc51d2010-11-20 15:07:30 +00001825 # descriptor
1826 descriptor.__set__ = lambda s, i, v: None
1827 self.assertEqual(inspect.getattr_static(foo, 'd'), Foo.__dict__['d'])
1828
1829
1830 def test_metaclass_with_descriptor(self):
1831 class descriptor(object):
1832 def __get__(self, instance, owner):
1833 return 3
1834 class meta(type):
1835 d = descriptor()
1836 class Thing(object, metaclass=meta):
1837 pass
1838 self.assertEqual(inspect.getattr_static(Thing, 'd'), meta.__dict__['d'])
1839
1840
Michael Foordcc7ebb82010-11-20 16:20:16 +00001841 def test_class_as_property(self):
1842 class Base(object):
1843 foo = 3
1844
1845 class Something(Base):
Michael Foord35184ed2010-11-20 16:58:30 +00001846 executed = False
Michael Foordcc7ebb82010-11-20 16:20:16 +00001847 @property
1848 def __class__(self):
Michael Foord35184ed2010-11-20 16:58:30 +00001849 self.executed = True
Michael Foordcc7ebb82010-11-20 16:20:16 +00001850 return object
1851
Michael Foord35184ed2010-11-20 16:58:30 +00001852 instance = Something()
1853 self.assertEqual(inspect.getattr_static(instance, 'foo'), 3)
1854 self.assertFalse(instance.executed)
Michael Foordcc7ebb82010-11-20 16:20:16 +00001855 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1856
Michael Foorde5162652010-11-20 16:40:44 +00001857 def test_mro_as_property(self):
1858 class Meta(type):
1859 @property
1860 def __mro__(self):
1861 return (object,)
1862
1863 class Base(object):
1864 foo = 3
1865
1866 class Something(Base, metaclass=Meta):
1867 pass
1868
1869 self.assertEqual(inspect.getattr_static(Something(), 'foo'), 3)
1870 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1871
Michael Foorddcebe0f2011-03-15 19:20:44 -04001872 def test_dict_as_property(self):
1873 test = self
1874 test.called = False
1875
1876 class Foo(dict):
1877 a = 3
1878 @property
1879 def __dict__(self):
1880 test.called = True
1881 return {}
1882
1883 foo = Foo()
1884 foo.a = 4
1885 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1886 self.assertFalse(test.called)
1887
1888 def test_custom_object_dict(self):
1889 test = self
1890 test.called = False
1891
1892 class Custom(dict):
1893 def get(self, key, default=None):
1894 test.called = True
1895 super().get(key, default)
1896
1897 class Foo(object):
1898 a = 3
1899 foo = Foo()
1900 foo.__dict__ = Custom()
1901 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1902 self.assertFalse(test.called)
1903
1904 def test_metaclass_dict_as_property(self):
1905 class Meta(type):
1906 @property
1907 def __dict__(self):
1908 self.executed = True
1909
1910 class Thing(metaclass=Meta):
1911 executed = False
1912
1913 def __init__(self):
1914 self.spam = 42
1915
1916 instance = Thing()
1917 self.assertEqual(inspect.getattr_static(instance, "spam"), 42)
1918 self.assertFalse(Thing.executed)
Michael Foorde5162652010-11-20 16:40:44 +00001919
Michael Foorda51623b2011-12-18 22:01:40 +00001920 def test_module(self):
1921 sentinel = object()
1922 self.assertIsNot(inspect.getattr_static(sys, "version", sentinel),
1923 sentinel)
1924
Michael Foord3ba95f82011-12-22 01:13:37 +00001925 def test_metaclass_with_metaclass_with_dict_as_property(self):
1926 class MetaMeta(type):
1927 @property
1928 def __dict__(self):
1929 self.executed = True
1930 return dict(spam=42)
1931
1932 class Meta(type, metaclass=MetaMeta):
1933 executed = False
1934
1935 class Thing(metaclass=Meta):
1936 pass
1937
1938 with self.assertRaises(AttributeError):
1939 inspect.getattr_static(Thing, "spam")
1940 self.assertFalse(Thing.executed)
1941
Nick Coghlane0f04652010-11-21 03:44:04 +00001942class TestGetGeneratorState(unittest.TestCase):
1943
1944 def setUp(self):
1945 def number_generator():
1946 for number in range(5):
1947 yield number
1948 self.generator = number_generator()
1949
1950 def _generatorstate(self):
1951 return inspect.getgeneratorstate(self.generator)
1952
1953 def test_created(self):
1954 self.assertEqual(self._generatorstate(), inspect.GEN_CREATED)
1955
1956 def test_suspended(self):
1957 next(self.generator)
1958 self.assertEqual(self._generatorstate(), inspect.GEN_SUSPENDED)
1959
1960 def test_closed_after_exhaustion(self):
1961 for i in self.generator:
1962 pass
1963 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1964
1965 def test_closed_after_immediate_exception(self):
1966 with self.assertRaises(RuntimeError):
1967 self.generator.throw(RuntimeError)
1968 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1969
1970 def test_running(self):
1971 # As mentioned on issue #10220, checking for the RUNNING state only
1972 # makes sense inside the generator itself.
1973 # The following generator checks for this by using the closure's
1974 # reference to self and the generator state checking helper method
1975 def running_check_generator():
1976 for number in range(5):
1977 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1978 yield number
1979 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1980 self.generator = running_check_generator()
1981 # Running up to the first yield
1982 next(self.generator)
1983 # Running after the first yield
1984 next(self.generator)
1985
Nick Coghlan7921b9f2010-11-30 06:36:04 +00001986 def test_easy_debugging(self):
1987 # repr() and str() of a generator state should contain the state name
1988 names = 'GEN_CREATED GEN_RUNNING GEN_SUSPENDED GEN_CLOSED'.split()
1989 for name in names:
1990 state = getattr(inspect, name)
1991 self.assertIn(name, repr(state))
1992 self.assertIn(name, str(state))
1993
Nick Coghlan04e2e3f2012-06-23 19:52:05 +10001994 def test_getgeneratorlocals(self):
1995 def each(lst, a=None):
1996 b=(1, 2, 3)
1997 for v in lst:
1998 if v == 3:
1999 c = 12
2000 yield v
2001
2002 numbers = each([1, 2, 3])
2003 self.assertEqual(inspect.getgeneratorlocals(numbers),
2004 {'a': None, 'lst': [1, 2, 3]})
2005 next(numbers)
2006 self.assertEqual(inspect.getgeneratorlocals(numbers),
2007 {'a': None, 'lst': [1, 2, 3], 'v': 1,
2008 'b': (1, 2, 3)})
2009 next(numbers)
2010 self.assertEqual(inspect.getgeneratorlocals(numbers),
2011 {'a': None, 'lst': [1, 2, 3], 'v': 2,
2012 'b': (1, 2, 3)})
2013 next(numbers)
2014 self.assertEqual(inspect.getgeneratorlocals(numbers),
2015 {'a': None, 'lst': [1, 2, 3], 'v': 3,
2016 'b': (1, 2, 3), 'c': 12})
2017 try:
2018 next(numbers)
2019 except StopIteration:
2020 pass
2021 self.assertEqual(inspect.getgeneratorlocals(numbers), {})
2022
2023 def test_getgeneratorlocals_empty(self):
2024 def yield_one():
2025 yield 1
2026 one = yield_one()
2027 self.assertEqual(inspect.getgeneratorlocals(one), {})
2028 try:
2029 next(one)
2030 except StopIteration:
2031 pass
2032 self.assertEqual(inspect.getgeneratorlocals(one), {})
2033
2034 def test_getgeneratorlocals_error(self):
2035 self.assertRaises(TypeError, inspect.getgeneratorlocals, 1)
2036 self.assertRaises(TypeError, inspect.getgeneratorlocals, lambda x: True)
2037 self.assertRaises(TypeError, inspect.getgeneratorlocals, set)
2038 self.assertRaises(TypeError, inspect.getgeneratorlocals, (2,3))
2039
Nick Coghlane0f04652010-11-21 03:44:04 +00002040
Yury Selivanov5376ba92015-06-22 12:19:30 -04002041class TestGetCoroutineState(unittest.TestCase):
2042
2043 def setUp(self):
2044 @types.coroutine
2045 def number_coroutine():
2046 for number in range(5):
2047 yield number
2048 async def coroutine():
2049 await number_coroutine()
2050 self.coroutine = coroutine()
2051
2052 def tearDown(self):
2053 self.coroutine.close()
2054
2055 def _coroutinestate(self):
2056 return inspect.getcoroutinestate(self.coroutine)
2057
2058 def test_created(self):
2059 self.assertEqual(self._coroutinestate(), inspect.CORO_CREATED)
2060
2061 def test_suspended(self):
2062 self.coroutine.send(None)
2063 self.assertEqual(self._coroutinestate(), inspect.CORO_SUSPENDED)
2064
2065 def test_closed_after_exhaustion(self):
2066 while True:
2067 try:
2068 self.coroutine.send(None)
2069 except StopIteration:
2070 break
2071
2072 self.assertEqual(self._coroutinestate(), inspect.CORO_CLOSED)
2073
2074 def test_closed_after_immediate_exception(self):
2075 with self.assertRaises(RuntimeError):
2076 self.coroutine.throw(RuntimeError)
2077 self.assertEqual(self._coroutinestate(), inspect.CORO_CLOSED)
2078
2079 def test_easy_debugging(self):
2080 # repr() and str() of a coroutine state should contain the state name
2081 names = 'CORO_CREATED CORO_RUNNING CORO_SUSPENDED CORO_CLOSED'.split()
2082 for name in names:
2083 state = getattr(inspect, name)
2084 self.assertIn(name, repr(state))
2085 self.assertIn(name, str(state))
2086
2087 def test_getcoroutinelocals(self):
2088 @types.coroutine
2089 def gencoro():
2090 yield
2091
2092 gencoro = gencoro()
2093 async def func(a=None):
2094 b = 'spam'
2095 await gencoro
2096
2097 coro = func()
2098 self.assertEqual(inspect.getcoroutinelocals(coro),
2099 {'a': None, 'gencoro': gencoro})
2100 coro.send(None)
2101 self.assertEqual(inspect.getcoroutinelocals(coro),
2102 {'a': None, 'gencoro': gencoro, 'b': 'spam'})
2103
2104
Yury Selivanova5d63dd2014-03-27 11:31:43 -04002105class MySignature(inspect.Signature):
2106 # Top-level to make it picklable;
2107 # used in test_signature_object_pickle
2108 pass
2109
2110class MyParameter(inspect.Parameter):
2111 # Top-level to make it picklable;
2112 # used in test_signature_object_pickle
2113 pass
2114
Nick Coghlanf9e227e2014-08-17 14:01:19 +10002115
Yury Selivanova5d63dd2014-03-27 11:31:43 -04002116
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002117class TestSignatureObject(unittest.TestCase):
2118 @staticmethod
Yury Selivanovbcd4fc12015-05-20 14:30:08 -04002119 def signature(func, **kw):
2120 sig = inspect.signature(func, **kw)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002121 return (tuple((param.name,
2122 (... if param.default is param.empty else param.default),
2123 (... if param.annotation is param.empty
2124 else param.annotation),
2125 str(param.kind).lower())
2126 for param in sig.parameters.values()),
2127 (... if sig.return_annotation is sig.empty
2128 else sig.return_annotation))
2129
2130 def test_signature_object(self):
2131 S = inspect.Signature
2132 P = inspect.Parameter
2133
2134 self.assertEqual(str(S()), '()')
Jens Reidel611836a2020-03-18 03:22:46 +01002135 self.assertEqual(repr(S().parameters), 'mappingproxy(OrderedDict())')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002136
Yury Selivanov07a9e452014-01-29 10:58:16 -05002137 def test(po, pk, pod=42, pkd=100, *args, ko, **kwargs):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002138 pass
2139 sig = inspect.signature(test)
2140 po = sig.parameters['po'].replace(kind=P.POSITIONAL_ONLY)
Yury Selivanov07a9e452014-01-29 10:58:16 -05002141 pod = sig.parameters['pod'].replace(kind=P.POSITIONAL_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002142 pk = sig.parameters['pk']
Yury Selivanov07a9e452014-01-29 10:58:16 -05002143 pkd = sig.parameters['pkd']
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002144 args = sig.parameters['args']
2145 ko = sig.parameters['ko']
2146 kwargs = sig.parameters['kwargs']
2147
2148 S((po, pk, args, ko, kwargs))
2149
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002150 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002151 S((pk, po, args, ko, kwargs))
2152
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002153 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002154 S((po, args, pk, ko, kwargs))
2155
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002156 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002157 S((args, po, pk, ko, kwargs))
2158
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002159 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002160 S((po, pk, args, kwargs, ko))
2161
2162 kwargs2 = kwargs.replace(name='args')
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002163 with self.assertRaisesRegex(ValueError, 'duplicate parameter name'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002164 S((po, pk, args, kwargs2, ko))
2165
Yury Selivanov07a9e452014-01-29 10:58:16 -05002166 with self.assertRaisesRegex(ValueError, 'follows default argument'):
2167 S((pod, po))
2168
2169 with self.assertRaisesRegex(ValueError, 'follows default argument'):
2170 S((po, pkd, pk))
2171
2172 with self.assertRaisesRegex(ValueError, 'follows default argument'):
2173 S((pkd, pk))
2174
Yury Selivanov374375d2014-03-27 12:41:53 -04002175 self.assertTrue(repr(sig).startswith('<Signature'))
Yury Selivanov0cd2bf42015-05-15 12:55:20 -04002176 self.assertTrue('(po, pk' in repr(sig))
Yury Selivanov374375d2014-03-27 12:41:53 -04002177
Yury Selivanova5d63dd2014-03-27 11:31:43 -04002178 def test_signature_object_pickle(self):
2179 def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
2180 foo_partial = functools.partial(foo, a=1)
2181
2182 sig = inspect.signature(foo_partial)
Yury Selivanova5d63dd2014-03-27 11:31:43 -04002183
2184 for ver in range(pickle.HIGHEST_PROTOCOL + 1):
2185 with self.subTest(pickle_ver=ver, subclass=False):
2186 sig_pickled = pickle.loads(pickle.dumps(sig, ver))
2187 self.assertEqual(sig, sig_pickled)
Yury Selivanova5d63dd2014-03-27 11:31:43 -04002188
2189 # Test that basic sub-classing works
2190 sig = inspect.signature(foo)
2191 myparam = MyParameter(name='z', kind=inspect.Parameter.POSITIONAL_ONLY)
2192 myparams = collections.OrderedDict(sig.parameters, a=myparam)
2193 mysig = MySignature().replace(parameters=myparams.values(),
2194 return_annotation=sig.return_annotation)
2195 self.assertTrue(isinstance(mysig, MySignature))
2196 self.assertTrue(isinstance(mysig.parameters['z'], MyParameter))
2197
2198 for ver in range(pickle.HIGHEST_PROTOCOL + 1):
2199 with self.subTest(pickle_ver=ver, subclass=True):
2200 sig_pickled = pickle.loads(pickle.dumps(mysig, ver))
2201 self.assertEqual(mysig, sig_pickled)
2202 self.assertTrue(isinstance(sig_pickled, MySignature))
2203 self.assertTrue(isinstance(sig_pickled.parameters['z'],
2204 MyParameter))
2205
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002206 def test_signature_immutability(self):
2207 def test(a):
2208 pass
2209 sig = inspect.signature(test)
2210
2211 with self.assertRaises(AttributeError):
2212 sig.foo = 'bar'
2213
2214 with self.assertRaises(TypeError):
2215 sig.parameters['a'] = None
2216
2217 def test_signature_on_noarg(self):
2218 def test():
2219 pass
2220 self.assertEqual(self.signature(test), ((), ...))
2221
2222 def test_signature_on_wargs(self):
2223 def test(a, b:'foo') -> 123:
2224 pass
2225 self.assertEqual(self.signature(test),
2226 ((('a', ..., ..., "positional_or_keyword"),
2227 ('b', ..., 'foo', "positional_or_keyword")),
2228 123))
2229
2230 def test_signature_on_wkwonly(self):
2231 def test(*, a:float, b:str) -> int:
2232 pass
2233 self.assertEqual(self.signature(test),
2234 ((('a', ..., float, "keyword_only"),
2235 ('b', ..., str, "keyword_only")),
2236 int))
2237
2238 def test_signature_on_complex_args(self):
2239 def test(a, b:'foo'=10, *args:'bar', spam:'baz', ham=123, **kwargs:int):
2240 pass
2241 self.assertEqual(self.signature(test),
2242 ((('a', ..., ..., "positional_or_keyword"),
2243 ('b', 10, 'foo', "positional_or_keyword"),
2244 ('args', ..., 'bar', "var_positional"),
2245 ('spam', ..., 'baz', "keyword_only"),
2246 ('ham', 123, ..., "keyword_only"),
2247 ('kwargs', ..., int, "var_keyword")),
2248 ...))
2249
Dong-hee Na378d7062017-05-18 04:00:51 +09002250 def test_signature_without_self(self):
2251 def test_args_only(*args): # NOQA
2252 pass
2253
2254 def test_args_kwargs_only(*args, **kwargs): # NOQA
2255 pass
2256
2257 class A:
2258 @classmethod
2259 def test_classmethod(*args): # NOQA
2260 pass
2261
2262 @staticmethod
2263 def test_staticmethod(*args): # NOQA
2264 pass
2265
2266 f1 = functools.partialmethod((test_classmethod), 1)
2267 f2 = functools.partialmethod((test_args_only), 1)
2268 f3 = functools.partialmethod((test_staticmethod), 1)
2269 f4 = functools.partialmethod((test_args_kwargs_only),1)
2270
2271 self.assertEqual(self.signature(test_args_only),
2272 ((('args', ..., ..., 'var_positional'),), ...))
2273 self.assertEqual(self.signature(test_args_kwargs_only),
2274 ((('args', ..., ..., 'var_positional'),
2275 ('kwargs', ..., ..., 'var_keyword')), ...))
2276 self.assertEqual(self.signature(A.f1),
2277 ((('args', ..., ..., 'var_positional'),), ...))
2278 self.assertEqual(self.signature(A.f2),
2279 ((('args', ..., ..., 'var_positional'),), ...))
2280 self.assertEqual(self.signature(A.f3),
2281 ((('args', ..., ..., 'var_positional'),), ...))
Serhiy Storchaka13ad3b72017-09-14 09:38:36 +03002282 self.assertEqual(self.signature(A.f4),
Dong-hee Na378d7062017-05-18 04:00:51 +09002283 ((('args', ..., ..., 'var_positional'),
2284 ('kwargs', ..., ..., 'var_keyword')), ...))
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002285 @cpython_only
Larry Hastingsfcafe432013-11-23 17:35:48 -08002286 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2287 "Signature information for builtins requires docstrings")
2288 def test_signature_on_builtins(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002289 import _testcapi
Larry Hastings16c51912014-01-07 11:53:01 -08002290
Larry Hastings5c661892014-01-24 06:17:25 -08002291 def test_unbound_method(o):
2292 """Use this to test unbound methods (things that should have a self)"""
2293 signature = inspect.signature(o)
2294 self.assertTrue(isinstance(signature, inspect.Signature))
2295 self.assertEqual(list(signature.parameters.values())[0].name, 'self')
2296 return signature
2297
2298 def test_callable(o):
2299 """Use this to test bound methods or normal callables (things that don't expect self)"""
2300 signature = inspect.signature(o)
2301 self.assertTrue(isinstance(signature, inspect.Signature))
2302 if signature.parameters:
2303 self.assertNotEqual(list(signature.parameters.values())[0].name, 'self')
2304 return signature
2305
2306 signature = test_callable(_testcapi.docstring_with_signature_with_defaults)
Larry Hastings16c51912014-01-07 11:53:01 -08002307 def p(name): return signature.parameters[name].default
2308 self.assertEqual(p('s'), 'avocado')
Larry Hastings2a727912014-01-16 11:32:01 -08002309 self.assertEqual(p('b'), b'bytes')
Larry Hastings16c51912014-01-07 11:53:01 -08002310 self.assertEqual(p('d'), 3.14)
2311 self.assertEqual(p('i'), 35)
Larry Hastings16c51912014-01-07 11:53:01 -08002312 self.assertEqual(p('n'), None)
2313 self.assertEqual(p('t'), True)
2314 self.assertEqual(p('f'), False)
Larry Hastings2a727912014-01-16 11:32:01 -08002315 self.assertEqual(p('local'), 3)
2316 self.assertEqual(p('sys'), sys.maxsize)
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +02002317 self.assertNotIn('exp', signature.parameters)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002318
Larry Hastings5c661892014-01-24 06:17:25 -08002319 test_callable(object)
2320
2321 # normal method
2322 # (PyMethodDescr_Type, "method_descriptor")
2323 test_unbound_method(_pickle.Pickler.dump)
2324 d = _pickle.Pickler(io.StringIO())
2325 test_callable(d.dump)
2326
2327 # static method
Serhiy Storchaka279f4462019-09-14 12:24:05 +03002328 test_callable(bytes.maketrans)
2329 test_callable(b'abc'.maketrans)
Larry Hastings5c661892014-01-24 06:17:25 -08002330
2331 # class method
2332 test_callable(dict.fromkeys)
2333 test_callable({}.fromkeys)
2334
2335 # wrapper around slot (PyWrapperDescr_Type, "wrapper_descriptor")
2336 test_unbound_method(type.__call__)
2337 test_unbound_method(int.__add__)
2338 test_callable((3).__add__)
2339
2340 # _PyMethodWrapper_Type
2341 # support for 'method-wrapper'
2342 test_callable(min.__call__)
2343
Larry Hastings2623c8c2014-02-08 22:15:29 -08002344 # This doesn't work now.
2345 # (We don't have a valid signature for "type" in 3.4)
2346 with self.assertRaisesRegex(ValueError, "no signature found"):
2347 class ThisWorksNow:
2348 __call__ = type
2349 test_callable(ThisWorksNow())
Larry Hastings5c661892014-01-24 06:17:25 -08002350
Yury Selivanov056e2652014-03-02 12:25:27 -05002351 # Regression test for issue #20786
2352 test_unbound_method(dict.__delitem__)
2353 test_unbound_method(property.__delete__)
2354
Zachary Ware8ef887c2015-04-13 18:22:35 -05002355 # Regression test for issue #20586
2356 test_callable(_testcapi.docstring_with_signature_but_no_doc)
2357
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002358 @cpython_only
Yury Selivanov76c6c592014-01-29 10:52:57 -05002359 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2360 "Signature information for builtins requires docstrings")
2361 def test_signature_on_decorated_builtins(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002362 import _testcapi
Yury Selivanov76c6c592014-01-29 10:52:57 -05002363 func = _testcapi.docstring_with_signature_with_defaults
2364
2365 def decorator(func):
2366 @functools.wraps(func)
2367 def wrapper(*args, **kwargs) -> int:
2368 return func(*args, **kwargs)
2369 return wrapper
2370
2371 decorated_func = decorator(func)
2372
2373 self.assertEqual(inspect.signature(func),
2374 inspect.signature(decorated_func))
Larry Hastings5c661892014-01-24 06:17:25 -08002375
Yury Selivanovbcd4fc12015-05-20 14:30:08 -04002376 def wrapper_like(*args, **kwargs) -> int: pass
2377 self.assertEqual(inspect.signature(decorated_func,
2378 follow_wrapped=False),
2379 inspect.signature(wrapper_like))
2380
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002381 @cpython_only
Larry Hastings5c661892014-01-24 06:17:25 -08002382 def test_signature_on_builtins_no_signature(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002383 import _testcapi
Yury Selivanovbf304fc2015-05-30 17:08:36 -04002384 with self.assertRaisesRegex(ValueError,
2385 'no signature found for builtin'):
Larry Hastings5c661892014-01-24 06:17:25 -08002386 inspect.signature(_testcapi.docstring_no_signature)
2387
Yury Selivanovbf304fc2015-05-30 17:08:36 -04002388 with self.assertRaisesRegex(ValueError,
2389 'no signature found for builtin'):
2390 inspect.signature(str)
2391
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002392 def test_signature_on_non_function(self):
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002393 with self.assertRaisesRegex(TypeError, 'is not a callable object'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002394 inspect.signature(42)
2395
Yury Selivanov63da7c72014-01-31 14:48:37 -05002396 def test_signature_from_functionlike_object(self):
2397 def func(a,b, *args, kwonly=True, kwonlyreq, **kwargs):
2398 pass
2399
2400 class funclike:
2401 # Has to be callable, and have correct
2402 # __code__, __annotations__, __defaults__, __name__,
2403 # and __kwdefaults__ attributes
2404
2405 def __init__(self, func):
2406 self.__name__ = func.__name__
2407 self.__code__ = func.__code__
2408 self.__annotations__ = func.__annotations__
2409 self.__defaults__ = func.__defaults__
2410 self.__kwdefaults__ = func.__kwdefaults__
2411 self.func = func
2412
2413 def __call__(self, *args, **kwargs):
2414 return self.func(*args, **kwargs)
2415
Yury Selivanov57c74fc2015-05-20 23:07:02 -04002416 sig_func = inspect.Signature.from_callable(func)
Yury Selivanov63da7c72014-01-31 14:48:37 -05002417
Yury Selivanov57c74fc2015-05-20 23:07:02 -04002418 sig_funclike = inspect.Signature.from_callable(funclike(func))
Yury Selivanov63da7c72014-01-31 14:48:37 -05002419 self.assertEqual(sig_funclike, sig_func)
2420
2421 sig_funclike = inspect.signature(funclike(func))
2422 self.assertEqual(sig_funclike, sig_func)
2423
2424 # If object is not a duck type of function, then
2425 # signature will try to get a signature for its '__call__'
2426 # method
2427 fl = funclike(func)
2428 del fl.__defaults__
2429 self.assertEqual(self.signature(fl),
2430 ((('args', ..., ..., "var_positional"),
2431 ('kwargs', ..., ..., "var_keyword")),
2432 ...))
2433
Yury Selivanova773de02014-02-21 18:30:53 -05002434 # Test with cython-like builtins:
2435 _orig_isdesc = inspect.ismethoddescriptor
2436 def _isdesc(obj):
2437 if hasattr(obj, '_builtinmock'):
2438 return True
2439 return _orig_isdesc(obj)
2440
2441 with unittest.mock.patch('inspect.ismethoddescriptor', _isdesc):
2442 builtin_func = funclike(func)
2443 # Make sure that our mock setup is working
2444 self.assertFalse(inspect.ismethoddescriptor(builtin_func))
2445 builtin_func._builtinmock = True
2446 self.assertTrue(inspect.ismethoddescriptor(builtin_func))
2447 self.assertEqual(inspect.signature(builtin_func), sig_func)
2448
Yury Selivanov63da7c72014-01-31 14:48:37 -05002449 def test_signature_functionlike_class(self):
2450 # We only want to duck type function-like objects,
2451 # not classes.
2452
2453 def func(a,b, *args, kwonly=True, kwonlyreq, **kwargs):
2454 pass
2455
2456 class funclike:
2457 def __init__(self, marker):
2458 pass
2459
2460 __name__ = func.__name__
2461 __code__ = func.__code__
2462 __annotations__ = func.__annotations__
2463 __defaults__ = func.__defaults__
2464 __kwdefaults__ = func.__kwdefaults__
2465
Yury Selivanov63da7c72014-01-31 14:48:37 -05002466 self.assertEqual(str(inspect.signature(funclike)), '(marker)')
2467
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002468 def test_signature_on_method(self):
2469 class Test:
Yury Selivanov62560fb2014-01-28 12:26:24 -05002470 def __init__(*args):
2471 pass
2472 def m1(self, arg1, arg2=1) -> int:
2473 pass
2474 def m2(*args):
2475 pass
2476 def __call__(*, a):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002477 pass
2478
Yury Selivanov62560fb2014-01-28 12:26:24 -05002479 self.assertEqual(self.signature(Test().m1),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002480 ((('arg1', ..., ..., "positional_or_keyword"),
2481 ('arg2', 1, ..., "positional_or_keyword")),
2482 int))
2483
Yury Selivanov62560fb2014-01-28 12:26:24 -05002484 self.assertEqual(self.signature(Test().m2),
2485 ((('args', ..., ..., "var_positional"),),
2486 ...))
2487
2488 self.assertEqual(self.signature(Test),
2489 ((('args', ..., ..., "var_positional"),),
2490 ...))
2491
2492 with self.assertRaisesRegex(ValueError, 'invalid method signature'):
2493 self.signature(Test())
2494
Yury Selivanov46c759d2015-05-27 21:56:53 -04002495 def test_signature_wrapped_bound_method(self):
2496 # Issue 24298
2497 class Test:
2498 def m1(self, arg1, arg2=1) -> int:
2499 pass
2500 @functools.wraps(Test().m1)
2501 def m1d(*args, **kwargs):
2502 pass
2503 self.assertEqual(self.signature(m1d),
2504 ((('arg1', ..., ..., "positional_or_keyword"),
2505 ('arg2', 1, ..., "positional_or_keyword")),
2506 int))
2507
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002508 def test_signature_on_classmethod(self):
2509 class Test:
2510 @classmethod
2511 def foo(cls, arg1, *, arg2=1):
2512 pass
2513
2514 meth = Test().foo
2515 self.assertEqual(self.signature(meth),
2516 ((('arg1', ..., ..., "positional_or_keyword"),
2517 ('arg2', 1, ..., "keyword_only")),
2518 ...))
2519
2520 meth = Test.foo
2521 self.assertEqual(self.signature(meth),
2522 ((('arg1', ..., ..., "positional_or_keyword"),
2523 ('arg2', 1, ..., "keyword_only")),
2524 ...))
2525
2526 def test_signature_on_staticmethod(self):
2527 class Test:
2528 @staticmethod
2529 def foo(cls, *, arg):
2530 pass
2531
2532 meth = Test().foo
2533 self.assertEqual(self.signature(meth),
2534 ((('cls', ..., ..., "positional_or_keyword"),
2535 ('arg', ..., ..., "keyword_only")),
2536 ...))
2537
2538 meth = Test.foo
2539 self.assertEqual(self.signature(meth),
2540 ((('cls', ..., ..., "positional_or_keyword"),
2541 ('arg', ..., ..., "keyword_only")),
2542 ...))
2543
2544 def test_signature_on_partial(self):
2545 from functools import partial
2546
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002547 Parameter = inspect.Parameter
2548
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002549 def test():
2550 pass
2551
2552 self.assertEqual(self.signature(partial(test)), ((), ...))
2553
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002554 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002555 inspect.signature(partial(test, 1))
2556
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002557 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002558 inspect.signature(partial(test, a=1))
2559
2560 def test(a, b, *, c, d):
2561 pass
2562
2563 self.assertEqual(self.signature(partial(test)),
2564 ((('a', ..., ..., "positional_or_keyword"),
2565 ('b', ..., ..., "positional_or_keyword"),
2566 ('c', ..., ..., "keyword_only"),
2567 ('d', ..., ..., "keyword_only")),
2568 ...))
2569
2570 self.assertEqual(self.signature(partial(test, 1)),
2571 ((('b', ..., ..., "positional_or_keyword"),
2572 ('c', ..., ..., "keyword_only"),
2573 ('d', ..., ..., "keyword_only")),
2574 ...))
2575
2576 self.assertEqual(self.signature(partial(test, 1, c=2)),
2577 ((('b', ..., ..., "positional_or_keyword"),
2578 ('c', 2, ..., "keyword_only"),
2579 ('d', ..., ..., "keyword_only")),
2580 ...))
2581
2582 self.assertEqual(self.signature(partial(test, b=1, c=2)),
2583 ((('a', ..., ..., "positional_or_keyword"),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002584 ('b', 1, ..., "keyword_only"),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002585 ('c', 2, ..., "keyword_only"),
2586 ('d', ..., ..., "keyword_only")),
2587 ...))
2588
2589 self.assertEqual(self.signature(partial(test, 0, b=1, c=2)),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002590 ((('b', 1, ..., "keyword_only"),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002591 ('c', 2, ..., "keyword_only"),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002592 ('d', ..., ..., "keyword_only")),
2593 ...))
2594
2595 self.assertEqual(self.signature(partial(test, a=1)),
2596 ((('a', 1, ..., "keyword_only"),
2597 ('b', ..., ..., "keyword_only"),
2598 ('c', ..., ..., "keyword_only"),
2599 ('d', ..., ..., "keyword_only")),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002600 ...))
2601
2602 def test(a, *args, b, **kwargs):
2603 pass
2604
2605 self.assertEqual(self.signature(partial(test, 1)),
2606 ((('args', ..., ..., "var_positional"),
2607 ('b', ..., ..., "keyword_only"),
2608 ('kwargs', ..., ..., "var_keyword")),
2609 ...))
2610
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002611 self.assertEqual(self.signature(partial(test, a=1)),
2612 ((('a', 1, ..., "keyword_only"),
2613 ('b', ..., ..., "keyword_only"),
2614 ('kwargs', ..., ..., "var_keyword")),
2615 ...))
2616
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002617 self.assertEqual(self.signature(partial(test, 1, 2, 3)),
2618 ((('args', ..., ..., "var_positional"),
2619 ('b', ..., ..., "keyword_only"),
2620 ('kwargs', ..., ..., "var_keyword")),
2621 ...))
2622
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002623 self.assertEqual(self.signature(partial(test, 1, 2, 3, test=True)),
2624 ((('args', ..., ..., "var_positional"),
2625 ('b', ..., ..., "keyword_only"),
2626 ('kwargs', ..., ..., "var_keyword")),
2627 ...))
2628
2629 self.assertEqual(self.signature(partial(test, 1, 2, 3, test=1, b=0)),
2630 ((('args', ..., ..., "var_positional"),
2631 ('b', 0, ..., "keyword_only"),
2632 ('kwargs', ..., ..., "var_keyword")),
2633 ...))
2634
2635 self.assertEqual(self.signature(partial(test, b=0)),
2636 ((('a', ..., ..., "positional_or_keyword"),
2637 ('args', ..., ..., "var_positional"),
2638 ('b', 0, ..., "keyword_only"),
2639 ('kwargs', ..., ..., "var_keyword")),
2640 ...))
2641
2642 self.assertEqual(self.signature(partial(test, b=0, test=1)),
2643 ((('a', ..., ..., "positional_or_keyword"),
2644 ('args', ..., ..., "var_positional"),
2645 ('b', 0, ..., "keyword_only"),
2646 ('kwargs', ..., ..., "var_keyword")),
2647 ...))
2648
2649 def test(a, b, c:int) -> 42:
2650 pass
2651
2652 sig = test.__signature__ = inspect.signature(test)
2653
2654 self.assertEqual(self.signature(partial(partial(test, 1))),
2655 ((('b', ..., ..., "positional_or_keyword"),
2656 ('c', ..., int, "positional_or_keyword")),
2657 42))
2658
2659 self.assertEqual(self.signature(partial(partial(test, 1), 2)),
2660 ((('c', ..., int, "positional_or_keyword"),),
2661 42))
2662
2663 psig = inspect.signature(partial(partial(test, 1), 2))
2664
2665 def foo(a):
2666 return a
2667 _foo = partial(partial(foo, a=10), a=20)
2668 self.assertEqual(self.signature(_foo),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002669 ((('a', 20, ..., "keyword_only"),),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002670 ...))
2671 # check that we don't have any side-effects in signature(),
2672 # and the partial object is still functioning
2673 self.assertEqual(_foo(), 20)
2674
2675 def foo(a, b, c):
2676 return a, b, c
2677 _foo = partial(partial(foo, 1, b=20), b=30)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002678
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002679 self.assertEqual(self.signature(_foo),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002680 ((('b', 30, ..., "keyword_only"),
2681 ('c', ..., ..., "keyword_only")),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002682 ...))
2683 self.assertEqual(_foo(c=10), (1, 30, 10))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002684
2685 def foo(a, b, c, *, d):
2686 return a, b, c, d
2687 _foo = partial(partial(foo, d=20, c=20), b=10, d=30)
2688 self.assertEqual(self.signature(_foo),
2689 ((('a', ..., ..., "positional_or_keyword"),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002690 ('b', 10, ..., "keyword_only"),
2691 ('c', 20, ..., "keyword_only"),
2692 ('d', 30, ..., "keyword_only"),
2693 ),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002694 ...))
2695 ba = inspect.signature(_foo).bind(a=200, b=11)
2696 self.assertEqual(_foo(*ba.args, **ba.kwargs), (200, 11, 20, 30))
2697
2698 def foo(a=1, b=2, c=3):
2699 return a, b, c
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002700 _foo = partial(foo, c=13) # (a=1, b=2, *, c=13)
2701
2702 ba = inspect.signature(_foo).bind(a=11)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002703 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 2, 13))
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002704
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002705 ba = inspect.signature(_foo).bind(11, 12)
2706 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002707
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002708 ba = inspect.signature(_foo).bind(11, b=12)
2709 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002710
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002711 ba = inspect.signature(_foo).bind(b=12)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002712 self.assertEqual(_foo(*ba.args, **ba.kwargs), (1, 12, 13))
2713
2714 _foo = partial(_foo, b=10, c=20)
2715 ba = inspect.signature(_foo).bind(12)
2716 self.assertEqual(_foo(*ba.args, **ba.kwargs), (12, 10, 20))
2717
2718
2719 def foo(a, b, c, d, **kwargs):
2720 pass
2721 sig = inspect.signature(foo)
2722 params = sig.parameters.copy()
2723 params['a'] = params['a'].replace(kind=Parameter.POSITIONAL_ONLY)
2724 params['b'] = params['b'].replace(kind=Parameter.POSITIONAL_ONLY)
2725 foo.__signature__ = inspect.Signature(params.values())
2726 sig = inspect.signature(foo)
2727 self.assertEqual(str(sig), '(a, b, /, c, d, **kwargs)')
2728
2729 self.assertEqual(self.signature(partial(foo, 1)),
2730 ((('b', ..., ..., 'positional_only'),
2731 ('c', ..., ..., 'positional_or_keyword'),
2732 ('d', ..., ..., 'positional_or_keyword'),
2733 ('kwargs', ..., ..., 'var_keyword')),
2734 ...))
2735
2736 self.assertEqual(self.signature(partial(foo, 1, 2)),
2737 ((('c', ..., ..., 'positional_or_keyword'),
2738 ('d', ..., ..., 'positional_or_keyword'),
2739 ('kwargs', ..., ..., 'var_keyword')),
2740 ...))
2741
2742 self.assertEqual(self.signature(partial(foo, 1, 2, 3)),
2743 ((('d', ..., ..., 'positional_or_keyword'),
2744 ('kwargs', ..., ..., 'var_keyword')),
2745 ...))
2746
2747 self.assertEqual(self.signature(partial(foo, 1, 2, c=3)),
2748 ((('c', 3, ..., 'keyword_only'),
2749 ('d', ..., ..., 'keyword_only'),
2750 ('kwargs', ..., ..., 'var_keyword')),
2751 ...))
2752
2753 self.assertEqual(self.signature(partial(foo, 1, c=3)),
2754 ((('b', ..., ..., 'positional_only'),
2755 ('c', 3, ..., 'keyword_only'),
2756 ('d', ..., ..., 'keyword_only'),
2757 ('kwargs', ..., ..., 'var_keyword')),
2758 ...))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002759
Yury Selivanovda5fe4f2014-01-27 17:28:37 -05002760 def test_signature_on_partialmethod(self):
2761 from functools import partialmethod
2762
2763 class Spam:
2764 def test():
2765 pass
2766 ham = partialmethod(test)
2767
2768 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
2769 inspect.signature(Spam.ham)
2770
2771 class Spam:
2772 def test(it, a, *, c) -> 'spam':
2773 pass
2774 ham = partialmethod(test, c=1)
2775
2776 self.assertEqual(self.signature(Spam.ham),
2777 ((('it', ..., ..., 'positional_or_keyword'),
2778 ('a', ..., ..., 'positional_or_keyword'),
2779 ('c', 1, ..., 'keyword_only')),
2780 'spam'))
2781
2782 self.assertEqual(self.signature(Spam().ham),
2783 ((('a', ..., ..., 'positional_or_keyword'),
2784 ('c', 1, ..., 'keyword_only')),
2785 'spam'))
2786
Yury Selivanov8a387212018-03-06 12:59:45 -05002787 class Spam:
2788 def test(self: 'anno', x):
2789 pass
2790
2791 g = partialmethod(test, 1)
2792
2793 self.assertEqual(self.signature(Spam.g),
2794 ((('self', ..., 'anno', 'positional_or_keyword'),),
2795 ...))
2796
Yury Selivanov0486f812014-01-29 12:18:59 -05002797 def test_signature_on_fake_partialmethod(self):
2798 def foo(a): pass
2799 foo._partialmethod = 'spam'
2800 self.assertEqual(str(inspect.signature(foo)), '(a)')
2801
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002802 def test_signature_on_decorated(self):
2803 import functools
2804
2805 def decorator(func):
2806 @functools.wraps(func)
2807 def wrapper(*args, **kwargs) -> int:
2808 return func(*args, **kwargs)
2809 return wrapper
2810
2811 class Foo:
2812 @decorator
2813 def bar(self, a, b):
2814 pass
2815
2816 self.assertEqual(self.signature(Foo.bar),
2817 ((('self', ..., ..., "positional_or_keyword"),
2818 ('a', ..., ..., "positional_or_keyword"),
2819 ('b', ..., ..., "positional_or_keyword")),
2820 ...))
2821
2822 self.assertEqual(self.signature(Foo().bar),
2823 ((('a', ..., ..., "positional_or_keyword"),
2824 ('b', ..., ..., "positional_or_keyword")),
2825 ...))
2826
Yury Selivanovbcd4fc12015-05-20 14:30:08 -04002827 self.assertEqual(self.signature(Foo.bar, follow_wrapped=False),
2828 ((('args', ..., ..., "var_positional"),
2829 ('kwargs', ..., ..., "var_keyword")),
2830 ...)) # functools.wraps will copy __annotations__
2831 # from "func" to "wrapper", hence no
2832 # return_annotation
2833
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002834 # Test that we handle method wrappers correctly
2835 def decorator(func):
2836 @functools.wraps(func)
2837 def wrapper(*args, **kwargs) -> int:
2838 return func(42, *args, **kwargs)
2839 sig = inspect.signature(func)
2840 new_params = tuple(sig.parameters.values())[1:]
2841 wrapper.__signature__ = sig.replace(parameters=new_params)
2842 return wrapper
2843
2844 class Foo:
2845 @decorator
2846 def __call__(self, a, b):
2847 pass
2848
2849 self.assertEqual(self.signature(Foo.__call__),
2850 ((('a', ..., ..., "positional_or_keyword"),
2851 ('b', ..., ..., "positional_or_keyword")),
2852 ...))
2853
2854 self.assertEqual(self.signature(Foo().__call__),
2855 ((('b', ..., ..., "positional_or_keyword"),),
2856 ...))
2857
Nick Coghlane8c45d62013-07-28 20:00:01 +10002858 # Test we handle __signature__ partway down the wrapper stack
2859 def wrapped_foo_call():
2860 pass
2861 wrapped_foo_call.__wrapped__ = Foo.__call__
2862
2863 self.assertEqual(self.signature(wrapped_foo_call),
2864 ((('a', ..., ..., "positional_or_keyword"),
2865 ('b', ..., ..., "positional_or_keyword")),
2866 ...))
2867
2868
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002869 def test_signature_on_class(self):
2870 class C:
2871 def __init__(self, a):
2872 pass
2873
2874 self.assertEqual(self.signature(C),
2875 ((('a', ..., ..., "positional_or_keyword"),),
2876 ...))
2877
2878 class CM(type):
2879 def __call__(cls, a):
2880 pass
2881 class C(metaclass=CM):
2882 def __init__(self, b):
2883 pass
2884
2885 self.assertEqual(self.signature(C),
2886 ((('a', ..., ..., "positional_or_keyword"),),
2887 ...))
2888
2889 class CM(type):
2890 def __new__(mcls, name, bases, dct, *, foo=1):
2891 return super().__new__(mcls, name, bases, dct)
2892 class C(metaclass=CM):
2893 def __init__(self, b):
2894 pass
2895
2896 self.assertEqual(self.signature(C),
2897 ((('b', ..., ..., "positional_or_keyword"),),
2898 ...))
2899
2900 self.assertEqual(self.signature(CM),
2901 ((('name', ..., ..., "positional_or_keyword"),
2902 ('bases', ..., ..., "positional_or_keyword"),
2903 ('dct', ..., ..., "positional_or_keyword"),
2904 ('foo', 1, ..., "keyword_only")),
2905 ...))
2906
2907 class CMM(type):
2908 def __new__(mcls, name, bases, dct, *, foo=1):
2909 return super().__new__(mcls, name, bases, dct)
2910 def __call__(cls, nm, bs, dt):
2911 return type(nm, bs, dt)
2912 class CM(type, metaclass=CMM):
2913 def __new__(mcls, name, bases, dct, *, bar=2):
2914 return super().__new__(mcls, name, bases, dct)
2915 class C(metaclass=CM):
2916 def __init__(self, b):
2917 pass
2918
2919 self.assertEqual(self.signature(CMM),
2920 ((('name', ..., ..., "positional_or_keyword"),
2921 ('bases', ..., ..., "positional_or_keyword"),
2922 ('dct', ..., ..., "positional_or_keyword"),
2923 ('foo', 1, ..., "keyword_only")),
2924 ...))
2925
2926 self.assertEqual(self.signature(CM),
2927 ((('nm', ..., ..., "positional_or_keyword"),
2928 ('bs', ..., ..., "positional_or_keyword"),
2929 ('dt', ..., ..., "positional_or_keyword")),
2930 ...))
2931
2932 self.assertEqual(self.signature(C),
2933 ((('b', ..., ..., "positional_or_keyword"),),
2934 ...))
2935
2936 class CM(type):
2937 def __init__(cls, name, bases, dct, *, bar=2):
2938 return super().__init__(name, bases, dct)
2939 class C(metaclass=CM):
2940 def __init__(self, b):
2941 pass
2942
2943 self.assertEqual(self.signature(CM),
2944 ((('name', ..., ..., "positional_or_keyword"),
2945 ('bases', ..., ..., "positional_or_keyword"),
2946 ('dct', ..., ..., "positional_or_keyword"),
2947 ('bar', 2, ..., "keyword_only")),
2948 ...))
2949
Yury Selivanov145dff82014-02-01 13:49:29 -05002950 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2951 "Signature information for builtins requires docstrings")
2952 def test_signature_on_class_without_init(self):
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002953 # Test classes without user-defined __init__ or __new__
2954 class C: pass
2955 self.assertEqual(str(inspect.signature(C)), '()')
2956 class D(C): pass
2957 self.assertEqual(str(inspect.signature(D)), '()')
2958
2959 # Test meta-classes without user-defined __init__ or __new__
2960 class C(type): pass
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002961 class D(C): pass
Larry Hastings2623c8c2014-02-08 22:15:29 -08002962 with self.assertRaisesRegex(ValueError, "callable.*is not supported"):
2963 self.assertEqual(inspect.signature(C), None)
2964 with self.assertRaisesRegex(ValueError, "callable.*is not supported"):
2965 self.assertEqual(inspect.signature(D), None)
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002966
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002967 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2968 "Signature information for builtins requires docstrings")
2969 def test_signature_on_builtin_class(self):
Antoine Pitrou91f43802019-05-26 17:10:09 +02002970 expected = ('(file, protocol=None, fix_imports=True, '
2971 'buffer_callback=None)')
2972 self.assertEqual(str(inspect.signature(_pickle.Pickler)), expected)
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002973
2974 class P(_pickle.Pickler): pass
2975 class EmptyTrait: pass
2976 class P2(EmptyTrait, P): pass
Antoine Pitrou91f43802019-05-26 17:10:09 +02002977 self.assertEqual(str(inspect.signature(P)), expected)
2978 self.assertEqual(str(inspect.signature(P2)), expected)
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002979
2980 class P3(P2):
2981 def __init__(self, spam):
2982 pass
2983 self.assertEqual(str(inspect.signature(P3)), '(spam)')
2984
2985 class MetaP(type):
2986 def __call__(cls, foo, bar):
2987 pass
2988 class P4(P2, metaclass=MetaP):
2989 pass
2990 self.assertEqual(str(inspect.signature(P4)), '(foo, bar)')
2991
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002992 def test_signature_on_callable_objects(self):
2993 class Foo:
2994 def __call__(self, a):
2995 pass
2996
2997 self.assertEqual(self.signature(Foo()),
2998 ((('a', ..., ..., "positional_or_keyword"),),
2999 ...))
3000
3001 class Spam:
3002 pass
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003003 with self.assertRaisesRegex(TypeError, "is not a callable object"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003004 inspect.signature(Spam())
3005
3006 class Bar(Spam, Foo):
3007 pass
3008
3009 self.assertEqual(self.signature(Bar()),
3010 ((('a', ..., ..., "positional_or_keyword"),),
3011 ...))
3012
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003013 class Wrapped:
3014 pass
3015 Wrapped.__wrapped__ = lambda a: None
3016 self.assertEqual(self.signature(Wrapped),
3017 ((('a', ..., ..., "positional_or_keyword"),),
3018 ...))
Nick Coghlane8c45d62013-07-28 20:00:01 +10003019 # wrapper loop:
3020 Wrapped.__wrapped__ = Wrapped
3021 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3022 self.signature(Wrapped)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003023
3024 def test_signature_on_lambdas(self):
3025 self.assertEqual(self.signature((lambda a=10: a)),
3026 ((('a', 10, ..., "positional_or_keyword"),),
3027 ...))
3028
3029 def test_signature_equality(self):
3030 def foo(a, *, b:int) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003031 self.assertFalse(inspect.signature(foo) == 42)
3032 self.assertTrue(inspect.signature(foo) != 42)
Serhiy Storchaka7d44e7a2019-08-08 08:43:18 +03003033 self.assertTrue(inspect.signature(foo) == ALWAYS_EQ)
3034 self.assertFalse(inspect.signature(foo) != ALWAYS_EQ)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003035
3036 def bar(a, *, b:int) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003037 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
3038 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003039 self.assertEqual(
3040 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003041
3042 def bar(a, *, b:int) -> int: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003043 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
3044 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003045 self.assertNotEqual(
3046 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003047
3048 def bar(a, *, b:int): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003049 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
3050 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003051 self.assertNotEqual(
3052 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003053
3054 def bar(a, *, b:int=42) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003055 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
3056 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003057 self.assertNotEqual(
3058 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003059
3060 def bar(a, *, c) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003061 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
3062 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003063 self.assertNotEqual(
3064 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003065
3066 def bar(a, b:int) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003067 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
3068 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003069 self.assertNotEqual(
3070 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003071 def spam(b:int, a) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003072 self.assertFalse(inspect.signature(spam) == inspect.signature(bar))
3073 self.assertTrue(inspect.signature(spam) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003074 self.assertNotEqual(
3075 hash(inspect.signature(spam)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003076
3077 def foo(*, a, b, c): pass
3078 def bar(*, c, b, a): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003079 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
3080 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003081 self.assertEqual(
3082 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003083
3084 def foo(*, a=1, b, c): pass
3085 def bar(*, c, b, a=1): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003086 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
3087 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003088 self.assertEqual(
3089 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003090
3091 def foo(pos, *, a=1, b, c): pass
3092 def bar(pos, *, c, b, a=1): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003093 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
3094 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003095 self.assertEqual(
3096 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003097
3098 def foo(pos, *, a, b, c): pass
3099 def bar(pos, *, c, b, a=1): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003100 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
3101 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003102 self.assertNotEqual(
3103 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003104
3105 def foo(pos, *args, a=42, b, c, **kwargs:int): pass
3106 def bar(pos, *args, c, b, a=42, **kwargs:int): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003107 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
3108 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003109 self.assertEqual(
3110 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003111
Yury Selivanov67ae50e2014-04-08 11:46:50 -04003112 def test_signature_hashable(self):
3113 S = inspect.Signature
3114 P = inspect.Parameter
3115
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003116 def foo(a): pass
Yury Selivanov67ae50e2014-04-08 11:46:50 -04003117 foo_sig = inspect.signature(foo)
3118
3119 manual_sig = S(parameters=[P('a', P.POSITIONAL_OR_KEYWORD)])
3120
3121 self.assertEqual(hash(foo_sig), hash(manual_sig))
3122 self.assertNotEqual(hash(foo_sig),
3123 hash(manual_sig.replace(return_annotation='spam')))
3124
3125 def bar(a) -> 1: pass
3126 self.assertNotEqual(hash(foo_sig), hash(inspect.signature(bar)))
3127
3128 def foo(a={}): pass
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003129 with self.assertRaisesRegex(TypeError, 'unhashable type'):
Yury Selivanov67ae50e2014-04-08 11:46:50 -04003130 hash(inspect.signature(foo))
3131
3132 def foo(a) -> {}: pass
3133 with self.assertRaisesRegex(TypeError, 'unhashable type'):
3134 hash(inspect.signature(foo))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003135
3136 def test_signature_str(self):
3137 def foo(a:int=1, *, b, c=None, **kwargs) -> 42:
3138 pass
3139 self.assertEqual(str(inspect.signature(foo)),
Dong-hee Na762b9572017-11-16 03:30:59 +09003140 '(a: int = 1, *, b, c=None, **kwargs) -> 42')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003141
3142 def foo(a:int=1, *args, b, c=None, **kwargs) -> 42:
3143 pass
3144 self.assertEqual(str(inspect.signature(foo)),
Dong-hee Na762b9572017-11-16 03:30:59 +09003145 '(a: int = 1, *args, b, c=None, **kwargs) -> 42')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003146
3147 def foo():
3148 pass
3149 self.assertEqual(str(inspect.signature(foo)), '()')
3150
3151 def test_signature_str_positional_only(self):
3152 P = inspect.Parameter
Yury Selivanov2393dca2014-01-27 15:07:58 -05003153 S = inspect.Signature
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003154
3155 def test(a_po, *, b, **kwargs):
3156 return a_po, kwargs
3157
3158 sig = inspect.signature(test)
3159 new_params = list(sig.parameters.values())
3160 new_params[0] = new_params[0].replace(kind=P.POSITIONAL_ONLY)
3161 test.__signature__ = sig.replace(parameters=new_params)
3162
3163 self.assertEqual(str(inspect.signature(test)),
Yury Selivanov2393dca2014-01-27 15:07:58 -05003164 '(a_po, /, *, b, **kwargs)')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003165
Yury Selivanov2393dca2014-01-27 15:07:58 -05003166 self.assertEqual(str(S(parameters=[P('foo', P.POSITIONAL_ONLY)])),
3167 '(foo, /)')
3168
3169 self.assertEqual(str(S(parameters=[
3170 P('foo', P.POSITIONAL_ONLY),
3171 P('bar', P.VAR_KEYWORD)])),
3172 '(foo, /, **bar)')
3173
3174 self.assertEqual(str(S(parameters=[
3175 P('foo', P.POSITIONAL_ONLY),
3176 P('bar', P.VAR_POSITIONAL)])),
3177 '(foo, /, *bar)')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003178
3179 def test_signature_replace_anno(self):
3180 def test() -> 42:
3181 pass
3182
3183 sig = inspect.signature(test)
3184 sig = sig.replace(return_annotation=None)
3185 self.assertIs(sig.return_annotation, None)
3186 sig = sig.replace(return_annotation=sig.empty)
3187 self.assertIs(sig.return_annotation, sig.empty)
3188 sig = sig.replace(return_annotation=42)
3189 self.assertEqual(sig.return_annotation, 42)
3190 self.assertEqual(sig, inspect.signature(test))
3191
Yury Selivanov34ce99f2014-02-18 12:49:41 -05003192 def test_signature_on_mangled_parameters(self):
3193 class Spam:
3194 def foo(self, __p1:1=2, *, __p2:2=3):
3195 pass
3196 class Ham(Spam):
3197 pass
3198
3199 self.assertEqual(self.signature(Spam.foo),
3200 ((('self', ..., ..., "positional_or_keyword"),
3201 ('_Spam__p1', 2, 1, "positional_or_keyword"),
3202 ('_Spam__p2', 3, 2, "keyword_only")),
3203 ...))
3204
3205 self.assertEqual(self.signature(Spam.foo),
3206 self.signature(Ham.foo))
3207
Yury Selivanovda396452014-03-27 12:09:24 -04003208 def test_signature_from_callable_python_obj(self):
3209 class MySignature(inspect.Signature): pass
3210 def foo(a, *, b:1): pass
3211 foo_sig = MySignature.from_callable(foo)
Gregory P. Smith5b9ff7a2019-09-13 17:13:51 +01003212 self.assertIsInstance(foo_sig, MySignature)
3213
3214 def test_signature_from_callable_class(self):
3215 # A regression test for a class inheriting its signature from `object`.
3216 class MySignature(inspect.Signature): pass
3217 class foo: pass
3218 foo_sig = MySignature.from_callable(foo)
3219 self.assertIsInstance(foo_sig, MySignature)
Yury Selivanovda396452014-03-27 12:09:24 -04003220
3221 @unittest.skipIf(MISSING_C_DOCSTRINGS,
3222 "Signature information for builtins requires docstrings")
3223 def test_signature_from_callable_builtin_obj(self):
3224 class MySignature(inspect.Signature): pass
3225 sig = MySignature.from_callable(_pickle.Pickler)
Gregory P. Smith5b9ff7a2019-09-13 17:13:51 +01003226 self.assertIsInstance(sig, MySignature)
Yury Selivanovda396452014-03-27 12:09:24 -04003227
larryhastingsf36ba122018-01-28 11:13:09 -08003228 def test_signature_definition_order_preserved_on_kwonly(self):
3229 for fn in signatures_with_lexicographic_keyword_only_parameters():
3230 signature = inspect.signature(fn)
3231 l = list(signature.parameters)
3232 sorted_l = sorted(l)
3233 self.assertTrue(l)
3234 self.assertEqual(l, sorted_l)
3235 signature = inspect.signature(unsorted_keyword_only_parameters_fn)
3236 l = list(signature.parameters)
3237 self.assertEqual(l, unsorted_keyword_only_parameters)
3238
Jens Reidel611836a2020-03-18 03:22:46 +01003239 def test_signater_parameters_is_ordered(self):
3240 p1 = inspect.signature(lambda x, y: None).parameters
3241 p2 = inspect.signature(lambda y, x: None).parameters
3242 self.assertNotEqual(p1, p2)
3243
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003244
3245class TestParameterObject(unittest.TestCase):
3246 def test_signature_parameter_kinds(self):
3247 P = inspect.Parameter
3248 self.assertTrue(P.POSITIONAL_ONLY < P.POSITIONAL_OR_KEYWORD < \
3249 P.VAR_POSITIONAL < P.KEYWORD_ONLY < P.VAR_KEYWORD)
3250
3251 self.assertEqual(str(P.POSITIONAL_ONLY), 'POSITIONAL_ONLY')
3252 self.assertTrue('POSITIONAL_ONLY' in repr(P.POSITIONAL_ONLY))
3253
3254 def test_signature_parameter_object(self):
3255 p = inspect.Parameter('foo', default=10,
3256 kind=inspect.Parameter.POSITIONAL_ONLY)
3257 self.assertEqual(p.name, 'foo')
3258 self.assertEqual(p.default, 10)
3259 self.assertIs(p.annotation, p.empty)
3260 self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY)
3261
Dong-hee Naa9cab432018-05-30 00:04:08 +09003262 with self.assertRaisesRegex(ValueError, "value '123' is "
3263 "not a valid Parameter.kind"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003264 inspect.Parameter('foo', default=10, kind='123')
3265
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003266 with self.assertRaisesRegex(ValueError, 'not a valid parameter name'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003267 inspect.Parameter('1', kind=inspect.Parameter.VAR_KEYWORD)
3268
Yury Selivanov2393dca2014-01-27 15:07:58 -05003269 with self.assertRaisesRegex(TypeError, 'name must be a str'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003270 inspect.Parameter(None, kind=inspect.Parameter.VAR_KEYWORD)
3271
Yury Selivanov2393dca2014-01-27 15:07:58 -05003272 with self.assertRaisesRegex(ValueError,
3273 'is not a valid parameter name'):
3274 inspect.Parameter('$', kind=inspect.Parameter.VAR_KEYWORD)
3275
Nick Coghlanb4b966e2016-06-04 14:40:03 -07003276 with self.assertRaisesRegex(ValueError,
3277 'is not a valid parameter name'):
3278 inspect.Parameter('.a', kind=inspect.Parameter.VAR_KEYWORD)
3279
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003280 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003281 inspect.Parameter('a', default=42,
3282 kind=inspect.Parameter.VAR_KEYWORD)
3283
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003284 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003285 inspect.Parameter('a', default=42,
3286 kind=inspect.Parameter.VAR_POSITIONAL)
3287
3288 p = inspect.Parameter('a', default=42,
3289 kind=inspect.Parameter.POSITIONAL_OR_KEYWORD)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003290 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003291 p.replace(kind=inspect.Parameter.VAR_POSITIONAL)
3292
3293 self.assertTrue(repr(p).startswith('<Parameter'))
Yury Selivanov374375d2014-03-27 12:41:53 -04003294 self.assertTrue('"a=42"' in repr(p))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003295
Yury Selivanov67ae50e2014-04-08 11:46:50 -04003296 def test_signature_parameter_hashable(self):
3297 P = inspect.Parameter
3298 foo = P('foo', kind=P.POSITIONAL_ONLY)
3299 self.assertEqual(hash(foo), hash(P('foo', kind=P.POSITIONAL_ONLY)))
3300 self.assertNotEqual(hash(foo), hash(P('foo', kind=P.POSITIONAL_ONLY,
3301 default=42)))
3302 self.assertNotEqual(hash(foo),
3303 hash(foo.replace(kind=P.VAR_POSITIONAL)))
3304
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003305 def test_signature_parameter_equality(self):
3306 P = inspect.Parameter
3307 p = P('foo', default=42, kind=inspect.Parameter.KEYWORD_ONLY)
3308
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003309 self.assertTrue(p == p)
3310 self.assertFalse(p != p)
3311 self.assertFalse(p == 42)
3312 self.assertTrue(p != 42)
Serhiy Storchaka7d44e7a2019-08-08 08:43:18 +03003313 self.assertTrue(p == ALWAYS_EQ)
3314 self.assertFalse(p != ALWAYS_EQ)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003315
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003316 self.assertTrue(p == P('foo', default=42,
3317 kind=inspect.Parameter.KEYWORD_ONLY))
3318 self.assertFalse(p != P('foo', default=42,
3319 kind=inspect.Parameter.KEYWORD_ONLY))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003320
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003321 def test_signature_parameter_replace(self):
3322 p = inspect.Parameter('foo', default=42,
3323 kind=inspect.Parameter.KEYWORD_ONLY)
3324
3325 self.assertIsNot(p, p.replace())
3326 self.assertEqual(p, p.replace())
3327
3328 p2 = p.replace(annotation=1)
3329 self.assertEqual(p2.annotation, 1)
3330 p2 = p2.replace(annotation=p2.empty)
3331 self.assertEqual(p, p2)
3332
3333 p2 = p2.replace(name='bar')
3334 self.assertEqual(p2.name, 'bar')
3335 self.assertNotEqual(p2, p)
3336
Yury Selivanov2393dca2014-01-27 15:07:58 -05003337 with self.assertRaisesRegex(ValueError,
3338 'name is a required attribute'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003339 p2 = p2.replace(name=p2.empty)
3340
3341 p2 = p2.replace(name='foo', default=None)
3342 self.assertIs(p2.default, None)
3343 self.assertNotEqual(p2, p)
3344
3345 p2 = p2.replace(name='foo', default=p2.empty)
3346 self.assertIs(p2.default, p2.empty)
3347
3348
3349 p2 = p2.replace(default=42, kind=p2.POSITIONAL_OR_KEYWORD)
3350 self.assertEqual(p2.kind, p2.POSITIONAL_OR_KEYWORD)
3351 self.assertNotEqual(p2, p)
3352
Dong-hee Naa9cab432018-05-30 00:04:08 +09003353 with self.assertRaisesRegex(ValueError,
3354 "value <class 'inspect._empty'> "
3355 "is not a valid Parameter.kind"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003356 p2 = p2.replace(kind=p2.empty)
3357
3358 p2 = p2.replace(kind=p2.KEYWORD_ONLY)
3359 self.assertEqual(p2, p)
3360
3361 def test_signature_parameter_positional_only(self):
Yury Selivanov2393dca2014-01-27 15:07:58 -05003362 with self.assertRaisesRegex(TypeError, 'name must be a str'):
3363 inspect.Parameter(None, kind=inspect.Parameter.POSITIONAL_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003364
Nick Coghlanb4b966e2016-06-04 14:40:03 -07003365 @cpython_only
3366 def test_signature_parameter_implicit(self):
3367 with self.assertRaisesRegex(ValueError,
Dong-hee Naa9cab432018-05-30 00:04:08 +09003368 'implicit arguments must be passed as '
3369 'positional or keyword arguments, '
3370 'not positional-only'):
Nick Coghlanb4b966e2016-06-04 14:40:03 -07003371 inspect.Parameter('.0', kind=inspect.Parameter.POSITIONAL_ONLY)
3372
3373 param = inspect.Parameter(
3374 '.0', kind=inspect.Parameter.POSITIONAL_OR_KEYWORD)
3375 self.assertEqual(param.kind, inspect.Parameter.POSITIONAL_ONLY)
3376 self.assertEqual(param.name, 'implicit0')
3377
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003378 def test_signature_parameter_immutability(self):
Yury Selivanov2393dca2014-01-27 15:07:58 -05003379 p = inspect.Parameter('spam', kind=inspect.Parameter.KEYWORD_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003380
3381 with self.assertRaises(AttributeError):
3382 p.foo = 'bar'
3383
3384 with self.assertRaises(AttributeError):
3385 p.kind = 123
3386
3387
3388class TestSignatureBind(unittest.TestCase):
3389 @staticmethod
3390 def call(func, *args, **kwargs):
3391 sig = inspect.signature(func)
3392 ba = sig.bind(*args, **kwargs)
3393 return func(*ba.args, **ba.kwargs)
3394
3395 def test_signature_bind_empty(self):
3396 def test():
3397 return 42
3398
3399 self.assertEqual(self.call(test), 42)
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)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003402 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003403 self.call(test, 1, spam=10)
Yury Selivanov86872752015-05-19 00:27:49 -04003404 with self.assertRaisesRegex(
3405 TypeError, "got an unexpected keyword argument 'spam'"):
3406
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003407 self.call(test, spam=1)
3408
3409 def test_signature_bind_var(self):
3410 def test(*args, **kwargs):
3411 return args, kwargs
3412
3413 self.assertEqual(self.call(test), ((), {}))
3414 self.assertEqual(self.call(test, 1), ((1,), {}))
3415 self.assertEqual(self.call(test, 1, 2), ((1, 2), {}))
3416 self.assertEqual(self.call(test, foo='bar'), ((), {'foo': 'bar'}))
3417 self.assertEqual(self.call(test, 1, foo='bar'), ((1,), {'foo': 'bar'}))
3418 self.assertEqual(self.call(test, args=10), ((), {'args': 10}))
3419 self.assertEqual(self.call(test, 1, 2, foo='bar'),
3420 ((1, 2), {'foo': 'bar'}))
3421
3422 def test_signature_bind_just_args(self):
3423 def test(a, b, c):
3424 return a, b, c
3425
3426 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
3427
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003428 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003429 self.call(test, 1, 2, 3, 4)
3430
Yury Selivanov86872752015-05-19 00:27:49 -04003431 with self.assertRaisesRegex(TypeError,
3432 "missing a required argument: 'b'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003433 self.call(test, 1)
3434
Yury Selivanov86872752015-05-19 00:27:49 -04003435 with self.assertRaisesRegex(TypeError,
3436 "missing a required argument: 'a'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003437 self.call(test)
3438
3439 def test(a, b, c=10):
3440 return a, b, c
3441 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
3442 self.assertEqual(self.call(test, 1, 2), (1, 2, 10))
3443
3444 def test(a=1, b=2, c=3):
3445 return a, b, c
3446 self.assertEqual(self.call(test, a=10, c=13), (10, 2, 13))
3447 self.assertEqual(self.call(test, a=10), (10, 2, 3))
3448 self.assertEqual(self.call(test, b=10), (1, 10, 3))
3449
3450 def test_signature_bind_varargs_order(self):
3451 def test(*args):
3452 return args
3453
3454 self.assertEqual(self.call(test), ())
3455 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
3456
3457 def test_signature_bind_args_and_varargs(self):
3458 def test(a, b, c=3, *args):
3459 return a, b, c, args
3460
3461 self.assertEqual(self.call(test, 1, 2, 3, 4, 5), (1, 2, 3, (4, 5)))
3462 self.assertEqual(self.call(test, 1, 2), (1, 2, 3, ()))
3463 self.assertEqual(self.call(test, b=1, a=2), (2, 1, 3, ()))
3464 self.assertEqual(self.call(test, 1, b=2), (1, 2, 3, ()))
3465
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003466 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003467 "multiple values for argument 'c'"):
3468 self.call(test, 1, 2, 3, c=4)
3469
3470 def test_signature_bind_just_kwargs(self):
3471 def test(**kwargs):
3472 return kwargs
3473
3474 self.assertEqual(self.call(test), {})
3475 self.assertEqual(self.call(test, foo='bar', spam='ham'),
3476 {'foo': 'bar', 'spam': 'ham'})
3477
3478 def test_signature_bind_args_and_kwargs(self):
3479 def test(a, b, c=3, **kwargs):
3480 return a, b, c, kwargs
3481
3482 self.assertEqual(self.call(test, 1, 2), (1, 2, 3, {}))
3483 self.assertEqual(self.call(test, 1, 2, foo='bar', spam='ham'),
3484 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3485 self.assertEqual(self.call(test, b=2, a=1, foo='bar', spam='ham'),
3486 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3487 self.assertEqual(self.call(test, a=1, b=2, foo='bar', spam='ham'),
3488 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3489 self.assertEqual(self.call(test, 1, b=2, foo='bar', spam='ham'),
3490 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3491 self.assertEqual(self.call(test, 1, b=2, c=4, foo='bar', spam='ham'),
3492 (1, 2, 4, {'foo': 'bar', 'spam': 'ham'}))
3493 self.assertEqual(self.call(test, 1, 2, 4, foo='bar'),
3494 (1, 2, 4, {'foo': 'bar'}))
3495 self.assertEqual(self.call(test, c=5, a=4, b=3),
3496 (4, 3, 5, {}))
3497
3498 def test_signature_bind_kwonly(self):
3499 def test(*, foo):
3500 return foo
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003501 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003502 'too many positional arguments'):
3503 self.call(test, 1)
3504 self.assertEqual(self.call(test, foo=1), 1)
3505
3506 def test(a, *, foo=1, bar):
3507 return foo
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003508 with self.assertRaisesRegex(TypeError,
Yury Selivanov86872752015-05-19 00:27:49 -04003509 "missing a required argument: 'bar'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003510 self.call(test, 1)
3511
3512 def test(foo, *, bar):
3513 return foo, bar
3514 self.assertEqual(self.call(test, 1, bar=2), (1, 2))
3515 self.assertEqual(self.call(test, bar=2, foo=1), (1, 2))
3516
Yury Selivanov86872752015-05-19 00:27:49 -04003517 with self.assertRaisesRegex(
3518 TypeError, "got an unexpected keyword argument 'spam'"):
3519
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003520 self.call(test, bar=2, foo=1, spam=10)
3521
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003522 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003523 'too many positional arguments'):
3524 self.call(test, 1, 2)
3525
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003526 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003527 'too many positional arguments'):
3528 self.call(test, 1, 2, bar=2)
3529
Yury Selivanov86872752015-05-19 00:27:49 -04003530 with self.assertRaisesRegex(
3531 TypeError, "got an unexpected keyword argument 'spam'"):
3532
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003533 self.call(test, 1, bar=2, spam='ham')
3534
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003535 with self.assertRaisesRegex(TypeError,
Yury Selivanov86872752015-05-19 00:27:49 -04003536 "missing a required argument: 'bar'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003537 self.call(test, 1)
3538
3539 def test(foo, *, bar, **bin):
3540 return foo, bar, bin
3541 self.assertEqual(self.call(test, 1, bar=2), (1, 2, {}))
3542 self.assertEqual(self.call(test, foo=1, bar=2), (1, 2, {}))
3543 self.assertEqual(self.call(test, 1, bar=2, spam='ham'),
3544 (1, 2, {'spam': 'ham'}))
3545 self.assertEqual(self.call(test, spam='ham', foo=1, bar=2),
3546 (1, 2, {'spam': 'ham'}))
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003547 with self.assertRaisesRegex(TypeError,
Yury Selivanov86872752015-05-19 00:27:49 -04003548 "missing a required argument: 'foo'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003549 self.call(test, spam='ham', bar=2)
3550 self.assertEqual(self.call(test, 1, bar=2, bin=1, spam=10),
3551 (1, 2, {'bin': 1, 'spam': 10}))
3552
3553 def test_signature_bind_arguments(self):
3554 def test(a, *args, b, z=100, **kwargs):
3555 pass
3556 sig = inspect.signature(test)
3557 ba = sig.bind(10, 20, b=30, c=40, args=50, kwargs=60)
3558 # we won't have 'z' argument in the bound arguments object, as we didn't
3559 # pass it to the 'bind'
3560 self.assertEqual(tuple(ba.arguments.items()),
3561 (('a', 10), ('args', (20,)), ('b', 30),
3562 ('kwargs', {'c': 40, 'args': 50, 'kwargs': 60})))
3563 self.assertEqual(ba.kwargs,
3564 {'b': 30, 'c': 40, 'args': 50, 'kwargs': 60})
3565 self.assertEqual(ba.args, (10, 20))
3566
3567 def test_signature_bind_positional_only(self):
3568 P = inspect.Parameter
3569
3570 def test(a_po, b_po, c_po=3, foo=42, *, bar=50, **kwargs):
3571 return a_po, b_po, c_po, foo, bar, kwargs
3572
3573 sig = inspect.signature(test)
3574 new_params = collections.OrderedDict(tuple(sig.parameters.items()))
3575 for name in ('a_po', 'b_po', 'c_po'):
3576 new_params[name] = new_params[name].replace(kind=P.POSITIONAL_ONLY)
3577 new_sig = sig.replace(parameters=new_params.values())
3578 test.__signature__ = new_sig
3579
3580 self.assertEqual(self.call(test, 1, 2, 4, 5, bar=6),
3581 (1, 2, 4, 5, 6, {}))
3582
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05003583 self.assertEqual(self.call(test, 1, 2),
3584 (1, 2, 3, 42, 50, {}))
3585
3586 self.assertEqual(self.call(test, 1, 2, foo=4, bar=5),
3587 (1, 2, 3, 4, 5, {}))
3588
3589 with self.assertRaisesRegex(TypeError, "but was passed as a keyword"):
3590 self.call(test, 1, 2, foo=4, bar=5, c_po=10)
3591
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003592 with self.assertRaisesRegex(TypeError, "parameter is positional only"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003593 self.call(test, 1, 2, c_po=4)
3594
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003595 with self.assertRaisesRegex(TypeError, "parameter is positional only"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003596 self.call(test, a_po=1, b_po=2)
3597
Antoine Pitroubd41d1b2013-01-29 21:20:57 +01003598 def test_signature_bind_with_self_arg(self):
3599 # Issue #17071: one of the parameters is named "self
3600 def test(a, self, b):
3601 pass
3602 sig = inspect.signature(test)
3603 ba = sig.bind(1, 2, 3)
3604 self.assertEqual(ba.args, (1, 2, 3))
3605 ba = sig.bind(1, self=2, b=3)
3606 self.assertEqual(ba.args, (1, 2, 3))
3607
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05003608 def test_signature_bind_vararg_name(self):
3609 def test(a, *args):
3610 return a, args
3611 sig = inspect.signature(test)
3612
Yury Selivanov86872752015-05-19 00:27:49 -04003613 with self.assertRaisesRegex(
3614 TypeError, "got an unexpected keyword argument 'args'"):
3615
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05003616 sig.bind(a=0, args=1)
3617
3618 def test(*args, **kwargs):
3619 return args, kwargs
3620 self.assertEqual(self.call(test, args=1), ((), {'args': 1}))
3621
3622 sig = inspect.signature(test)
3623 ba = sig.bind(args=1)
3624 self.assertEqual(ba.arguments, {'kwargs': {'args': 1}})
3625
Nick Coghlanb4b966e2016-06-04 14:40:03 -07003626 @cpython_only
3627 def test_signature_bind_implicit_arg(self):
3628 # Issue #19611: getcallargs should work with set comprehensions
3629 def make_set():
3630 return {z * z for z in range(5)}
3631 setcomp_code = make_set.__code__.co_consts[1]
3632 setcomp_func = types.FunctionType(setcomp_code, {})
3633
3634 iterator = iter(range(5))
3635 self.assertEqual(self.call(setcomp_func, iterator), {0, 1, 4, 9, 16})
3636
Pablo Galindof3ef06a2019-10-15 12:40:02 +01003637 def test_signature_bind_posonly_kwargs(self):
3638 def foo(bar, /, **kwargs):
3639 return bar, kwargs.get(bar)
3640
3641 sig = inspect.signature(foo)
3642 result = sig.bind("pos-only", bar="keyword")
3643
3644 self.assertEqual(result.kwargs, {"bar": "keyword"})
3645 self.assertIn(("bar", "pos-only"), result.arguments.items())
3646
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003647
3648class TestBoundArguments(unittest.TestCase):
3649 def test_signature_bound_arguments_unhashable(self):
3650 def foo(a): pass
3651 ba = inspect.signature(foo).bind(1)
3652
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003653 with self.assertRaisesRegex(TypeError, 'unhashable type'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003654 hash(ba)
3655
3656 def test_signature_bound_arguments_equality(self):
3657 def foo(a): pass
3658 ba = inspect.signature(foo).bind(1)
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003659 self.assertTrue(ba == ba)
3660 self.assertFalse(ba != ba)
Serhiy Storchaka7d44e7a2019-08-08 08:43:18 +03003661 self.assertTrue(ba == ALWAYS_EQ)
3662 self.assertFalse(ba != ALWAYS_EQ)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003663
3664 ba2 = inspect.signature(foo).bind(1)
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003665 self.assertTrue(ba == ba2)
3666 self.assertFalse(ba != ba2)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003667
3668 ba3 = inspect.signature(foo).bind(2)
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003669 self.assertFalse(ba == ba3)
3670 self.assertTrue(ba != ba3)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003671 ba3.arguments['a'] = 1
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003672 self.assertTrue(ba == ba3)
3673 self.assertFalse(ba != ba3)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003674
3675 def bar(b): pass
3676 ba4 = inspect.signature(bar).bind(1)
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003677 self.assertFalse(ba == ba4)
3678 self.assertTrue(ba != ba4)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003679
Yury Selivanov4cfd4ea2015-05-14 18:30:27 -04003680 def foo(*, a, b): pass
3681 sig = inspect.signature(foo)
3682 ba1 = sig.bind(a=1, b=2)
3683 ba2 = sig.bind(b=2, a=1)
Serhiy Storchaka2489bd52015-07-18 23:20:50 +03003684 self.assertTrue(ba1 == ba2)
3685 self.assertFalse(ba1 != ba2)
Yury Selivanov4cfd4ea2015-05-14 18:30:27 -04003686
Yury Selivanova5d63dd2014-03-27 11:31:43 -04003687 def test_signature_bound_arguments_pickle(self):
3688 def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
3689 sig = inspect.signature(foo)
3690 ba = sig.bind(20, 30, z={})
3691
3692 for ver in range(pickle.HIGHEST_PROTOCOL + 1):
3693 with self.subTest(pickle_ver=ver):
3694 ba_pickled = pickle.loads(pickle.dumps(ba, ver))
3695 self.assertEqual(ba, ba_pickled)
3696
Yury Selivanov3f6538f2015-05-14 18:47:17 -04003697 def test_signature_bound_arguments_repr(self):
3698 def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
3699 sig = inspect.signature(foo)
3700 ba = sig.bind(20, 30, z={})
Yury Selivanovf229bc52015-05-15 12:53:56 -04003701 self.assertRegex(repr(ba), r'<BoundArguments \(a=20,.*\}\}\)>')
Yury Selivanov3f6538f2015-05-14 18:47:17 -04003702
Yury Selivanovb907a512015-05-16 13:45:09 -04003703 def test_signature_bound_arguments_apply_defaults(self):
3704 def foo(a, b=1, *args, c:1={}, **kw): pass
3705 sig = inspect.signature(foo)
3706
3707 ba = sig.bind(20)
3708 ba.apply_defaults()
3709 self.assertEqual(
3710 list(ba.arguments.items()),
3711 [('a', 20), ('b', 1), ('args', ()), ('c', {}), ('kw', {})])
3712
3713 # Make sure that we preserve the order:
3714 # i.e. 'c' should be *before* 'kw'.
3715 ba = sig.bind(10, 20, 30, d=1)
3716 ba.apply_defaults()
3717 self.assertEqual(
3718 list(ba.arguments.items()),
3719 [('a', 10), ('b', 20), ('args', (30,)), ('c', {}), ('kw', {'d':1})])
3720
3721 # Make sure that BoundArguments produced by bind_partial()
3722 # are supported.
3723 def foo(a, b): pass
3724 sig = inspect.signature(foo)
3725 ba = sig.bind_partial(20)
3726 ba.apply_defaults()
3727 self.assertEqual(
3728 list(ba.arguments.items()),
3729 [('a', 20)])
3730
3731 # Test no args
3732 def foo(): pass
3733 sig = inspect.signature(foo)
3734 ba = sig.bind()
3735 ba.apply_defaults()
3736 self.assertEqual(list(ba.arguments.items()), [])
3737
Yury Selivanovf9e1f2b2016-03-02 11:07:47 -05003738 # Make sure a no-args binding still acquires proper defaults.
3739 def foo(a='spam'): pass
3740 sig = inspect.signature(foo)
3741 ba = sig.bind()
3742 ba.apply_defaults()
3743 self.assertEqual(list(ba.arguments.items()), [('a', 'spam')])
3744
Rémi Lapeyre2cca8ef2020-01-28 13:47:03 +01003745 def test_signature_bound_arguments_arguments_type(self):
3746 def foo(a): pass
3747 ba = inspect.signature(foo).bind(1)
3748 self.assertIs(type(ba.arguments), dict)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003749
Yury Selivanovd82eddc2014-01-29 11:24:39 -05003750class TestSignaturePrivateHelpers(unittest.TestCase):
3751 def test_signature_get_bound_param(self):
3752 getter = inspect._signature_get_bound_param
3753
3754 self.assertEqual(getter('($self)'), 'self')
3755 self.assertEqual(getter('($self, obj)'), 'self')
3756 self.assertEqual(getter('($cls, /, obj)'), 'cls')
3757
Larry Hastings2623c8c2014-02-08 22:15:29 -08003758 def _strip_non_python_syntax(self, input,
3759 clean_signature, self_parameter, last_positional_only):
3760 computed_clean_signature, \
3761 computed_self_parameter, \
3762 computed_last_positional_only = \
3763 inspect._signature_strip_non_python_syntax(input)
3764 self.assertEqual(computed_clean_signature, clean_signature)
3765 self.assertEqual(computed_self_parameter, self_parameter)
3766 self.assertEqual(computed_last_positional_only, last_positional_only)
3767
3768 def test_signature_strip_non_python_syntax(self):
3769 self._strip_non_python_syntax(
3770 "($module, /, path, mode, *, dir_fd=None, " +
3771 "effective_ids=False,\n follow_symlinks=True)",
3772 "(module, path, mode, *, dir_fd=None, " +
3773 "effective_ids=False, follow_symlinks=True)",
3774 0,
3775 0)
3776
3777 self._strip_non_python_syntax(
3778 "($module, word, salt, /)",
3779 "(module, word, salt)",
3780 0,
3781 2)
3782
3783 self._strip_non_python_syntax(
3784 "(x, y=None, z=None, /)",
3785 "(x, y=None, z=None)",
3786 None,
3787 2)
3788
3789 self._strip_non_python_syntax(
3790 "(x, y=None, z=None)",
3791 "(x, y=None, z=None)",
3792 None,
3793 None)
3794
3795 self._strip_non_python_syntax(
3796 "(x,\n y=None,\n z = None )",
3797 "(x, y=None, z=None)",
3798 None,
3799 None)
3800
3801 self._strip_non_python_syntax(
3802 "",
3803 "",
3804 None,
3805 None)
3806
3807 self._strip_non_python_syntax(
3808 None,
3809 None,
3810 None,
3811 None)
3812
Nick Coghlan9c680b02015-04-13 12:54:54 -04003813class TestSignatureDefinitions(unittest.TestCase):
3814 # This test case provides a home for checking that particular APIs
3815 # have signatures available for introspection
3816
3817 @cpython_only
3818 @unittest.skipIf(MISSING_C_DOCSTRINGS,
3819 "Signature information for builtins requires docstrings")
3820 def test_builtins_have_signatures(self):
3821 # This checks all builtin callables in CPython have signatures
3822 # A few have signatures Signature can't yet handle, so we skip those
3823 # since they will have to wait until PEP 457 adds the required
3824 # introspection support to the inspect module
3825 # Some others also haven't been converted yet for various other
3826 # reasons, so we also skip those for the time being, but design
3827 # the test to fail in order to indicate when it needs to be
3828 # updated.
3829 no_signature = set()
3830 # These need PEP 457 groups
3831 needs_groups = {"range", "slice", "dir", "getattr",
3832 "next", "iter", "vars"}
3833 no_signature |= needs_groups
3834 # These need PEP 457 groups or a signature change to accept None
3835 needs_semantic_update = {"round"}
3836 no_signature |= needs_semantic_update
3837 # These need *args support in Argument Clinic
Barry Warsaw36c1d1f2017-10-05 12:11:18 -04003838 needs_varargs = {"breakpoint", "min", "max", "print",
3839 "__build_class__"}
Nick Coghlan9c680b02015-04-13 12:54:54 -04003840 no_signature |= needs_varargs
3841 # These simply weren't covered in the initial AC conversion
3842 # for builtin callables
3843 not_converted_yet = {"open", "__import__"}
3844 no_signature |= not_converted_yet
3845 # These builtin types are expected to provide introspection info
3846 types_with_signatures = set()
3847 # Check the signatures we expect to be there
3848 ns = vars(builtins)
3849 for name, obj in sorted(ns.items()):
3850 if not callable(obj):
3851 continue
3852 # The builtin types haven't been converted to AC yet
3853 if isinstance(obj, type) and (name not in types_with_signatures):
3854 # Note that this also skips all the exception types
3855 no_signature.add(name)
3856 if (name in no_signature):
3857 # Not yet converted
3858 continue
3859 with self.subTest(builtin=name):
3860 self.assertIsNotNone(inspect.signature(obj))
3861 # Check callables that haven't been converted don't claim a signature
3862 # This ensures this test will start failing as more signatures are
3863 # added, so the affected items can be moved into the scope of the
3864 # regression test above
3865 for name in no_signature:
3866 with self.subTest(builtin=name):
3867 self.assertIsNone(obj.__text_signature__)
3868
Serhiy Storchakad53cf992019-05-06 22:40:27 +03003869 def test_python_function_override_signature(self):
3870 def func(*args, **kwargs):
3871 pass
3872 func.__text_signature__ = '($self, a, b=1, *args, c, d=2, **kwargs)'
3873 sig = inspect.signature(func)
3874 self.assertIsNotNone(sig)
3875 self.assertEqual(str(sig), '(self, /, a, b=1, *args, c, d=2, **kwargs)')
3876 func.__text_signature__ = '($self, a, b=1, /, *args, c, d=2, **kwargs)'
3877 sig = inspect.signature(func)
3878 self.assertEqual(str(sig), '(self, a, b=1, /, *args, c, d=2, **kwargs)')
3879
Yury Selivanovd82eddc2014-01-29 11:24:39 -05003880
Thomas Kluyverf9169ce2017-05-23 04:27:52 +01003881class NTimesUnwrappable:
3882 def __init__(self, n):
3883 self.n = n
3884 self._next = None
3885
3886 @property
3887 def __wrapped__(self):
3888 if self.n <= 0:
3889 raise Exception("Unwrapped too many times")
3890 if self._next is None:
3891 self._next = NTimesUnwrappable(self.n - 1)
3892 return self._next
3893
Nick Coghlane8c45d62013-07-28 20:00:01 +10003894class TestUnwrap(unittest.TestCase):
3895
3896 def test_unwrap_one(self):
3897 def func(a, b):
3898 return a + b
3899 wrapper = functools.lru_cache(maxsize=20)(func)
3900 self.assertIs(inspect.unwrap(wrapper), func)
3901
3902 def test_unwrap_several(self):
3903 def func(a, b):
3904 return a + b
3905 wrapper = func
3906 for __ in range(10):
3907 @functools.wraps(wrapper)
3908 def wrapper():
3909 pass
3910 self.assertIsNot(wrapper.__wrapped__, func)
3911 self.assertIs(inspect.unwrap(wrapper), func)
3912
3913 def test_stop(self):
3914 def func1(a, b):
3915 return a + b
3916 @functools.wraps(func1)
3917 def func2():
3918 pass
3919 @functools.wraps(func2)
3920 def wrapper():
3921 pass
3922 func2.stop_here = 1
3923 unwrapped = inspect.unwrap(wrapper,
3924 stop=(lambda f: hasattr(f, "stop_here")))
3925 self.assertIs(unwrapped, func2)
3926
3927 def test_cycle(self):
3928 def func1(): pass
3929 func1.__wrapped__ = func1
3930 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3931 inspect.unwrap(func1)
3932
3933 def func2(): pass
3934 func2.__wrapped__ = func1
3935 func1.__wrapped__ = func2
3936 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3937 inspect.unwrap(func1)
3938 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3939 inspect.unwrap(func2)
3940
3941 def test_unhashable(self):
3942 def func(): pass
3943 func.__wrapped__ = None
3944 class C:
3945 __hash__ = None
3946 __wrapped__ = func
3947 self.assertIsNone(inspect.unwrap(C()))
3948
Thomas Kluyverf9169ce2017-05-23 04:27:52 +01003949 def test_recursion_limit(self):
3950 obj = NTimesUnwrappable(sys.getrecursionlimit() + 1)
3951 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3952 inspect.unwrap(obj)
3953
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003954class TestMain(unittest.TestCase):
3955 def test_only_source(self):
3956 module = importlib.import_module('unittest')
3957 rc, out, err = assert_python_ok('-m', 'inspect',
3958 'unittest')
3959 lines = out.decode().splitlines()
3960 # ignore the final newline
3961 self.assertEqual(lines[:-1], inspect.getsource(module).splitlines())
3962 self.assertEqual(err, b'')
3963
Yury Selivanov42407ab2014-06-23 10:23:50 -07003964 def test_custom_getattr(self):
3965 def foo():
3966 pass
3967 foo.__signature__ = 42
3968 with self.assertRaises(TypeError):
3969 inspect.signature(foo)
3970
Brett Cannon634a8fc2013-10-02 10:25:42 -04003971 @unittest.skipIf(ThreadPoolExecutor is None,
Brett Cannon0de3f012013-10-02 10:58:58 -04003972 'threads required to test __qualname__ for source files')
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003973 def test_qualname_source(self):
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003974 rc, out, err = assert_python_ok('-m', 'inspect',
3975 'concurrent.futures:ThreadPoolExecutor')
3976 lines = out.decode().splitlines()
3977 # ignore the final newline
3978 self.assertEqual(lines[:-1],
Brett Cannon634a8fc2013-10-02 10:25:42 -04003979 inspect.getsource(ThreadPoolExecutor).splitlines())
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003980 self.assertEqual(err, b'')
3981
3982 def test_builtins(self):
3983 module = importlib.import_module('unittest')
3984 _, out, err = assert_python_failure('-m', 'inspect',
3985 'sys')
3986 lines = err.decode().splitlines()
3987 self.assertEqual(lines, ["Can't get info for builtin modules."])
3988
3989 def test_details(self):
3990 module = importlib.import_module('unittest')
Victor Stinner9def2842016-01-18 12:15:08 +01003991 args = support.optim_args_from_interpreter_flags()
3992 rc, out, err = assert_python_ok(*args, '-m', 'inspect',
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003993 'unittest', '--details')
3994 output = out.decode()
3995 # Just a quick sanity check on the output
3996 self.assertIn(module.__name__, output)
3997 self.assertIn(module.__file__, output)
Victor Stinner9def2842016-01-18 12:15:08 +01003998 self.assertIn(module.__cached__, output)
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003999 self.assertEqual(err, b'')
4000
4001
Yury Selivanovef1e7502014-12-08 16:05:34 -05004002class TestReload(unittest.TestCase):
4003
4004 src_before = textwrap.dedent("""\
4005def foo():
4006 print("Bla")
4007 """)
4008
4009 src_after = textwrap.dedent("""\
4010def foo():
4011 print("Oh no!")
4012 """)
4013
4014 def assertInspectEqual(self, path, source):
4015 inspected_src = inspect.getsource(source)
4016 with open(path) as src:
4017 self.assertEqual(
4018 src.read().splitlines(True),
4019 inspected_src.splitlines(True)
4020 )
4021
4022 def test_getsource_reload(self):
4023 # see issue 1218234
4024 with _ready_to_import('reload_bug', self.src_before) as (name, path):
4025 module = importlib.import_module(name)
4026 self.assertInspectEqual(path, module)
4027 with open(path, 'w') as src:
4028 src.write(self.src_after)
4029 self.assertInspectEqual(path, module)
Nick Coghlanf94a16b2013-09-22 22:46:49 +10004030
Nick Coghlane8c45d62013-07-28 20:00:01 +10004031
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00004032def test_main():
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00004033 run_unittest(
Miss Islington (bot)81ac0302020-12-04 12:20:05 -08004034 TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBlockComments,
4035 TestBuggyCases, TestInterpreterStack, TestClassesAndFunctions, TestPredicates,
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00004036 TestGetcallargsFunctions, TestGetcallargsMethods,
Alexander Belopolskyf546e702010-12-02 00:10:11 +00004037 TestGetcallargsUnboundMethods, TestGetattrStatic, TestGetGeneratorState,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07004038 TestNoEOL, TestSignatureObject, TestSignatureBind, TestParameterObject,
Nick Coghlan9c680b02015-04-13 12:54:54 -04004039 TestBoundArguments, TestSignaturePrivateHelpers,
Aaron Hall, MBA4054b172018-05-20 19:46:42 -04004040 TestSignatureDefinitions, TestIsDataDescriptor,
Yury Selivanov5376ba92015-06-22 12:19:30 -04004041 TestGetClosureVars, TestUnwrap, TestMain, TestReload,
Vladimir Matveev91cb2982018-08-24 07:18:00 -07004042 TestGetCoroutineState, TestGettingSourceOfToplevelFrames
Michael Foord95fc51d2010-11-20 15:07:30 +00004043 )
Martin v. Löwis893ffa42003-10-31 15:35:53 +00004044
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00004045if __name__ == "__main__":
4046 test_main()