blob: d9e26a303366767ba3094ea3564040fd4e9aee16 [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
Miss Islington (bot)d1f07412020-12-04 14:41:58 -0800713 def test_findsource_with_out_of_bounds_lineno(self):
714 mod_len = len(inspect.getsource(mod))
715 src = '\n' * 2* mod_len + "def f(): pass"
716 co = compile(src, mod.__file__, "exec")
717 g, l = {}, {}
718 eval(co, g, l)
719 func = l['f']
720 self.assertEqual(func.__code__.co_firstlineno, 1+2*mod_len)
721 with self.assertRaisesRegex(IOError, "lineno is out of bounds"):
722 inspect.findsource(func)
723
Antoine Pitroua8723a02015-04-15 00:41:29 +0200724 def test_getsource_on_method(self):
725 self.assertSourceEqual(mod2.ClassWithMethod.method, 118, 119)
726
Yury Selivanov4f4913b2015-07-23 17:10:00 +0300727 def test_nested_func(self):
728 self.assertSourceEqual(mod2.cls135.func136, 136, 139)
729
Karthikeyan Singaravelan696136b2020-04-18 21:49:32 +0530730 def test_class_definition_in_multiline_string_definition(self):
731 self.assertSourceEqual(mod2.cls149, 149, 152)
732
733 def test_class_definition_in_multiline_comment(self):
734 self.assertSourceEqual(mod2.cls160, 160, 163)
735
736 def test_nested_class_definition_indented_string(self):
737 self.assertSourceEqual(mod2.cls173.cls175, 175, 176)
738
739 def test_nested_class_definition(self):
740 self.assertSourceEqual(mod2.cls183, 183, 188)
741 self.assertSourceEqual(mod2.cls183.cls185, 185, 188)
742
743 def test_class_decorator(self):
744 self.assertSourceEqual(mod2.cls196, 194, 201)
745 self.assertSourceEqual(mod2.cls196.cls200, 198, 201)
746
747 def test_class_inside_conditional(self):
748 self.assertSourceEqual(mod2.cls238, 238, 240)
749 self.assertSourceEqual(mod2.cls238.cls239, 239, 240)
750
751 def test_multiple_children_classes(self):
752 self.assertSourceEqual(mod2.cls203, 203, 209)
753 self.assertSourceEqual(mod2.cls203.cls204, 204, 206)
754 self.assertSourceEqual(mod2.cls203.cls204.cls205, 205, 206)
755 self.assertSourceEqual(mod2.cls203.cls207, 207, 209)
756 self.assertSourceEqual(mod2.cls203.cls207.cls205, 208, 209)
757
758 def test_nested_class_definition_inside_function(self):
759 self.assertSourceEqual(mod2.func212(), 213, 214)
760 self.assertSourceEqual(mod2.cls213, 218, 222)
761 self.assertSourceEqual(mod2.cls213().func219(), 220, 221)
762
763 def test_nested_class_definition_inside_async_function(self):
764 import asyncio
765 self.addCleanup(asyncio.set_event_loop_policy, None)
766 self.assertSourceEqual(asyncio.run(mod2.func225()), 226, 227)
767 self.assertSourceEqual(mod2.cls226, 231, 235)
768 self.assertSourceEqual(asyncio.run(mod2.cls226().func232()), 233, 234)
Yury Selivanov4f4913b2015-07-23 17:10:00 +0300769
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000770class TestNoEOL(GetSourceBase):
Yury Selivanov6738b112015-05-16 10:10:21 -0400771 def setUp(self):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000772 self.tempdir = TESTFN + '_dir'
773 os.mkdir(self.tempdir)
774 with open(os.path.join(self.tempdir,
775 'inspect_fodder3%spy' % os.extsep), 'w') as f:
776 f.write("class X:\n pass # No EOL")
777 with DirsOnSysPath(self.tempdir):
778 import inspect_fodder3 as mod3
779 self.fodderModule = mod3
Yury Selivanov6738b112015-05-16 10:10:21 -0400780 super().setUp()
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000781
782 def tearDown(self):
783 shutil.rmtree(self.tempdir)
784
785 def test_class(self):
786 self.assertSourceEqual(self.fodderModule.X, 1, 2)
787
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100788
789class _BrokenDataDescriptor(object):
790 """
791 A broken data descriptor. See bug #1785.
792 """
793 def __get__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700794 raise AttributeError("broken data descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100795
796 def __set__(*args):
797 raise RuntimeError
798
799 def __getattr__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700800 raise AttributeError("broken data descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100801
802
803class _BrokenMethodDescriptor(object):
804 """
805 A broken method descriptor. See bug #1785.
806 """
807 def __get__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700808 raise AttributeError("broken method descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100809
810 def __getattr__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700811 raise AttributeError("broken method descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100812
813
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000814# Helper for testing classify_class_attrs.
Tim Peters13b49d32001-09-23 02:00:29 +0000815def attrs_wo_objs(cls):
816 return [t[:3] for t in inspect.classify_class_attrs(cls)]
817
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100818
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000819class TestClassesAndFunctions(unittest.TestCase):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000820 def test_newstyle_mro(self):
821 # The same w/ new-class MRO.
822 class A(object): pass
823 class B(A): pass
824 class C(A): pass
825 class D(B, C): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000826
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000827 expected = (D, B, C, A, object)
828 got = inspect.getmro(D)
829 self.assertEqual(expected, got)
Tim Peters13b49d32001-09-23 02:00:29 +0000830
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500831 def assertArgSpecEquals(self, routine, args_e, varargs_e=None,
832 varkw_e=None, defaults_e=None, formatted=None):
Xtreak6d0b7472019-05-30 17:31:39 +0530833 with self.assertWarns(DeprecationWarning):
834 args, varargs, varkw, defaults = inspect.getargspec(routine)
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500835 self.assertEqual(args, args_e)
836 self.assertEqual(varargs, varargs_e)
837 self.assertEqual(varkw, varkw_e)
838 self.assertEqual(defaults, defaults_e)
839 if formatted is not None:
Xtreak6d0b7472019-05-30 17:31:39 +0530840 with self.assertWarns(DeprecationWarning):
841 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults),
842 formatted)
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500843
Christian Heimes3795b532007-11-08 13:48:53 +0000844 def assertFullArgSpecEquals(self, routine, args_e, varargs_e=None,
845 varkw_e=None, defaults_e=None,
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100846 posonlyargs_e=[], kwonlyargs_e=[],
847 kwonlydefaults_e=None,
Christian Heimes3795b532007-11-08 13:48:53 +0000848 ann_e={}, formatted=None):
Pablo Galindoaee19f52019-05-16 21:08:15 +0100849 args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \
850 inspect.getfullargspec(routine)
Christian Heimes3795b532007-11-08 13:48:53 +0000851 self.assertEqual(args, args_e)
852 self.assertEqual(varargs, varargs_e)
853 self.assertEqual(varkw, varkw_e)
854 self.assertEqual(defaults, defaults_e)
855 self.assertEqual(kwonlyargs, kwonlyargs_e)
856 self.assertEqual(kwonlydefaults, kwonlydefaults_e)
857 self.assertEqual(ann, ann_e)
858 if formatted is not None:
Xtreak6d0b7472019-05-30 17:31:39 +0530859 with self.assertWarns(DeprecationWarning):
860 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults,
861 kwonlyargs, kwonlydefaults, ann),
862 formatted)
Christian Heimes3795b532007-11-08 13:48:53 +0000863
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500864 def test_getargspec(self):
865 self.assertArgSpecEquals(mod.eggs, ['x', 'y'], formatted='(x, y)')
866
Pablo Galindod5d2b452019-04-30 02:01:14 +0100867 self.assertArgSpecEquals(mod.spam,
868 ['a', 'b', 'c', 'd', 'e', 'f'],
869 'g', 'h', (3, 4, 5),
870 '(a, b, c, d=3, e=4, f=5, *g, **h)')
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500871
872 self.assertRaises(ValueError, self.assertArgSpecEquals,
873 mod2.keyworded, [])
874
875 self.assertRaises(ValueError, self.assertArgSpecEquals,
876 mod2.annotated, [])
877 self.assertRaises(ValueError, self.assertArgSpecEquals,
878 mod2.keyword_only_arg, [])
879
880
Christian Heimes3795b532007-11-08 13:48:53 +0000881 def test_getfullargspec(self):
882 self.assertFullArgSpecEquals(mod2.keyworded, [], varargs_e='arg1',
883 kwonlyargs_e=['arg2'],
884 kwonlydefaults_e={'arg2':1},
885 formatted='(*arg1, arg2=1)')
886
887 self.assertFullArgSpecEquals(mod2.annotated, ['arg1'],
Christian Heimesc9543e42007-11-28 08:28:28 +0000888 ann_e={'arg1' : list},
Christian Heimes3795b532007-11-08 13:48:53 +0000889 formatted='(arg1: list)')
Benjamin Peterson9953a8d2009-01-17 04:15:01 +0000890 self.assertFullArgSpecEquals(mod2.keyword_only_arg, [],
891 kwonlyargs_e=['arg'],
892 formatted='(*, arg)')
893
Pablo Galindod5d2b452019-04-30 02:01:14 +0100894 self.assertFullArgSpecEquals(mod2.all_markers, ['a', 'b', 'c', 'd'],
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100895 kwonlyargs_e=['e', 'f'],
Pablo Galindod5d2b452019-04-30 02:01:14 +0100896 formatted='(a, b, c, d, *, e, f)')
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100897
898 self.assertFullArgSpecEquals(mod2.all_markers_with_args_and_kwargs,
Pablo Galindod5d2b452019-04-30 02:01:14 +0100899 ['a', 'b', 'c', 'd'],
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100900 varargs_e='args',
901 varkw_e='kwargs',
902 kwonlyargs_e=['e', 'f'],
Pablo Galindod5d2b452019-04-30 02:01:14 +0100903 formatted='(a, b, c, d, *args, e, f, **kwargs)')
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100904
Pablo Galindod5d2b452019-04-30 02:01:14 +0100905 self.assertFullArgSpecEquals(mod2.all_markers_with_defaults, ['a', 'b', 'c', 'd'],
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100906 defaults_e=(1,2,3),
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100907 kwonlyargs_e=['e', 'f'],
908 kwonlydefaults_e={'e': 4, 'f': 5},
Pablo Galindod5d2b452019-04-30 02:01:14 +0100909 formatted='(a, b=1, c=2, d=3, *, e=4, f=5)')
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100910
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500911 def test_argspec_api_ignores_wrapped(self):
Yury Selivanov57d240e2014-02-19 16:27:23 -0500912 # Issue 20684: low level introspection API must ignore __wrapped__
913 @functools.wraps(mod.spam)
914 def ham(x, y):
915 pass
916 # Basic check
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500917 self.assertArgSpecEquals(ham, ['x', 'y'], formatted='(x, y)')
Yury Selivanov57d240e2014-02-19 16:27:23 -0500918 self.assertFullArgSpecEquals(ham, ['x', 'y'], formatted='(x, y)')
919 self.assertFullArgSpecEquals(functools.partial(ham),
920 ['x', 'y'], formatted='(x, y)')
921 # Other variants
922 def check_method(f):
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500923 self.assertArgSpecEquals(f, ['self', 'x', 'y'],
924 formatted='(self, x, y)')
Yury Selivanov57d240e2014-02-19 16:27:23 -0500925 class C:
926 @functools.wraps(mod.spam)
927 def ham(self, x, y):
928 pass
929 pham = functools.partialmethod(ham)
930 @functools.wraps(mod.spam)
931 def __call__(self, x, y):
932 pass
933 check_method(C())
934 check_method(C.ham)
935 check_method(C().ham)
936 check_method(C.pham)
937 check_method(C().pham)
938
939 class C_new:
940 @functools.wraps(mod.spam)
941 def __new__(self, x, y):
942 pass
943 check_method(C_new)
944
945 class C_init:
946 @functools.wraps(mod.spam)
947 def __init__(self, x, y):
948 pass
949 check_method(C_init)
950
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500951 def test_getfullargspec_signature_attr(self):
952 def test():
953 pass
954 spam_param = inspect.Parameter('spam', inspect.Parameter.POSITIONAL_ONLY)
955 test.__signature__ = inspect.Signature(parameters=(spam_param,))
956
Pablo Galindod5d2b452019-04-30 02:01:14 +0100957 self.assertFullArgSpecEquals(test, ['spam'], formatted='(spam)')
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500958
Yury Selivanov4cb93912014-01-29 11:54:12 -0500959 def test_getfullargspec_signature_annos(self):
960 def test(a:'spam') -> 'ham': pass
Pablo Galindoaee19f52019-05-16 21:08:15 +0100961 spec = inspect.getfullargspec(test)
Yury Selivanov4cb93912014-01-29 11:54:12 -0500962 self.assertEqual(test.__annotations__, spec.annotations)
963
964 def test(): pass
Pablo Galindoaee19f52019-05-16 21:08:15 +0100965 spec = inspect.getfullargspec(test)
Yury Selivanov4cb93912014-01-29 11:54:12 -0500966 self.assertEqual(test.__annotations__, spec.annotations)
967
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500968 @unittest.skipIf(MISSING_C_DOCSTRINGS,
969 "Signature information for builtins requires docstrings")
970 def test_getfullargspec_builtin_methods(self):
Pablo Galindod5d2b452019-04-30 02:01:14 +0100971 self.assertFullArgSpecEquals(_pickle.Pickler.dump, ['self', 'obj'],
972 formatted='(self, obj)')
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500973
Pablo Galindod5d2b452019-04-30 02:01:14 +0100974 self.assertFullArgSpecEquals(_pickle.Pickler(io.BytesIO()).dump, ['self', 'obj'],
975 formatted='(self, obj)')
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500976
Yury Selivanov8c185ee2014-02-21 01:32:42 -0500977 self.assertFullArgSpecEquals(
978 os.stat,
979 args_e=['path'],
980 kwonlyargs_e=['dir_fd', 'follow_symlinks'],
981 kwonlydefaults_e={'dir_fd': None, 'follow_symlinks': True},
982 formatted='(path, *, dir_fd=None, follow_symlinks=True)')
983
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200984 @cpython_only
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500985 @unittest.skipIf(MISSING_C_DOCSTRINGS,
986 "Signature information for builtins requires docstrings")
Chih-Hsuan Yenc57eb9a2018-10-04 21:15:00 +0800987 def test_getfullargspec_builtin_func(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200988 import _testcapi
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500989 builtin = _testcapi.docstring_with_signature_with_defaults
Pablo Galindoaee19f52019-05-16 21:08:15 +0100990 spec = inspect.getfullargspec(builtin)
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500991 self.assertEqual(spec.defaults[0], 'avocado')
992
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200993 @cpython_only
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500994 @unittest.skipIf(MISSING_C_DOCSTRINGS,
995 "Signature information for builtins requires docstrings")
Chih-Hsuan Yenc57eb9a2018-10-04 21:15:00 +0800996 def test_getfullargspec_builtin_func_no_signature(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200997 import _testcapi
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500998 builtin = _testcapi.docstring_no_signature
Pablo Galindoaee19f52019-05-16 21:08:15 +0100999 with self.assertRaises(TypeError):
1000 inspect.getfullargspec(builtin)
Christian Heimes3795b532007-11-08 13:48:53 +00001001
larryhastingsf36ba122018-01-28 11:13:09 -08001002 def test_getfullargspec_definition_order_preserved_on_kwonly(self):
1003 for fn in signatures_with_lexicographic_keyword_only_parameters():
Pablo Galindoaee19f52019-05-16 21:08:15 +01001004 signature = inspect.getfullargspec(fn)
larryhastingsf36ba122018-01-28 11:13:09 -08001005 l = list(signature.kwonlyargs)
1006 sorted_l = sorted(l)
1007 self.assertTrue(l)
1008 self.assertEqual(l, sorted_l)
Pablo Galindoaee19f52019-05-16 21:08:15 +01001009 signature = inspect.getfullargspec(unsorted_keyword_only_parameters_fn)
larryhastingsf36ba122018-01-28 11:13:09 -08001010 l = list(signature.kwonlyargs)
1011 self.assertEqual(l, unsorted_keyword_only_parameters)
1012
Yury Selivanov37dc2b22016-01-11 15:15:01 -05001013 def test_getargspec_method(self):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001014 class A(object):
1015 def m(self):
1016 pass
Yury Selivanov37dc2b22016-01-11 15:15:01 -05001017 self.assertArgSpecEquals(A.m, ['self'])
Tim Peters13b49d32001-09-23 02:00:29 +00001018
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001019 def test_classify_newstyle(self):
1020 class A(object):
Tim Peters13b49d32001-09-23 02:00:29 +00001021
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001022 def s(): pass
1023 s = staticmethod(s)
Tim Peters13b49d32001-09-23 02:00:29 +00001024
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001025 def c(cls): pass
1026 c = classmethod(c)
Tim Peters13b49d32001-09-23 02:00:29 +00001027
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001028 def getp(self): pass
1029 p = property(getp)
Tim Peters13b49d32001-09-23 02:00:29 +00001030
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001031 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +00001032
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001033 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +00001034
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001035 datablob = '1'
Tim Peters13b49d32001-09-23 02:00:29 +00001036
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +01001037 dd = _BrokenDataDescriptor()
1038 md = _BrokenMethodDescriptor()
1039
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001040 attrs = attrs_wo_objs(A)
Yury Selivanov0860a0b2014-01-31 14:28:44 -05001041
Serhiy Storchaka3327a2d2017-12-15 14:13:41 +02001042 self.assertIn(('__new__', 'static method', object), attrs,
1043 'missing __new__')
Yury Selivanov0860a0b2014-01-31 14:28:44 -05001044 self.assertIn(('__init__', 'method', object), attrs, 'missing __init__')
1045
Benjamin Peterson577473f2010-01-19 00:09:57 +00001046 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
1047 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
1048 self.assertIn(('p', 'property', A), attrs, 'missing property')
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001049 self.assertIn(('m', 'method', A), attrs,
1050 'missing plain method: %r' % attrs)
Benjamin Peterson577473f2010-01-19 00:09:57 +00001051 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
1052 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +01001053 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
1054 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +00001055
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001056 class B(A):
Tim Peters13b49d32001-09-23 02:00:29 +00001057
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001058 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +00001059
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001060 attrs = attrs_wo_objs(B)
Benjamin Peterson577473f2010-01-19 00:09:57 +00001061 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
1062 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
1063 self.assertIn(('p', 'property', A), attrs, 'missing property')
1064 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
1065 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
1066 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +01001067 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
1068 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +00001069
1070
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001071 class C(A):
Tim Peters13b49d32001-09-23 02:00:29 +00001072
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001073 def m(self): pass
1074 def c(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +00001075
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001076 attrs = attrs_wo_objs(C)
Benjamin Peterson577473f2010-01-19 00:09:57 +00001077 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
1078 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
1079 self.assertIn(('p', 'property', A), attrs, 'missing property')
1080 self.assertIn(('m', 'method', C), attrs, 'missing plain method')
1081 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
1082 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +01001083 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
1084 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +00001085
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001086 class D(B, C):
Tim Peters13b49d32001-09-23 02:00:29 +00001087
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001088 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +00001089
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001090 attrs = attrs_wo_objs(D)
Benjamin Peterson577473f2010-01-19 00:09:57 +00001091 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
1092 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
1093 self.assertIn(('p', 'property', A), attrs, 'missing property')
1094 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
1095 self.assertIn(('m1', 'method', D), attrs, 'missing plain method')
1096 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +01001097 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
1098 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
1099
1100 def test_classify_builtin_types(self):
1101 # Simple sanity check that all built-in types can have their
1102 # attributes classified.
1103 for name in dir(__builtins__):
1104 builtin = getattr(__builtins__, name)
1105 if isinstance(builtin, type):
1106 inspect.classify_class_attrs(builtin)
1107
Serhiy Storchaka3327a2d2017-12-15 14:13:41 +02001108 attrs = attrs_wo_objs(bool)
1109 self.assertIn(('__new__', 'static method', bool), attrs,
1110 'missing __new__')
1111 self.assertIn(('from_bytes', 'class method', int), attrs,
1112 'missing class method')
1113 self.assertIn(('to_bytes', 'method', int), attrs,
1114 'missing plain method')
1115 self.assertIn(('__add__', 'method', int), attrs,
1116 'missing plain method')
1117 self.assertIn(('__and__', 'method', bool), attrs,
1118 'missing plain method')
1119
Ethan Furman63c141c2013-10-18 00:27:39 -07001120 def test_classify_DynamicClassAttribute(self):
1121 class Meta(type):
1122 def __getattr__(self, name):
1123 if name == 'ham':
1124 return 'spam'
1125 return super().__getattr__(name)
1126 class VA(metaclass=Meta):
Ethan Furmane03ea372013-09-25 07:14:41 -07001127 @types.DynamicClassAttribute
1128 def ham(self):
1129 return 'eggs'
Ethan Furman63c141c2013-10-18 00:27:39 -07001130 should_find_dca = inspect.Attribute('ham', 'data', VA, VA.__dict__['ham'])
1131 self.assertIn(should_find_dca, inspect.classify_class_attrs(VA))
Ethan Furmanb0c84cd2013-10-20 22:37:39 -07001132 should_find_ga = inspect.Attribute('ham', 'data', Meta, 'spam')
Ethan Furman63c141c2013-10-18 00:27:39 -07001133 self.assertIn(should_find_ga, inspect.classify_class_attrs(VA))
1134
Yury Selivanovbf341fb2015-05-21 15:41:57 -04001135 def test_classify_overrides_bool(self):
1136 class NoBool(object):
1137 def __eq__(self, other):
1138 return NoBool()
1139
1140 def __bool__(self):
1141 raise NotImplementedError(
1142 "This object does not specify a boolean value")
1143
1144 class HasNB(object):
1145 dd = NoBool()
1146
1147 should_find_attr = inspect.Attribute('dd', 'data', HasNB, HasNB.dd)
1148 self.assertIn(should_find_attr, inspect.classify_class_attrs(HasNB))
1149
Ethan Furmanb0c84cd2013-10-20 22:37:39 -07001150 def test_classify_metaclass_class_attribute(self):
1151 class Meta(type):
1152 fish = 'slap'
1153 def __dir__(self):
Serhiy Storchakaa60c2fe2015-03-12 21:56:08 +02001154 return ['__class__', '__module__', '__name__', 'fish']
Ethan Furmanb0c84cd2013-10-20 22:37:39 -07001155 class Class(metaclass=Meta):
1156 pass
1157 should_find = inspect.Attribute('fish', 'data', Meta, 'slap')
1158 self.assertIn(should_find, inspect.classify_class_attrs(Class))
1159
Ethan Furman63c141c2013-10-18 00:27:39 -07001160 def test_classify_VirtualAttribute(self):
1161 class Meta(type):
1162 def __dir__(cls):
1163 return ['__class__', '__module__', '__name__', 'BOOM']
1164 def __getattr__(self, name):
1165 if name =='BOOM':
1166 return 42
1167 return super().__getattr(name)
1168 class Class(metaclass=Meta):
1169 pass
Ethan Furmanb0c84cd2013-10-20 22:37:39 -07001170 should_find = inspect.Attribute('BOOM', 'data', Meta, 42)
Ethan Furman63c141c2013-10-18 00:27:39 -07001171 self.assertIn(should_find, inspect.classify_class_attrs(Class))
1172
1173 def test_classify_VirtualAttribute_multi_classes(self):
1174 class Meta1(type):
1175 def __dir__(cls):
1176 return ['__class__', '__module__', '__name__', 'one']
1177 def __getattr__(self, name):
1178 if name =='one':
1179 return 1
1180 return super().__getattr__(name)
1181 class Meta2(type):
1182 def __dir__(cls):
1183 return ['__class__', '__module__', '__name__', 'two']
1184 def __getattr__(self, name):
1185 if name =='two':
1186 return 2
1187 return super().__getattr__(name)
1188 class Meta3(Meta1, Meta2):
1189 def __dir__(cls):
1190 return list(sorted(set(['__class__', '__module__', '__name__', 'three'] +
1191 Meta1.__dir__(cls) + Meta2.__dir__(cls))))
1192 def __getattr__(self, name):
1193 if name =='three':
1194 return 3
1195 return super().__getattr__(name)
1196 class Class1(metaclass=Meta1):
1197 pass
1198 class Class2(Class1, metaclass=Meta3):
1199 pass
1200
Ethan Furmanb0c84cd2013-10-20 22:37:39 -07001201 should_find1 = inspect.Attribute('one', 'data', Meta1, 1)
1202 should_find2 = inspect.Attribute('two', 'data', Meta2, 2)
1203 should_find3 = inspect.Attribute('three', 'data', Meta3, 3)
Ethan Furman63c141c2013-10-18 00:27:39 -07001204 cca = inspect.classify_class_attrs(Class2)
1205 for sf in (should_find1, should_find2, should_find3):
1206 self.assertIn(sf, cca)
1207
1208 def test_classify_class_attrs_with_buggy_dir(self):
1209 class M(type):
1210 def __dir__(cls):
1211 return ['__class__', '__name__', 'missing']
1212 class C(metaclass=M):
1213 pass
1214 attrs = [a[0] for a in inspect.classify_class_attrs(C)]
1215 self.assertNotIn('missing', attrs)
Ethan Furmane03ea372013-09-25 07:14:41 -07001216
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +01001217 def test_getmembers_descriptors(self):
1218 class A(object):
1219 dd = _BrokenDataDescriptor()
1220 md = _BrokenMethodDescriptor()
1221
1222 def pred_wrapper(pred):
1223 # A quick'n'dirty way to discard standard attributes of new-style
1224 # classes.
1225 class Empty(object):
1226 pass
1227 def wrapped(x):
1228 if '__name__' in dir(x) and hasattr(Empty, x.__name__):
1229 return False
1230 return pred(x)
1231 return wrapped
1232
1233 ismethoddescriptor = pred_wrapper(inspect.ismethoddescriptor)
1234 isdatadescriptor = pred_wrapper(inspect.isdatadescriptor)
1235
1236 self.assertEqual(inspect.getmembers(A, ismethoddescriptor),
1237 [('md', A.__dict__['md'])])
1238 self.assertEqual(inspect.getmembers(A, isdatadescriptor),
1239 [('dd', A.__dict__['dd'])])
1240
1241 class B(A):
1242 pass
1243
1244 self.assertEqual(inspect.getmembers(B, ismethoddescriptor),
1245 [('md', A.__dict__['md'])])
1246 self.assertEqual(inspect.getmembers(B, isdatadescriptor),
1247 [('dd', A.__dict__['dd'])])
1248
Antoine Pitrou0c603812012-01-18 17:40:18 +01001249 def test_getmembers_method(self):
1250 class B:
1251 def f(self):
1252 pass
1253
1254 self.assertIn(('f', B.f), inspect.getmembers(B))
1255 self.assertNotIn(('f', B.f), inspect.getmembers(B, inspect.ismethod))
1256 b = B()
1257 self.assertIn(('f', b.f), inspect.getmembers(b))
1258 self.assertIn(('f', b.f), inspect.getmembers(b, inspect.ismethod))
1259
Ethan Furmane03ea372013-09-25 07:14:41 -07001260 def test_getmembers_VirtualAttribute(self):
Ethan Furman63c141c2013-10-18 00:27:39 -07001261 class M(type):
1262 def __getattr__(cls, name):
1263 if name == 'eggs':
1264 return 'scrambled'
1265 return super().__getattr__(name)
1266 class A(metaclass=M):
Ethan Furmane03ea372013-09-25 07:14:41 -07001267 @types.DynamicClassAttribute
1268 def eggs(self):
1269 return 'spam'
Ethan Furman63c141c2013-10-18 00:27:39 -07001270 self.assertIn(('eggs', 'scrambled'), inspect.getmembers(A))
1271 self.assertIn(('eggs', 'spam'), inspect.getmembers(A()))
1272
1273 def test_getmembers_with_buggy_dir(self):
1274 class M(type):
1275 def __dir__(cls):
1276 return ['__class__', '__name__', 'missing']
1277 class C(metaclass=M):
1278 pass
1279 attrs = [a[0] for a in inspect.getmembers(C)]
1280 self.assertNotIn('missing', attrs)
Ethan Furmane03ea372013-09-25 07:14:41 -07001281
Aaron Hall, MBA4054b172018-05-20 19:46:42 -04001282class TestIsDataDescriptor(unittest.TestCase):
1283
1284 def test_custom_descriptors(self):
1285 class NonDataDescriptor:
1286 def __get__(self, value, type=None): pass
1287 class DataDescriptor0:
1288 def __set__(self, name, value): pass
1289 class DataDescriptor1:
1290 def __delete__(self, name): pass
1291 class DataDescriptor2:
1292 __set__ = None
1293 self.assertFalse(inspect.isdatadescriptor(NonDataDescriptor()),
1294 'class with only __get__ not a data descriptor')
1295 self.assertTrue(inspect.isdatadescriptor(DataDescriptor0()),
1296 'class with __set__ is a data descriptor')
1297 self.assertTrue(inspect.isdatadescriptor(DataDescriptor1()),
1298 'class with __delete__ is a data descriptor')
1299 self.assertTrue(inspect.isdatadescriptor(DataDescriptor2()),
1300 'class with __set__ = None is a data descriptor')
1301
1302 def test_slot(self):
1303 class Slotted:
1304 __slots__ = 'foo',
1305 self.assertTrue(inspect.isdatadescriptor(Slotted.foo),
1306 'a slot is a data descriptor')
1307
1308 def test_property(self):
1309 class Propertied:
1310 @property
1311 def a_property(self):
1312 pass
1313 self.assertTrue(inspect.isdatadescriptor(Propertied.a_property),
1314 'a property is a data descriptor')
1315
1316 def test_functions(self):
1317 class Test(object):
1318 def instance_method(self): pass
1319 @classmethod
1320 def class_method(cls): pass
1321 @staticmethod
1322 def static_method(): pass
1323 def function():
1324 pass
1325 a_lambda = lambda: None
1326 self.assertFalse(inspect.isdatadescriptor(Test().instance_method),
1327 'a instance method is not a data descriptor')
1328 self.assertFalse(inspect.isdatadescriptor(Test().class_method),
1329 'a class method is not a data descriptor')
1330 self.assertFalse(inspect.isdatadescriptor(Test().static_method),
1331 'a static method is not a data descriptor')
1332 self.assertFalse(inspect.isdatadescriptor(function),
1333 'a function is not a data descriptor')
1334 self.assertFalse(inspect.isdatadescriptor(a_lambda),
1335 'a lambda is not a data descriptor')
1336
Jeremy Hyltonc4bf5ed2003-06-27 18:43:12 +00001337
Nick Coghlan2f92e542012-06-23 19:39:55 +10001338_global_ref = object()
1339class TestGetClosureVars(unittest.TestCase):
1340
1341 def test_name_resolution(self):
1342 # Basic test of the 4 different resolution mechanisms
1343 def f(nonlocal_ref):
1344 def g(local_ref):
1345 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
1346 return g
1347 _arg = object()
1348 nonlocal_vars = {"nonlocal_ref": _arg}
1349 global_vars = {"_global_ref": _global_ref}
1350 builtin_vars = {"print": print}
1351 unbound_names = {"unbound_ref"}
1352 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
1353 builtin_vars, unbound_names)
1354 self.assertEqual(inspect.getclosurevars(f(_arg)), expected)
1355
1356 def test_generator_closure(self):
1357 def f(nonlocal_ref):
1358 def g(local_ref):
1359 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
1360 yield
1361 return g
1362 _arg = object()
1363 nonlocal_vars = {"nonlocal_ref": _arg}
1364 global_vars = {"_global_ref": _global_ref}
1365 builtin_vars = {"print": print}
1366 unbound_names = {"unbound_ref"}
1367 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
1368 builtin_vars, unbound_names)
1369 self.assertEqual(inspect.getclosurevars(f(_arg)), expected)
1370
1371 def test_method_closure(self):
1372 class C:
1373 def f(self, nonlocal_ref):
1374 def g(local_ref):
1375 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
1376 return g
1377 _arg = object()
1378 nonlocal_vars = {"nonlocal_ref": _arg}
1379 global_vars = {"_global_ref": _global_ref}
1380 builtin_vars = {"print": print}
1381 unbound_names = {"unbound_ref"}
1382 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
1383 builtin_vars, unbound_names)
1384 self.assertEqual(inspect.getclosurevars(C().f(_arg)), expected)
1385
1386 def test_nonlocal_vars(self):
1387 # More complex tests of nonlocal resolution
1388 def _nonlocal_vars(f):
1389 return inspect.getclosurevars(f).nonlocals
1390
1391 def make_adder(x):
1392 def add(y):
1393 return x + y
1394 return add
1395
1396 def curry(func, arg1):
1397 return lambda arg2: func(arg1, arg2)
1398
1399 def less_than(a, b):
1400 return a < b
1401
1402 # The infamous Y combinator.
1403 def Y(le):
1404 def g(f):
1405 return le(lambda x: f(f)(x))
1406 Y.g_ref = g
1407 return g(g)
1408
1409 def check_y_combinator(func):
1410 self.assertEqual(_nonlocal_vars(func), {'f': Y.g_ref})
1411
1412 inc = make_adder(1)
1413 add_two = make_adder(2)
1414 greater_than_five = curry(less_than, 5)
1415
1416 self.assertEqual(_nonlocal_vars(inc), {'x': 1})
1417 self.assertEqual(_nonlocal_vars(add_two), {'x': 2})
1418 self.assertEqual(_nonlocal_vars(greater_than_five),
1419 {'arg1': 5, 'func': less_than})
1420 self.assertEqual(_nonlocal_vars((lambda x: lambda y: x + y)(3)),
1421 {'x': 3})
1422 Y(check_y_combinator)
1423
1424 def test_getclosurevars_empty(self):
1425 def foo(): pass
1426 _empty = inspect.ClosureVars({}, {}, {}, set())
1427 self.assertEqual(inspect.getclosurevars(lambda: True), _empty)
1428 self.assertEqual(inspect.getclosurevars(foo), _empty)
1429
1430 def test_getclosurevars_error(self):
1431 class T: pass
1432 self.assertRaises(TypeError, inspect.getclosurevars, 1)
1433 self.assertRaises(TypeError, inspect.getclosurevars, list)
1434 self.assertRaises(TypeError, inspect.getclosurevars, {})
1435
Nick Coghlan6c6e2542012-06-23 20:07:39 +10001436 def _private_globals(self):
1437 code = """def f(): print(path)"""
1438 ns = {}
1439 exec(code, ns)
1440 return ns["f"], ns
1441
1442 def test_builtins_fallback(self):
1443 f, ns = self._private_globals()
1444 ns.pop("__builtins__", None)
1445 expected = inspect.ClosureVars({}, {}, {"print":print}, {"path"})
1446 self.assertEqual(inspect.getclosurevars(f), expected)
1447
1448 def test_builtins_as_dict(self):
1449 f, ns = self._private_globals()
1450 ns["__builtins__"] = {"path":1}
1451 expected = inspect.ClosureVars({}, {}, {"path":1}, {"print"})
1452 self.assertEqual(inspect.getclosurevars(f), expected)
1453
1454 def test_builtins_as_module(self):
1455 f, ns = self._private_globals()
1456 ns["__builtins__"] = os
1457 expected = inspect.ClosureVars({}, {}, {"path":os.path}, {"print"})
1458 self.assertEqual(inspect.getclosurevars(f), expected)
1459
Nick Coghlan2f92e542012-06-23 19:39:55 +10001460
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001461class TestGetcallargsFunctions(unittest.TestCase):
1462
1463 def assertEqualCallArgs(self, func, call_params_string, locs=None):
1464 locs = dict(locs or {}, func=func)
1465 r1 = eval('func(%s)' % call_params_string, None, locs)
Pablo Galindoaee19f52019-05-16 21:08:15 +01001466 r2 = eval('inspect.getcallargs(func, %s)' % call_params_string, None,
1467 locs)
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001468 self.assertEqual(r1, r2)
1469
1470 def assertEqualException(self, func, call_param_string, locs=None):
1471 locs = dict(locs or {}, func=func)
1472 try:
1473 eval('func(%s)' % call_param_string, None, locs)
1474 except Exception as e:
1475 ex1 = e
1476 else:
1477 self.fail('Exception not raised')
1478 try:
Pablo Galindoaee19f52019-05-16 21:08:15 +01001479 eval('inspect.getcallargs(func, %s)' % call_param_string, None,
1480 locs)
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001481 except Exception as e:
1482 ex2 = e
1483 else:
1484 self.fail('Exception not raised')
1485 self.assertIs(type(ex1), type(ex2))
1486 self.assertEqual(str(ex1), str(ex2))
1487 del ex1, ex2
1488
1489 def makeCallable(self, signature):
1490 """Create a function that returns its locals()"""
1491 code = "lambda %s: locals()"
1492 return eval(code % signature)
1493
1494 def test_plain(self):
1495 f = self.makeCallable('a, b=1')
1496 self.assertEqualCallArgs(f, '2')
1497 self.assertEqualCallArgs(f, '2, 3')
1498 self.assertEqualCallArgs(f, 'a=2')
1499 self.assertEqualCallArgs(f, 'b=3, a=2')
1500 self.assertEqualCallArgs(f, '2, b=3')
1501 # expand *iterable / **mapping
1502 self.assertEqualCallArgs(f, '*(2,)')
1503 self.assertEqualCallArgs(f, '*[2]')
1504 self.assertEqualCallArgs(f, '*(2, 3)')
1505 self.assertEqualCallArgs(f, '*[2, 3]')
1506 self.assertEqualCallArgs(f, '**{"a":2}')
1507 self.assertEqualCallArgs(f, 'b=3, **{"a":2}')
1508 self.assertEqualCallArgs(f, '2, **{"b":3}')
1509 self.assertEqualCallArgs(f, '**{"b":3, "a":2}')
1510 # expand UserList / UserDict
1511 self.assertEqualCallArgs(f, '*collections.UserList([2])')
1512 self.assertEqualCallArgs(f, '*collections.UserList([2, 3])')
1513 self.assertEqualCallArgs(f, '**collections.UserDict(a=2)')
1514 self.assertEqualCallArgs(f, '2, **collections.UserDict(b=3)')
1515 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3)')
1516
1517 def test_varargs(self):
1518 f = self.makeCallable('a, b=1, *c')
1519 self.assertEqualCallArgs(f, '2')
1520 self.assertEqualCallArgs(f, '2, 3')
1521 self.assertEqualCallArgs(f, '2, 3, 4')
1522 self.assertEqualCallArgs(f, '*(2,3,4)')
1523 self.assertEqualCallArgs(f, '2, *[3,4]')
1524 self.assertEqualCallArgs(f, '2, 3, *collections.UserList([4])')
1525
1526 def test_varkw(self):
1527 f = self.makeCallable('a, b=1, **c')
1528 self.assertEqualCallArgs(f, 'a=2')
1529 self.assertEqualCallArgs(f, '2, b=3, c=4')
1530 self.assertEqualCallArgs(f, 'b=3, a=2, c=4')
1531 self.assertEqualCallArgs(f, 'c=4, **{"a":2, "b":3}')
1532 self.assertEqualCallArgs(f, '2, c=4, **{"b":3}')
1533 self.assertEqualCallArgs(f, 'b=2, **{"a":3, "c":4}')
1534 self.assertEqualCallArgs(f, '**collections.UserDict(a=2, b=3, c=4)')
1535 self.assertEqualCallArgs(f, '2, c=4, **collections.UserDict(b=3)')
1536 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3, c=4)')
1537
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001538 def test_varkw_only(self):
1539 # issue11256:
1540 f = self.makeCallable('**c')
1541 self.assertEqualCallArgs(f, '')
1542 self.assertEqualCallArgs(f, 'a=1')
1543 self.assertEqualCallArgs(f, 'a=1, b=2')
1544 self.assertEqualCallArgs(f, 'c=3, **{"a": 1, "b": 2}')
1545 self.assertEqualCallArgs(f, '**collections.UserDict(a=1, b=2)')
1546 self.assertEqualCallArgs(f, 'c=3, **collections.UserDict(a=1, b=2)')
1547
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001548 def test_keyword_only(self):
1549 f = self.makeCallable('a=3, *, c, d=2')
1550 self.assertEqualCallArgs(f, 'c=3')
1551 self.assertEqualCallArgs(f, 'c=3, a=3')
1552 self.assertEqualCallArgs(f, 'a=2, c=4')
1553 self.assertEqualCallArgs(f, '4, c=4')
1554 self.assertEqualException(f, '')
1555 self.assertEqualException(f, '3')
1556 self.assertEqualException(f, 'a=3')
1557 self.assertEqualException(f, 'd=4')
1558
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001559 f = self.makeCallable('*, c, d=2')
1560 self.assertEqualCallArgs(f, 'c=3')
1561 self.assertEqualCallArgs(f, 'c=3, d=4')
1562 self.assertEqualCallArgs(f, 'd=4, c=3')
1563
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001564 def test_multiple_features(self):
1565 f = self.makeCallable('a, b=2, *f, **g')
1566 self.assertEqualCallArgs(f, '2, 3, 7')
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')
1570 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9')
1571 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
1572 '[2, 3, (4,[5,6])]), **{"y":9, "z":10}')
1573 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
1574 '(4,[5,6])]), **collections.UserDict('
1575 'y=9, z=10)')
1576
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001577 f = self.makeCallable('a, b=2, *f, x, y=99, **g')
1578 self.assertEqualCallArgs(f, '2, 3, x=8')
1579 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
1580 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9, z=10')
1581 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9, z=10')
1582 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
1583 '[2, 3, (4,[5,6])]), q=0, **{"y":9, "z":10}')
1584 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
1585 '(4,[5,6])]), q=0, **collections.UserDict('
1586 'y=9, z=10)')
1587
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001588 def test_errors(self):
1589 f0 = self.makeCallable('')
1590 f1 = self.makeCallable('a, b')
1591 f2 = self.makeCallable('a, b=1')
1592 # f0 takes no arguments
1593 self.assertEqualException(f0, '1')
1594 self.assertEqualException(f0, 'x=1')
1595 self.assertEqualException(f0, '1,x=1')
1596 # f1 takes exactly 2 arguments
1597 self.assertEqualException(f1, '')
1598 self.assertEqualException(f1, '1')
1599 self.assertEqualException(f1, 'a=2')
1600 self.assertEqualException(f1, 'b=3')
1601 # f2 takes at least 1 argument
1602 self.assertEqualException(f2, '')
1603 self.assertEqualException(f2, 'b=3')
1604 for f in f1, f2:
1605 # f1/f2 takes exactly/at most 2 arguments
1606 self.assertEqualException(f, '2, 3, 4')
1607 self.assertEqualException(f, '1, 2, 3, a=1')
1608 self.assertEqualException(f, '2, 3, 4, c=5')
Georg Brandl178e5ea2012-02-21 00:32:36 +01001609 # XXX: success of this one depends on dict order
1610 ## self.assertEqualException(f, '2, 3, 4, a=1, c=5')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001611 # f got an unexpected keyword argument
1612 self.assertEqualException(f, 'c=2')
1613 self.assertEqualException(f, '2, c=3')
1614 self.assertEqualException(f, '2, 3, c=4')
1615 self.assertEqualException(f, '2, c=4, b=3')
1616 self.assertEqualException(f, '**{u"\u03c0\u03b9": 4}')
1617 # f got multiple values for keyword argument
1618 self.assertEqualException(f, '1, a=2')
1619 self.assertEqualException(f, '1, **{"a":2}')
1620 self.assertEqualException(f, '1, 2, b=3')
1621 # XXX: Python inconsistency
1622 # - for functions and bound methods: unexpected keyword 'c'
1623 # - for unbound methods: multiple values for keyword 'a'
1624 #self.assertEqualException(f, '1, c=3, a=2')
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001625 # issue11256:
1626 f3 = self.makeCallable('**c')
1627 self.assertEqualException(f3, '1, 2')
1628 self.assertEqualException(f3, '1, 2, a=1, b=2')
1629 f4 = self.makeCallable('*, a, b=0')
1630 self.assertEqualException(f3, '1, 2')
1631 self.assertEqualException(f3, '1, 2, a=1, b=2')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001632
Yury Selivanov875df202014-03-27 18:23:03 -04001633 # issue #20816: getcallargs() fails to iterate over non-existent
1634 # kwonlydefaults and raises a wrong TypeError
1635 def f5(*, a): pass
1636 with self.assertRaisesRegex(TypeError,
1637 'missing 1 required keyword-only'):
Pablo Galindoaee19f52019-05-16 21:08:15 +01001638 inspect.getcallargs(f5)
Yury Selivanov875df202014-03-27 18:23:03 -04001639
1640
Yury Selivanovdccfa132014-03-27 18:42:52 -04001641 # issue20817:
1642 def f6(a, b, c):
1643 pass
1644 with self.assertRaisesRegex(TypeError, "'a', 'b' and 'c'"):
Pablo Galindoaee19f52019-05-16 21:08:15 +01001645 inspect.getcallargs(f6)
Yury Selivanovdccfa132014-03-27 18:42:52 -04001646
Dong-hee Naa9cab432018-05-30 00:04:08 +09001647 # bpo-33197
1648 with self.assertRaisesRegex(ValueError,
1649 'variadic keyword parameters cannot'
1650 ' have default values'):
1651 inspect.Parameter("foo", kind=inspect.Parameter.VAR_KEYWORD,
1652 default=42)
1653 with self.assertRaisesRegex(ValueError,
1654 "value 5 is not a valid Parameter.kind"):
1655 inspect.Parameter("bar", kind=5, default=42)
1656
1657 with self.assertRaisesRegex(TypeError,
1658 'name must be a str, not a int'):
1659 inspect.Parameter(123, kind=4)
1660
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001661class TestGetcallargsMethods(TestGetcallargsFunctions):
1662
1663 def setUp(self):
1664 class Foo(object):
1665 pass
1666 self.cls = Foo
1667 self.inst = Foo()
1668
1669 def makeCallable(self, signature):
1670 assert 'self' not in signature
1671 mk = super(TestGetcallargsMethods, self).makeCallable
1672 self.cls.method = mk('self, ' + signature)
1673 return self.inst.method
1674
1675class TestGetcallargsUnboundMethods(TestGetcallargsMethods):
1676
1677 def makeCallable(self, signature):
1678 super(TestGetcallargsUnboundMethods, self).makeCallable(signature)
1679 return self.cls.method
1680
1681 def assertEqualCallArgs(self, func, call_params_string, locs=None):
1682 return super(TestGetcallargsUnboundMethods, self).assertEqualCallArgs(
1683 *self._getAssertEqualParams(func, call_params_string, locs))
1684
1685 def assertEqualException(self, func, call_params_string, locs=None):
1686 return super(TestGetcallargsUnboundMethods, self).assertEqualException(
1687 *self._getAssertEqualParams(func, call_params_string, locs))
1688
1689 def _getAssertEqualParams(self, func, call_params_string, locs=None):
1690 assert 'inst' not in call_params_string
1691 locs = dict(locs or {}, inst=self.inst)
1692 return (func, 'inst,' + call_params_string, locs)
1693
Michael Foord95fc51d2010-11-20 15:07:30 +00001694
1695class TestGetattrStatic(unittest.TestCase):
1696
1697 def test_basic(self):
1698 class Thing(object):
1699 x = object()
1700
1701 thing = Thing()
1702 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1703 self.assertEqual(inspect.getattr_static(thing, 'x', None), Thing.x)
1704 with self.assertRaises(AttributeError):
1705 inspect.getattr_static(thing, 'y')
1706
1707 self.assertEqual(inspect.getattr_static(thing, 'y', 3), 3)
1708
1709 def test_inherited(self):
1710 class Thing(object):
1711 x = object()
1712 class OtherThing(Thing):
1713 pass
1714
1715 something = OtherThing()
1716 self.assertEqual(inspect.getattr_static(something, 'x'), Thing.x)
1717
1718 def test_instance_attr(self):
1719 class Thing(object):
1720 x = 2
1721 def __init__(self, x):
1722 self.x = x
1723 thing = Thing(3)
1724 self.assertEqual(inspect.getattr_static(thing, 'x'), 3)
1725 del thing.x
1726 self.assertEqual(inspect.getattr_static(thing, 'x'), 2)
1727
1728 def test_property(self):
1729 class Thing(object):
1730 @property
1731 def x(self):
1732 raise AttributeError("I'm pretending not to exist")
1733 thing = Thing()
1734 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1735
Ezio Melotti75cbd732011-04-28 00:59:29 +03001736 def test_descriptor_raises_AttributeError(self):
Michael Foord95fc51d2010-11-20 15:07:30 +00001737 class descriptor(object):
1738 def __get__(*_):
1739 raise AttributeError("I'm pretending not to exist")
1740 desc = descriptor()
1741 class Thing(object):
1742 x = desc
1743 thing = Thing()
1744 self.assertEqual(inspect.getattr_static(thing, 'x'), desc)
1745
1746 def test_classAttribute(self):
1747 class Thing(object):
1748 x = object()
1749
1750 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.x)
1751
Ethan Furmane03ea372013-09-25 07:14:41 -07001752 def test_classVirtualAttribute(self):
1753 class Thing(object):
1754 @types.DynamicClassAttribute
1755 def x(self):
1756 return self._x
1757 _x = object()
1758
1759 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.__dict__['x'])
1760
Michael Foord95fc51d2010-11-20 15:07:30 +00001761 def test_inherited_classattribute(self):
1762 class Thing(object):
1763 x = object()
1764 class OtherThing(Thing):
1765 pass
1766
1767 self.assertEqual(inspect.getattr_static(OtherThing, 'x'), Thing.x)
1768
1769 def test_slots(self):
1770 class Thing(object):
1771 y = 'bar'
1772 __slots__ = ['x']
1773 def __init__(self):
1774 self.x = 'foo'
1775 thing = Thing()
1776 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1777 self.assertEqual(inspect.getattr_static(thing, 'y'), 'bar')
1778
1779 del thing.x
1780 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1781
1782 def test_metaclass(self):
1783 class meta(type):
1784 attr = 'foo'
1785 class Thing(object, metaclass=meta):
1786 pass
1787 self.assertEqual(inspect.getattr_static(Thing, 'attr'), 'foo')
1788
1789 class sub(meta):
1790 pass
1791 class OtherThing(object, metaclass=sub):
1792 x = 3
1793 self.assertEqual(inspect.getattr_static(OtherThing, 'attr'), 'foo')
1794
1795 class OtherOtherThing(OtherThing):
1796 pass
1797 # this test is odd, but it was added as it exposed a bug
1798 self.assertEqual(inspect.getattr_static(OtherOtherThing, 'x'), 3)
1799
1800 def test_no_dict_no_slots(self):
1801 self.assertEqual(inspect.getattr_static(1, 'foo', None), None)
1802 self.assertNotEqual(inspect.getattr_static('foo', 'lower'), None)
1803
1804 def test_no_dict_no_slots_instance_member(self):
1805 # returns descriptor
1806 with open(__file__) as handle:
1807 self.assertEqual(inspect.getattr_static(handle, 'name'), type(handle).name)
1808
1809 def test_inherited_slots(self):
1810 # returns descriptor
1811 class Thing(object):
1812 __slots__ = ['x']
1813 def __init__(self):
1814 self.x = 'foo'
1815
1816 class OtherThing(Thing):
1817 pass
1818 # it would be nice if this worked...
1819 # we get the descriptor instead of the instance attribute
1820 self.assertEqual(inspect.getattr_static(OtherThing(), 'x'), Thing.x)
1821
1822 def test_descriptor(self):
1823 class descriptor(object):
1824 def __get__(self, instance, owner):
1825 return 3
1826 class Foo(object):
1827 d = descriptor()
1828
1829 foo = Foo()
1830
1831 # for a non data descriptor we return the instance attribute
1832 foo.__dict__['d'] = 1
1833 self.assertEqual(inspect.getattr_static(foo, 'd'), 1)
1834
Mike53f7a7c2017-12-14 14:04:53 +03001835 # if the descriptor is a data-descriptor we should return the
Michael Foord95fc51d2010-11-20 15:07:30 +00001836 # descriptor
1837 descriptor.__set__ = lambda s, i, v: None
1838 self.assertEqual(inspect.getattr_static(foo, 'd'), Foo.__dict__['d'])
1839
1840
1841 def test_metaclass_with_descriptor(self):
1842 class descriptor(object):
1843 def __get__(self, instance, owner):
1844 return 3
1845 class meta(type):
1846 d = descriptor()
1847 class Thing(object, metaclass=meta):
1848 pass
1849 self.assertEqual(inspect.getattr_static(Thing, 'd'), meta.__dict__['d'])
1850
1851
Michael Foordcc7ebb82010-11-20 16:20:16 +00001852 def test_class_as_property(self):
1853 class Base(object):
1854 foo = 3
1855
1856 class Something(Base):
Michael Foord35184ed2010-11-20 16:58:30 +00001857 executed = False
Michael Foordcc7ebb82010-11-20 16:20:16 +00001858 @property
1859 def __class__(self):
Michael Foord35184ed2010-11-20 16:58:30 +00001860 self.executed = True
Michael Foordcc7ebb82010-11-20 16:20:16 +00001861 return object
1862
Michael Foord35184ed2010-11-20 16:58:30 +00001863 instance = Something()
1864 self.assertEqual(inspect.getattr_static(instance, 'foo'), 3)
1865 self.assertFalse(instance.executed)
Michael Foordcc7ebb82010-11-20 16:20:16 +00001866 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1867
Michael Foorde5162652010-11-20 16:40:44 +00001868 def test_mro_as_property(self):
1869 class Meta(type):
1870 @property
1871 def __mro__(self):
1872 return (object,)
1873
1874 class Base(object):
1875 foo = 3
1876
1877 class Something(Base, metaclass=Meta):
1878 pass
1879
1880 self.assertEqual(inspect.getattr_static(Something(), 'foo'), 3)
1881 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1882
Michael Foorddcebe0f2011-03-15 19:20:44 -04001883 def test_dict_as_property(self):
1884 test = self
1885 test.called = False
1886
1887 class Foo(dict):
1888 a = 3
1889 @property
1890 def __dict__(self):
1891 test.called = True
1892 return {}
1893
1894 foo = Foo()
1895 foo.a = 4
1896 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1897 self.assertFalse(test.called)
1898
1899 def test_custom_object_dict(self):
1900 test = self
1901 test.called = False
1902
1903 class Custom(dict):
1904 def get(self, key, default=None):
1905 test.called = True
1906 super().get(key, default)
1907
1908 class Foo(object):
1909 a = 3
1910 foo = Foo()
1911 foo.__dict__ = Custom()
1912 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1913 self.assertFalse(test.called)
1914
1915 def test_metaclass_dict_as_property(self):
1916 class Meta(type):
1917 @property
1918 def __dict__(self):
1919 self.executed = True
1920
1921 class Thing(metaclass=Meta):
1922 executed = False
1923
1924 def __init__(self):
1925 self.spam = 42
1926
1927 instance = Thing()
1928 self.assertEqual(inspect.getattr_static(instance, "spam"), 42)
1929 self.assertFalse(Thing.executed)
Michael Foorde5162652010-11-20 16:40:44 +00001930
Michael Foorda51623b2011-12-18 22:01:40 +00001931 def test_module(self):
1932 sentinel = object()
1933 self.assertIsNot(inspect.getattr_static(sys, "version", sentinel),
1934 sentinel)
1935
Michael Foord3ba95f82011-12-22 01:13:37 +00001936 def test_metaclass_with_metaclass_with_dict_as_property(self):
1937 class MetaMeta(type):
1938 @property
1939 def __dict__(self):
1940 self.executed = True
1941 return dict(spam=42)
1942
1943 class Meta(type, metaclass=MetaMeta):
1944 executed = False
1945
1946 class Thing(metaclass=Meta):
1947 pass
1948
1949 with self.assertRaises(AttributeError):
1950 inspect.getattr_static(Thing, "spam")
1951 self.assertFalse(Thing.executed)
1952
Nick Coghlane0f04652010-11-21 03:44:04 +00001953class TestGetGeneratorState(unittest.TestCase):
1954
1955 def setUp(self):
1956 def number_generator():
1957 for number in range(5):
1958 yield number
1959 self.generator = number_generator()
1960
1961 def _generatorstate(self):
1962 return inspect.getgeneratorstate(self.generator)
1963
1964 def test_created(self):
1965 self.assertEqual(self._generatorstate(), inspect.GEN_CREATED)
1966
1967 def test_suspended(self):
1968 next(self.generator)
1969 self.assertEqual(self._generatorstate(), inspect.GEN_SUSPENDED)
1970
1971 def test_closed_after_exhaustion(self):
1972 for i in self.generator:
1973 pass
1974 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1975
1976 def test_closed_after_immediate_exception(self):
1977 with self.assertRaises(RuntimeError):
1978 self.generator.throw(RuntimeError)
1979 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1980
1981 def test_running(self):
1982 # As mentioned on issue #10220, checking for the RUNNING state only
1983 # makes sense inside the generator itself.
1984 # The following generator checks for this by using the closure's
1985 # reference to self and the generator state checking helper method
1986 def running_check_generator():
1987 for number in range(5):
1988 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1989 yield number
1990 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1991 self.generator = running_check_generator()
1992 # Running up to the first yield
1993 next(self.generator)
1994 # Running after the first yield
1995 next(self.generator)
1996
Nick Coghlan7921b9f2010-11-30 06:36:04 +00001997 def test_easy_debugging(self):
1998 # repr() and str() of a generator state should contain the state name
1999 names = 'GEN_CREATED GEN_RUNNING GEN_SUSPENDED GEN_CLOSED'.split()
2000 for name in names:
2001 state = getattr(inspect, name)
2002 self.assertIn(name, repr(state))
2003 self.assertIn(name, str(state))
2004
Nick Coghlan04e2e3f2012-06-23 19:52:05 +10002005 def test_getgeneratorlocals(self):
2006 def each(lst, a=None):
2007 b=(1, 2, 3)
2008 for v in lst:
2009 if v == 3:
2010 c = 12
2011 yield v
2012
2013 numbers = each([1, 2, 3])
2014 self.assertEqual(inspect.getgeneratorlocals(numbers),
2015 {'a': None, 'lst': [1, 2, 3]})
2016 next(numbers)
2017 self.assertEqual(inspect.getgeneratorlocals(numbers),
2018 {'a': None, 'lst': [1, 2, 3], 'v': 1,
2019 'b': (1, 2, 3)})
2020 next(numbers)
2021 self.assertEqual(inspect.getgeneratorlocals(numbers),
2022 {'a': None, 'lst': [1, 2, 3], 'v': 2,
2023 'b': (1, 2, 3)})
2024 next(numbers)
2025 self.assertEqual(inspect.getgeneratorlocals(numbers),
2026 {'a': None, 'lst': [1, 2, 3], 'v': 3,
2027 'b': (1, 2, 3), 'c': 12})
2028 try:
2029 next(numbers)
2030 except StopIteration:
2031 pass
2032 self.assertEqual(inspect.getgeneratorlocals(numbers), {})
2033
2034 def test_getgeneratorlocals_empty(self):
2035 def yield_one():
2036 yield 1
2037 one = yield_one()
2038 self.assertEqual(inspect.getgeneratorlocals(one), {})
2039 try:
2040 next(one)
2041 except StopIteration:
2042 pass
2043 self.assertEqual(inspect.getgeneratorlocals(one), {})
2044
2045 def test_getgeneratorlocals_error(self):
2046 self.assertRaises(TypeError, inspect.getgeneratorlocals, 1)
2047 self.assertRaises(TypeError, inspect.getgeneratorlocals, lambda x: True)
2048 self.assertRaises(TypeError, inspect.getgeneratorlocals, set)
2049 self.assertRaises(TypeError, inspect.getgeneratorlocals, (2,3))
2050
Nick Coghlane0f04652010-11-21 03:44:04 +00002051
Yury Selivanov5376ba92015-06-22 12:19:30 -04002052class TestGetCoroutineState(unittest.TestCase):
2053
2054 def setUp(self):
2055 @types.coroutine
2056 def number_coroutine():
2057 for number in range(5):
2058 yield number
2059 async def coroutine():
2060 await number_coroutine()
2061 self.coroutine = coroutine()
2062
2063 def tearDown(self):
2064 self.coroutine.close()
2065
2066 def _coroutinestate(self):
2067 return inspect.getcoroutinestate(self.coroutine)
2068
2069 def test_created(self):
2070 self.assertEqual(self._coroutinestate(), inspect.CORO_CREATED)
2071
2072 def test_suspended(self):
2073 self.coroutine.send(None)
2074 self.assertEqual(self._coroutinestate(), inspect.CORO_SUSPENDED)
2075
2076 def test_closed_after_exhaustion(self):
2077 while True:
2078 try:
2079 self.coroutine.send(None)
2080 except StopIteration:
2081 break
2082
2083 self.assertEqual(self._coroutinestate(), inspect.CORO_CLOSED)
2084
2085 def test_closed_after_immediate_exception(self):
2086 with self.assertRaises(RuntimeError):
2087 self.coroutine.throw(RuntimeError)
2088 self.assertEqual(self._coroutinestate(), inspect.CORO_CLOSED)
2089
2090 def test_easy_debugging(self):
2091 # repr() and str() of a coroutine state should contain the state name
2092 names = 'CORO_CREATED CORO_RUNNING CORO_SUSPENDED CORO_CLOSED'.split()
2093 for name in names:
2094 state = getattr(inspect, name)
2095 self.assertIn(name, repr(state))
2096 self.assertIn(name, str(state))
2097
2098 def test_getcoroutinelocals(self):
2099 @types.coroutine
2100 def gencoro():
2101 yield
2102
2103 gencoro = gencoro()
2104 async def func(a=None):
2105 b = 'spam'
2106 await gencoro
2107
2108 coro = func()
2109 self.assertEqual(inspect.getcoroutinelocals(coro),
2110 {'a': None, 'gencoro': gencoro})
2111 coro.send(None)
2112 self.assertEqual(inspect.getcoroutinelocals(coro),
2113 {'a': None, 'gencoro': gencoro, 'b': 'spam'})
2114
2115
Yury Selivanova5d63dd2014-03-27 11:31:43 -04002116class MySignature(inspect.Signature):
2117 # Top-level to make it picklable;
2118 # used in test_signature_object_pickle
2119 pass
2120
2121class MyParameter(inspect.Parameter):
2122 # Top-level to make it picklable;
2123 # used in test_signature_object_pickle
2124 pass
2125
Nick Coghlanf9e227e2014-08-17 14:01:19 +10002126
Yury Selivanova5d63dd2014-03-27 11:31:43 -04002127
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002128class TestSignatureObject(unittest.TestCase):
2129 @staticmethod
Yury Selivanovbcd4fc12015-05-20 14:30:08 -04002130 def signature(func, **kw):
2131 sig = inspect.signature(func, **kw)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002132 return (tuple((param.name,
2133 (... if param.default is param.empty else param.default),
2134 (... if param.annotation is param.empty
2135 else param.annotation),
2136 str(param.kind).lower())
2137 for param in sig.parameters.values()),
2138 (... if sig.return_annotation is sig.empty
2139 else sig.return_annotation))
2140
2141 def test_signature_object(self):
2142 S = inspect.Signature
2143 P = inspect.Parameter
2144
2145 self.assertEqual(str(S()), '()')
Jens Reidel611836a2020-03-18 03:22:46 +01002146 self.assertEqual(repr(S().parameters), 'mappingproxy(OrderedDict())')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002147
Yury Selivanov07a9e452014-01-29 10:58:16 -05002148 def test(po, pk, pod=42, pkd=100, *args, ko, **kwargs):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002149 pass
2150 sig = inspect.signature(test)
2151 po = sig.parameters['po'].replace(kind=P.POSITIONAL_ONLY)
Yury Selivanov07a9e452014-01-29 10:58:16 -05002152 pod = sig.parameters['pod'].replace(kind=P.POSITIONAL_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002153 pk = sig.parameters['pk']
Yury Selivanov07a9e452014-01-29 10:58:16 -05002154 pkd = sig.parameters['pkd']
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002155 args = sig.parameters['args']
2156 ko = sig.parameters['ko']
2157 kwargs = sig.parameters['kwargs']
2158
2159 S((po, pk, args, ko, kwargs))
2160
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002161 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002162 S((pk, po, args, ko, kwargs))
2163
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002164 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002165 S((po, args, pk, ko, kwargs))
2166
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002167 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002168 S((args, po, pk, ko, kwargs))
2169
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002170 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002171 S((po, pk, args, kwargs, ko))
2172
2173 kwargs2 = kwargs.replace(name='args')
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002174 with self.assertRaisesRegex(ValueError, 'duplicate parameter name'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002175 S((po, pk, args, kwargs2, ko))
2176
Yury Selivanov07a9e452014-01-29 10:58:16 -05002177 with self.assertRaisesRegex(ValueError, 'follows default argument'):
2178 S((pod, po))
2179
2180 with self.assertRaisesRegex(ValueError, 'follows default argument'):
2181 S((po, pkd, pk))
2182
2183 with self.assertRaisesRegex(ValueError, 'follows default argument'):
2184 S((pkd, pk))
2185
Yury Selivanov374375d2014-03-27 12:41:53 -04002186 self.assertTrue(repr(sig).startswith('<Signature'))
Yury Selivanov0cd2bf42015-05-15 12:55:20 -04002187 self.assertTrue('(po, pk' in repr(sig))
Yury Selivanov374375d2014-03-27 12:41:53 -04002188
Yury Selivanova5d63dd2014-03-27 11:31:43 -04002189 def test_signature_object_pickle(self):
2190 def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
2191 foo_partial = functools.partial(foo, a=1)
2192
2193 sig = inspect.signature(foo_partial)
Yury Selivanova5d63dd2014-03-27 11:31:43 -04002194
2195 for ver in range(pickle.HIGHEST_PROTOCOL + 1):
2196 with self.subTest(pickle_ver=ver, subclass=False):
2197 sig_pickled = pickle.loads(pickle.dumps(sig, ver))
2198 self.assertEqual(sig, sig_pickled)
Yury Selivanova5d63dd2014-03-27 11:31:43 -04002199
2200 # Test that basic sub-classing works
2201 sig = inspect.signature(foo)
2202 myparam = MyParameter(name='z', kind=inspect.Parameter.POSITIONAL_ONLY)
2203 myparams = collections.OrderedDict(sig.parameters, a=myparam)
2204 mysig = MySignature().replace(parameters=myparams.values(),
2205 return_annotation=sig.return_annotation)
2206 self.assertTrue(isinstance(mysig, MySignature))
2207 self.assertTrue(isinstance(mysig.parameters['z'], MyParameter))
2208
2209 for ver in range(pickle.HIGHEST_PROTOCOL + 1):
2210 with self.subTest(pickle_ver=ver, subclass=True):
2211 sig_pickled = pickle.loads(pickle.dumps(mysig, ver))
2212 self.assertEqual(mysig, sig_pickled)
2213 self.assertTrue(isinstance(sig_pickled, MySignature))
2214 self.assertTrue(isinstance(sig_pickled.parameters['z'],
2215 MyParameter))
2216
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002217 def test_signature_immutability(self):
2218 def test(a):
2219 pass
2220 sig = inspect.signature(test)
2221
2222 with self.assertRaises(AttributeError):
2223 sig.foo = 'bar'
2224
2225 with self.assertRaises(TypeError):
2226 sig.parameters['a'] = None
2227
2228 def test_signature_on_noarg(self):
2229 def test():
2230 pass
2231 self.assertEqual(self.signature(test), ((), ...))
2232
2233 def test_signature_on_wargs(self):
2234 def test(a, b:'foo') -> 123:
2235 pass
2236 self.assertEqual(self.signature(test),
2237 ((('a', ..., ..., "positional_or_keyword"),
2238 ('b', ..., 'foo', "positional_or_keyword")),
2239 123))
2240
2241 def test_signature_on_wkwonly(self):
2242 def test(*, a:float, b:str) -> int:
2243 pass
2244 self.assertEqual(self.signature(test),
2245 ((('a', ..., float, "keyword_only"),
2246 ('b', ..., str, "keyword_only")),
2247 int))
2248
2249 def test_signature_on_complex_args(self):
2250 def test(a, b:'foo'=10, *args:'bar', spam:'baz', ham=123, **kwargs:int):
2251 pass
2252 self.assertEqual(self.signature(test),
2253 ((('a', ..., ..., "positional_or_keyword"),
2254 ('b', 10, 'foo', "positional_or_keyword"),
2255 ('args', ..., 'bar', "var_positional"),
2256 ('spam', ..., 'baz', "keyword_only"),
2257 ('ham', 123, ..., "keyword_only"),
2258 ('kwargs', ..., int, "var_keyword")),
2259 ...))
2260
Dong-hee Na378d7062017-05-18 04:00:51 +09002261 def test_signature_without_self(self):
2262 def test_args_only(*args): # NOQA
2263 pass
2264
2265 def test_args_kwargs_only(*args, **kwargs): # NOQA
2266 pass
2267
2268 class A:
2269 @classmethod
2270 def test_classmethod(*args): # NOQA
2271 pass
2272
2273 @staticmethod
2274 def test_staticmethod(*args): # NOQA
2275 pass
2276
2277 f1 = functools.partialmethod((test_classmethod), 1)
2278 f2 = functools.partialmethod((test_args_only), 1)
2279 f3 = functools.partialmethod((test_staticmethod), 1)
2280 f4 = functools.partialmethod((test_args_kwargs_only),1)
2281
2282 self.assertEqual(self.signature(test_args_only),
2283 ((('args', ..., ..., 'var_positional'),), ...))
2284 self.assertEqual(self.signature(test_args_kwargs_only),
2285 ((('args', ..., ..., 'var_positional'),
2286 ('kwargs', ..., ..., 'var_keyword')), ...))
2287 self.assertEqual(self.signature(A.f1),
2288 ((('args', ..., ..., 'var_positional'),), ...))
2289 self.assertEqual(self.signature(A.f2),
2290 ((('args', ..., ..., 'var_positional'),), ...))
2291 self.assertEqual(self.signature(A.f3),
2292 ((('args', ..., ..., 'var_positional'),), ...))
Serhiy Storchaka13ad3b72017-09-14 09:38:36 +03002293 self.assertEqual(self.signature(A.f4),
Dong-hee Na378d7062017-05-18 04:00:51 +09002294 ((('args', ..., ..., 'var_positional'),
2295 ('kwargs', ..., ..., 'var_keyword')), ...))
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002296 @cpython_only
Larry Hastingsfcafe432013-11-23 17:35:48 -08002297 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2298 "Signature information for builtins requires docstrings")
2299 def test_signature_on_builtins(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002300 import _testcapi
Larry Hastings16c51912014-01-07 11:53:01 -08002301
Larry Hastings5c661892014-01-24 06:17:25 -08002302 def test_unbound_method(o):
2303 """Use this to test unbound methods (things that should have a self)"""
2304 signature = inspect.signature(o)
2305 self.assertTrue(isinstance(signature, inspect.Signature))
2306 self.assertEqual(list(signature.parameters.values())[0].name, 'self')
2307 return signature
2308
2309 def test_callable(o):
2310 """Use this to test bound methods or normal callables (things that don't expect self)"""
2311 signature = inspect.signature(o)
2312 self.assertTrue(isinstance(signature, inspect.Signature))
2313 if signature.parameters:
2314 self.assertNotEqual(list(signature.parameters.values())[0].name, 'self')
2315 return signature
2316
2317 signature = test_callable(_testcapi.docstring_with_signature_with_defaults)
Larry Hastings16c51912014-01-07 11:53:01 -08002318 def p(name): return signature.parameters[name].default
2319 self.assertEqual(p('s'), 'avocado')
Larry Hastings2a727912014-01-16 11:32:01 -08002320 self.assertEqual(p('b'), b'bytes')
Larry Hastings16c51912014-01-07 11:53:01 -08002321 self.assertEqual(p('d'), 3.14)
2322 self.assertEqual(p('i'), 35)
Larry Hastings16c51912014-01-07 11:53:01 -08002323 self.assertEqual(p('n'), None)
2324 self.assertEqual(p('t'), True)
2325 self.assertEqual(p('f'), False)
Larry Hastings2a727912014-01-16 11:32:01 -08002326 self.assertEqual(p('local'), 3)
2327 self.assertEqual(p('sys'), sys.maxsize)
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +02002328 self.assertNotIn('exp', signature.parameters)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002329
Larry Hastings5c661892014-01-24 06:17:25 -08002330 test_callable(object)
2331
2332 # normal method
2333 # (PyMethodDescr_Type, "method_descriptor")
2334 test_unbound_method(_pickle.Pickler.dump)
2335 d = _pickle.Pickler(io.StringIO())
2336 test_callable(d.dump)
2337
2338 # static method
Serhiy Storchaka279f4462019-09-14 12:24:05 +03002339 test_callable(bytes.maketrans)
2340 test_callable(b'abc'.maketrans)
Larry Hastings5c661892014-01-24 06:17:25 -08002341
2342 # class method
2343 test_callable(dict.fromkeys)
2344 test_callable({}.fromkeys)
2345
2346 # wrapper around slot (PyWrapperDescr_Type, "wrapper_descriptor")
2347 test_unbound_method(type.__call__)
2348 test_unbound_method(int.__add__)
2349 test_callable((3).__add__)
2350
2351 # _PyMethodWrapper_Type
2352 # support for 'method-wrapper'
2353 test_callable(min.__call__)
2354
Larry Hastings2623c8c2014-02-08 22:15:29 -08002355 # This doesn't work now.
2356 # (We don't have a valid signature for "type" in 3.4)
2357 with self.assertRaisesRegex(ValueError, "no signature found"):
2358 class ThisWorksNow:
2359 __call__ = type
2360 test_callable(ThisWorksNow())
Larry Hastings5c661892014-01-24 06:17:25 -08002361
Yury Selivanov056e2652014-03-02 12:25:27 -05002362 # Regression test for issue #20786
2363 test_unbound_method(dict.__delitem__)
2364 test_unbound_method(property.__delete__)
2365
Zachary Ware8ef887c2015-04-13 18:22:35 -05002366 # Regression test for issue #20586
2367 test_callable(_testcapi.docstring_with_signature_but_no_doc)
2368
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002369 @cpython_only
Yury Selivanov76c6c592014-01-29 10:52:57 -05002370 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2371 "Signature information for builtins requires docstrings")
2372 def test_signature_on_decorated_builtins(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002373 import _testcapi
Yury Selivanov76c6c592014-01-29 10:52:57 -05002374 func = _testcapi.docstring_with_signature_with_defaults
2375
2376 def decorator(func):
2377 @functools.wraps(func)
2378 def wrapper(*args, **kwargs) -> int:
2379 return func(*args, **kwargs)
2380 return wrapper
2381
2382 decorated_func = decorator(func)
2383
2384 self.assertEqual(inspect.signature(func),
2385 inspect.signature(decorated_func))
Larry Hastings5c661892014-01-24 06:17:25 -08002386
Yury Selivanovbcd4fc12015-05-20 14:30:08 -04002387 def wrapper_like(*args, **kwargs) -> int: pass
2388 self.assertEqual(inspect.signature(decorated_func,
2389 follow_wrapped=False),
2390 inspect.signature(wrapper_like))
2391
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002392 @cpython_only
Larry Hastings5c661892014-01-24 06:17:25 -08002393 def test_signature_on_builtins_no_signature(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002394 import _testcapi
Yury Selivanovbf304fc2015-05-30 17:08:36 -04002395 with self.assertRaisesRegex(ValueError,
2396 'no signature found for builtin'):
Larry Hastings5c661892014-01-24 06:17:25 -08002397 inspect.signature(_testcapi.docstring_no_signature)
2398
Yury Selivanovbf304fc2015-05-30 17:08:36 -04002399 with self.assertRaisesRegex(ValueError,
2400 'no signature found for builtin'):
2401 inspect.signature(str)
2402
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002403 def test_signature_on_non_function(self):
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002404 with self.assertRaisesRegex(TypeError, 'is not a callable object'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002405 inspect.signature(42)
2406
Yury Selivanov63da7c72014-01-31 14:48:37 -05002407 def test_signature_from_functionlike_object(self):
2408 def func(a,b, *args, kwonly=True, kwonlyreq, **kwargs):
2409 pass
2410
2411 class funclike:
2412 # Has to be callable, and have correct
2413 # __code__, __annotations__, __defaults__, __name__,
2414 # and __kwdefaults__ attributes
2415
2416 def __init__(self, func):
2417 self.__name__ = func.__name__
2418 self.__code__ = func.__code__
2419 self.__annotations__ = func.__annotations__
2420 self.__defaults__ = func.__defaults__
2421 self.__kwdefaults__ = func.__kwdefaults__
2422 self.func = func
2423
2424 def __call__(self, *args, **kwargs):
2425 return self.func(*args, **kwargs)
2426
Yury Selivanov57c74fc2015-05-20 23:07:02 -04002427 sig_func = inspect.Signature.from_callable(func)
Yury Selivanov63da7c72014-01-31 14:48:37 -05002428
Yury Selivanov57c74fc2015-05-20 23:07:02 -04002429 sig_funclike = inspect.Signature.from_callable(funclike(func))
Yury Selivanov63da7c72014-01-31 14:48:37 -05002430 self.assertEqual(sig_funclike, sig_func)
2431
2432 sig_funclike = inspect.signature(funclike(func))
2433 self.assertEqual(sig_funclike, sig_func)
2434
2435 # If object is not a duck type of function, then
2436 # signature will try to get a signature for its '__call__'
2437 # method
2438 fl = funclike(func)
2439 del fl.__defaults__
2440 self.assertEqual(self.signature(fl),
2441 ((('args', ..., ..., "var_positional"),
2442 ('kwargs', ..., ..., "var_keyword")),
2443 ...))
2444
Yury Selivanova773de02014-02-21 18:30:53 -05002445 # Test with cython-like builtins:
2446 _orig_isdesc = inspect.ismethoddescriptor
2447 def _isdesc(obj):
2448 if hasattr(obj, '_builtinmock'):
2449 return True
2450 return _orig_isdesc(obj)
2451
2452 with unittest.mock.patch('inspect.ismethoddescriptor', _isdesc):
2453 builtin_func = funclike(func)
2454 # Make sure that our mock setup is working
2455 self.assertFalse(inspect.ismethoddescriptor(builtin_func))
2456 builtin_func._builtinmock = True
2457 self.assertTrue(inspect.ismethoddescriptor(builtin_func))
2458 self.assertEqual(inspect.signature(builtin_func), sig_func)
2459
Yury Selivanov63da7c72014-01-31 14:48:37 -05002460 def test_signature_functionlike_class(self):
2461 # We only want to duck type function-like objects,
2462 # not classes.
2463
2464 def func(a,b, *args, kwonly=True, kwonlyreq, **kwargs):
2465 pass
2466
2467 class funclike:
2468 def __init__(self, marker):
2469 pass
2470
2471 __name__ = func.__name__
2472 __code__ = func.__code__
2473 __annotations__ = func.__annotations__
2474 __defaults__ = func.__defaults__
2475 __kwdefaults__ = func.__kwdefaults__
2476
Yury Selivanov63da7c72014-01-31 14:48:37 -05002477 self.assertEqual(str(inspect.signature(funclike)), '(marker)')
2478
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002479 def test_signature_on_method(self):
2480 class Test:
Yury Selivanov62560fb2014-01-28 12:26:24 -05002481 def __init__(*args):
2482 pass
2483 def m1(self, arg1, arg2=1) -> int:
2484 pass
2485 def m2(*args):
2486 pass
2487 def __call__(*, a):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002488 pass
2489
Yury Selivanov62560fb2014-01-28 12:26:24 -05002490 self.assertEqual(self.signature(Test().m1),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002491 ((('arg1', ..., ..., "positional_or_keyword"),
2492 ('arg2', 1, ..., "positional_or_keyword")),
2493 int))
2494
Yury Selivanov62560fb2014-01-28 12:26:24 -05002495 self.assertEqual(self.signature(Test().m2),
2496 ((('args', ..., ..., "var_positional"),),
2497 ...))
2498
2499 self.assertEqual(self.signature(Test),
2500 ((('args', ..., ..., "var_positional"),),
2501 ...))
2502
2503 with self.assertRaisesRegex(ValueError, 'invalid method signature'):
2504 self.signature(Test())
2505
Yury Selivanov46c759d2015-05-27 21:56:53 -04002506 def test_signature_wrapped_bound_method(self):
2507 # Issue 24298
2508 class Test:
2509 def m1(self, arg1, arg2=1) -> int:
2510 pass
2511 @functools.wraps(Test().m1)
2512 def m1d(*args, **kwargs):
2513 pass
2514 self.assertEqual(self.signature(m1d),
2515 ((('arg1', ..., ..., "positional_or_keyword"),
2516 ('arg2', 1, ..., "positional_or_keyword")),
2517 int))
2518
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002519 def test_signature_on_classmethod(self):
2520 class Test:
2521 @classmethod
2522 def foo(cls, arg1, *, arg2=1):
2523 pass
2524
2525 meth = Test().foo
2526 self.assertEqual(self.signature(meth),
2527 ((('arg1', ..., ..., "positional_or_keyword"),
2528 ('arg2', 1, ..., "keyword_only")),
2529 ...))
2530
2531 meth = Test.foo
2532 self.assertEqual(self.signature(meth),
2533 ((('arg1', ..., ..., "positional_or_keyword"),
2534 ('arg2', 1, ..., "keyword_only")),
2535 ...))
2536
2537 def test_signature_on_staticmethod(self):
2538 class Test:
2539 @staticmethod
2540 def foo(cls, *, arg):
2541 pass
2542
2543 meth = Test().foo
2544 self.assertEqual(self.signature(meth),
2545 ((('cls', ..., ..., "positional_or_keyword"),
2546 ('arg', ..., ..., "keyword_only")),
2547 ...))
2548
2549 meth = Test.foo
2550 self.assertEqual(self.signature(meth),
2551 ((('cls', ..., ..., "positional_or_keyword"),
2552 ('arg', ..., ..., "keyword_only")),
2553 ...))
2554
2555 def test_signature_on_partial(self):
2556 from functools import partial
2557
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002558 Parameter = inspect.Parameter
2559
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002560 def test():
2561 pass
2562
2563 self.assertEqual(self.signature(partial(test)), ((), ...))
2564
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002565 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002566 inspect.signature(partial(test, 1))
2567
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002568 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002569 inspect.signature(partial(test, a=1))
2570
2571 def test(a, b, *, c, d):
2572 pass
2573
2574 self.assertEqual(self.signature(partial(test)),
2575 ((('a', ..., ..., "positional_or_keyword"),
2576 ('b', ..., ..., "positional_or_keyword"),
2577 ('c', ..., ..., "keyword_only"),
2578 ('d', ..., ..., "keyword_only")),
2579 ...))
2580
2581 self.assertEqual(self.signature(partial(test, 1)),
2582 ((('b', ..., ..., "positional_or_keyword"),
2583 ('c', ..., ..., "keyword_only"),
2584 ('d', ..., ..., "keyword_only")),
2585 ...))
2586
2587 self.assertEqual(self.signature(partial(test, 1, c=2)),
2588 ((('b', ..., ..., "positional_or_keyword"),
2589 ('c', 2, ..., "keyword_only"),
2590 ('d', ..., ..., "keyword_only")),
2591 ...))
2592
2593 self.assertEqual(self.signature(partial(test, b=1, c=2)),
2594 ((('a', ..., ..., "positional_or_keyword"),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002595 ('b', 1, ..., "keyword_only"),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002596 ('c', 2, ..., "keyword_only"),
2597 ('d', ..., ..., "keyword_only")),
2598 ...))
2599
2600 self.assertEqual(self.signature(partial(test, 0, b=1, c=2)),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002601 ((('b', 1, ..., "keyword_only"),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002602 ('c', 2, ..., "keyword_only"),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002603 ('d', ..., ..., "keyword_only")),
2604 ...))
2605
2606 self.assertEqual(self.signature(partial(test, a=1)),
2607 ((('a', 1, ..., "keyword_only"),
2608 ('b', ..., ..., "keyword_only"),
2609 ('c', ..., ..., "keyword_only"),
2610 ('d', ..., ..., "keyword_only")),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002611 ...))
2612
2613 def test(a, *args, b, **kwargs):
2614 pass
2615
2616 self.assertEqual(self.signature(partial(test, 1)),
2617 ((('args', ..., ..., "var_positional"),
2618 ('b', ..., ..., "keyword_only"),
2619 ('kwargs', ..., ..., "var_keyword")),
2620 ...))
2621
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002622 self.assertEqual(self.signature(partial(test, a=1)),
2623 ((('a', 1, ..., "keyword_only"),
2624 ('b', ..., ..., "keyword_only"),
2625 ('kwargs', ..., ..., "var_keyword")),
2626 ...))
2627
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002628 self.assertEqual(self.signature(partial(test, 1, 2, 3)),
2629 ((('args', ..., ..., "var_positional"),
2630 ('b', ..., ..., "keyword_only"),
2631 ('kwargs', ..., ..., "var_keyword")),
2632 ...))
2633
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002634 self.assertEqual(self.signature(partial(test, 1, 2, 3, test=True)),
2635 ((('args', ..., ..., "var_positional"),
2636 ('b', ..., ..., "keyword_only"),
2637 ('kwargs', ..., ..., "var_keyword")),
2638 ...))
2639
2640 self.assertEqual(self.signature(partial(test, 1, 2, 3, test=1, b=0)),
2641 ((('args', ..., ..., "var_positional"),
2642 ('b', 0, ..., "keyword_only"),
2643 ('kwargs', ..., ..., "var_keyword")),
2644 ...))
2645
2646 self.assertEqual(self.signature(partial(test, b=0)),
2647 ((('a', ..., ..., "positional_or_keyword"),
2648 ('args', ..., ..., "var_positional"),
2649 ('b', 0, ..., "keyword_only"),
2650 ('kwargs', ..., ..., "var_keyword")),
2651 ...))
2652
2653 self.assertEqual(self.signature(partial(test, b=0, test=1)),
2654 ((('a', ..., ..., "positional_or_keyword"),
2655 ('args', ..., ..., "var_positional"),
2656 ('b', 0, ..., "keyword_only"),
2657 ('kwargs', ..., ..., "var_keyword")),
2658 ...))
2659
2660 def test(a, b, c:int) -> 42:
2661 pass
2662
2663 sig = test.__signature__ = inspect.signature(test)
2664
2665 self.assertEqual(self.signature(partial(partial(test, 1))),
2666 ((('b', ..., ..., "positional_or_keyword"),
2667 ('c', ..., int, "positional_or_keyword")),
2668 42))
2669
2670 self.assertEqual(self.signature(partial(partial(test, 1), 2)),
2671 ((('c', ..., int, "positional_or_keyword"),),
2672 42))
2673
2674 psig = inspect.signature(partial(partial(test, 1), 2))
2675
2676 def foo(a):
2677 return a
2678 _foo = partial(partial(foo, a=10), a=20)
2679 self.assertEqual(self.signature(_foo),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002680 ((('a', 20, ..., "keyword_only"),),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002681 ...))
2682 # check that we don't have any side-effects in signature(),
2683 # and the partial object is still functioning
2684 self.assertEqual(_foo(), 20)
2685
2686 def foo(a, b, c):
2687 return a, b, c
2688 _foo = partial(partial(foo, 1, b=20), b=30)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002689
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002690 self.assertEqual(self.signature(_foo),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002691 ((('b', 30, ..., "keyword_only"),
2692 ('c', ..., ..., "keyword_only")),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002693 ...))
2694 self.assertEqual(_foo(c=10), (1, 30, 10))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002695
2696 def foo(a, b, c, *, d):
2697 return a, b, c, d
2698 _foo = partial(partial(foo, d=20, c=20), b=10, d=30)
2699 self.assertEqual(self.signature(_foo),
2700 ((('a', ..., ..., "positional_or_keyword"),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002701 ('b', 10, ..., "keyword_only"),
2702 ('c', 20, ..., "keyword_only"),
2703 ('d', 30, ..., "keyword_only"),
2704 ),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002705 ...))
2706 ba = inspect.signature(_foo).bind(a=200, b=11)
2707 self.assertEqual(_foo(*ba.args, **ba.kwargs), (200, 11, 20, 30))
2708
2709 def foo(a=1, b=2, c=3):
2710 return a, b, c
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002711 _foo = partial(foo, c=13) # (a=1, b=2, *, c=13)
2712
2713 ba = inspect.signature(_foo).bind(a=11)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002714 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 2, 13))
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002715
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002716 ba = inspect.signature(_foo).bind(11, 12)
2717 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002718
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002719 ba = inspect.signature(_foo).bind(11, b=12)
2720 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002721
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002722 ba = inspect.signature(_foo).bind(b=12)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002723 self.assertEqual(_foo(*ba.args, **ba.kwargs), (1, 12, 13))
2724
2725 _foo = partial(_foo, b=10, c=20)
2726 ba = inspect.signature(_foo).bind(12)
2727 self.assertEqual(_foo(*ba.args, **ba.kwargs), (12, 10, 20))
2728
2729
2730 def foo(a, b, c, d, **kwargs):
2731 pass
2732 sig = inspect.signature(foo)
2733 params = sig.parameters.copy()
2734 params['a'] = params['a'].replace(kind=Parameter.POSITIONAL_ONLY)
2735 params['b'] = params['b'].replace(kind=Parameter.POSITIONAL_ONLY)
2736 foo.__signature__ = inspect.Signature(params.values())
2737 sig = inspect.signature(foo)
2738 self.assertEqual(str(sig), '(a, b, /, c, d, **kwargs)')
2739
2740 self.assertEqual(self.signature(partial(foo, 1)),
2741 ((('b', ..., ..., 'positional_only'),
2742 ('c', ..., ..., 'positional_or_keyword'),
2743 ('d', ..., ..., 'positional_or_keyword'),
2744 ('kwargs', ..., ..., 'var_keyword')),
2745 ...))
2746
2747 self.assertEqual(self.signature(partial(foo, 1, 2)),
2748 ((('c', ..., ..., 'positional_or_keyword'),
2749 ('d', ..., ..., 'positional_or_keyword'),
2750 ('kwargs', ..., ..., 'var_keyword')),
2751 ...))
2752
2753 self.assertEqual(self.signature(partial(foo, 1, 2, 3)),
2754 ((('d', ..., ..., 'positional_or_keyword'),
2755 ('kwargs', ..., ..., 'var_keyword')),
2756 ...))
2757
2758 self.assertEqual(self.signature(partial(foo, 1, 2, c=3)),
2759 ((('c', 3, ..., 'keyword_only'),
2760 ('d', ..., ..., 'keyword_only'),
2761 ('kwargs', ..., ..., 'var_keyword')),
2762 ...))
2763
2764 self.assertEqual(self.signature(partial(foo, 1, c=3)),
2765 ((('b', ..., ..., 'positional_only'),
2766 ('c', 3, ..., 'keyword_only'),
2767 ('d', ..., ..., 'keyword_only'),
2768 ('kwargs', ..., ..., 'var_keyword')),
2769 ...))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002770
Yury Selivanovda5fe4f2014-01-27 17:28:37 -05002771 def test_signature_on_partialmethod(self):
2772 from functools import partialmethod
2773
2774 class Spam:
2775 def test():
2776 pass
2777 ham = partialmethod(test)
2778
2779 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
2780 inspect.signature(Spam.ham)
2781
2782 class Spam:
2783 def test(it, a, *, c) -> 'spam':
2784 pass
2785 ham = partialmethod(test, c=1)
2786
2787 self.assertEqual(self.signature(Spam.ham),
2788 ((('it', ..., ..., 'positional_or_keyword'),
2789 ('a', ..., ..., 'positional_or_keyword'),
2790 ('c', 1, ..., 'keyword_only')),
2791 'spam'))
2792
2793 self.assertEqual(self.signature(Spam().ham),
2794 ((('a', ..., ..., 'positional_or_keyword'),
2795 ('c', 1, ..., 'keyword_only')),
2796 'spam'))
2797
Yury Selivanov8a387212018-03-06 12:59:45 -05002798 class Spam:
2799 def test(self: 'anno', x):
2800 pass
2801
2802 g = partialmethod(test, 1)
2803
2804 self.assertEqual(self.signature(Spam.g),
2805 ((('self', ..., 'anno', 'positional_or_keyword'),),
2806 ...))
2807
Yury Selivanov0486f812014-01-29 12:18:59 -05002808 def test_signature_on_fake_partialmethod(self):
2809 def foo(a): pass
2810 foo._partialmethod = 'spam'
2811 self.assertEqual(str(inspect.signature(foo)), '(a)')
2812
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002813 def test_signature_on_decorated(self):
2814 import functools
2815
2816 def decorator(func):
2817 @functools.wraps(func)
2818 def wrapper(*args, **kwargs) -> int:
2819 return func(*args, **kwargs)
2820 return wrapper
2821
2822 class Foo:
2823 @decorator
2824 def bar(self, a, b):
2825 pass
2826
2827 self.assertEqual(self.signature(Foo.bar),
2828 ((('self', ..., ..., "positional_or_keyword"),
2829 ('a', ..., ..., "positional_or_keyword"),
2830 ('b', ..., ..., "positional_or_keyword")),
2831 ...))
2832
2833 self.assertEqual(self.signature(Foo().bar),
2834 ((('a', ..., ..., "positional_or_keyword"),
2835 ('b', ..., ..., "positional_or_keyword")),
2836 ...))
2837
Yury Selivanovbcd4fc12015-05-20 14:30:08 -04002838 self.assertEqual(self.signature(Foo.bar, follow_wrapped=False),
2839 ((('args', ..., ..., "var_positional"),
2840 ('kwargs', ..., ..., "var_keyword")),
2841 ...)) # functools.wraps will copy __annotations__
2842 # from "func" to "wrapper", hence no
2843 # return_annotation
2844
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002845 # Test that we handle method wrappers correctly
2846 def decorator(func):
2847 @functools.wraps(func)
2848 def wrapper(*args, **kwargs) -> int:
2849 return func(42, *args, **kwargs)
2850 sig = inspect.signature(func)
2851 new_params = tuple(sig.parameters.values())[1:]
2852 wrapper.__signature__ = sig.replace(parameters=new_params)
2853 return wrapper
2854
2855 class Foo:
2856 @decorator
2857 def __call__(self, a, b):
2858 pass
2859
2860 self.assertEqual(self.signature(Foo.__call__),
2861 ((('a', ..., ..., "positional_or_keyword"),
2862 ('b', ..., ..., "positional_or_keyword")),
2863 ...))
2864
2865 self.assertEqual(self.signature(Foo().__call__),
2866 ((('b', ..., ..., "positional_or_keyword"),),
2867 ...))
2868
Nick Coghlane8c45d62013-07-28 20:00:01 +10002869 # Test we handle __signature__ partway down the wrapper stack
2870 def wrapped_foo_call():
2871 pass
2872 wrapped_foo_call.__wrapped__ = Foo.__call__
2873
2874 self.assertEqual(self.signature(wrapped_foo_call),
2875 ((('a', ..., ..., "positional_or_keyword"),
2876 ('b', ..., ..., "positional_or_keyword")),
2877 ...))
2878
2879
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002880 def test_signature_on_class(self):
2881 class C:
2882 def __init__(self, a):
2883 pass
2884
2885 self.assertEqual(self.signature(C),
2886 ((('a', ..., ..., "positional_or_keyword"),),
2887 ...))
2888
2889 class CM(type):
2890 def __call__(cls, a):
2891 pass
2892 class C(metaclass=CM):
2893 def __init__(self, b):
2894 pass
2895
2896 self.assertEqual(self.signature(C),
2897 ((('a', ..., ..., "positional_or_keyword"),),
2898 ...))
2899
2900 class CM(type):
2901 def __new__(mcls, name, bases, dct, *, foo=1):
2902 return super().__new__(mcls, name, bases, dct)
2903 class C(metaclass=CM):
2904 def __init__(self, b):
2905 pass
2906
2907 self.assertEqual(self.signature(C),
2908 ((('b', ..., ..., "positional_or_keyword"),),
2909 ...))
2910
2911 self.assertEqual(self.signature(CM),
2912 ((('name', ..., ..., "positional_or_keyword"),
2913 ('bases', ..., ..., "positional_or_keyword"),
2914 ('dct', ..., ..., "positional_or_keyword"),
2915 ('foo', 1, ..., "keyword_only")),
2916 ...))
2917
2918 class CMM(type):
2919 def __new__(mcls, name, bases, dct, *, foo=1):
2920 return super().__new__(mcls, name, bases, dct)
2921 def __call__(cls, nm, bs, dt):
2922 return type(nm, bs, dt)
2923 class CM(type, metaclass=CMM):
2924 def __new__(mcls, name, bases, dct, *, bar=2):
2925 return super().__new__(mcls, name, bases, dct)
2926 class C(metaclass=CM):
2927 def __init__(self, b):
2928 pass
2929
2930 self.assertEqual(self.signature(CMM),
2931 ((('name', ..., ..., "positional_or_keyword"),
2932 ('bases', ..., ..., "positional_or_keyword"),
2933 ('dct', ..., ..., "positional_or_keyword"),
2934 ('foo', 1, ..., "keyword_only")),
2935 ...))
2936
2937 self.assertEqual(self.signature(CM),
2938 ((('nm', ..., ..., "positional_or_keyword"),
2939 ('bs', ..., ..., "positional_or_keyword"),
2940 ('dt', ..., ..., "positional_or_keyword")),
2941 ...))
2942
2943 self.assertEqual(self.signature(C),
2944 ((('b', ..., ..., "positional_or_keyword"),),
2945 ...))
2946
2947 class CM(type):
2948 def __init__(cls, name, bases, dct, *, bar=2):
2949 return super().__init__(name, bases, dct)
2950 class C(metaclass=CM):
2951 def __init__(self, b):
2952 pass
2953
2954 self.assertEqual(self.signature(CM),
2955 ((('name', ..., ..., "positional_or_keyword"),
2956 ('bases', ..., ..., "positional_or_keyword"),
2957 ('dct', ..., ..., "positional_or_keyword"),
2958 ('bar', 2, ..., "keyword_only")),
2959 ...))
2960
Yury Selivanov145dff82014-02-01 13:49:29 -05002961 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2962 "Signature information for builtins requires docstrings")
2963 def test_signature_on_class_without_init(self):
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002964 # Test classes without user-defined __init__ or __new__
2965 class C: pass
2966 self.assertEqual(str(inspect.signature(C)), '()')
2967 class D(C): pass
2968 self.assertEqual(str(inspect.signature(D)), '()')
2969
2970 # Test meta-classes without user-defined __init__ or __new__
2971 class C(type): pass
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002972 class D(C): pass
Larry Hastings2623c8c2014-02-08 22:15:29 -08002973 with self.assertRaisesRegex(ValueError, "callable.*is not supported"):
2974 self.assertEqual(inspect.signature(C), None)
2975 with self.assertRaisesRegex(ValueError, "callable.*is not supported"):
2976 self.assertEqual(inspect.signature(D), None)
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002977
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002978 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2979 "Signature information for builtins requires docstrings")
2980 def test_signature_on_builtin_class(self):
Antoine Pitrou91f43802019-05-26 17:10:09 +02002981 expected = ('(file, protocol=None, fix_imports=True, '
2982 'buffer_callback=None)')
2983 self.assertEqual(str(inspect.signature(_pickle.Pickler)), expected)
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002984
2985 class P(_pickle.Pickler): pass
2986 class EmptyTrait: pass
2987 class P2(EmptyTrait, P): pass
Antoine Pitrou91f43802019-05-26 17:10:09 +02002988 self.assertEqual(str(inspect.signature(P)), expected)
2989 self.assertEqual(str(inspect.signature(P2)), expected)
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002990
2991 class P3(P2):
2992 def __init__(self, spam):
2993 pass
2994 self.assertEqual(str(inspect.signature(P3)), '(spam)')
2995
2996 class MetaP(type):
2997 def __call__(cls, foo, bar):
2998 pass
2999 class P4(P2, metaclass=MetaP):
3000 pass
3001 self.assertEqual(str(inspect.signature(P4)), '(foo, bar)')
3002
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003003 def test_signature_on_callable_objects(self):
3004 class Foo:
3005 def __call__(self, a):
3006 pass
3007
3008 self.assertEqual(self.signature(Foo()),
3009 ((('a', ..., ..., "positional_or_keyword"),),
3010 ...))
3011
3012 class Spam:
3013 pass
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003014 with self.assertRaisesRegex(TypeError, "is not a callable object"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003015 inspect.signature(Spam())
3016
3017 class Bar(Spam, Foo):
3018 pass
3019
3020 self.assertEqual(self.signature(Bar()),
3021 ((('a', ..., ..., "positional_or_keyword"),),
3022 ...))
3023
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003024 class Wrapped:
3025 pass
3026 Wrapped.__wrapped__ = lambda a: None
3027 self.assertEqual(self.signature(Wrapped),
3028 ((('a', ..., ..., "positional_or_keyword"),),
3029 ...))
Nick Coghlane8c45d62013-07-28 20:00:01 +10003030 # wrapper loop:
3031 Wrapped.__wrapped__ = Wrapped
3032 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3033 self.signature(Wrapped)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003034
3035 def test_signature_on_lambdas(self):
3036 self.assertEqual(self.signature((lambda a=10: a)),
3037 ((('a', 10, ..., "positional_or_keyword"),),
3038 ...))
3039
3040 def test_signature_equality(self):
3041 def foo(a, *, b:int) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003042 self.assertFalse(inspect.signature(foo) == 42)
3043 self.assertTrue(inspect.signature(foo) != 42)
Serhiy Storchaka7d44e7a2019-08-08 08:43:18 +03003044 self.assertTrue(inspect.signature(foo) == ALWAYS_EQ)
3045 self.assertFalse(inspect.signature(foo) != ALWAYS_EQ)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003046
3047 def bar(a, *, b:int) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003048 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
3049 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003050 self.assertEqual(
3051 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003052
3053 def bar(a, *, b:int) -> int: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003054 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
3055 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003056 self.assertNotEqual(
3057 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003058
3059 def bar(a, *, b:int): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003060 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
3061 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003062 self.assertNotEqual(
3063 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003064
3065 def bar(a, *, b:int=42) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003066 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
3067 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003068 self.assertNotEqual(
3069 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003070
3071 def bar(a, *, c) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003072 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
3073 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003074 self.assertNotEqual(
3075 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003076
3077 def bar(a, b:int) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003078 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
3079 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003080 self.assertNotEqual(
3081 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003082 def spam(b:int, a) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003083 self.assertFalse(inspect.signature(spam) == inspect.signature(bar))
3084 self.assertTrue(inspect.signature(spam) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003085 self.assertNotEqual(
3086 hash(inspect.signature(spam)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003087
3088 def foo(*, a, b, c): pass
3089 def bar(*, c, b, a): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003090 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
3091 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003092 self.assertEqual(
3093 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003094
3095 def foo(*, a=1, b, c): pass
3096 def bar(*, c, b, a=1): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003097 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
3098 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003099 self.assertEqual(
3100 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003101
3102 def foo(pos, *, a=1, b, c): pass
3103 def bar(pos, *, c, b, a=1): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003104 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
3105 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003106 self.assertEqual(
3107 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003108
3109 def foo(pos, *, a, b, c): pass
3110 def bar(pos, *, c, b, a=1): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003111 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
3112 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003113 self.assertNotEqual(
3114 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003115
3116 def foo(pos, *args, a=42, b, c, **kwargs:int): pass
3117 def bar(pos, *args, c, b, a=42, **kwargs:int): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003118 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
3119 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003120 self.assertEqual(
3121 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003122
Yury Selivanov67ae50e2014-04-08 11:46:50 -04003123 def test_signature_hashable(self):
3124 S = inspect.Signature
3125 P = inspect.Parameter
3126
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003127 def foo(a): pass
Yury Selivanov67ae50e2014-04-08 11:46:50 -04003128 foo_sig = inspect.signature(foo)
3129
3130 manual_sig = S(parameters=[P('a', P.POSITIONAL_OR_KEYWORD)])
3131
3132 self.assertEqual(hash(foo_sig), hash(manual_sig))
3133 self.assertNotEqual(hash(foo_sig),
3134 hash(manual_sig.replace(return_annotation='spam')))
3135
3136 def bar(a) -> 1: pass
3137 self.assertNotEqual(hash(foo_sig), hash(inspect.signature(bar)))
3138
3139 def foo(a={}): pass
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003140 with self.assertRaisesRegex(TypeError, 'unhashable type'):
Yury Selivanov67ae50e2014-04-08 11:46:50 -04003141 hash(inspect.signature(foo))
3142
3143 def foo(a) -> {}: pass
3144 with self.assertRaisesRegex(TypeError, 'unhashable type'):
3145 hash(inspect.signature(foo))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003146
3147 def test_signature_str(self):
3148 def foo(a:int=1, *, b, c=None, **kwargs) -> 42:
3149 pass
3150 self.assertEqual(str(inspect.signature(foo)),
Dong-hee Na762b9572017-11-16 03:30:59 +09003151 '(a: int = 1, *, b, c=None, **kwargs) -> 42')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003152
3153 def foo(a:int=1, *args, b, c=None, **kwargs) -> 42:
3154 pass
3155 self.assertEqual(str(inspect.signature(foo)),
Dong-hee Na762b9572017-11-16 03:30:59 +09003156 '(a: int = 1, *args, b, c=None, **kwargs) -> 42')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003157
3158 def foo():
3159 pass
3160 self.assertEqual(str(inspect.signature(foo)), '()')
3161
3162 def test_signature_str_positional_only(self):
3163 P = inspect.Parameter
Yury Selivanov2393dca2014-01-27 15:07:58 -05003164 S = inspect.Signature
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003165
3166 def test(a_po, *, b, **kwargs):
3167 return a_po, kwargs
3168
3169 sig = inspect.signature(test)
3170 new_params = list(sig.parameters.values())
3171 new_params[0] = new_params[0].replace(kind=P.POSITIONAL_ONLY)
3172 test.__signature__ = sig.replace(parameters=new_params)
3173
3174 self.assertEqual(str(inspect.signature(test)),
Yury Selivanov2393dca2014-01-27 15:07:58 -05003175 '(a_po, /, *, b, **kwargs)')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003176
Yury Selivanov2393dca2014-01-27 15:07:58 -05003177 self.assertEqual(str(S(parameters=[P('foo', P.POSITIONAL_ONLY)])),
3178 '(foo, /)')
3179
3180 self.assertEqual(str(S(parameters=[
3181 P('foo', P.POSITIONAL_ONLY),
3182 P('bar', P.VAR_KEYWORD)])),
3183 '(foo, /, **bar)')
3184
3185 self.assertEqual(str(S(parameters=[
3186 P('foo', P.POSITIONAL_ONLY),
3187 P('bar', P.VAR_POSITIONAL)])),
3188 '(foo, /, *bar)')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003189
3190 def test_signature_replace_anno(self):
3191 def test() -> 42:
3192 pass
3193
3194 sig = inspect.signature(test)
3195 sig = sig.replace(return_annotation=None)
3196 self.assertIs(sig.return_annotation, None)
3197 sig = sig.replace(return_annotation=sig.empty)
3198 self.assertIs(sig.return_annotation, sig.empty)
3199 sig = sig.replace(return_annotation=42)
3200 self.assertEqual(sig.return_annotation, 42)
3201 self.assertEqual(sig, inspect.signature(test))
3202
Yury Selivanov34ce99f2014-02-18 12:49:41 -05003203 def test_signature_on_mangled_parameters(self):
3204 class Spam:
3205 def foo(self, __p1:1=2, *, __p2:2=3):
3206 pass
3207 class Ham(Spam):
3208 pass
3209
3210 self.assertEqual(self.signature(Spam.foo),
3211 ((('self', ..., ..., "positional_or_keyword"),
3212 ('_Spam__p1', 2, 1, "positional_or_keyword"),
3213 ('_Spam__p2', 3, 2, "keyword_only")),
3214 ...))
3215
3216 self.assertEqual(self.signature(Spam.foo),
3217 self.signature(Ham.foo))
3218
Yury Selivanovda396452014-03-27 12:09:24 -04003219 def test_signature_from_callable_python_obj(self):
3220 class MySignature(inspect.Signature): pass
3221 def foo(a, *, b:1): pass
3222 foo_sig = MySignature.from_callable(foo)
Gregory P. Smith5b9ff7a2019-09-13 17:13:51 +01003223 self.assertIsInstance(foo_sig, MySignature)
3224
3225 def test_signature_from_callable_class(self):
3226 # A regression test for a class inheriting its signature from `object`.
3227 class MySignature(inspect.Signature): pass
3228 class foo: pass
3229 foo_sig = MySignature.from_callable(foo)
3230 self.assertIsInstance(foo_sig, MySignature)
Yury Selivanovda396452014-03-27 12:09:24 -04003231
3232 @unittest.skipIf(MISSING_C_DOCSTRINGS,
3233 "Signature information for builtins requires docstrings")
3234 def test_signature_from_callable_builtin_obj(self):
3235 class MySignature(inspect.Signature): pass
3236 sig = MySignature.from_callable(_pickle.Pickler)
Gregory P. Smith5b9ff7a2019-09-13 17:13:51 +01003237 self.assertIsInstance(sig, MySignature)
Yury Selivanovda396452014-03-27 12:09:24 -04003238
larryhastingsf36ba122018-01-28 11:13:09 -08003239 def test_signature_definition_order_preserved_on_kwonly(self):
3240 for fn in signatures_with_lexicographic_keyword_only_parameters():
3241 signature = inspect.signature(fn)
3242 l = list(signature.parameters)
3243 sorted_l = sorted(l)
3244 self.assertTrue(l)
3245 self.assertEqual(l, sorted_l)
3246 signature = inspect.signature(unsorted_keyword_only_parameters_fn)
3247 l = list(signature.parameters)
3248 self.assertEqual(l, unsorted_keyword_only_parameters)
3249
Jens Reidel611836a2020-03-18 03:22:46 +01003250 def test_signater_parameters_is_ordered(self):
3251 p1 = inspect.signature(lambda x, y: None).parameters
3252 p2 = inspect.signature(lambda y, x: None).parameters
3253 self.assertNotEqual(p1, p2)
3254
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003255
3256class TestParameterObject(unittest.TestCase):
3257 def test_signature_parameter_kinds(self):
3258 P = inspect.Parameter
3259 self.assertTrue(P.POSITIONAL_ONLY < P.POSITIONAL_OR_KEYWORD < \
3260 P.VAR_POSITIONAL < P.KEYWORD_ONLY < P.VAR_KEYWORD)
3261
3262 self.assertEqual(str(P.POSITIONAL_ONLY), 'POSITIONAL_ONLY')
3263 self.assertTrue('POSITIONAL_ONLY' in repr(P.POSITIONAL_ONLY))
3264
3265 def test_signature_parameter_object(self):
3266 p = inspect.Parameter('foo', default=10,
3267 kind=inspect.Parameter.POSITIONAL_ONLY)
3268 self.assertEqual(p.name, 'foo')
3269 self.assertEqual(p.default, 10)
3270 self.assertIs(p.annotation, p.empty)
3271 self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY)
3272
Dong-hee Naa9cab432018-05-30 00:04:08 +09003273 with self.assertRaisesRegex(ValueError, "value '123' is "
3274 "not a valid Parameter.kind"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003275 inspect.Parameter('foo', default=10, kind='123')
3276
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003277 with self.assertRaisesRegex(ValueError, 'not a valid parameter name'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003278 inspect.Parameter('1', kind=inspect.Parameter.VAR_KEYWORD)
3279
Yury Selivanov2393dca2014-01-27 15:07:58 -05003280 with self.assertRaisesRegex(TypeError, 'name must be a str'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003281 inspect.Parameter(None, kind=inspect.Parameter.VAR_KEYWORD)
3282
Yury Selivanov2393dca2014-01-27 15:07:58 -05003283 with self.assertRaisesRegex(ValueError,
3284 'is not a valid parameter name'):
3285 inspect.Parameter('$', kind=inspect.Parameter.VAR_KEYWORD)
3286
Nick Coghlanb4b966e2016-06-04 14:40:03 -07003287 with self.assertRaisesRegex(ValueError,
3288 'is not a valid parameter name'):
3289 inspect.Parameter('.a', kind=inspect.Parameter.VAR_KEYWORD)
3290
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003291 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003292 inspect.Parameter('a', default=42,
3293 kind=inspect.Parameter.VAR_KEYWORD)
3294
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003295 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003296 inspect.Parameter('a', default=42,
3297 kind=inspect.Parameter.VAR_POSITIONAL)
3298
3299 p = inspect.Parameter('a', default=42,
3300 kind=inspect.Parameter.POSITIONAL_OR_KEYWORD)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003301 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003302 p.replace(kind=inspect.Parameter.VAR_POSITIONAL)
3303
3304 self.assertTrue(repr(p).startswith('<Parameter'))
Yury Selivanov374375d2014-03-27 12:41:53 -04003305 self.assertTrue('"a=42"' in repr(p))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003306
Yury Selivanov67ae50e2014-04-08 11:46:50 -04003307 def test_signature_parameter_hashable(self):
3308 P = inspect.Parameter
3309 foo = P('foo', kind=P.POSITIONAL_ONLY)
3310 self.assertEqual(hash(foo), hash(P('foo', kind=P.POSITIONAL_ONLY)))
3311 self.assertNotEqual(hash(foo), hash(P('foo', kind=P.POSITIONAL_ONLY,
3312 default=42)))
3313 self.assertNotEqual(hash(foo),
3314 hash(foo.replace(kind=P.VAR_POSITIONAL)))
3315
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003316 def test_signature_parameter_equality(self):
3317 P = inspect.Parameter
3318 p = P('foo', default=42, kind=inspect.Parameter.KEYWORD_ONLY)
3319
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003320 self.assertTrue(p == p)
3321 self.assertFalse(p != p)
3322 self.assertFalse(p == 42)
3323 self.assertTrue(p != 42)
Serhiy Storchaka7d44e7a2019-08-08 08:43:18 +03003324 self.assertTrue(p == ALWAYS_EQ)
3325 self.assertFalse(p != ALWAYS_EQ)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003326
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003327 self.assertTrue(p == P('foo', default=42,
3328 kind=inspect.Parameter.KEYWORD_ONLY))
3329 self.assertFalse(p != P('foo', default=42,
3330 kind=inspect.Parameter.KEYWORD_ONLY))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003331
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003332 def test_signature_parameter_replace(self):
3333 p = inspect.Parameter('foo', default=42,
3334 kind=inspect.Parameter.KEYWORD_ONLY)
3335
3336 self.assertIsNot(p, p.replace())
3337 self.assertEqual(p, p.replace())
3338
3339 p2 = p.replace(annotation=1)
3340 self.assertEqual(p2.annotation, 1)
3341 p2 = p2.replace(annotation=p2.empty)
3342 self.assertEqual(p, p2)
3343
3344 p2 = p2.replace(name='bar')
3345 self.assertEqual(p2.name, 'bar')
3346 self.assertNotEqual(p2, p)
3347
Yury Selivanov2393dca2014-01-27 15:07:58 -05003348 with self.assertRaisesRegex(ValueError,
3349 'name is a required attribute'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003350 p2 = p2.replace(name=p2.empty)
3351
3352 p2 = p2.replace(name='foo', default=None)
3353 self.assertIs(p2.default, None)
3354 self.assertNotEqual(p2, p)
3355
3356 p2 = p2.replace(name='foo', default=p2.empty)
3357 self.assertIs(p2.default, p2.empty)
3358
3359
3360 p2 = p2.replace(default=42, kind=p2.POSITIONAL_OR_KEYWORD)
3361 self.assertEqual(p2.kind, p2.POSITIONAL_OR_KEYWORD)
3362 self.assertNotEqual(p2, p)
3363
Dong-hee Naa9cab432018-05-30 00:04:08 +09003364 with self.assertRaisesRegex(ValueError,
3365 "value <class 'inspect._empty'> "
3366 "is not a valid Parameter.kind"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003367 p2 = p2.replace(kind=p2.empty)
3368
3369 p2 = p2.replace(kind=p2.KEYWORD_ONLY)
3370 self.assertEqual(p2, p)
3371
3372 def test_signature_parameter_positional_only(self):
Yury Selivanov2393dca2014-01-27 15:07:58 -05003373 with self.assertRaisesRegex(TypeError, 'name must be a str'):
3374 inspect.Parameter(None, kind=inspect.Parameter.POSITIONAL_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003375
Nick Coghlanb4b966e2016-06-04 14:40:03 -07003376 @cpython_only
3377 def test_signature_parameter_implicit(self):
3378 with self.assertRaisesRegex(ValueError,
Dong-hee Naa9cab432018-05-30 00:04:08 +09003379 'implicit arguments must be passed as '
3380 'positional or keyword arguments, '
3381 'not positional-only'):
Nick Coghlanb4b966e2016-06-04 14:40:03 -07003382 inspect.Parameter('.0', kind=inspect.Parameter.POSITIONAL_ONLY)
3383
3384 param = inspect.Parameter(
3385 '.0', kind=inspect.Parameter.POSITIONAL_OR_KEYWORD)
3386 self.assertEqual(param.kind, inspect.Parameter.POSITIONAL_ONLY)
3387 self.assertEqual(param.name, 'implicit0')
3388
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003389 def test_signature_parameter_immutability(self):
Yury Selivanov2393dca2014-01-27 15:07:58 -05003390 p = inspect.Parameter('spam', kind=inspect.Parameter.KEYWORD_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003391
3392 with self.assertRaises(AttributeError):
3393 p.foo = 'bar'
3394
3395 with self.assertRaises(AttributeError):
3396 p.kind = 123
3397
3398
3399class TestSignatureBind(unittest.TestCase):
3400 @staticmethod
3401 def call(func, *args, **kwargs):
3402 sig = inspect.signature(func)
3403 ba = sig.bind(*args, **kwargs)
3404 return func(*ba.args, **ba.kwargs)
3405
3406 def test_signature_bind_empty(self):
3407 def test():
3408 return 42
3409
3410 self.assertEqual(self.call(test), 42)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003411 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003412 self.call(test, 1)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003413 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003414 self.call(test, 1, spam=10)
Yury Selivanov86872752015-05-19 00:27:49 -04003415 with self.assertRaisesRegex(
3416 TypeError, "got an unexpected keyword argument 'spam'"):
3417
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003418 self.call(test, spam=1)
3419
3420 def test_signature_bind_var(self):
3421 def test(*args, **kwargs):
3422 return args, kwargs
3423
3424 self.assertEqual(self.call(test), ((), {}))
3425 self.assertEqual(self.call(test, 1), ((1,), {}))
3426 self.assertEqual(self.call(test, 1, 2), ((1, 2), {}))
3427 self.assertEqual(self.call(test, foo='bar'), ((), {'foo': 'bar'}))
3428 self.assertEqual(self.call(test, 1, foo='bar'), ((1,), {'foo': 'bar'}))
3429 self.assertEqual(self.call(test, args=10), ((), {'args': 10}))
3430 self.assertEqual(self.call(test, 1, 2, foo='bar'),
3431 ((1, 2), {'foo': 'bar'}))
3432
3433 def test_signature_bind_just_args(self):
3434 def test(a, b, c):
3435 return a, b, c
3436
3437 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
3438
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003439 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003440 self.call(test, 1, 2, 3, 4)
3441
Yury Selivanov86872752015-05-19 00:27:49 -04003442 with self.assertRaisesRegex(TypeError,
3443 "missing a required argument: 'b'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003444 self.call(test, 1)
3445
Yury Selivanov86872752015-05-19 00:27:49 -04003446 with self.assertRaisesRegex(TypeError,
3447 "missing a required argument: 'a'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003448 self.call(test)
3449
3450 def test(a, b, c=10):
3451 return a, b, c
3452 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
3453 self.assertEqual(self.call(test, 1, 2), (1, 2, 10))
3454
3455 def test(a=1, b=2, c=3):
3456 return a, b, c
3457 self.assertEqual(self.call(test, a=10, c=13), (10, 2, 13))
3458 self.assertEqual(self.call(test, a=10), (10, 2, 3))
3459 self.assertEqual(self.call(test, b=10), (1, 10, 3))
3460
3461 def test_signature_bind_varargs_order(self):
3462 def test(*args):
3463 return args
3464
3465 self.assertEqual(self.call(test), ())
3466 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
3467
3468 def test_signature_bind_args_and_varargs(self):
3469 def test(a, b, c=3, *args):
3470 return a, b, c, args
3471
3472 self.assertEqual(self.call(test, 1, 2, 3, 4, 5), (1, 2, 3, (4, 5)))
3473 self.assertEqual(self.call(test, 1, 2), (1, 2, 3, ()))
3474 self.assertEqual(self.call(test, b=1, a=2), (2, 1, 3, ()))
3475 self.assertEqual(self.call(test, 1, b=2), (1, 2, 3, ()))
3476
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003477 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003478 "multiple values for argument 'c'"):
3479 self.call(test, 1, 2, 3, c=4)
3480
3481 def test_signature_bind_just_kwargs(self):
3482 def test(**kwargs):
3483 return kwargs
3484
3485 self.assertEqual(self.call(test), {})
3486 self.assertEqual(self.call(test, foo='bar', spam='ham'),
3487 {'foo': 'bar', 'spam': 'ham'})
3488
3489 def test_signature_bind_args_and_kwargs(self):
3490 def test(a, b, c=3, **kwargs):
3491 return a, b, c, kwargs
3492
3493 self.assertEqual(self.call(test, 1, 2), (1, 2, 3, {}))
3494 self.assertEqual(self.call(test, 1, 2, foo='bar', spam='ham'),
3495 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3496 self.assertEqual(self.call(test, b=2, a=1, foo='bar', spam='ham'),
3497 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3498 self.assertEqual(self.call(test, a=1, b=2, foo='bar', spam='ham'),
3499 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3500 self.assertEqual(self.call(test, 1, b=2, foo='bar', spam='ham'),
3501 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3502 self.assertEqual(self.call(test, 1, b=2, c=4, foo='bar', spam='ham'),
3503 (1, 2, 4, {'foo': 'bar', 'spam': 'ham'}))
3504 self.assertEqual(self.call(test, 1, 2, 4, foo='bar'),
3505 (1, 2, 4, {'foo': 'bar'}))
3506 self.assertEqual(self.call(test, c=5, a=4, b=3),
3507 (4, 3, 5, {}))
3508
3509 def test_signature_bind_kwonly(self):
3510 def test(*, foo):
3511 return foo
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003512 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003513 'too many positional arguments'):
3514 self.call(test, 1)
3515 self.assertEqual(self.call(test, foo=1), 1)
3516
3517 def test(a, *, foo=1, bar):
3518 return foo
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003519 with self.assertRaisesRegex(TypeError,
Yury Selivanov86872752015-05-19 00:27:49 -04003520 "missing a required argument: 'bar'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003521 self.call(test, 1)
3522
3523 def test(foo, *, bar):
3524 return foo, bar
3525 self.assertEqual(self.call(test, 1, bar=2), (1, 2))
3526 self.assertEqual(self.call(test, bar=2, foo=1), (1, 2))
3527
Yury Selivanov86872752015-05-19 00:27:49 -04003528 with self.assertRaisesRegex(
3529 TypeError, "got an unexpected keyword argument 'spam'"):
3530
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003531 self.call(test, bar=2, foo=1, spam=10)
3532
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003533 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003534 'too many positional arguments'):
3535 self.call(test, 1, 2)
3536
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003537 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003538 'too many positional arguments'):
3539 self.call(test, 1, 2, bar=2)
3540
Yury Selivanov86872752015-05-19 00:27:49 -04003541 with self.assertRaisesRegex(
3542 TypeError, "got an unexpected keyword argument 'spam'"):
3543
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003544 self.call(test, 1, bar=2, spam='ham')
3545
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003546 with self.assertRaisesRegex(TypeError,
Yury Selivanov86872752015-05-19 00:27:49 -04003547 "missing a required argument: 'bar'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003548 self.call(test, 1)
3549
3550 def test(foo, *, bar, **bin):
3551 return foo, bar, bin
3552 self.assertEqual(self.call(test, 1, bar=2), (1, 2, {}))
3553 self.assertEqual(self.call(test, foo=1, bar=2), (1, 2, {}))
3554 self.assertEqual(self.call(test, 1, bar=2, spam='ham'),
3555 (1, 2, {'spam': 'ham'}))
3556 self.assertEqual(self.call(test, spam='ham', foo=1, bar=2),
3557 (1, 2, {'spam': 'ham'}))
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003558 with self.assertRaisesRegex(TypeError,
Yury Selivanov86872752015-05-19 00:27:49 -04003559 "missing a required argument: 'foo'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003560 self.call(test, spam='ham', bar=2)
3561 self.assertEqual(self.call(test, 1, bar=2, bin=1, spam=10),
3562 (1, 2, {'bin': 1, 'spam': 10}))
3563
3564 def test_signature_bind_arguments(self):
3565 def test(a, *args, b, z=100, **kwargs):
3566 pass
3567 sig = inspect.signature(test)
3568 ba = sig.bind(10, 20, b=30, c=40, args=50, kwargs=60)
3569 # we won't have 'z' argument in the bound arguments object, as we didn't
3570 # pass it to the 'bind'
3571 self.assertEqual(tuple(ba.arguments.items()),
3572 (('a', 10), ('args', (20,)), ('b', 30),
3573 ('kwargs', {'c': 40, 'args': 50, 'kwargs': 60})))
3574 self.assertEqual(ba.kwargs,
3575 {'b': 30, 'c': 40, 'args': 50, 'kwargs': 60})
3576 self.assertEqual(ba.args, (10, 20))
3577
3578 def test_signature_bind_positional_only(self):
3579 P = inspect.Parameter
3580
3581 def test(a_po, b_po, c_po=3, foo=42, *, bar=50, **kwargs):
3582 return a_po, b_po, c_po, foo, bar, kwargs
3583
3584 sig = inspect.signature(test)
3585 new_params = collections.OrderedDict(tuple(sig.parameters.items()))
3586 for name in ('a_po', 'b_po', 'c_po'):
3587 new_params[name] = new_params[name].replace(kind=P.POSITIONAL_ONLY)
3588 new_sig = sig.replace(parameters=new_params.values())
3589 test.__signature__ = new_sig
3590
3591 self.assertEqual(self.call(test, 1, 2, 4, 5, bar=6),
3592 (1, 2, 4, 5, 6, {}))
3593
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05003594 self.assertEqual(self.call(test, 1, 2),
3595 (1, 2, 3, 42, 50, {}))
3596
3597 self.assertEqual(self.call(test, 1, 2, foo=4, bar=5),
3598 (1, 2, 3, 4, 5, {}))
3599
3600 with self.assertRaisesRegex(TypeError, "but was passed as a keyword"):
3601 self.call(test, 1, 2, foo=4, bar=5, c_po=10)
3602
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003603 with self.assertRaisesRegex(TypeError, "parameter is positional only"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003604 self.call(test, 1, 2, c_po=4)
3605
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003606 with self.assertRaisesRegex(TypeError, "parameter is positional only"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003607 self.call(test, a_po=1, b_po=2)
3608
Antoine Pitroubd41d1b2013-01-29 21:20:57 +01003609 def test_signature_bind_with_self_arg(self):
3610 # Issue #17071: one of the parameters is named "self
3611 def test(a, self, b):
3612 pass
3613 sig = inspect.signature(test)
3614 ba = sig.bind(1, 2, 3)
3615 self.assertEqual(ba.args, (1, 2, 3))
3616 ba = sig.bind(1, self=2, b=3)
3617 self.assertEqual(ba.args, (1, 2, 3))
3618
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05003619 def test_signature_bind_vararg_name(self):
3620 def test(a, *args):
3621 return a, args
3622 sig = inspect.signature(test)
3623
Yury Selivanov86872752015-05-19 00:27:49 -04003624 with self.assertRaisesRegex(
3625 TypeError, "got an unexpected keyword argument 'args'"):
3626
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05003627 sig.bind(a=0, args=1)
3628
3629 def test(*args, **kwargs):
3630 return args, kwargs
3631 self.assertEqual(self.call(test, args=1), ((), {'args': 1}))
3632
3633 sig = inspect.signature(test)
3634 ba = sig.bind(args=1)
3635 self.assertEqual(ba.arguments, {'kwargs': {'args': 1}})
3636
Nick Coghlanb4b966e2016-06-04 14:40:03 -07003637 @cpython_only
3638 def test_signature_bind_implicit_arg(self):
3639 # Issue #19611: getcallargs should work with set comprehensions
3640 def make_set():
3641 return {z * z for z in range(5)}
3642 setcomp_code = make_set.__code__.co_consts[1]
3643 setcomp_func = types.FunctionType(setcomp_code, {})
3644
3645 iterator = iter(range(5))
3646 self.assertEqual(self.call(setcomp_func, iterator), {0, 1, 4, 9, 16})
3647
Pablo Galindof3ef06a2019-10-15 12:40:02 +01003648 def test_signature_bind_posonly_kwargs(self):
3649 def foo(bar, /, **kwargs):
3650 return bar, kwargs.get(bar)
3651
3652 sig = inspect.signature(foo)
3653 result = sig.bind("pos-only", bar="keyword")
3654
3655 self.assertEqual(result.kwargs, {"bar": "keyword"})
3656 self.assertIn(("bar", "pos-only"), result.arguments.items())
3657
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003658
3659class TestBoundArguments(unittest.TestCase):
3660 def test_signature_bound_arguments_unhashable(self):
3661 def foo(a): pass
3662 ba = inspect.signature(foo).bind(1)
3663
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003664 with self.assertRaisesRegex(TypeError, 'unhashable type'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003665 hash(ba)
3666
3667 def test_signature_bound_arguments_equality(self):
3668 def foo(a): pass
3669 ba = inspect.signature(foo).bind(1)
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003670 self.assertTrue(ba == ba)
3671 self.assertFalse(ba != ba)
Serhiy Storchaka7d44e7a2019-08-08 08:43:18 +03003672 self.assertTrue(ba == ALWAYS_EQ)
3673 self.assertFalse(ba != ALWAYS_EQ)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003674
3675 ba2 = inspect.signature(foo).bind(1)
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003676 self.assertTrue(ba == ba2)
3677 self.assertFalse(ba != ba2)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003678
3679 ba3 = inspect.signature(foo).bind(2)
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003680 self.assertFalse(ba == ba3)
3681 self.assertTrue(ba != ba3)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003682 ba3.arguments['a'] = 1
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003683 self.assertTrue(ba == ba3)
3684 self.assertFalse(ba != ba3)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003685
3686 def bar(b): pass
3687 ba4 = inspect.signature(bar).bind(1)
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003688 self.assertFalse(ba == ba4)
3689 self.assertTrue(ba != ba4)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003690
Yury Selivanov4cfd4ea2015-05-14 18:30:27 -04003691 def foo(*, a, b): pass
3692 sig = inspect.signature(foo)
3693 ba1 = sig.bind(a=1, b=2)
3694 ba2 = sig.bind(b=2, a=1)
Serhiy Storchaka2489bd52015-07-18 23:20:50 +03003695 self.assertTrue(ba1 == ba2)
3696 self.assertFalse(ba1 != ba2)
Yury Selivanov4cfd4ea2015-05-14 18:30:27 -04003697
Yury Selivanova5d63dd2014-03-27 11:31:43 -04003698 def test_signature_bound_arguments_pickle(self):
3699 def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
3700 sig = inspect.signature(foo)
3701 ba = sig.bind(20, 30, z={})
3702
3703 for ver in range(pickle.HIGHEST_PROTOCOL + 1):
3704 with self.subTest(pickle_ver=ver):
3705 ba_pickled = pickle.loads(pickle.dumps(ba, ver))
3706 self.assertEqual(ba, ba_pickled)
3707
Yury Selivanov3f6538f2015-05-14 18:47:17 -04003708 def test_signature_bound_arguments_repr(self):
3709 def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
3710 sig = inspect.signature(foo)
3711 ba = sig.bind(20, 30, z={})
Yury Selivanovf229bc52015-05-15 12:53:56 -04003712 self.assertRegex(repr(ba), r'<BoundArguments \(a=20,.*\}\}\)>')
Yury Selivanov3f6538f2015-05-14 18:47:17 -04003713
Yury Selivanovb907a512015-05-16 13:45:09 -04003714 def test_signature_bound_arguments_apply_defaults(self):
3715 def foo(a, b=1, *args, c:1={}, **kw): pass
3716 sig = inspect.signature(foo)
3717
3718 ba = sig.bind(20)
3719 ba.apply_defaults()
3720 self.assertEqual(
3721 list(ba.arguments.items()),
3722 [('a', 20), ('b', 1), ('args', ()), ('c', {}), ('kw', {})])
3723
3724 # Make sure that we preserve the order:
3725 # i.e. 'c' should be *before* 'kw'.
3726 ba = sig.bind(10, 20, 30, d=1)
3727 ba.apply_defaults()
3728 self.assertEqual(
3729 list(ba.arguments.items()),
3730 [('a', 10), ('b', 20), ('args', (30,)), ('c', {}), ('kw', {'d':1})])
3731
3732 # Make sure that BoundArguments produced by bind_partial()
3733 # are supported.
3734 def foo(a, b): pass
3735 sig = inspect.signature(foo)
3736 ba = sig.bind_partial(20)
3737 ba.apply_defaults()
3738 self.assertEqual(
3739 list(ba.arguments.items()),
3740 [('a', 20)])
3741
3742 # Test no args
3743 def foo(): pass
3744 sig = inspect.signature(foo)
3745 ba = sig.bind()
3746 ba.apply_defaults()
3747 self.assertEqual(list(ba.arguments.items()), [])
3748
Yury Selivanovf9e1f2b2016-03-02 11:07:47 -05003749 # Make sure a no-args binding still acquires proper defaults.
3750 def foo(a='spam'): pass
3751 sig = inspect.signature(foo)
3752 ba = sig.bind()
3753 ba.apply_defaults()
3754 self.assertEqual(list(ba.arguments.items()), [('a', 'spam')])
3755
Rémi Lapeyre2cca8ef2020-01-28 13:47:03 +01003756 def test_signature_bound_arguments_arguments_type(self):
3757 def foo(a): pass
3758 ba = inspect.signature(foo).bind(1)
3759 self.assertIs(type(ba.arguments), dict)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003760
Yury Selivanovd82eddc2014-01-29 11:24:39 -05003761class TestSignaturePrivateHelpers(unittest.TestCase):
3762 def test_signature_get_bound_param(self):
3763 getter = inspect._signature_get_bound_param
3764
3765 self.assertEqual(getter('($self)'), 'self')
3766 self.assertEqual(getter('($self, obj)'), 'self')
3767 self.assertEqual(getter('($cls, /, obj)'), 'cls')
3768
Larry Hastings2623c8c2014-02-08 22:15:29 -08003769 def _strip_non_python_syntax(self, input,
3770 clean_signature, self_parameter, last_positional_only):
3771 computed_clean_signature, \
3772 computed_self_parameter, \
3773 computed_last_positional_only = \
3774 inspect._signature_strip_non_python_syntax(input)
3775 self.assertEqual(computed_clean_signature, clean_signature)
3776 self.assertEqual(computed_self_parameter, self_parameter)
3777 self.assertEqual(computed_last_positional_only, last_positional_only)
3778
3779 def test_signature_strip_non_python_syntax(self):
3780 self._strip_non_python_syntax(
3781 "($module, /, path, mode, *, dir_fd=None, " +
3782 "effective_ids=False,\n follow_symlinks=True)",
3783 "(module, path, mode, *, dir_fd=None, " +
3784 "effective_ids=False, follow_symlinks=True)",
3785 0,
3786 0)
3787
3788 self._strip_non_python_syntax(
3789 "($module, word, salt, /)",
3790 "(module, word, salt)",
3791 0,
3792 2)
3793
3794 self._strip_non_python_syntax(
3795 "(x, y=None, z=None, /)",
3796 "(x, y=None, z=None)",
3797 None,
3798 2)
3799
3800 self._strip_non_python_syntax(
3801 "(x, y=None, z=None)",
3802 "(x, y=None, z=None)",
3803 None,
3804 None)
3805
3806 self._strip_non_python_syntax(
3807 "(x,\n y=None,\n z = None )",
3808 "(x, y=None, z=None)",
3809 None,
3810 None)
3811
3812 self._strip_non_python_syntax(
3813 "",
3814 "",
3815 None,
3816 None)
3817
3818 self._strip_non_python_syntax(
3819 None,
3820 None,
3821 None,
3822 None)
3823
Nick Coghlan9c680b02015-04-13 12:54:54 -04003824class TestSignatureDefinitions(unittest.TestCase):
3825 # This test case provides a home for checking that particular APIs
3826 # have signatures available for introspection
3827
3828 @cpython_only
3829 @unittest.skipIf(MISSING_C_DOCSTRINGS,
3830 "Signature information for builtins requires docstrings")
3831 def test_builtins_have_signatures(self):
3832 # This checks all builtin callables in CPython have signatures
3833 # A few have signatures Signature can't yet handle, so we skip those
3834 # since they will have to wait until PEP 457 adds the required
3835 # introspection support to the inspect module
3836 # Some others also haven't been converted yet for various other
3837 # reasons, so we also skip those for the time being, but design
3838 # the test to fail in order to indicate when it needs to be
3839 # updated.
3840 no_signature = set()
3841 # These need PEP 457 groups
3842 needs_groups = {"range", "slice", "dir", "getattr",
3843 "next", "iter", "vars"}
3844 no_signature |= needs_groups
3845 # These need PEP 457 groups or a signature change to accept None
3846 needs_semantic_update = {"round"}
3847 no_signature |= needs_semantic_update
3848 # These need *args support in Argument Clinic
Barry Warsaw36c1d1f2017-10-05 12:11:18 -04003849 needs_varargs = {"breakpoint", "min", "max", "print",
3850 "__build_class__"}
Nick Coghlan9c680b02015-04-13 12:54:54 -04003851 no_signature |= needs_varargs
3852 # These simply weren't covered in the initial AC conversion
3853 # for builtin callables
3854 not_converted_yet = {"open", "__import__"}
3855 no_signature |= not_converted_yet
3856 # These builtin types are expected to provide introspection info
3857 types_with_signatures = set()
3858 # Check the signatures we expect to be there
3859 ns = vars(builtins)
3860 for name, obj in sorted(ns.items()):
3861 if not callable(obj):
3862 continue
3863 # The builtin types haven't been converted to AC yet
3864 if isinstance(obj, type) and (name not in types_with_signatures):
3865 # Note that this also skips all the exception types
3866 no_signature.add(name)
3867 if (name in no_signature):
3868 # Not yet converted
3869 continue
3870 with self.subTest(builtin=name):
3871 self.assertIsNotNone(inspect.signature(obj))
3872 # Check callables that haven't been converted don't claim a signature
3873 # This ensures this test will start failing as more signatures are
3874 # added, so the affected items can be moved into the scope of the
3875 # regression test above
3876 for name in no_signature:
3877 with self.subTest(builtin=name):
3878 self.assertIsNone(obj.__text_signature__)
3879
Serhiy Storchakad53cf992019-05-06 22:40:27 +03003880 def test_python_function_override_signature(self):
3881 def func(*args, **kwargs):
3882 pass
3883 func.__text_signature__ = '($self, a, b=1, *args, c, d=2, **kwargs)'
3884 sig = inspect.signature(func)
3885 self.assertIsNotNone(sig)
3886 self.assertEqual(str(sig), '(self, /, a, b=1, *args, c, d=2, **kwargs)')
3887 func.__text_signature__ = '($self, a, b=1, /, *args, c, d=2, **kwargs)'
3888 sig = inspect.signature(func)
3889 self.assertEqual(str(sig), '(self, a, b=1, /, *args, c, d=2, **kwargs)')
3890
Yury Selivanovd82eddc2014-01-29 11:24:39 -05003891
Thomas Kluyverf9169ce2017-05-23 04:27:52 +01003892class NTimesUnwrappable:
3893 def __init__(self, n):
3894 self.n = n
3895 self._next = None
3896
3897 @property
3898 def __wrapped__(self):
3899 if self.n <= 0:
3900 raise Exception("Unwrapped too many times")
3901 if self._next is None:
3902 self._next = NTimesUnwrappable(self.n - 1)
3903 return self._next
3904
Nick Coghlane8c45d62013-07-28 20:00:01 +10003905class TestUnwrap(unittest.TestCase):
3906
3907 def test_unwrap_one(self):
3908 def func(a, b):
3909 return a + b
3910 wrapper = functools.lru_cache(maxsize=20)(func)
3911 self.assertIs(inspect.unwrap(wrapper), func)
3912
3913 def test_unwrap_several(self):
3914 def func(a, b):
3915 return a + b
3916 wrapper = func
3917 for __ in range(10):
3918 @functools.wraps(wrapper)
3919 def wrapper():
3920 pass
3921 self.assertIsNot(wrapper.__wrapped__, func)
3922 self.assertIs(inspect.unwrap(wrapper), func)
3923
3924 def test_stop(self):
3925 def func1(a, b):
3926 return a + b
3927 @functools.wraps(func1)
3928 def func2():
3929 pass
3930 @functools.wraps(func2)
3931 def wrapper():
3932 pass
3933 func2.stop_here = 1
3934 unwrapped = inspect.unwrap(wrapper,
3935 stop=(lambda f: hasattr(f, "stop_here")))
3936 self.assertIs(unwrapped, func2)
3937
3938 def test_cycle(self):
3939 def func1(): pass
3940 func1.__wrapped__ = func1
3941 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3942 inspect.unwrap(func1)
3943
3944 def func2(): pass
3945 func2.__wrapped__ = func1
3946 func1.__wrapped__ = func2
3947 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3948 inspect.unwrap(func1)
3949 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3950 inspect.unwrap(func2)
3951
3952 def test_unhashable(self):
3953 def func(): pass
3954 func.__wrapped__ = None
3955 class C:
3956 __hash__ = None
3957 __wrapped__ = func
3958 self.assertIsNone(inspect.unwrap(C()))
3959
Thomas Kluyverf9169ce2017-05-23 04:27:52 +01003960 def test_recursion_limit(self):
3961 obj = NTimesUnwrappable(sys.getrecursionlimit() + 1)
3962 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3963 inspect.unwrap(obj)
3964
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003965class TestMain(unittest.TestCase):
3966 def test_only_source(self):
3967 module = importlib.import_module('unittest')
3968 rc, out, err = assert_python_ok('-m', 'inspect',
3969 'unittest')
3970 lines = out.decode().splitlines()
3971 # ignore the final newline
3972 self.assertEqual(lines[:-1], inspect.getsource(module).splitlines())
3973 self.assertEqual(err, b'')
3974
Yury Selivanov42407ab2014-06-23 10:23:50 -07003975 def test_custom_getattr(self):
3976 def foo():
3977 pass
3978 foo.__signature__ = 42
3979 with self.assertRaises(TypeError):
3980 inspect.signature(foo)
3981
Brett Cannon634a8fc2013-10-02 10:25:42 -04003982 @unittest.skipIf(ThreadPoolExecutor is None,
Brett Cannon0de3f012013-10-02 10:58:58 -04003983 'threads required to test __qualname__ for source files')
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003984 def test_qualname_source(self):
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003985 rc, out, err = assert_python_ok('-m', 'inspect',
3986 'concurrent.futures:ThreadPoolExecutor')
3987 lines = out.decode().splitlines()
3988 # ignore the final newline
3989 self.assertEqual(lines[:-1],
Brett Cannon634a8fc2013-10-02 10:25:42 -04003990 inspect.getsource(ThreadPoolExecutor).splitlines())
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003991 self.assertEqual(err, b'')
3992
3993 def test_builtins(self):
3994 module = importlib.import_module('unittest')
3995 _, out, err = assert_python_failure('-m', 'inspect',
3996 'sys')
3997 lines = err.decode().splitlines()
3998 self.assertEqual(lines, ["Can't get info for builtin modules."])
3999
4000 def test_details(self):
4001 module = importlib.import_module('unittest')
Victor Stinner9def2842016-01-18 12:15:08 +01004002 args = support.optim_args_from_interpreter_flags()
4003 rc, out, err = assert_python_ok(*args, '-m', 'inspect',
Nick Coghlanf94a16b2013-09-22 22:46:49 +10004004 'unittest', '--details')
4005 output = out.decode()
4006 # Just a quick sanity check on the output
4007 self.assertIn(module.__name__, output)
4008 self.assertIn(module.__file__, output)
Victor Stinner9def2842016-01-18 12:15:08 +01004009 self.assertIn(module.__cached__, output)
Nick Coghlanf94a16b2013-09-22 22:46:49 +10004010 self.assertEqual(err, b'')
4011
4012
Yury Selivanovef1e7502014-12-08 16:05:34 -05004013class TestReload(unittest.TestCase):
4014
4015 src_before = textwrap.dedent("""\
4016def foo():
4017 print("Bla")
4018 """)
4019
4020 src_after = textwrap.dedent("""\
4021def foo():
4022 print("Oh no!")
4023 """)
4024
4025 def assertInspectEqual(self, path, source):
4026 inspected_src = inspect.getsource(source)
4027 with open(path) as src:
4028 self.assertEqual(
4029 src.read().splitlines(True),
4030 inspected_src.splitlines(True)
4031 )
4032
4033 def test_getsource_reload(self):
4034 # see issue 1218234
4035 with _ready_to_import('reload_bug', self.src_before) as (name, path):
4036 module = importlib.import_module(name)
4037 self.assertInspectEqual(path, module)
4038 with open(path, 'w') as src:
4039 src.write(self.src_after)
4040 self.assertInspectEqual(path, module)
Nick Coghlanf94a16b2013-09-22 22:46:49 +10004041
Nick Coghlane8c45d62013-07-28 20:00:01 +10004042
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00004043def test_main():
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00004044 run_unittest(
Miss Islington (bot)81ac0302020-12-04 12:20:05 -08004045 TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBlockComments,
4046 TestBuggyCases, TestInterpreterStack, TestClassesAndFunctions, TestPredicates,
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00004047 TestGetcallargsFunctions, TestGetcallargsMethods,
Alexander Belopolskyf546e702010-12-02 00:10:11 +00004048 TestGetcallargsUnboundMethods, TestGetattrStatic, TestGetGeneratorState,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07004049 TestNoEOL, TestSignatureObject, TestSignatureBind, TestParameterObject,
Nick Coghlan9c680b02015-04-13 12:54:54 -04004050 TestBoundArguments, TestSignaturePrivateHelpers,
Aaron Hall, MBA4054b172018-05-20 19:46:42 -04004051 TestSignatureDefinitions, TestIsDataDescriptor,
Yury Selivanov5376ba92015-06-22 12:19:30 -04004052 TestGetClosureVars, TestUnwrap, TestMain, TestReload,
Vladimir Matveev91cb2982018-08-24 07:18:00 -07004053 TestGetCoroutineState, TestGettingSourceOfToplevelFrames
Michael Foord95fc51d2010-11-20 15:07:30 +00004054 )
Martin v. Löwis893ffa42003-10-31 15:35:53 +00004055
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00004056if __name__ == "__main__":
4057 test_main()