blob: facf040d3cd302217f766563ca2bb20850b90476 [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 re
14import shutil
15import sys
16import types
Yury Selivanovef1e7502014-12-08 16:05:34 -050017import textwrap
Larry Hastings5c661892014-01-24 06:17:25 -080018import unicodedata
19import unittest
Yury Selivanova773de02014-02-21 18:30:53 -050020import unittest.mock
Yury Selivanov75445082015-05-11 22:57:16 -040021import warnings
Larry Hastings5c661892014-01-24 06:17:25 -080022
Brett Cannon634a8fc2013-10-02 10:25:42 -040023try:
24 from concurrent.futures import ThreadPoolExecutor
25except ImportError:
26 ThreadPoolExecutor = None
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000027
Serhiy Storchakaf28ba362014-02-07 10:10:55 +020028from test.support import run_unittest, TESTFN, DirsOnSysPath, cpython_only
Nick Coghlanf9e227e2014-08-17 14:01:19 +100029from test.support import MISSING_C_DOCSTRINGS, cpython_only
Berker Peksagce643912015-05-06 06:33:17 +030030from test.support.script_helper import assert_python_ok, assert_python_failure
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000031from test import inspect_fodder as mod
32from test import inspect_fodder2 as mod2
Victor Stinner9def2842016-01-18 12:15:08 +010033from test import support
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000034
Yury Selivanovef1e7502014-12-08 16:05:34 -050035from test.test_import import _ready_to_import
36
R. David Murray74b89242009-05-13 17:33:03 +000037
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000038# Functions tested in this suite:
39# ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode,
Christian Heimes7131fd92008-02-19 14:21:46 +000040# isbuiltin, isroutine, isgenerator, isgeneratorfunction, getmembers,
41# getdoc, getfile, getmodule, getsourcefile, getcomments, getsource,
Berker Peksagfa3922c2015-07-31 04:11:29 +030042# getclasstree, getargvalues, formatargspec, formatargvalues,
Christian Heimes7131fd92008-02-19 14:21:46 +000043# currentframe, stack, trace, isdatadescriptor
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000044
Nick Coghlanf088e5e2008-12-14 11:50:48 +000045# NOTE: There are some additional tests relating to interaction with
46# zipimport in the test_zipimport_support test module.
47
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000048modfile = mod.__file__
Thomas Wouters0e3f5912006-08-11 14:57:12 +000049if modfile.endswith(('c', 'o')):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000050 modfile = modfile[:-1]
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000051
Christian Heimesa3538eb2007-11-06 11:44:48 +000052# Normalize file names: on Windows, the case of file names of compiled
53# modules depends on the path used to start the python executable.
54modfile = normcase(modfile)
55
56def revise(filename, *args):
57 return (normcase(filename),) + args
58
Georg Brandl1a3284e2007-12-02 09:40:06 +000059import builtins
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000060
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000061git = mod.StupidGit()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000062
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000063class IsTestBase(unittest.TestCase):
64 predicates = set([inspect.isbuiltin, inspect.isclass, inspect.iscode,
65 inspect.isframe, inspect.isfunction, inspect.ismethod,
Christian Heimes7131fd92008-02-19 14:21:46 +000066 inspect.ismodule, inspect.istraceback,
Yury Selivanov75445082015-05-11 22:57:16 -040067 inspect.isgenerator, inspect.isgeneratorfunction,
Yury Selivanoveb636452016-09-08 22:01:51 -070068 inspect.iscoroutine, inspect.iscoroutinefunction,
69 inspect.isasyncgen, inspect.isasyncgenfunction])
Tim Peters5a9fb3c2005-01-07 16:01:32 +000070
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000071 def istest(self, predicate, exp):
72 obj = eval(exp)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000073 self.assertTrue(predicate(obj), '%s(%s)' % (predicate.__name__, exp))
Tim Peters5a9fb3c2005-01-07 16:01:32 +000074
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000075 for other in self.predicates - set([predicate]):
Yury Selivanov75445082015-05-11 22:57:16 -040076 if (predicate == inspect.isgeneratorfunction or \
Yury Selivanoveb636452016-09-08 22:01:51 -070077 predicate == inspect.isasyncgenfunction or \
Yury Selivanov75445082015-05-11 22:57:16 -040078 predicate == inspect.iscoroutinefunction) and \
Christian Heimes7131fd92008-02-19 14:21:46 +000079 other == inspect.isfunction:
80 continue
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000081 self.assertFalse(other(obj), 'not %s(%s)' % (other.__name__, exp))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000082
Christian Heimes7131fd92008-02-19 14:21:46 +000083def generator_function_example(self):
84 for i in range(2):
85 yield i
86
Yury Selivanoveb636452016-09-08 22:01:51 -070087async def async_generator_function_example(self):
88 async for i in range(2):
89 yield i
90
Yury Selivanov75445082015-05-11 22:57:16 -040091async def coroutine_function_example(self):
92 return 'spam'
93
94@types.coroutine
95def gen_coroutine_function_example(self):
96 yield
97 return 'spam'
98
Serhiy Storchaka3018cc42015-07-18 23:19:05 +030099class EqualsToAll:
100 def __eq__(self, other):
101 return True
Yury Selivanova5d63dd2014-03-27 11:31:43 -0400102
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000103class TestPredicates(IsTestBase):
Christian Heimes7131fd92008-02-19 14:21:46 +0000104
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000105 def test_excluding_predicates(self):
Antoine Pitroud5a1a212012-06-17 23:18:07 +0200106 global tb
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000107 self.istest(inspect.isbuiltin, 'sys.exit')
108 self.istest(inspect.isbuiltin, '[].append')
Neal Norwitz221085d2007-02-25 20:55:47 +0000109 self.istest(inspect.iscode, 'mod.spam.__code__')
Antoine Pitroud5a1a212012-06-17 23:18:07 +0200110 try:
111 1/0
112 except:
113 tb = sys.exc_info()[2]
114 self.istest(inspect.isframe, 'tb.tb_frame')
115 self.istest(inspect.istraceback, 'tb')
116 if hasattr(types, 'GetSetDescriptorType'):
117 self.istest(inspect.isgetsetdescriptor,
118 'type(tb.tb_frame).f_locals')
119 else:
120 self.assertFalse(inspect.isgetsetdescriptor(type(tb.tb_frame).f_locals))
121 finally:
122 # Clear traceback and all the frames and local variables hanging to it.
123 tb = None
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000124 self.istest(inspect.isfunction, 'mod.spam')
Christian Heimes4a22b5d2007-11-25 09:39:14 +0000125 self.istest(inspect.isfunction, 'mod.StupidGit.abuse')
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000126 self.istest(inspect.ismethod, 'git.argue')
127 self.istest(inspect.ismodule, 'mod')
Guido van Rossum813b0e52007-05-21 18:11:34 +0000128 self.istest(inspect.isdatadescriptor, 'collections.defaultdict.default_factory')
Christian Heimes7131fd92008-02-19 14:21:46 +0000129 self.istest(inspect.isgenerator, '(x for x in range(2))')
130 self.istest(inspect.isgeneratorfunction, 'generator_function_example')
Yury Selivanoveb636452016-09-08 22:01:51 -0700131 self.istest(inspect.isasyncgen,
132 'async_generator_function_example(1)')
133 self.istest(inspect.isasyncgenfunction,
134 'async_generator_function_example')
Yury Selivanov75445082015-05-11 22:57:16 -0400135
136 with warnings.catch_warnings():
137 warnings.simplefilter("ignore")
138 self.istest(inspect.iscoroutine, 'coroutine_function_example(1)')
139 self.istest(inspect.iscoroutinefunction, 'coroutine_function_example')
140
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000141 if hasattr(types, 'MemberDescriptorType'):
142 self.istest(inspect.ismemberdescriptor, 'datetime.timedelta.days')
143 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000144 self.assertFalse(inspect.ismemberdescriptor(datetime.timedelta.days))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000145
Yury Selivanov75445082015-05-11 22:57:16 -0400146 def test_iscoroutine(self):
147 gen_coro = gen_coroutine_function_example(1)
148 coro = coroutine_function_example(1)
149
Yury Selivanov5376ba92015-06-22 12:19:30 -0400150 self.assertFalse(
Yury Selivanov75445082015-05-11 22:57:16 -0400151 inspect.iscoroutinefunction(gen_coroutine_function_example))
Yury Selivanov5376ba92015-06-22 12:19:30 -0400152 self.assertFalse(inspect.iscoroutine(gen_coro))
Yury Selivanov75445082015-05-11 22:57:16 -0400153
154 self.assertTrue(
155 inspect.isgeneratorfunction(gen_coroutine_function_example))
156 self.assertTrue(inspect.isgenerator(gen_coro))
157
158 self.assertTrue(
159 inspect.iscoroutinefunction(coroutine_function_example))
160 self.assertTrue(inspect.iscoroutine(coro))
161
162 self.assertFalse(
163 inspect.isgeneratorfunction(coroutine_function_example))
164 self.assertFalse(inspect.isgenerator(coro))
165
166 coro.close(); gen_coro.close() # silence warnings
167
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -0400168 def test_isawaitable(self):
169 def gen(): yield
170 self.assertFalse(inspect.isawaitable(gen()))
171
172 coro = coroutine_function_example(1)
173 gen_coro = gen_coroutine_function_example(1)
174
175 self.assertTrue(inspect.isawaitable(coro))
176 self.assertTrue(inspect.isawaitable(gen_coro))
177
178 class Future:
179 def __await__():
180 pass
181 self.assertTrue(inspect.isawaitable(Future()))
182 self.assertFalse(inspect.isawaitable(Future))
183
184 class NotFuture: pass
185 not_fut = NotFuture()
186 not_fut.__await__ = lambda: None
187 self.assertFalse(inspect.isawaitable(not_fut))
188
189 coro.close(); gen_coro.close() # silence warnings
190
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000191 def test_isroutine(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000192 self.assertTrue(inspect.isroutine(mod.spam))
193 self.assertTrue(inspect.isroutine([].count))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000194
Benjamin Petersonc4656002009-01-17 22:41:18 +0000195 def test_isclass(self):
196 self.istest(inspect.isclass, 'mod.StupidGit')
197 self.assertTrue(inspect.isclass(list))
198
199 class CustomGetattr(object):
200 def __getattr__(self, attr):
201 return None
202 self.assertFalse(inspect.isclass(CustomGetattr()))
203
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000204 def test_get_slot_members(self):
205 class C(object):
206 __slots__ = ("a", "b")
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000207 x = C()
208 x.a = 42
209 members = dict(inspect.getmembers(x))
Benjamin Peterson577473f2010-01-19 00:09:57 +0000210 self.assertIn('a', members)
211 self.assertNotIn('b', members)
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000212
Benjamin Petersona0dfa822009-11-13 02:25:08 +0000213 def test_isabstract(self):
214 from abc import ABCMeta, abstractmethod
215
216 class AbstractClassExample(metaclass=ABCMeta):
217
218 @abstractmethod
219 def foo(self):
220 pass
221
222 class ClassExample(AbstractClassExample):
223 def foo(self):
224 pass
225
226 a = ClassExample()
227
228 # Test general behaviour.
229 self.assertTrue(inspect.isabstract(AbstractClassExample))
230 self.assertFalse(inspect.isabstract(ClassExample))
231 self.assertFalse(inspect.isabstract(a))
232 self.assertFalse(inspect.isabstract(int))
233 self.assertFalse(inspect.isabstract(5))
234
Nate09b6c0c2017-06-06 21:21:34 -0700235 def test_isabstract_during_init_subclass(self):
236 from abc import ABCMeta, abstractmethod
237 isabstract_checks = []
238 class AbstractChecker(metaclass=ABCMeta):
239 def __init_subclass__(cls):
240 isabstract_checks.append(inspect.isabstract(cls))
241 class AbstractClassExample(AbstractChecker):
242 @abstractmethod
243 def foo(self):
244 pass
245 class ClassExample(AbstractClassExample):
246 def foo(self):
247 pass
248 self.assertEqual(isabstract_checks, [True, False])
249
250 isabstract_checks.clear()
251 class AbstractChild(AbstractClassExample):
252 pass
253 class AbstractGrandchild(AbstractChild):
254 pass
255 class ConcreteGrandchild(ClassExample):
256 pass
257 self.assertEqual(isabstract_checks, [True, True, False])
258
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000259
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000260class TestInterpreterStack(IsTestBase):
261 def __init__(self, *args, **kwargs):
262 unittest.TestCase.__init__(self, *args, **kwargs)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000263
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000264 git.abuse(7, 8, 9)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000265
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000266 def test_abuse_done(self):
267 self.istest(inspect.istraceback, 'git.ex[2]')
268 self.istest(inspect.isframe, 'mod.fr')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000269
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000270 def test_stack(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000271 self.assertTrue(len(mod.st) >= 5)
Christian Heimesa3538eb2007-11-06 11:44:48 +0000272 self.assertEqual(revise(*mod.st[0][1:]),
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000273 (modfile, 16, 'eggs', [' st = inspect.stack()\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000274 self.assertEqual(revise(*mod.st[1][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000275 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000276 self.assertEqual(revise(*mod.st[2][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000277 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000278 self.assertEqual(revise(*mod.st[3][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000279 (modfile, 39, 'abuse', [' self.argue(a, b, c)\n'], 0))
Antoine Pitroucdcafb72014-08-24 10:50:28 -0400280 # Test named tuple fields
281 record = mod.st[0]
282 self.assertIs(record.frame, mod.fr)
283 self.assertEqual(record.lineno, 16)
284 self.assertEqual(record.filename, mod.__file__)
285 self.assertEqual(record.function, 'eggs')
286 self.assertIn('inspect.stack()', record.code_context[0])
287 self.assertEqual(record.index, 0)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000288
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000289 def test_trace(self):
290 self.assertEqual(len(git.tr), 3)
Florent Xiclunac8575922010-03-24 17:37:49 +0000291 self.assertEqual(revise(*git.tr[0][1:]),
292 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
293 self.assertEqual(revise(*git.tr[1][1:]),
294 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
295 self.assertEqual(revise(*git.tr[2][1:]),
296 (modfile, 18, 'eggs', [' q = y / 0\n'], 0))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000297
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000298 def test_frame(self):
299 args, varargs, varkw, locals = inspect.getargvalues(mod.fr)
300 self.assertEqual(args, ['x', 'y'])
301 self.assertEqual(varargs, None)
302 self.assertEqual(varkw, None)
303 self.assertEqual(locals, {'x': 11, 'p': 11, 'y': 14})
304 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
305 '(x=11, y=14)')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000306
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000307 def test_previous_frame(self):
308 args, varargs, varkw, locals = inspect.getargvalues(mod.fr.f_back)
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000309 self.assertEqual(args, ['a', 'b', 'c', 'd', 'e', 'f'])
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000310 self.assertEqual(varargs, 'g')
311 self.assertEqual(varkw, 'h')
312 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000313 '(a=7, b=8, c=9, d=3, e=4, f=5, *g=(), **h={})')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000314
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000315class GetSourceBase(unittest.TestCase):
316 # Subclasses must override.
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000317 fodderModule = None
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000318
Yury Selivanov6738b112015-05-16 10:10:21 -0400319 def setUp(self):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000320 with open(inspect.getsourcefile(self.fodderModule)) as fp:
Philip Jenveya27c5bd2009-05-28 06:09:08 +0000321 self.source = fp.read()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000322
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000323 def sourcerange(self, top, bottom):
324 lines = self.source.split("\n")
325 return "\n".join(lines[top-1:bottom]) + "\n"
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000326
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000327 def assertSourceEqual(self, obj, top, bottom):
328 self.assertEqual(inspect.getsource(obj),
329 self.sourcerange(top, bottom))
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000330
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000331class TestRetrievingSourceCode(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000332 fodderModule = mod
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000333
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000334 def test_getclasses(self):
335 classes = inspect.getmembers(mod, inspect.isclass)
336 self.assertEqual(classes,
337 [('FesteringGob', mod.FesteringGob),
338 ('MalodorousPervert', mod.MalodorousPervert),
339 ('ParrotDroppings', mod.ParrotDroppings),
Serhiy Storchaka362c1b52013-09-05 17:14:32 +0300340 ('StupidGit', mod.StupidGit),
341 ('Tit', mod.MalodorousPervert),
342 ])
343 tree = inspect.getclasstree([cls[1] for cls in classes])
344 self.assertEqual(tree,
345 [(object, ()),
346 [(mod.ParrotDroppings, (object,)),
347 [(mod.FesteringGob, (mod.MalodorousPervert,
348 mod.ParrotDroppings))
349 ],
350 (mod.StupidGit, (object,)),
351 [(mod.MalodorousPervert, (mod.StupidGit,)),
352 [(mod.FesteringGob, (mod.MalodorousPervert,
353 mod.ParrotDroppings))
354 ]
355 ]
356 ]
357 ])
358 tree = inspect.getclasstree([cls[1] for cls in classes], True)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000359 self.assertEqual(tree,
Thomas Wouters725af872006-04-15 09:13:19 +0000360 [(object, ()),
361 [(mod.ParrotDroppings, (object,)),
362 (mod.StupidGit, (object,)),
363 [(mod.MalodorousPervert, (mod.StupidGit,)),
364 [(mod.FesteringGob, (mod.MalodorousPervert,
365 mod.ParrotDroppings))
366 ]
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000367 ]
368 ]
369 ])
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000370
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000371 def test_getfunctions(self):
372 functions = inspect.getmembers(mod, inspect.isfunction)
373 self.assertEqual(functions, [('eggs', mod.eggs),
Yury Selivanove4e811d2015-07-21 19:01:52 +0300374 ('lobbest', mod.lobbest),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000375 ('spam', mod.spam)])
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000376
R. David Murray378c0cf2010-02-24 01:46:21 +0000377 @unittest.skipIf(sys.flags.optimize >= 2,
378 "Docstrings are omitted with -O2 and above")
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000379 def test_getdoc(self):
380 self.assertEqual(inspect.getdoc(mod), 'A module docstring.')
381 self.assertEqual(inspect.getdoc(mod.StupidGit),
382 'A longer,\n\nindented\n\ndocstring.')
383 self.assertEqual(inspect.getdoc(git.abuse),
384 'Another\n\ndocstring\n\ncontaining\n\ntabs')
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000385
Serhiy Storchaka5cf2b7252015-04-03 22:38:53 +0300386 @unittest.skipIf(sys.flags.optimize >= 2,
387 "Docstrings are omitted with -O2 and above")
388 def test_getdoc_inherited(self):
389 self.assertEqual(inspect.getdoc(mod.FesteringGob),
390 'A longer,\n\nindented\n\ndocstring.')
391 self.assertEqual(inspect.getdoc(mod.FesteringGob.abuse),
392 'Another\n\ndocstring\n\ncontaining\n\ntabs')
393 self.assertEqual(inspect.getdoc(mod.FesteringGob().abuse),
394 'Another\n\ndocstring\n\ncontaining\n\ntabs')
395 self.assertEqual(inspect.getdoc(mod.FesteringGob.contradiction),
396 'The automatic gainsaying.')
397
398 @unittest.skipIf(MISSING_C_DOCSTRINGS, "test requires docstrings")
399 def test_finddoc(self):
400 finddoc = inspect._finddoc
401 self.assertEqual(finddoc(int), int.__doc__)
402 self.assertEqual(finddoc(int.to_bytes), int.to_bytes.__doc__)
403 self.assertEqual(finddoc(int().to_bytes), int.to_bytes.__doc__)
404 self.assertEqual(finddoc(int.from_bytes), int.from_bytes.__doc__)
405 self.assertEqual(finddoc(int.real), int.real.__doc__)
406
Georg Brandl0c77a822008-06-10 16:37:50 +0000407 def test_cleandoc(self):
408 self.assertEqual(inspect.cleandoc('An\n indented\n docstring.'),
409 'An\nindented\ndocstring.')
410
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000411 def test_getcomments(self):
412 self.assertEqual(inspect.getcomments(mod), '# line 1\n')
413 self.assertEqual(inspect.getcomments(mod.StupidGit), '# line 20\n')
Berker Peksag948171b2017-03-17 14:59:16 +0300414 # If the object source file is not available, return None.
415 co = compile('x=1', '_non_existing_filename.py', 'exec')
416 self.assertIsNone(inspect.getcomments(co))
417 # If the object has been defined in C, return None.
418 self.assertIsNone(inspect.getcomments(list))
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000419
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000420 def test_getmodule(self):
Thomas Wouters89f507f2006-12-13 04:49:30 +0000421 # Check actual module
422 self.assertEqual(inspect.getmodule(mod), mod)
423 # Check class (uses __module__ attribute)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000424 self.assertEqual(inspect.getmodule(mod.StupidGit), mod)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000425 # Check a method (no __module__ attribute, falls back to filename)
426 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
427 # Do it again (check the caching isn't broken)
428 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
429 # Check a builtin
Georg Brandl1a3284e2007-12-02 09:40:06 +0000430 self.assertEqual(inspect.getmodule(str), sys.modules["builtins"])
Thomas Wouters89f507f2006-12-13 04:49:30 +0000431 # Check filename override
432 self.assertEqual(inspect.getmodule(None, modfile), mod)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000433
Berker Peksagff0e3b72017-01-02 06:57:43 +0300434 def test_getframeinfo_get_first_line(self):
435 frame_info = inspect.getframeinfo(self.fodderModule.fr, 50)
436 self.assertEqual(frame_info.code_context[0], "# line 1\n")
437 self.assertEqual(frame_info.code_context[1], "'A module docstring.'\n")
438
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000439 def test_getsource(self):
440 self.assertSourceEqual(git.abuse, 29, 39)
Serhiy Storchakaac4bdcc2015-10-29 08:15:50 +0200441 self.assertSourceEqual(mod.StupidGit, 21, 51)
442 self.assertSourceEqual(mod.lobbest, 75, 76)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000443
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000444 def test_getsourcefile(self):
Christian Heimesa3538eb2007-11-06 11:44:48 +0000445 self.assertEqual(normcase(inspect.getsourcefile(mod.spam)), modfile)
446 self.assertEqual(normcase(inspect.getsourcefile(git.abuse)), modfile)
R. David Murraya1b37402010-06-17 02:04:29 +0000447 fn = "_non_existing_filename_used_for_sourcefile_test.py"
Victor Stinner51d8c522016-02-08 17:57:02 +0100448 co = compile("x=1", fn, "exec")
R. David Murray4155f972010-06-17 13:23:18 +0000449 self.assertEqual(inspect.getsourcefile(co), None)
R. David Murraya1b37402010-06-17 02:04:29 +0000450 linecache.cache[co.co_filename] = (1, None, "None", co.co_filename)
Antoine Pitrou5d62a612012-07-08 13:48:46 +0200451 try:
452 self.assertEqual(normcase(inspect.getsourcefile(co)), fn)
453 finally:
454 del linecache.cache[co.co_filename]
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000455
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000456 def test_getfile(self):
457 self.assertEqual(inspect.getfile(mod.StupidGit), mod.__file__)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000458
Yury Selivanov2eed8b72014-01-27 13:24:56 -0500459 def test_getfile_class_without_module(self):
460 class CM(type):
461 @property
462 def __module__(cls):
463 raise AttributeError
464 class C(metaclass=CM):
465 pass
466 with self.assertRaises(TypeError):
467 inspect.getfile(C)
468
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000469 def test_getmodule_recursion(self):
Christian Heimes45f9af32007-11-27 21:50:00 +0000470 from types import ModuleType
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000471 name = '__inspect_dummy'
Christian Heimes45f9af32007-11-27 21:50:00 +0000472 m = sys.modules[name] = ModuleType(name)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000473 m.__file__ = "<string>" # hopefully not a real filename...
474 m.__loader__ = "dummy" # pretend the filename is understood by a loader
Georg Brandl7cae87c2006-09-06 06:51:57 +0000475 exec("def x(): pass", m.__dict__)
Neal Norwitz221085d2007-02-25 20:55:47 +0000476 self.assertEqual(inspect.getsourcefile(m.x.__code__), '<string>')
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000477 del sys.modules[name]
478 inspect.getmodule(compile('a=10','','single'))
479
Benjamin Peterson9620cc02011-06-11 15:53:11 -0500480 def test_proceed_with_fake_filename(self):
481 '''doctest monkeypatches linecache to enable inspection'''
482 fn, source = '<test>', 'def x(): pass\n'
483 getlines = linecache.getlines
484 def monkey(filename, module_globals=None):
485 if filename == fn:
Ezio Melottid8b509b2011-09-28 17:37:55 +0300486 return source.splitlines(keepends=True)
Benjamin Peterson9620cc02011-06-11 15:53:11 -0500487 else:
488 return getlines(filename, module_globals)
489 linecache.getlines = monkey
490 try:
491 ns = {}
492 exec(compile(source, fn, 'single'), ns)
493 inspect.getsource(ns["x"])
494 finally:
495 linecache.getlines = getlines
496
Antoine Pitroua8723a02015-04-15 00:41:29 +0200497 def test_getsource_on_code_object(self):
498 self.assertSourceEqual(mod.eggs.__code__, 12, 18)
499
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000500class TestDecorators(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000501 fodderModule = mod2
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000502
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000503 def test_wrapped_decorator(self):
Christian Heimes09aaa882008-02-23 15:01:06 +0000504 self.assertSourceEqual(mod2.wrapped, 14, 17)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000505
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000506 def test_replacing_decorator(self):
507 self.assertSourceEqual(mod2.gone, 9, 10)
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000508
Yury Selivanov081bbf62014-09-26 17:34:54 -0400509 def test_getsource_unwrap(self):
Antoine Pitroua8723a02015-04-15 00:41:29 +0200510 self.assertSourceEqual(mod2.real, 130, 132)
511
512 def test_decorator_with_lambda(self):
513 self.assertSourceEqual(mod2.func114, 113, 115)
Yury Selivanov081bbf62014-09-26 17:34:54 -0400514
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000515class TestOneliners(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000516 fodderModule = mod2
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000517 def test_oneline_lambda(self):
518 # Test inspect.getsource with a one-line lambda function.
519 self.assertSourceEqual(mod2.oll, 25, 25)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000520
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000521 def test_threeline_lambda(self):
522 # Test inspect.getsource with a three-line lambda function,
523 # where the second and third lines are _not_ indented.
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000524 self.assertSourceEqual(mod2.tll, 28, 30)
525
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000526 def test_twoline_indented_lambda(self):
527 # Test inspect.getsource with a two-line lambda function,
528 # where the second line _is_ indented.
529 self.assertSourceEqual(mod2.tlli, 33, 34)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000530
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000531 def test_onelinefunc(self):
532 # Test inspect.getsource with a regular one-line function.
533 self.assertSourceEqual(mod2.onelinefunc, 37, 37)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000534
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000535 def test_manyargs(self):
536 # Test inspect.getsource with a regular function where
537 # the arguments are on two lines and _not_ indented and
538 # the body on the second line with the last arguments.
539 self.assertSourceEqual(mod2.manyargs, 40, 41)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000540
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000541 def test_twolinefunc(self):
542 # Test inspect.getsource with a regular function where
543 # the body is on two lines, following the argument list and
544 # continued on the next line by a \\.
545 self.assertSourceEqual(mod2.twolinefunc, 44, 45)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000546
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000547 def test_lambda_in_list(self):
548 # Test inspect.getsource with a one-line lambda function
549 # defined in a list, indented.
550 self.assertSourceEqual(mod2.a[1], 49, 49)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000551
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000552 def test_anonymous(self):
553 # Test inspect.getsource with a lambda function defined
554 # as argument to another function.
555 self.assertSourceEqual(mod2.anonymous, 55, 55)
556
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000557class TestBuggyCases(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000558 fodderModule = mod2
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000559
560 def test_with_comment(self):
561 self.assertSourceEqual(mod2.with_comment, 58, 59)
562
563 def test_multiline_sig(self):
564 self.assertSourceEqual(mod2.multiline_sig[0], 63, 64)
565
Armin Rigodd5c0232005-09-25 11:45:45 +0000566 def test_nested_class(self):
567 self.assertSourceEqual(mod2.func69().func71, 71, 72)
568
569 def test_one_liner_followed_by_non_name(self):
570 self.assertSourceEqual(mod2.func77, 77, 77)
571
572 def test_one_liner_dedent_non_name(self):
573 self.assertSourceEqual(mod2.cls82.func83, 83, 83)
574
575 def test_with_comment_instead_of_docstring(self):
576 self.assertSourceEqual(mod2.func88, 88, 90)
577
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000578 def test_method_in_dynamic_class(self):
579 self.assertSourceEqual(mod2.method_in_dynamic_class, 95, 97)
580
R David Murray32562d72014-10-03 11:15:38 -0400581 # This should not skip for CPython, but might on a repackaged python where
582 # unicodedata is not an external module, or on pypy.
583 @unittest.skipIf(not hasattr(unicodedata, '__file__') or
584 unicodedata.__file__.endswith('.py'),
585 "unicodedata is not an external binary module")
R. David Murray74b89242009-05-13 17:33:03 +0000586 def test_findsource_binary(self):
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200587 self.assertRaises(OSError, inspect.getsource, unicodedata)
588 self.assertRaises(OSError, inspect.findsource, unicodedata)
R. David Murray74b89242009-05-13 17:33:03 +0000589
R. David Murraya1b37402010-06-17 02:04:29 +0000590 def test_findsource_code_in_linecache(self):
591 lines = ["x=1"]
592 co = compile(lines[0], "_dynamically_created_file", "exec")
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200593 self.assertRaises(OSError, inspect.findsource, co)
594 self.assertRaises(OSError, inspect.getsource, co)
R. David Murraya1b37402010-06-17 02:04:29 +0000595 linecache.cache[co.co_filename] = (1, None, lines, co.co_filename)
Antoine Pitrou5d62a612012-07-08 13:48:46 +0200596 try:
597 self.assertEqual(inspect.findsource(co), (lines,0))
598 self.assertEqual(inspect.getsource(co), lines[0])
599 finally:
600 del linecache.cache[co.co_filename]
R. David Murraya1b37402010-06-17 02:04:29 +0000601
Ezio Melotti1b145922013-03-30 05:17:24 +0200602 def test_findsource_without_filename(self):
603 for fname in ['', '<string>']:
604 co = compile('x=1', fname, "exec")
605 self.assertRaises(IOError, inspect.findsource, co)
606 self.assertRaises(IOError, inspect.getsource, co)
607
Antoine Pitroua8723a02015-04-15 00:41:29 +0200608 def test_getsource_on_method(self):
609 self.assertSourceEqual(mod2.ClassWithMethod.method, 118, 119)
610
Yury Selivanov4f4913b2015-07-23 17:10:00 +0300611 def test_nested_func(self):
612 self.assertSourceEqual(mod2.cls135.func136, 136, 139)
613
614
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000615class TestNoEOL(GetSourceBase):
Yury Selivanov6738b112015-05-16 10:10:21 -0400616 def setUp(self):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000617 self.tempdir = TESTFN + '_dir'
618 os.mkdir(self.tempdir)
619 with open(os.path.join(self.tempdir,
620 'inspect_fodder3%spy' % os.extsep), 'w') as f:
621 f.write("class X:\n pass # No EOL")
622 with DirsOnSysPath(self.tempdir):
623 import inspect_fodder3 as mod3
624 self.fodderModule = mod3
Yury Selivanov6738b112015-05-16 10:10:21 -0400625 super().setUp()
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000626
627 def tearDown(self):
628 shutil.rmtree(self.tempdir)
629
630 def test_class(self):
631 self.assertSourceEqual(self.fodderModule.X, 1, 2)
632
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100633
634class _BrokenDataDescriptor(object):
635 """
636 A broken data descriptor. See bug #1785.
637 """
638 def __get__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700639 raise AttributeError("broken data descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100640
641 def __set__(*args):
642 raise RuntimeError
643
644 def __getattr__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700645 raise AttributeError("broken data descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100646
647
648class _BrokenMethodDescriptor(object):
649 """
650 A broken method descriptor. See bug #1785.
651 """
652 def __get__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700653 raise AttributeError("broken method descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100654
655 def __getattr__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700656 raise AttributeError("broken method descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100657
658
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000659# Helper for testing classify_class_attrs.
Tim Peters13b49d32001-09-23 02:00:29 +0000660def attrs_wo_objs(cls):
661 return [t[:3] for t in inspect.classify_class_attrs(cls)]
662
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100663
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000664class TestClassesAndFunctions(unittest.TestCase):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000665 def test_newstyle_mro(self):
666 # The same w/ new-class MRO.
667 class A(object): pass
668 class B(A): pass
669 class C(A): pass
670 class D(B, C): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000671
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000672 expected = (D, B, C, A, object)
673 got = inspect.getmro(D)
674 self.assertEqual(expected, got)
Tim Peters13b49d32001-09-23 02:00:29 +0000675
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500676 def assertArgSpecEquals(self, routine, args_e, varargs_e=None,
677 varkw_e=None, defaults_e=None, formatted=None):
678 with self.assertWarns(DeprecationWarning):
679 args, varargs, varkw, defaults = inspect.getargspec(routine)
680 self.assertEqual(args, args_e)
681 self.assertEqual(varargs, varargs_e)
682 self.assertEqual(varkw, varkw_e)
683 self.assertEqual(defaults, defaults_e)
684 if formatted is not None:
685 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults),
686 formatted)
687
Christian Heimes3795b532007-11-08 13:48:53 +0000688 def assertFullArgSpecEquals(self, routine, args_e, varargs_e=None,
689 varkw_e=None, defaults_e=None,
690 kwonlyargs_e=[], kwonlydefaults_e=None,
691 ann_e={}, formatted=None):
692 args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \
693 inspect.getfullargspec(routine)
694 self.assertEqual(args, args_e)
695 self.assertEqual(varargs, varargs_e)
696 self.assertEqual(varkw, varkw_e)
697 self.assertEqual(defaults, defaults_e)
698 self.assertEqual(kwonlyargs, kwonlyargs_e)
699 self.assertEqual(kwonlydefaults, kwonlydefaults_e)
700 self.assertEqual(ann, ann_e)
701 if formatted is not None:
702 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults,
703 kwonlyargs, kwonlydefaults, ann),
704 formatted)
705
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500706 def test_getargspec(self):
707 self.assertArgSpecEquals(mod.eggs, ['x', 'y'], formatted='(x, y)')
708
709 self.assertArgSpecEquals(mod.spam,
710 ['a', 'b', 'c', 'd', 'e', 'f'],
711 'g', 'h', (3, 4, 5),
712 '(a, b, c, d=3, e=4, f=5, *g, **h)')
713
714 self.assertRaises(ValueError, self.assertArgSpecEquals,
715 mod2.keyworded, [])
716
717 self.assertRaises(ValueError, self.assertArgSpecEquals,
718 mod2.annotated, [])
719 self.assertRaises(ValueError, self.assertArgSpecEquals,
720 mod2.keyword_only_arg, [])
721
722
Christian Heimes3795b532007-11-08 13:48:53 +0000723 def test_getfullargspec(self):
724 self.assertFullArgSpecEquals(mod2.keyworded, [], varargs_e='arg1',
725 kwonlyargs_e=['arg2'],
726 kwonlydefaults_e={'arg2':1},
727 formatted='(*arg1, arg2=1)')
728
729 self.assertFullArgSpecEquals(mod2.annotated, ['arg1'],
Christian Heimesc9543e42007-11-28 08:28:28 +0000730 ann_e={'arg1' : list},
Christian Heimes3795b532007-11-08 13:48:53 +0000731 formatted='(arg1: list)')
Benjamin Peterson9953a8d2009-01-17 04:15:01 +0000732 self.assertFullArgSpecEquals(mod2.keyword_only_arg, [],
733 kwonlyargs_e=['arg'],
734 formatted='(*, arg)')
735
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500736 def test_argspec_api_ignores_wrapped(self):
Yury Selivanov57d240e2014-02-19 16:27:23 -0500737 # Issue 20684: low level introspection API must ignore __wrapped__
738 @functools.wraps(mod.spam)
739 def ham(x, y):
740 pass
741 # Basic check
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500742 self.assertArgSpecEquals(ham, ['x', 'y'], formatted='(x, y)')
Yury Selivanov57d240e2014-02-19 16:27:23 -0500743 self.assertFullArgSpecEquals(ham, ['x', 'y'], formatted='(x, y)')
744 self.assertFullArgSpecEquals(functools.partial(ham),
745 ['x', 'y'], formatted='(x, y)')
746 # Other variants
747 def check_method(f):
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500748 self.assertArgSpecEquals(f, ['self', 'x', 'y'],
749 formatted='(self, x, y)')
Yury Selivanov57d240e2014-02-19 16:27:23 -0500750 class C:
751 @functools.wraps(mod.spam)
752 def ham(self, x, y):
753 pass
754 pham = functools.partialmethod(ham)
755 @functools.wraps(mod.spam)
756 def __call__(self, x, y):
757 pass
758 check_method(C())
759 check_method(C.ham)
760 check_method(C().ham)
761 check_method(C.pham)
762 check_method(C().pham)
763
764 class C_new:
765 @functools.wraps(mod.spam)
766 def __new__(self, x, y):
767 pass
768 check_method(C_new)
769
770 class C_init:
771 @functools.wraps(mod.spam)
772 def __init__(self, x, y):
773 pass
774 check_method(C_init)
775
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500776 def test_getfullargspec_signature_attr(self):
777 def test():
778 pass
779 spam_param = inspect.Parameter('spam', inspect.Parameter.POSITIONAL_ONLY)
780 test.__signature__ = inspect.Signature(parameters=(spam_param,))
781
782 self.assertFullArgSpecEquals(test, args_e=['spam'], formatted='(spam)')
783
Yury Selivanov4cb93912014-01-29 11:54:12 -0500784 def test_getfullargspec_signature_annos(self):
785 def test(a:'spam') -> 'ham': pass
786 spec = inspect.getfullargspec(test)
787 self.assertEqual(test.__annotations__, spec.annotations)
788
789 def test(): pass
790 spec = inspect.getfullargspec(test)
791 self.assertEqual(test.__annotations__, spec.annotations)
792
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500793 @unittest.skipIf(MISSING_C_DOCSTRINGS,
794 "Signature information for builtins requires docstrings")
795 def test_getfullargspec_builtin_methods(self):
796 self.assertFullArgSpecEquals(_pickle.Pickler.dump,
797 args_e=['self', 'obj'], formatted='(self, obj)')
798
799 self.assertFullArgSpecEquals(_pickle.Pickler(io.BytesIO()).dump,
800 args_e=['self', 'obj'], formatted='(self, obj)')
801
Yury Selivanov8c185ee2014-02-21 01:32:42 -0500802 self.assertFullArgSpecEquals(
803 os.stat,
804 args_e=['path'],
805 kwonlyargs_e=['dir_fd', 'follow_symlinks'],
806 kwonlydefaults_e={'dir_fd': None, 'follow_symlinks': True},
807 formatted='(path, *, dir_fd=None, follow_symlinks=True)')
808
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200809 @cpython_only
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500810 @unittest.skipIf(MISSING_C_DOCSTRINGS,
811 "Signature information for builtins requires docstrings")
812 def test_getfullagrspec_builtin_func(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200813 import _testcapi
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500814 builtin = _testcapi.docstring_with_signature_with_defaults
815 spec = inspect.getfullargspec(builtin)
816 self.assertEqual(spec.defaults[0], 'avocado')
817
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200818 @cpython_only
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500819 @unittest.skipIf(MISSING_C_DOCSTRINGS,
820 "Signature information for builtins requires docstrings")
821 def test_getfullagrspec_builtin_func_no_signature(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200822 import _testcapi
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500823 builtin = _testcapi.docstring_no_signature
824 with self.assertRaises(TypeError):
825 inspect.getfullargspec(builtin)
Christian Heimes3795b532007-11-08 13:48:53 +0000826
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500827 def test_getargspec_method(self):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000828 class A(object):
829 def m(self):
830 pass
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500831 self.assertArgSpecEquals(A.m, ['self'])
Tim Peters13b49d32001-09-23 02:00:29 +0000832
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000833 def test_classify_newstyle(self):
834 class A(object):
Tim Peters13b49d32001-09-23 02:00:29 +0000835
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000836 def s(): pass
837 s = staticmethod(s)
Tim Peters13b49d32001-09-23 02:00:29 +0000838
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000839 def c(cls): pass
840 c = classmethod(c)
Tim Peters13b49d32001-09-23 02:00:29 +0000841
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000842 def getp(self): pass
843 p = property(getp)
Tim Peters13b49d32001-09-23 02:00:29 +0000844
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000845 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000846
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000847 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000848
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000849 datablob = '1'
Tim Peters13b49d32001-09-23 02:00:29 +0000850
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100851 dd = _BrokenDataDescriptor()
852 md = _BrokenMethodDescriptor()
853
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000854 attrs = attrs_wo_objs(A)
Yury Selivanov0860a0b2014-01-31 14:28:44 -0500855
856 self.assertIn(('__new__', 'method', object), attrs, 'missing __new__')
857 self.assertIn(('__init__', 'method', object), attrs, 'missing __init__')
858
Benjamin Peterson577473f2010-01-19 00:09:57 +0000859 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
860 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
861 self.assertIn(('p', 'property', A), attrs, 'missing property')
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000862 self.assertIn(('m', 'method', A), attrs,
863 'missing plain method: %r' % attrs)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000864 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
865 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100866 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
867 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000868
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000869 class B(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000870
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000871 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000872
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000873 attrs = attrs_wo_objs(B)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000874 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
875 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
876 self.assertIn(('p', 'property', A), attrs, 'missing property')
877 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
878 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
879 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100880 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
881 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000882
883
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000884 class C(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000885
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000886 def m(self): pass
887 def c(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000888
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000889 attrs = attrs_wo_objs(C)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000890 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
891 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
892 self.assertIn(('p', 'property', A), attrs, 'missing property')
893 self.assertIn(('m', 'method', C), attrs, 'missing plain method')
894 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
895 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100896 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
897 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000898
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000899 class D(B, C):
Tim Peters13b49d32001-09-23 02:00:29 +0000900
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000901 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000902
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000903 attrs = attrs_wo_objs(D)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000904 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
905 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
906 self.assertIn(('p', 'property', A), attrs, 'missing property')
907 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
908 self.assertIn(('m1', 'method', D), attrs, 'missing plain method')
909 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100910 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
911 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
912
913 def test_classify_builtin_types(self):
914 # Simple sanity check that all built-in types can have their
915 # attributes classified.
916 for name in dir(__builtins__):
917 builtin = getattr(__builtins__, name)
918 if isinstance(builtin, type):
919 inspect.classify_class_attrs(builtin)
920
Ethan Furman63c141c2013-10-18 00:27:39 -0700921 def test_classify_DynamicClassAttribute(self):
922 class Meta(type):
923 def __getattr__(self, name):
924 if name == 'ham':
925 return 'spam'
926 return super().__getattr__(name)
927 class VA(metaclass=Meta):
Ethan Furmane03ea372013-09-25 07:14:41 -0700928 @types.DynamicClassAttribute
929 def ham(self):
930 return 'eggs'
Ethan Furman63c141c2013-10-18 00:27:39 -0700931 should_find_dca = inspect.Attribute('ham', 'data', VA, VA.__dict__['ham'])
932 self.assertIn(should_find_dca, inspect.classify_class_attrs(VA))
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700933 should_find_ga = inspect.Attribute('ham', 'data', Meta, 'spam')
Ethan Furman63c141c2013-10-18 00:27:39 -0700934 self.assertIn(should_find_ga, inspect.classify_class_attrs(VA))
935
Yury Selivanovbf341fb2015-05-21 15:41:57 -0400936 def test_classify_overrides_bool(self):
937 class NoBool(object):
938 def __eq__(self, other):
939 return NoBool()
940
941 def __bool__(self):
942 raise NotImplementedError(
943 "This object does not specify a boolean value")
944
945 class HasNB(object):
946 dd = NoBool()
947
948 should_find_attr = inspect.Attribute('dd', 'data', HasNB, HasNB.dd)
949 self.assertIn(should_find_attr, inspect.classify_class_attrs(HasNB))
950
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700951 def test_classify_metaclass_class_attribute(self):
952 class Meta(type):
953 fish = 'slap'
954 def __dir__(self):
Serhiy Storchakaa60c2fe2015-03-12 21:56:08 +0200955 return ['__class__', '__module__', '__name__', 'fish']
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700956 class Class(metaclass=Meta):
957 pass
958 should_find = inspect.Attribute('fish', 'data', Meta, 'slap')
959 self.assertIn(should_find, inspect.classify_class_attrs(Class))
960
Ethan Furman63c141c2013-10-18 00:27:39 -0700961 def test_classify_VirtualAttribute(self):
962 class Meta(type):
963 def __dir__(cls):
964 return ['__class__', '__module__', '__name__', 'BOOM']
965 def __getattr__(self, name):
966 if name =='BOOM':
967 return 42
968 return super().__getattr(name)
969 class Class(metaclass=Meta):
970 pass
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700971 should_find = inspect.Attribute('BOOM', 'data', Meta, 42)
Ethan Furman63c141c2013-10-18 00:27:39 -0700972 self.assertIn(should_find, inspect.classify_class_attrs(Class))
973
974 def test_classify_VirtualAttribute_multi_classes(self):
975 class Meta1(type):
976 def __dir__(cls):
977 return ['__class__', '__module__', '__name__', 'one']
978 def __getattr__(self, name):
979 if name =='one':
980 return 1
981 return super().__getattr__(name)
982 class Meta2(type):
983 def __dir__(cls):
984 return ['__class__', '__module__', '__name__', 'two']
985 def __getattr__(self, name):
986 if name =='two':
987 return 2
988 return super().__getattr__(name)
989 class Meta3(Meta1, Meta2):
990 def __dir__(cls):
991 return list(sorted(set(['__class__', '__module__', '__name__', 'three'] +
992 Meta1.__dir__(cls) + Meta2.__dir__(cls))))
993 def __getattr__(self, name):
994 if name =='three':
995 return 3
996 return super().__getattr__(name)
997 class Class1(metaclass=Meta1):
998 pass
999 class Class2(Class1, metaclass=Meta3):
1000 pass
1001
Ethan Furmanb0c84cd2013-10-20 22:37:39 -07001002 should_find1 = inspect.Attribute('one', 'data', Meta1, 1)
1003 should_find2 = inspect.Attribute('two', 'data', Meta2, 2)
1004 should_find3 = inspect.Attribute('three', 'data', Meta3, 3)
Ethan Furman63c141c2013-10-18 00:27:39 -07001005 cca = inspect.classify_class_attrs(Class2)
1006 for sf in (should_find1, should_find2, should_find3):
1007 self.assertIn(sf, cca)
1008
1009 def test_classify_class_attrs_with_buggy_dir(self):
1010 class M(type):
1011 def __dir__(cls):
1012 return ['__class__', '__name__', 'missing']
1013 class C(metaclass=M):
1014 pass
1015 attrs = [a[0] for a in inspect.classify_class_attrs(C)]
1016 self.assertNotIn('missing', attrs)
Ethan Furmane03ea372013-09-25 07:14:41 -07001017
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +01001018 def test_getmembers_descriptors(self):
1019 class A(object):
1020 dd = _BrokenDataDescriptor()
1021 md = _BrokenMethodDescriptor()
1022
1023 def pred_wrapper(pred):
1024 # A quick'n'dirty way to discard standard attributes of new-style
1025 # classes.
1026 class Empty(object):
1027 pass
1028 def wrapped(x):
1029 if '__name__' in dir(x) and hasattr(Empty, x.__name__):
1030 return False
1031 return pred(x)
1032 return wrapped
1033
1034 ismethoddescriptor = pred_wrapper(inspect.ismethoddescriptor)
1035 isdatadescriptor = pred_wrapper(inspect.isdatadescriptor)
1036
1037 self.assertEqual(inspect.getmembers(A, ismethoddescriptor),
1038 [('md', A.__dict__['md'])])
1039 self.assertEqual(inspect.getmembers(A, isdatadescriptor),
1040 [('dd', A.__dict__['dd'])])
1041
1042 class B(A):
1043 pass
1044
1045 self.assertEqual(inspect.getmembers(B, ismethoddescriptor),
1046 [('md', A.__dict__['md'])])
1047 self.assertEqual(inspect.getmembers(B, isdatadescriptor),
1048 [('dd', A.__dict__['dd'])])
1049
Antoine Pitrou0c603812012-01-18 17:40:18 +01001050 def test_getmembers_method(self):
1051 class B:
1052 def f(self):
1053 pass
1054
1055 self.assertIn(('f', B.f), inspect.getmembers(B))
1056 self.assertNotIn(('f', B.f), inspect.getmembers(B, inspect.ismethod))
1057 b = B()
1058 self.assertIn(('f', b.f), inspect.getmembers(b))
1059 self.assertIn(('f', b.f), inspect.getmembers(b, inspect.ismethod))
1060
Ethan Furmane03ea372013-09-25 07:14:41 -07001061 def test_getmembers_VirtualAttribute(self):
Ethan Furman63c141c2013-10-18 00:27:39 -07001062 class M(type):
1063 def __getattr__(cls, name):
1064 if name == 'eggs':
1065 return 'scrambled'
1066 return super().__getattr__(name)
1067 class A(metaclass=M):
Ethan Furmane03ea372013-09-25 07:14:41 -07001068 @types.DynamicClassAttribute
1069 def eggs(self):
1070 return 'spam'
Ethan Furman63c141c2013-10-18 00:27:39 -07001071 self.assertIn(('eggs', 'scrambled'), inspect.getmembers(A))
1072 self.assertIn(('eggs', 'spam'), inspect.getmembers(A()))
1073
1074 def test_getmembers_with_buggy_dir(self):
1075 class M(type):
1076 def __dir__(cls):
1077 return ['__class__', '__name__', 'missing']
1078 class C(metaclass=M):
1079 pass
1080 attrs = [a[0] for a in inspect.getmembers(C)]
1081 self.assertNotIn('missing', attrs)
Ethan Furmane03ea372013-09-25 07:14:41 -07001082
Jeremy Hyltonc4bf5ed2003-06-27 18:43:12 +00001083
Nick Coghlan2f92e542012-06-23 19:39:55 +10001084_global_ref = object()
1085class TestGetClosureVars(unittest.TestCase):
1086
1087 def test_name_resolution(self):
1088 # Basic test of the 4 different resolution mechanisms
1089 def f(nonlocal_ref):
1090 def g(local_ref):
1091 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
1092 return g
1093 _arg = object()
1094 nonlocal_vars = {"nonlocal_ref": _arg}
1095 global_vars = {"_global_ref": _global_ref}
1096 builtin_vars = {"print": print}
1097 unbound_names = {"unbound_ref"}
1098 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
1099 builtin_vars, unbound_names)
1100 self.assertEqual(inspect.getclosurevars(f(_arg)), expected)
1101
1102 def test_generator_closure(self):
1103 def f(nonlocal_ref):
1104 def g(local_ref):
1105 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
1106 yield
1107 return g
1108 _arg = object()
1109 nonlocal_vars = {"nonlocal_ref": _arg}
1110 global_vars = {"_global_ref": _global_ref}
1111 builtin_vars = {"print": print}
1112 unbound_names = {"unbound_ref"}
1113 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
1114 builtin_vars, unbound_names)
1115 self.assertEqual(inspect.getclosurevars(f(_arg)), expected)
1116
1117 def test_method_closure(self):
1118 class C:
1119 def f(self, nonlocal_ref):
1120 def g(local_ref):
1121 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
1122 return g
1123 _arg = object()
1124 nonlocal_vars = {"nonlocal_ref": _arg}
1125 global_vars = {"_global_ref": _global_ref}
1126 builtin_vars = {"print": print}
1127 unbound_names = {"unbound_ref"}
1128 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
1129 builtin_vars, unbound_names)
1130 self.assertEqual(inspect.getclosurevars(C().f(_arg)), expected)
1131
1132 def test_nonlocal_vars(self):
1133 # More complex tests of nonlocal resolution
1134 def _nonlocal_vars(f):
1135 return inspect.getclosurevars(f).nonlocals
1136
1137 def make_adder(x):
1138 def add(y):
1139 return x + y
1140 return add
1141
1142 def curry(func, arg1):
1143 return lambda arg2: func(arg1, arg2)
1144
1145 def less_than(a, b):
1146 return a < b
1147
1148 # The infamous Y combinator.
1149 def Y(le):
1150 def g(f):
1151 return le(lambda x: f(f)(x))
1152 Y.g_ref = g
1153 return g(g)
1154
1155 def check_y_combinator(func):
1156 self.assertEqual(_nonlocal_vars(func), {'f': Y.g_ref})
1157
1158 inc = make_adder(1)
1159 add_two = make_adder(2)
1160 greater_than_five = curry(less_than, 5)
1161
1162 self.assertEqual(_nonlocal_vars(inc), {'x': 1})
1163 self.assertEqual(_nonlocal_vars(add_two), {'x': 2})
1164 self.assertEqual(_nonlocal_vars(greater_than_five),
1165 {'arg1': 5, 'func': less_than})
1166 self.assertEqual(_nonlocal_vars((lambda x: lambda y: x + y)(3)),
1167 {'x': 3})
1168 Y(check_y_combinator)
1169
1170 def test_getclosurevars_empty(self):
1171 def foo(): pass
1172 _empty = inspect.ClosureVars({}, {}, {}, set())
1173 self.assertEqual(inspect.getclosurevars(lambda: True), _empty)
1174 self.assertEqual(inspect.getclosurevars(foo), _empty)
1175
1176 def test_getclosurevars_error(self):
1177 class T: pass
1178 self.assertRaises(TypeError, inspect.getclosurevars, 1)
1179 self.assertRaises(TypeError, inspect.getclosurevars, list)
1180 self.assertRaises(TypeError, inspect.getclosurevars, {})
1181
Nick Coghlan6c6e2542012-06-23 20:07:39 +10001182 def _private_globals(self):
1183 code = """def f(): print(path)"""
1184 ns = {}
1185 exec(code, ns)
1186 return ns["f"], ns
1187
1188 def test_builtins_fallback(self):
1189 f, ns = self._private_globals()
1190 ns.pop("__builtins__", None)
1191 expected = inspect.ClosureVars({}, {}, {"print":print}, {"path"})
1192 self.assertEqual(inspect.getclosurevars(f), expected)
1193
1194 def test_builtins_as_dict(self):
1195 f, ns = self._private_globals()
1196 ns["__builtins__"] = {"path":1}
1197 expected = inspect.ClosureVars({}, {}, {"path":1}, {"print"})
1198 self.assertEqual(inspect.getclosurevars(f), expected)
1199
1200 def test_builtins_as_module(self):
1201 f, ns = self._private_globals()
1202 ns["__builtins__"] = os
1203 expected = inspect.ClosureVars({}, {}, {"path":os.path}, {"print"})
1204 self.assertEqual(inspect.getclosurevars(f), expected)
1205
Nick Coghlan2f92e542012-06-23 19:39:55 +10001206
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001207class TestGetcallargsFunctions(unittest.TestCase):
1208
1209 def assertEqualCallArgs(self, func, call_params_string, locs=None):
1210 locs = dict(locs or {}, func=func)
1211 r1 = eval('func(%s)' % call_params_string, None, locs)
1212 r2 = eval('inspect.getcallargs(func, %s)' % call_params_string, None,
1213 locs)
1214 self.assertEqual(r1, r2)
1215
1216 def assertEqualException(self, func, call_param_string, locs=None):
1217 locs = dict(locs or {}, func=func)
1218 try:
1219 eval('func(%s)' % call_param_string, None, locs)
1220 except Exception as e:
1221 ex1 = e
1222 else:
1223 self.fail('Exception not raised')
1224 try:
1225 eval('inspect.getcallargs(func, %s)' % call_param_string, None,
1226 locs)
1227 except Exception as e:
1228 ex2 = e
1229 else:
1230 self.fail('Exception not raised')
1231 self.assertIs(type(ex1), type(ex2))
1232 self.assertEqual(str(ex1), str(ex2))
1233 del ex1, ex2
1234
1235 def makeCallable(self, signature):
1236 """Create a function that returns its locals()"""
1237 code = "lambda %s: locals()"
1238 return eval(code % signature)
1239
1240 def test_plain(self):
1241 f = self.makeCallable('a, b=1')
1242 self.assertEqualCallArgs(f, '2')
1243 self.assertEqualCallArgs(f, '2, 3')
1244 self.assertEqualCallArgs(f, 'a=2')
1245 self.assertEqualCallArgs(f, 'b=3, a=2')
1246 self.assertEqualCallArgs(f, '2, b=3')
1247 # expand *iterable / **mapping
1248 self.assertEqualCallArgs(f, '*(2,)')
1249 self.assertEqualCallArgs(f, '*[2]')
1250 self.assertEqualCallArgs(f, '*(2, 3)')
1251 self.assertEqualCallArgs(f, '*[2, 3]')
1252 self.assertEqualCallArgs(f, '**{"a":2}')
1253 self.assertEqualCallArgs(f, 'b=3, **{"a":2}')
1254 self.assertEqualCallArgs(f, '2, **{"b":3}')
1255 self.assertEqualCallArgs(f, '**{"b":3, "a":2}')
1256 # expand UserList / UserDict
1257 self.assertEqualCallArgs(f, '*collections.UserList([2])')
1258 self.assertEqualCallArgs(f, '*collections.UserList([2, 3])')
1259 self.assertEqualCallArgs(f, '**collections.UserDict(a=2)')
1260 self.assertEqualCallArgs(f, '2, **collections.UserDict(b=3)')
1261 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3)')
1262
1263 def test_varargs(self):
1264 f = self.makeCallable('a, b=1, *c')
1265 self.assertEqualCallArgs(f, '2')
1266 self.assertEqualCallArgs(f, '2, 3')
1267 self.assertEqualCallArgs(f, '2, 3, 4')
1268 self.assertEqualCallArgs(f, '*(2,3,4)')
1269 self.assertEqualCallArgs(f, '2, *[3,4]')
1270 self.assertEqualCallArgs(f, '2, 3, *collections.UserList([4])')
1271
1272 def test_varkw(self):
1273 f = self.makeCallable('a, b=1, **c')
1274 self.assertEqualCallArgs(f, 'a=2')
1275 self.assertEqualCallArgs(f, '2, b=3, c=4')
1276 self.assertEqualCallArgs(f, 'b=3, a=2, c=4')
1277 self.assertEqualCallArgs(f, 'c=4, **{"a":2, "b":3}')
1278 self.assertEqualCallArgs(f, '2, c=4, **{"b":3}')
1279 self.assertEqualCallArgs(f, 'b=2, **{"a":3, "c":4}')
1280 self.assertEqualCallArgs(f, '**collections.UserDict(a=2, b=3, c=4)')
1281 self.assertEqualCallArgs(f, '2, c=4, **collections.UserDict(b=3)')
1282 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3, c=4)')
1283
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001284 def test_varkw_only(self):
1285 # issue11256:
1286 f = self.makeCallable('**c')
1287 self.assertEqualCallArgs(f, '')
1288 self.assertEqualCallArgs(f, 'a=1')
1289 self.assertEqualCallArgs(f, 'a=1, b=2')
1290 self.assertEqualCallArgs(f, 'c=3, **{"a": 1, "b": 2}')
1291 self.assertEqualCallArgs(f, '**collections.UserDict(a=1, b=2)')
1292 self.assertEqualCallArgs(f, 'c=3, **collections.UserDict(a=1, b=2)')
1293
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001294 def test_keyword_only(self):
1295 f = self.makeCallable('a=3, *, c, d=2')
1296 self.assertEqualCallArgs(f, 'c=3')
1297 self.assertEqualCallArgs(f, 'c=3, a=3')
1298 self.assertEqualCallArgs(f, 'a=2, c=4')
1299 self.assertEqualCallArgs(f, '4, c=4')
1300 self.assertEqualException(f, '')
1301 self.assertEqualException(f, '3')
1302 self.assertEqualException(f, 'a=3')
1303 self.assertEqualException(f, 'd=4')
1304
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001305 f = self.makeCallable('*, c, d=2')
1306 self.assertEqualCallArgs(f, 'c=3')
1307 self.assertEqualCallArgs(f, 'c=3, d=4')
1308 self.assertEqualCallArgs(f, 'd=4, c=3')
1309
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001310 def test_multiple_features(self):
1311 f = self.makeCallable('a, b=2, *f, **g')
1312 self.assertEqualCallArgs(f, '2, 3, 7')
1313 self.assertEqualCallArgs(f, '2, 3, x=8')
1314 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
1315 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9')
1316 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9')
1317 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
1318 '[2, 3, (4,[5,6])]), **{"y":9, "z":10}')
1319 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
1320 '(4,[5,6])]), **collections.UserDict('
1321 'y=9, z=10)')
1322
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001323 f = self.makeCallable('a, b=2, *f, x, y=99, **g')
1324 self.assertEqualCallArgs(f, '2, 3, x=8')
1325 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
1326 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9, z=10')
1327 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9, z=10')
1328 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
1329 '[2, 3, (4,[5,6])]), q=0, **{"y":9, "z":10}')
1330 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
1331 '(4,[5,6])]), q=0, **collections.UserDict('
1332 'y=9, z=10)')
1333
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001334 def test_errors(self):
1335 f0 = self.makeCallable('')
1336 f1 = self.makeCallable('a, b')
1337 f2 = self.makeCallable('a, b=1')
1338 # f0 takes no arguments
1339 self.assertEqualException(f0, '1')
1340 self.assertEqualException(f0, 'x=1')
1341 self.assertEqualException(f0, '1,x=1')
1342 # f1 takes exactly 2 arguments
1343 self.assertEqualException(f1, '')
1344 self.assertEqualException(f1, '1')
1345 self.assertEqualException(f1, 'a=2')
1346 self.assertEqualException(f1, 'b=3')
1347 # f2 takes at least 1 argument
1348 self.assertEqualException(f2, '')
1349 self.assertEqualException(f2, 'b=3')
1350 for f in f1, f2:
1351 # f1/f2 takes exactly/at most 2 arguments
1352 self.assertEqualException(f, '2, 3, 4')
1353 self.assertEqualException(f, '1, 2, 3, a=1')
1354 self.assertEqualException(f, '2, 3, 4, c=5')
Georg Brandl178e5ea2012-02-21 00:32:36 +01001355 # XXX: success of this one depends on dict order
1356 ## self.assertEqualException(f, '2, 3, 4, a=1, c=5')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001357 # f got an unexpected keyword argument
1358 self.assertEqualException(f, 'c=2')
1359 self.assertEqualException(f, '2, c=3')
1360 self.assertEqualException(f, '2, 3, c=4')
1361 self.assertEqualException(f, '2, c=4, b=3')
1362 self.assertEqualException(f, '**{u"\u03c0\u03b9": 4}')
1363 # f got multiple values for keyword argument
1364 self.assertEqualException(f, '1, a=2')
1365 self.assertEqualException(f, '1, **{"a":2}')
1366 self.assertEqualException(f, '1, 2, b=3')
1367 # XXX: Python inconsistency
1368 # - for functions and bound methods: unexpected keyword 'c'
1369 # - for unbound methods: multiple values for keyword 'a'
1370 #self.assertEqualException(f, '1, c=3, a=2')
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001371 # issue11256:
1372 f3 = self.makeCallable('**c')
1373 self.assertEqualException(f3, '1, 2')
1374 self.assertEqualException(f3, '1, 2, a=1, b=2')
1375 f4 = self.makeCallable('*, a, b=0')
1376 self.assertEqualException(f3, '1, 2')
1377 self.assertEqualException(f3, '1, 2, a=1, b=2')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001378
Yury Selivanov875df202014-03-27 18:23:03 -04001379 # issue #20816: getcallargs() fails to iterate over non-existent
1380 # kwonlydefaults and raises a wrong TypeError
1381 def f5(*, a): pass
1382 with self.assertRaisesRegex(TypeError,
1383 'missing 1 required keyword-only'):
1384 inspect.getcallargs(f5)
1385
1386
Yury Selivanovdccfa132014-03-27 18:42:52 -04001387 # issue20817:
1388 def f6(a, b, c):
1389 pass
1390 with self.assertRaisesRegex(TypeError, "'a', 'b' and 'c'"):
1391 inspect.getcallargs(f6)
1392
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001393class TestGetcallargsMethods(TestGetcallargsFunctions):
1394
1395 def setUp(self):
1396 class Foo(object):
1397 pass
1398 self.cls = Foo
1399 self.inst = Foo()
1400
1401 def makeCallable(self, signature):
1402 assert 'self' not in signature
1403 mk = super(TestGetcallargsMethods, self).makeCallable
1404 self.cls.method = mk('self, ' + signature)
1405 return self.inst.method
1406
1407class TestGetcallargsUnboundMethods(TestGetcallargsMethods):
1408
1409 def makeCallable(self, signature):
1410 super(TestGetcallargsUnboundMethods, self).makeCallable(signature)
1411 return self.cls.method
1412
1413 def assertEqualCallArgs(self, func, call_params_string, locs=None):
1414 return super(TestGetcallargsUnboundMethods, self).assertEqualCallArgs(
1415 *self._getAssertEqualParams(func, call_params_string, locs))
1416
1417 def assertEqualException(self, func, call_params_string, locs=None):
1418 return super(TestGetcallargsUnboundMethods, self).assertEqualException(
1419 *self._getAssertEqualParams(func, call_params_string, locs))
1420
1421 def _getAssertEqualParams(self, func, call_params_string, locs=None):
1422 assert 'inst' not in call_params_string
1423 locs = dict(locs or {}, inst=self.inst)
1424 return (func, 'inst,' + call_params_string, locs)
1425
Michael Foord95fc51d2010-11-20 15:07:30 +00001426
1427class TestGetattrStatic(unittest.TestCase):
1428
1429 def test_basic(self):
1430 class Thing(object):
1431 x = object()
1432
1433 thing = Thing()
1434 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1435 self.assertEqual(inspect.getattr_static(thing, 'x', None), Thing.x)
1436 with self.assertRaises(AttributeError):
1437 inspect.getattr_static(thing, 'y')
1438
1439 self.assertEqual(inspect.getattr_static(thing, 'y', 3), 3)
1440
1441 def test_inherited(self):
1442 class Thing(object):
1443 x = object()
1444 class OtherThing(Thing):
1445 pass
1446
1447 something = OtherThing()
1448 self.assertEqual(inspect.getattr_static(something, 'x'), Thing.x)
1449
1450 def test_instance_attr(self):
1451 class Thing(object):
1452 x = 2
1453 def __init__(self, x):
1454 self.x = x
1455 thing = Thing(3)
1456 self.assertEqual(inspect.getattr_static(thing, 'x'), 3)
1457 del thing.x
1458 self.assertEqual(inspect.getattr_static(thing, 'x'), 2)
1459
1460 def test_property(self):
1461 class Thing(object):
1462 @property
1463 def x(self):
1464 raise AttributeError("I'm pretending not to exist")
1465 thing = Thing()
1466 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1467
Ezio Melotti75cbd732011-04-28 00:59:29 +03001468 def test_descriptor_raises_AttributeError(self):
Michael Foord95fc51d2010-11-20 15:07:30 +00001469 class descriptor(object):
1470 def __get__(*_):
1471 raise AttributeError("I'm pretending not to exist")
1472 desc = descriptor()
1473 class Thing(object):
1474 x = desc
1475 thing = Thing()
1476 self.assertEqual(inspect.getattr_static(thing, 'x'), desc)
1477
1478 def test_classAttribute(self):
1479 class Thing(object):
1480 x = object()
1481
1482 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.x)
1483
Ethan Furmane03ea372013-09-25 07:14:41 -07001484 def test_classVirtualAttribute(self):
1485 class Thing(object):
1486 @types.DynamicClassAttribute
1487 def x(self):
1488 return self._x
1489 _x = object()
1490
1491 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.__dict__['x'])
1492
Michael Foord95fc51d2010-11-20 15:07:30 +00001493 def test_inherited_classattribute(self):
1494 class Thing(object):
1495 x = object()
1496 class OtherThing(Thing):
1497 pass
1498
1499 self.assertEqual(inspect.getattr_static(OtherThing, 'x'), Thing.x)
1500
1501 def test_slots(self):
1502 class Thing(object):
1503 y = 'bar'
1504 __slots__ = ['x']
1505 def __init__(self):
1506 self.x = 'foo'
1507 thing = Thing()
1508 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1509 self.assertEqual(inspect.getattr_static(thing, 'y'), 'bar')
1510
1511 del thing.x
1512 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1513
1514 def test_metaclass(self):
1515 class meta(type):
1516 attr = 'foo'
1517 class Thing(object, metaclass=meta):
1518 pass
1519 self.assertEqual(inspect.getattr_static(Thing, 'attr'), 'foo')
1520
1521 class sub(meta):
1522 pass
1523 class OtherThing(object, metaclass=sub):
1524 x = 3
1525 self.assertEqual(inspect.getattr_static(OtherThing, 'attr'), 'foo')
1526
1527 class OtherOtherThing(OtherThing):
1528 pass
1529 # this test is odd, but it was added as it exposed a bug
1530 self.assertEqual(inspect.getattr_static(OtherOtherThing, 'x'), 3)
1531
1532 def test_no_dict_no_slots(self):
1533 self.assertEqual(inspect.getattr_static(1, 'foo', None), None)
1534 self.assertNotEqual(inspect.getattr_static('foo', 'lower'), None)
1535
1536 def test_no_dict_no_slots_instance_member(self):
1537 # returns descriptor
1538 with open(__file__) as handle:
1539 self.assertEqual(inspect.getattr_static(handle, 'name'), type(handle).name)
1540
1541 def test_inherited_slots(self):
1542 # returns descriptor
1543 class Thing(object):
1544 __slots__ = ['x']
1545 def __init__(self):
1546 self.x = 'foo'
1547
1548 class OtherThing(Thing):
1549 pass
1550 # it would be nice if this worked...
1551 # we get the descriptor instead of the instance attribute
1552 self.assertEqual(inspect.getattr_static(OtherThing(), 'x'), Thing.x)
1553
1554 def test_descriptor(self):
1555 class descriptor(object):
1556 def __get__(self, instance, owner):
1557 return 3
1558 class Foo(object):
1559 d = descriptor()
1560
1561 foo = Foo()
1562
1563 # for a non data descriptor we return the instance attribute
1564 foo.__dict__['d'] = 1
1565 self.assertEqual(inspect.getattr_static(foo, 'd'), 1)
1566
1567 # if the descriptor is a data-desciptor we should return the
1568 # descriptor
1569 descriptor.__set__ = lambda s, i, v: None
1570 self.assertEqual(inspect.getattr_static(foo, 'd'), Foo.__dict__['d'])
1571
1572
1573 def test_metaclass_with_descriptor(self):
1574 class descriptor(object):
1575 def __get__(self, instance, owner):
1576 return 3
1577 class meta(type):
1578 d = descriptor()
1579 class Thing(object, metaclass=meta):
1580 pass
1581 self.assertEqual(inspect.getattr_static(Thing, 'd'), meta.__dict__['d'])
1582
1583
Michael Foordcc7ebb82010-11-20 16:20:16 +00001584 def test_class_as_property(self):
1585 class Base(object):
1586 foo = 3
1587
1588 class Something(Base):
Michael Foord35184ed2010-11-20 16:58:30 +00001589 executed = False
Michael Foordcc7ebb82010-11-20 16:20:16 +00001590 @property
1591 def __class__(self):
Michael Foord35184ed2010-11-20 16:58:30 +00001592 self.executed = True
Michael Foordcc7ebb82010-11-20 16:20:16 +00001593 return object
1594
Michael Foord35184ed2010-11-20 16:58:30 +00001595 instance = Something()
1596 self.assertEqual(inspect.getattr_static(instance, 'foo'), 3)
1597 self.assertFalse(instance.executed)
Michael Foordcc7ebb82010-11-20 16:20:16 +00001598 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1599
Michael Foorde5162652010-11-20 16:40:44 +00001600 def test_mro_as_property(self):
1601 class Meta(type):
1602 @property
1603 def __mro__(self):
1604 return (object,)
1605
1606 class Base(object):
1607 foo = 3
1608
1609 class Something(Base, metaclass=Meta):
1610 pass
1611
1612 self.assertEqual(inspect.getattr_static(Something(), 'foo'), 3)
1613 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1614
Michael Foorddcebe0f2011-03-15 19:20:44 -04001615 def test_dict_as_property(self):
1616 test = self
1617 test.called = False
1618
1619 class Foo(dict):
1620 a = 3
1621 @property
1622 def __dict__(self):
1623 test.called = True
1624 return {}
1625
1626 foo = Foo()
1627 foo.a = 4
1628 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1629 self.assertFalse(test.called)
1630
1631 def test_custom_object_dict(self):
1632 test = self
1633 test.called = False
1634
1635 class Custom(dict):
1636 def get(self, key, default=None):
1637 test.called = True
1638 super().get(key, default)
1639
1640 class Foo(object):
1641 a = 3
1642 foo = Foo()
1643 foo.__dict__ = Custom()
1644 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1645 self.assertFalse(test.called)
1646
1647 def test_metaclass_dict_as_property(self):
1648 class Meta(type):
1649 @property
1650 def __dict__(self):
1651 self.executed = True
1652
1653 class Thing(metaclass=Meta):
1654 executed = False
1655
1656 def __init__(self):
1657 self.spam = 42
1658
1659 instance = Thing()
1660 self.assertEqual(inspect.getattr_static(instance, "spam"), 42)
1661 self.assertFalse(Thing.executed)
Michael Foorde5162652010-11-20 16:40:44 +00001662
Michael Foorda51623b2011-12-18 22:01:40 +00001663 def test_module(self):
1664 sentinel = object()
1665 self.assertIsNot(inspect.getattr_static(sys, "version", sentinel),
1666 sentinel)
1667
Michael Foord3ba95f82011-12-22 01:13:37 +00001668 def test_metaclass_with_metaclass_with_dict_as_property(self):
1669 class MetaMeta(type):
1670 @property
1671 def __dict__(self):
1672 self.executed = True
1673 return dict(spam=42)
1674
1675 class Meta(type, metaclass=MetaMeta):
1676 executed = False
1677
1678 class Thing(metaclass=Meta):
1679 pass
1680
1681 with self.assertRaises(AttributeError):
1682 inspect.getattr_static(Thing, "spam")
1683 self.assertFalse(Thing.executed)
1684
Nick Coghlane0f04652010-11-21 03:44:04 +00001685class TestGetGeneratorState(unittest.TestCase):
1686
1687 def setUp(self):
1688 def number_generator():
1689 for number in range(5):
1690 yield number
1691 self.generator = number_generator()
1692
1693 def _generatorstate(self):
1694 return inspect.getgeneratorstate(self.generator)
1695
1696 def test_created(self):
1697 self.assertEqual(self._generatorstate(), inspect.GEN_CREATED)
1698
1699 def test_suspended(self):
1700 next(self.generator)
1701 self.assertEqual(self._generatorstate(), inspect.GEN_SUSPENDED)
1702
1703 def test_closed_after_exhaustion(self):
1704 for i in self.generator:
1705 pass
1706 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1707
1708 def test_closed_after_immediate_exception(self):
1709 with self.assertRaises(RuntimeError):
1710 self.generator.throw(RuntimeError)
1711 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1712
1713 def test_running(self):
1714 # As mentioned on issue #10220, checking for the RUNNING state only
1715 # makes sense inside the generator itself.
1716 # The following generator checks for this by using the closure's
1717 # reference to self and the generator state checking helper method
1718 def running_check_generator():
1719 for number in range(5):
1720 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1721 yield number
1722 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1723 self.generator = running_check_generator()
1724 # Running up to the first yield
1725 next(self.generator)
1726 # Running after the first yield
1727 next(self.generator)
1728
Nick Coghlan7921b9f2010-11-30 06:36:04 +00001729 def test_easy_debugging(self):
1730 # repr() and str() of a generator state should contain the state name
1731 names = 'GEN_CREATED GEN_RUNNING GEN_SUSPENDED GEN_CLOSED'.split()
1732 for name in names:
1733 state = getattr(inspect, name)
1734 self.assertIn(name, repr(state))
1735 self.assertIn(name, str(state))
1736
Nick Coghlan04e2e3f2012-06-23 19:52:05 +10001737 def test_getgeneratorlocals(self):
1738 def each(lst, a=None):
1739 b=(1, 2, 3)
1740 for v in lst:
1741 if v == 3:
1742 c = 12
1743 yield v
1744
1745 numbers = each([1, 2, 3])
1746 self.assertEqual(inspect.getgeneratorlocals(numbers),
1747 {'a': None, 'lst': [1, 2, 3]})
1748 next(numbers)
1749 self.assertEqual(inspect.getgeneratorlocals(numbers),
1750 {'a': None, 'lst': [1, 2, 3], 'v': 1,
1751 'b': (1, 2, 3)})
1752 next(numbers)
1753 self.assertEqual(inspect.getgeneratorlocals(numbers),
1754 {'a': None, 'lst': [1, 2, 3], 'v': 2,
1755 'b': (1, 2, 3)})
1756 next(numbers)
1757 self.assertEqual(inspect.getgeneratorlocals(numbers),
1758 {'a': None, 'lst': [1, 2, 3], 'v': 3,
1759 'b': (1, 2, 3), 'c': 12})
1760 try:
1761 next(numbers)
1762 except StopIteration:
1763 pass
1764 self.assertEqual(inspect.getgeneratorlocals(numbers), {})
1765
1766 def test_getgeneratorlocals_empty(self):
1767 def yield_one():
1768 yield 1
1769 one = yield_one()
1770 self.assertEqual(inspect.getgeneratorlocals(one), {})
1771 try:
1772 next(one)
1773 except StopIteration:
1774 pass
1775 self.assertEqual(inspect.getgeneratorlocals(one), {})
1776
1777 def test_getgeneratorlocals_error(self):
1778 self.assertRaises(TypeError, inspect.getgeneratorlocals, 1)
1779 self.assertRaises(TypeError, inspect.getgeneratorlocals, lambda x: True)
1780 self.assertRaises(TypeError, inspect.getgeneratorlocals, set)
1781 self.assertRaises(TypeError, inspect.getgeneratorlocals, (2,3))
1782
Nick Coghlane0f04652010-11-21 03:44:04 +00001783
Yury Selivanov5376ba92015-06-22 12:19:30 -04001784class TestGetCoroutineState(unittest.TestCase):
1785
1786 def setUp(self):
1787 @types.coroutine
1788 def number_coroutine():
1789 for number in range(5):
1790 yield number
1791 async def coroutine():
1792 await number_coroutine()
1793 self.coroutine = coroutine()
1794
1795 def tearDown(self):
1796 self.coroutine.close()
1797
1798 def _coroutinestate(self):
1799 return inspect.getcoroutinestate(self.coroutine)
1800
1801 def test_created(self):
1802 self.assertEqual(self._coroutinestate(), inspect.CORO_CREATED)
1803
1804 def test_suspended(self):
1805 self.coroutine.send(None)
1806 self.assertEqual(self._coroutinestate(), inspect.CORO_SUSPENDED)
1807
1808 def test_closed_after_exhaustion(self):
1809 while True:
1810 try:
1811 self.coroutine.send(None)
1812 except StopIteration:
1813 break
1814
1815 self.assertEqual(self._coroutinestate(), inspect.CORO_CLOSED)
1816
1817 def test_closed_after_immediate_exception(self):
1818 with self.assertRaises(RuntimeError):
1819 self.coroutine.throw(RuntimeError)
1820 self.assertEqual(self._coroutinestate(), inspect.CORO_CLOSED)
1821
1822 def test_easy_debugging(self):
1823 # repr() and str() of a coroutine state should contain the state name
1824 names = 'CORO_CREATED CORO_RUNNING CORO_SUSPENDED CORO_CLOSED'.split()
1825 for name in names:
1826 state = getattr(inspect, name)
1827 self.assertIn(name, repr(state))
1828 self.assertIn(name, str(state))
1829
1830 def test_getcoroutinelocals(self):
1831 @types.coroutine
1832 def gencoro():
1833 yield
1834
1835 gencoro = gencoro()
1836 async def func(a=None):
1837 b = 'spam'
1838 await gencoro
1839
1840 coro = func()
1841 self.assertEqual(inspect.getcoroutinelocals(coro),
1842 {'a': None, 'gencoro': gencoro})
1843 coro.send(None)
1844 self.assertEqual(inspect.getcoroutinelocals(coro),
1845 {'a': None, 'gencoro': gencoro, 'b': 'spam'})
1846
1847
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001848class MySignature(inspect.Signature):
1849 # Top-level to make it picklable;
1850 # used in test_signature_object_pickle
1851 pass
1852
1853class MyParameter(inspect.Parameter):
1854 # Top-level to make it picklable;
1855 # used in test_signature_object_pickle
1856 pass
1857
Nick Coghlanf9e227e2014-08-17 14:01:19 +10001858
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001859
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001860class TestSignatureObject(unittest.TestCase):
1861 @staticmethod
Yury Selivanovbcd4fc12015-05-20 14:30:08 -04001862 def signature(func, **kw):
1863 sig = inspect.signature(func, **kw)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001864 return (tuple((param.name,
1865 (... if param.default is param.empty else param.default),
1866 (... if param.annotation is param.empty
1867 else param.annotation),
1868 str(param.kind).lower())
1869 for param in sig.parameters.values()),
1870 (... if sig.return_annotation is sig.empty
1871 else sig.return_annotation))
1872
1873 def test_signature_object(self):
1874 S = inspect.Signature
1875 P = inspect.Parameter
1876
1877 self.assertEqual(str(S()), '()')
1878
Yury Selivanov07a9e452014-01-29 10:58:16 -05001879 def test(po, pk, pod=42, pkd=100, *args, ko, **kwargs):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001880 pass
1881 sig = inspect.signature(test)
1882 po = sig.parameters['po'].replace(kind=P.POSITIONAL_ONLY)
Yury Selivanov07a9e452014-01-29 10:58:16 -05001883 pod = sig.parameters['pod'].replace(kind=P.POSITIONAL_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001884 pk = sig.parameters['pk']
Yury Selivanov07a9e452014-01-29 10:58:16 -05001885 pkd = sig.parameters['pkd']
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001886 args = sig.parameters['args']
1887 ko = sig.parameters['ko']
1888 kwargs = sig.parameters['kwargs']
1889
1890 S((po, pk, args, ko, kwargs))
1891
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001892 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001893 S((pk, po, args, ko, kwargs))
1894
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001895 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001896 S((po, args, pk, ko, kwargs))
1897
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001898 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001899 S((args, po, pk, ko, kwargs))
1900
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001901 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001902 S((po, pk, args, kwargs, ko))
1903
1904 kwargs2 = kwargs.replace(name='args')
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001905 with self.assertRaisesRegex(ValueError, 'duplicate parameter name'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001906 S((po, pk, args, kwargs2, ko))
1907
Yury Selivanov07a9e452014-01-29 10:58:16 -05001908 with self.assertRaisesRegex(ValueError, 'follows default argument'):
1909 S((pod, po))
1910
1911 with self.assertRaisesRegex(ValueError, 'follows default argument'):
1912 S((po, pkd, pk))
1913
1914 with self.assertRaisesRegex(ValueError, 'follows default argument'):
1915 S((pkd, pk))
1916
Yury Selivanov374375d2014-03-27 12:41:53 -04001917 self.assertTrue(repr(sig).startswith('<Signature'))
Yury Selivanov0cd2bf42015-05-15 12:55:20 -04001918 self.assertTrue('(po, pk' in repr(sig))
Yury Selivanov374375d2014-03-27 12:41:53 -04001919
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001920 def test_signature_object_pickle(self):
1921 def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
1922 foo_partial = functools.partial(foo, a=1)
1923
1924 sig = inspect.signature(foo_partial)
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001925
1926 for ver in range(pickle.HIGHEST_PROTOCOL + 1):
1927 with self.subTest(pickle_ver=ver, subclass=False):
1928 sig_pickled = pickle.loads(pickle.dumps(sig, ver))
1929 self.assertEqual(sig, sig_pickled)
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001930
1931 # Test that basic sub-classing works
1932 sig = inspect.signature(foo)
1933 myparam = MyParameter(name='z', kind=inspect.Parameter.POSITIONAL_ONLY)
1934 myparams = collections.OrderedDict(sig.parameters, a=myparam)
1935 mysig = MySignature().replace(parameters=myparams.values(),
1936 return_annotation=sig.return_annotation)
1937 self.assertTrue(isinstance(mysig, MySignature))
1938 self.assertTrue(isinstance(mysig.parameters['z'], MyParameter))
1939
1940 for ver in range(pickle.HIGHEST_PROTOCOL + 1):
1941 with self.subTest(pickle_ver=ver, subclass=True):
1942 sig_pickled = pickle.loads(pickle.dumps(mysig, ver))
1943 self.assertEqual(mysig, sig_pickled)
1944 self.assertTrue(isinstance(sig_pickled, MySignature))
1945 self.assertTrue(isinstance(sig_pickled.parameters['z'],
1946 MyParameter))
1947
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001948 def test_signature_immutability(self):
1949 def test(a):
1950 pass
1951 sig = inspect.signature(test)
1952
1953 with self.assertRaises(AttributeError):
1954 sig.foo = 'bar'
1955
1956 with self.assertRaises(TypeError):
1957 sig.parameters['a'] = None
1958
1959 def test_signature_on_noarg(self):
1960 def test():
1961 pass
1962 self.assertEqual(self.signature(test), ((), ...))
1963
1964 def test_signature_on_wargs(self):
1965 def test(a, b:'foo') -> 123:
1966 pass
1967 self.assertEqual(self.signature(test),
1968 ((('a', ..., ..., "positional_or_keyword"),
1969 ('b', ..., 'foo', "positional_or_keyword")),
1970 123))
1971
1972 def test_signature_on_wkwonly(self):
1973 def test(*, a:float, b:str) -> int:
1974 pass
1975 self.assertEqual(self.signature(test),
1976 ((('a', ..., float, "keyword_only"),
1977 ('b', ..., str, "keyword_only")),
1978 int))
1979
1980 def test_signature_on_complex_args(self):
1981 def test(a, b:'foo'=10, *args:'bar', spam:'baz', ham=123, **kwargs:int):
1982 pass
1983 self.assertEqual(self.signature(test),
1984 ((('a', ..., ..., "positional_or_keyword"),
1985 ('b', 10, 'foo', "positional_or_keyword"),
1986 ('args', ..., 'bar', "var_positional"),
1987 ('spam', ..., 'baz', "keyword_only"),
1988 ('ham', 123, ..., "keyword_only"),
1989 ('kwargs', ..., int, "var_keyword")),
1990 ...))
1991
Dong-hee Nae45ea372017-06-15 23:41:57 +09001992 def test_signature_without_self(self):
1993 def test_args_only(*args): # NOQA
1994 pass
1995
1996 def test_args_kwargs_only(*args, **kwargs): # NOQA
1997 pass
1998
1999 class A:
2000 @classmethod
2001 def test_classmethod(*args): # NOQA
2002 pass
2003
2004 @staticmethod
2005 def test_staticmethod(*args): # NOQA
2006 pass
2007
2008 f1 = functools.partialmethod((test_classmethod), 1)
2009 f2 = functools.partialmethod((test_args_only), 1)
2010 f3 = functools.partialmethod((test_staticmethod), 1)
2011 f4 = functools.partialmethod((test_args_kwargs_only),1)
2012
2013 self.assertEqual(self.signature(test_args_only),
2014 ((('args', ..., ..., 'var_positional'),), ...))
2015 self.assertEqual(self.signature(test_args_kwargs_only),
2016 ((('args', ..., ..., 'var_positional'),
2017 ('kwargs', ..., ..., 'var_keyword')), ...))
2018 self.assertEqual(self.signature(A.f1),
2019 ((('args', ..., ..., 'var_positional'),), ...))
2020 self.assertEqual(self.signature(A.f2),
2021 ((('args', ..., ..., 'var_positional'),), ...))
2022 self.assertEqual(self.signature(A.f3),
2023 ((('args', ..., ..., 'var_positional'),), ...))
2024 self.assertEqual(self.signature(A.f4),
2025 ((('args', ..., ..., 'var_positional'),
2026 ('kwargs', ..., ..., 'var_keyword')), ...))
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002027 @cpython_only
Larry Hastingsfcafe432013-11-23 17:35:48 -08002028 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2029 "Signature information for builtins requires docstrings")
2030 def test_signature_on_builtins(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002031 import _testcapi
Larry Hastings16c51912014-01-07 11:53:01 -08002032
Larry Hastings5c661892014-01-24 06:17:25 -08002033 def test_unbound_method(o):
2034 """Use this to test unbound methods (things that should have a self)"""
2035 signature = inspect.signature(o)
2036 self.assertTrue(isinstance(signature, inspect.Signature))
2037 self.assertEqual(list(signature.parameters.values())[0].name, 'self')
2038 return signature
2039
2040 def test_callable(o):
2041 """Use this to test bound methods or normal callables (things that don't expect self)"""
2042 signature = inspect.signature(o)
2043 self.assertTrue(isinstance(signature, inspect.Signature))
2044 if signature.parameters:
2045 self.assertNotEqual(list(signature.parameters.values())[0].name, 'self')
2046 return signature
2047
2048 signature = test_callable(_testcapi.docstring_with_signature_with_defaults)
Larry Hastings16c51912014-01-07 11:53:01 -08002049 def p(name): return signature.parameters[name].default
2050 self.assertEqual(p('s'), 'avocado')
Larry Hastings2a727912014-01-16 11:32:01 -08002051 self.assertEqual(p('b'), b'bytes')
Larry Hastings16c51912014-01-07 11:53:01 -08002052 self.assertEqual(p('d'), 3.14)
2053 self.assertEqual(p('i'), 35)
Larry Hastings16c51912014-01-07 11:53:01 -08002054 self.assertEqual(p('n'), None)
2055 self.assertEqual(p('t'), True)
2056 self.assertEqual(p('f'), False)
Larry Hastings2a727912014-01-16 11:32:01 -08002057 self.assertEqual(p('local'), 3)
2058 self.assertEqual(p('sys'), sys.maxsize)
2059 self.assertEqual(p('exp'), sys.maxsize - 1)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002060
Larry Hastings5c661892014-01-24 06:17:25 -08002061 test_callable(object)
2062
2063 # normal method
2064 # (PyMethodDescr_Type, "method_descriptor")
2065 test_unbound_method(_pickle.Pickler.dump)
2066 d = _pickle.Pickler(io.StringIO())
2067 test_callable(d.dump)
2068
2069 # static method
2070 test_callable(str.maketrans)
2071 test_callable('abc'.maketrans)
2072
2073 # class method
2074 test_callable(dict.fromkeys)
2075 test_callable({}.fromkeys)
2076
2077 # wrapper around slot (PyWrapperDescr_Type, "wrapper_descriptor")
2078 test_unbound_method(type.__call__)
2079 test_unbound_method(int.__add__)
2080 test_callable((3).__add__)
2081
2082 # _PyMethodWrapper_Type
2083 # support for 'method-wrapper'
2084 test_callable(min.__call__)
2085
Larry Hastings2623c8c2014-02-08 22:15:29 -08002086 # This doesn't work now.
2087 # (We don't have a valid signature for "type" in 3.4)
2088 with self.assertRaisesRegex(ValueError, "no signature found"):
2089 class ThisWorksNow:
2090 __call__ = type
2091 test_callable(ThisWorksNow())
Larry Hastings5c661892014-01-24 06:17:25 -08002092
Yury Selivanov056e2652014-03-02 12:25:27 -05002093 # Regression test for issue #20786
2094 test_unbound_method(dict.__delitem__)
2095 test_unbound_method(property.__delete__)
2096
Zachary Ware8ef887c2015-04-13 18:22:35 -05002097 # Regression test for issue #20586
2098 test_callable(_testcapi.docstring_with_signature_but_no_doc)
2099
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002100 @cpython_only
Yury Selivanov76c6c592014-01-29 10:52:57 -05002101 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2102 "Signature information for builtins requires docstrings")
2103 def test_signature_on_decorated_builtins(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002104 import _testcapi
Yury Selivanov76c6c592014-01-29 10:52:57 -05002105 func = _testcapi.docstring_with_signature_with_defaults
2106
2107 def decorator(func):
2108 @functools.wraps(func)
2109 def wrapper(*args, **kwargs) -> int:
2110 return func(*args, **kwargs)
2111 return wrapper
2112
2113 decorated_func = decorator(func)
2114
2115 self.assertEqual(inspect.signature(func),
2116 inspect.signature(decorated_func))
Larry Hastings5c661892014-01-24 06:17:25 -08002117
Yury Selivanovbcd4fc12015-05-20 14:30:08 -04002118 def wrapper_like(*args, **kwargs) -> int: pass
2119 self.assertEqual(inspect.signature(decorated_func,
2120 follow_wrapped=False),
2121 inspect.signature(wrapper_like))
2122
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002123 @cpython_only
Larry Hastings5c661892014-01-24 06:17:25 -08002124 def test_signature_on_builtins_no_signature(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002125 import _testcapi
Yury Selivanovbf304fc2015-05-30 17:08:36 -04002126 with self.assertRaisesRegex(ValueError,
2127 'no signature found for builtin'):
Larry Hastings5c661892014-01-24 06:17:25 -08002128 inspect.signature(_testcapi.docstring_no_signature)
2129
Yury Selivanovbf304fc2015-05-30 17:08:36 -04002130 with self.assertRaisesRegex(ValueError,
2131 'no signature found for builtin'):
2132 inspect.signature(str)
2133
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002134 def test_signature_on_non_function(self):
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002135 with self.assertRaisesRegex(TypeError, 'is not a callable object'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002136 inspect.signature(42)
2137
Yury Selivanov63da7c72014-01-31 14:48:37 -05002138 def test_signature_from_functionlike_object(self):
2139 def func(a,b, *args, kwonly=True, kwonlyreq, **kwargs):
2140 pass
2141
2142 class funclike:
2143 # Has to be callable, and have correct
2144 # __code__, __annotations__, __defaults__, __name__,
2145 # and __kwdefaults__ attributes
2146
2147 def __init__(self, func):
2148 self.__name__ = func.__name__
2149 self.__code__ = func.__code__
2150 self.__annotations__ = func.__annotations__
2151 self.__defaults__ = func.__defaults__
2152 self.__kwdefaults__ = func.__kwdefaults__
2153 self.func = func
2154
2155 def __call__(self, *args, **kwargs):
2156 return self.func(*args, **kwargs)
2157
Yury Selivanov57c74fc2015-05-20 23:07:02 -04002158 sig_func = inspect.Signature.from_callable(func)
Yury Selivanov63da7c72014-01-31 14:48:37 -05002159
Yury Selivanov57c74fc2015-05-20 23:07:02 -04002160 sig_funclike = inspect.Signature.from_callable(funclike(func))
Yury Selivanov63da7c72014-01-31 14:48:37 -05002161 self.assertEqual(sig_funclike, sig_func)
2162
2163 sig_funclike = inspect.signature(funclike(func))
2164 self.assertEqual(sig_funclike, sig_func)
2165
2166 # If object is not a duck type of function, then
2167 # signature will try to get a signature for its '__call__'
2168 # method
2169 fl = funclike(func)
2170 del fl.__defaults__
2171 self.assertEqual(self.signature(fl),
2172 ((('args', ..., ..., "var_positional"),
2173 ('kwargs', ..., ..., "var_keyword")),
2174 ...))
2175
Yury Selivanova773de02014-02-21 18:30:53 -05002176 # Test with cython-like builtins:
2177 _orig_isdesc = inspect.ismethoddescriptor
2178 def _isdesc(obj):
2179 if hasattr(obj, '_builtinmock'):
2180 return True
2181 return _orig_isdesc(obj)
2182
2183 with unittest.mock.patch('inspect.ismethoddescriptor', _isdesc):
2184 builtin_func = funclike(func)
2185 # Make sure that our mock setup is working
2186 self.assertFalse(inspect.ismethoddescriptor(builtin_func))
2187 builtin_func._builtinmock = True
2188 self.assertTrue(inspect.ismethoddescriptor(builtin_func))
2189 self.assertEqual(inspect.signature(builtin_func), sig_func)
2190
Yury Selivanov63da7c72014-01-31 14:48:37 -05002191 def test_signature_functionlike_class(self):
2192 # We only want to duck type function-like objects,
2193 # not classes.
2194
2195 def func(a,b, *args, kwonly=True, kwonlyreq, **kwargs):
2196 pass
2197
2198 class funclike:
2199 def __init__(self, marker):
2200 pass
2201
2202 __name__ = func.__name__
2203 __code__ = func.__code__
2204 __annotations__ = func.__annotations__
2205 __defaults__ = func.__defaults__
2206 __kwdefaults__ = func.__kwdefaults__
2207
Yury Selivanov63da7c72014-01-31 14:48:37 -05002208 self.assertEqual(str(inspect.signature(funclike)), '(marker)')
2209
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002210 def test_signature_on_method(self):
2211 class Test:
Yury Selivanov62560fb2014-01-28 12:26:24 -05002212 def __init__(*args):
2213 pass
2214 def m1(self, arg1, arg2=1) -> int:
2215 pass
2216 def m2(*args):
2217 pass
2218 def __call__(*, a):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002219 pass
2220
Yury Selivanov62560fb2014-01-28 12:26:24 -05002221 self.assertEqual(self.signature(Test().m1),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002222 ((('arg1', ..., ..., "positional_or_keyword"),
2223 ('arg2', 1, ..., "positional_or_keyword")),
2224 int))
2225
Yury Selivanov62560fb2014-01-28 12:26:24 -05002226 self.assertEqual(self.signature(Test().m2),
2227 ((('args', ..., ..., "var_positional"),),
2228 ...))
2229
2230 self.assertEqual(self.signature(Test),
2231 ((('args', ..., ..., "var_positional"),),
2232 ...))
2233
2234 with self.assertRaisesRegex(ValueError, 'invalid method signature'):
2235 self.signature(Test())
2236
Yury Selivanov46c759d2015-05-27 21:56:53 -04002237 def test_signature_wrapped_bound_method(self):
2238 # Issue 24298
2239 class Test:
2240 def m1(self, arg1, arg2=1) -> int:
2241 pass
2242 @functools.wraps(Test().m1)
2243 def m1d(*args, **kwargs):
2244 pass
2245 self.assertEqual(self.signature(m1d),
2246 ((('arg1', ..., ..., "positional_or_keyword"),
2247 ('arg2', 1, ..., "positional_or_keyword")),
2248 int))
2249
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002250 def test_signature_on_classmethod(self):
2251 class Test:
2252 @classmethod
2253 def foo(cls, arg1, *, arg2=1):
2254 pass
2255
2256 meth = Test().foo
2257 self.assertEqual(self.signature(meth),
2258 ((('arg1', ..., ..., "positional_or_keyword"),
2259 ('arg2', 1, ..., "keyword_only")),
2260 ...))
2261
2262 meth = Test.foo
2263 self.assertEqual(self.signature(meth),
2264 ((('arg1', ..., ..., "positional_or_keyword"),
2265 ('arg2', 1, ..., "keyword_only")),
2266 ...))
2267
2268 def test_signature_on_staticmethod(self):
2269 class Test:
2270 @staticmethod
2271 def foo(cls, *, arg):
2272 pass
2273
2274 meth = Test().foo
2275 self.assertEqual(self.signature(meth),
2276 ((('cls', ..., ..., "positional_or_keyword"),
2277 ('arg', ..., ..., "keyword_only")),
2278 ...))
2279
2280 meth = Test.foo
2281 self.assertEqual(self.signature(meth),
2282 ((('cls', ..., ..., "positional_or_keyword"),
2283 ('arg', ..., ..., "keyword_only")),
2284 ...))
2285
2286 def test_signature_on_partial(self):
2287 from functools import partial
2288
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002289 Parameter = inspect.Parameter
2290
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002291 def test():
2292 pass
2293
2294 self.assertEqual(self.signature(partial(test)), ((), ...))
2295
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002296 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002297 inspect.signature(partial(test, 1))
2298
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002299 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002300 inspect.signature(partial(test, a=1))
2301
2302 def test(a, b, *, c, d):
2303 pass
2304
2305 self.assertEqual(self.signature(partial(test)),
2306 ((('a', ..., ..., "positional_or_keyword"),
2307 ('b', ..., ..., "positional_or_keyword"),
2308 ('c', ..., ..., "keyword_only"),
2309 ('d', ..., ..., "keyword_only")),
2310 ...))
2311
2312 self.assertEqual(self.signature(partial(test, 1)),
2313 ((('b', ..., ..., "positional_or_keyword"),
2314 ('c', ..., ..., "keyword_only"),
2315 ('d', ..., ..., "keyword_only")),
2316 ...))
2317
2318 self.assertEqual(self.signature(partial(test, 1, c=2)),
2319 ((('b', ..., ..., "positional_or_keyword"),
2320 ('c', 2, ..., "keyword_only"),
2321 ('d', ..., ..., "keyword_only")),
2322 ...))
2323
2324 self.assertEqual(self.signature(partial(test, b=1, c=2)),
2325 ((('a', ..., ..., "positional_or_keyword"),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002326 ('b', 1, ..., "keyword_only"),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002327 ('c', 2, ..., "keyword_only"),
2328 ('d', ..., ..., "keyword_only")),
2329 ...))
2330
2331 self.assertEqual(self.signature(partial(test, 0, b=1, c=2)),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002332 ((('b', 1, ..., "keyword_only"),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002333 ('c', 2, ..., "keyword_only"),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002334 ('d', ..., ..., "keyword_only")),
2335 ...))
2336
2337 self.assertEqual(self.signature(partial(test, a=1)),
2338 ((('a', 1, ..., "keyword_only"),
2339 ('b', ..., ..., "keyword_only"),
2340 ('c', ..., ..., "keyword_only"),
2341 ('d', ..., ..., "keyword_only")),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002342 ...))
2343
2344 def test(a, *args, b, **kwargs):
2345 pass
2346
2347 self.assertEqual(self.signature(partial(test, 1)),
2348 ((('args', ..., ..., "var_positional"),
2349 ('b', ..., ..., "keyword_only"),
2350 ('kwargs', ..., ..., "var_keyword")),
2351 ...))
2352
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002353 self.assertEqual(self.signature(partial(test, a=1)),
2354 ((('a', 1, ..., "keyword_only"),
2355 ('b', ..., ..., "keyword_only"),
2356 ('kwargs', ..., ..., "var_keyword")),
2357 ...))
2358
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002359 self.assertEqual(self.signature(partial(test, 1, 2, 3)),
2360 ((('args', ..., ..., "var_positional"),
2361 ('b', ..., ..., "keyword_only"),
2362 ('kwargs', ..., ..., "var_keyword")),
2363 ...))
2364
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002365 self.assertEqual(self.signature(partial(test, 1, 2, 3, test=True)),
2366 ((('args', ..., ..., "var_positional"),
2367 ('b', ..., ..., "keyword_only"),
2368 ('kwargs', ..., ..., "var_keyword")),
2369 ...))
2370
2371 self.assertEqual(self.signature(partial(test, 1, 2, 3, test=1, b=0)),
2372 ((('args', ..., ..., "var_positional"),
2373 ('b', 0, ..., "keyword_only"),
2374 ('kwargs', ..., ..., "var_keyword")),
2375 ...))
2376
2377 self.assertEqual(self.signature(partial(test, b=0)),
2378 ((('a', ..., ..., "positional_or_keyword"),
2379 ('args', ..., ..., "var_positional"),
2380 ('b', 0, ..., "keyword_only"),
2381 ('kwargs', ..., ..., "var_keyword")),
2382 ...))
2383
2384 self.assertEqual(self.signature(partial(test, b=0, test=1)),
2385 ((('a', ..., ..., "positional_or_keyword"),
2386 ('args', ..., ..., "var_positional"),
2387 ('b', 0, ..., "keyword_only"),
2388 ('kwargs', ..., ..., "var_keyword")),
2389 ...))
2390
2391 def test(a, b, c:int) -> 42:
2392 pass
2393
2394 sig = test.__signature__ = inspect.signature(test)
2395
2396 self.assertEqual(self.signature(partial(partial(test, 1))),
2397 ((('b', ..., ..., "positional_or_keyword"),
2398 ('c', ..., int, "positional_or_keyword")),
2399 42))
2400
2401 self.assertEqual(self.signature(partial(partial(test, 1), 2)),
2402 ((('c', ..., int, "positional_or_keyword"),),
2403 42))
2404
2405 psig = inspect.signature(partial(partial(test, 1), 2))
2406
2407 def foo(a):
2408 return a
2409 _foo = partial(partial(foo, a=10), a=20)
2410 self.assertEqual(self.signature(_foo),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002411 ((('a', 20, ..., "keyword_only"),),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002412 ...))
2413 # check that we don't have any side-effects in signature(),
2414 # and the partial object is still functioning
2415 self.assertEqual(_foo(), 20)
2416
2417 def foo(a, b, c):
2418 return a, b, c
2419 _foo = partial(partial(foo, 1, b=20), b=30)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002420
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002421 self.assertEqual(self.signature(_foo),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002422 ((('b', 30, ..., "keyword_only"),
2423 ('c', ..., ..., "keyword_only")),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002424 ...))
2425 self.assertEqual(_foo(c=10), (1, 30, 10))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002426
2427 def foo(a, b, c, *, d):
2428 return a, b, c, d
2429 _foo = partial(partial(foo, d=20, c=20), b=10, d=30)
2430 self.assertEqual(self.signature(_foo),
2431 ((('a', ..., ..., "positional_or_keyword"),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002432 ('b', 10, ..., "keyword_only"),
2433 ('c', 20, ..., "keyword_only"),
2434 ('d', 30, ..., "keyword_only"),
2435 ),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002436 ...))
2437 ba = inspect.signature(_foo).bind(a=200, b=11)
2438 self.assertEqual(_foo(*ba.args, **ba.kwargs), (200, 11, 20, 30))
2439
2440 def foo(a=1, b=2, c=3):
2441 return a, b, c
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002442 _foo = partial(foo, c=13) # (a=1, b=2, *, c=13)
2443
2444 ba = inspect.signature(_foo).bind(a=11)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002445 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 2, 13))
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002446
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002447 ba = inspect.signature(_foo).bind(11, 12)
2448 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002449
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002450 ba = inspect.signature(_foo).bind(11, b=12)
2451 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002452
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002453 ba = inspect.signature(_foo).bind(b=12)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002454 self.assertEqual(_foo(*ba.args, **ba.kwargs), (1, 12, 13))
2455
2456 _foo = partial(_foo, b=10, c=20)
2457 ba = inspect.signature(_foo).bind(12)
2458 self.assertEqual(_foo(*ba.args, **ba.kwargs), (12, 10, 20))
2459
2460
2461 def foo(a, b, c, d, **kwargs):
2462 pass
2463 sig = inspect.signature(foo)
2464 params = sig.parameters.copy()
2465 params['a'] = params['a'].replace(kind=Parameter.POSITIONAL_ONLY)
2466 params['b'] = params['b'].replace(kind=Parameter.POSITIONAL_ONLY)
2467 foo.__signature__ = inspect.Signature(params.values())
2468 sig = inspect.signature(foo)
2469 self.assertEqual(str(sig), '(a, b, /, c, d, **kwargs)')
2470
2471 self.assertEqual(self.signature(partial(foo, 1)),
2472 ((('b', ..., ..., 'positional_only'),
2473 ('c', ..., ..., 'positional_or_keyword'),
2474 ('d', ..., ..., 'positional_or_keyword'),
2475 ('kwargs', ..., ..., 'var_keyword')),
2476 ...))
2477
2478 self.assertEqual(self.signature(partial(foo, 1, 2)),
2479 ((('c', ..., ..., 'positional_or_keyword'),
2480 ('d', ..., ..., 'positional_or_keyword'),
2481 ('kwargs', ..., ..., 'var_keyword')),
2482 ...))
2483
2484 self.assertEqual(self.signature(partial(foo, 1, 2, 3)),
2485 ((('d', ..., ..., 'positional_or_keyword'),
2486 ('kwargs', ..., ..., 'var_keyword')),
2487 ...))
2488
2489 self.assertEqual(self.signature(partial(foo, 1, 2, c=3)),
2490 ((('c', 3, ..., 'keyword_only'),
2491 ('d', ..., ..., 'keyword_only'),
2492 ('kwargs', ..., ..., 'var_keyword')),
2493 ...))
2494
2495 self.assertEqual(self.signature(partial(foo, 1, c=3)),
2496 ((('b', ..., ..., 'positional_only'),
2497 ('c', 3, ..., 'keyword_only'),
2498 ('d', ..., ..., 'keyword_only'),
2499 ('kwargs', ..., ..., 'var_keyword')),
2500 ...))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002501
Yury Selivanovda5fe4f2014-01-27 17:28:37 -05002502 def test_signature_on_partialmethod(self):
2503 from functools import partialmethod
2504
2505 class Spam:
2506 def test():
2507 pass
2508 ham = partialmethod(test)
2509
2510 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
2511 inspect.signature(Spam.ham)
2512
2513 class Spam:
2514 def test(it, a, *, c) -> 'spam':
2515 pass
2516 ham = partialmethod(test, c=1)
2517
2518 self.assertEqual(self.signature(Spam.ham),
2519 ((('it', ..., ..., 'positional_or_keyword'),
2520 ('a', ..., ..., 'positional_or_keyword'),
2521 ('c', 1, ..., 'keyword_only')),
2522 'spam'))
2523
2524 self.assertEqual(self.signature(Spam().ham),
2525 ((('a', ..., ..., 'positional_or_keyword'),
2526 ('c', 1, ..., 'keyword_only')),
2527 'spam'))
2528
Yury Selivanov0486f812014-01-29 12:18:59 -05002529 def test_signature_on_fake_partialmethod(self):
2530 def foo(a): pass
2531 foo._partialmethod = 'spam'
2532 self.assertEqual(str(inspect.signature(foo)), '(a)')
2533
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002534 def test_signature_on_decorated(self):
2535 import functools
2536
2537 def decorator(func):
2538 @functools.wraps(func)
2539 def wrapper(*args, **kwargs) -> int:
2540 return func(*args, **kwargs)
2541 return wrapper
2542
2543 class Foo:
2544 @decorator
2545 def bar(self, a, b):
2546 pass
2547
2548 self.assertEqual(self.signature(Foo.bar),
2549 ((('self', ..., ..., "positional_or_keyword"),
2550 ('a', ..., ..., "positional_or_keyword"),
2551 ('b', ..., ..., "positional_or_keyword")),
2552 ...))
2553
2554 self.assertEqual(self.signature(Foo().bar),
2555 ((('a', ..., ..., "positional_or_keyword"),
2556 ('b', ..., ..., "positional_or_keyword")),
2557 ...))
2558
Yury Selivanovbcd4fc12015-05-20 14:30:08 -04002559 self.assertEqual(self.signature(Foo.bar, follow_wrapped=False),
2560 ((('args', ..., ..., "var_positional"),
2561 ('kwargs', ..., ..., "var_keyword")),
2562 ...)) # functools.wraps will copy __annotations__
2563 # from "func" to "wrapper", hence no
2564 # return_annotation
2565
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002566 # Test that we handle method wrappers correctly
2567 def decorator(func):
2568 @functools.wraps(func)
2569 def wrapper(*args, **kwargs) -> int:
2570 return func(42, *args, **kwargs)
2571 sig = inspect.signature(func)
2572 new_params = tuple(sig.parameters.values())[1:]
2573 wrapper.__signature__ = sig.replace(parameters=new_params)
2574 return wrapper
2575
2576 class Foo:
2577 @decorator
2578 def __call__(self, a, b):
2579 pass
2580
2581 self.assertEqual(self.signature(Foo.__call__),
2582 ((('a', ..., ..., "positional_or_keyword"),
2583 ('b', ..., ..., "positional_or_keyword")),
2584 ...))
2585
2586 self.assertEqual(self.signature(Foo().__call__),
2587 ((('b', ..., ..., "positional_or_keyword"),),
2588 ...))
2589
Nick Coghlane8c45d62013-07-28 20:00:01 +10002590 # Test we handle __signature__ partway down the wrapper stack
2591 def wrapped_foo_call():
2592 pass
2593 wrapped_foo_call.__wrapped__ = Foo.__call__
2594
2595 self.assertEqual(self.signature(wrapped_foo_call),
2596 ((('a', ..., ..., "positional_or_keyword"),
2597 ('b', ..., ..., "positional_or_keyword")),
2598 ...))
2599
2600
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002601 def test_signature_on_class(self):
2602 class C:
2603 def __init__(self, a):
2604 pass
2605
2606 self.assertEqual(self.signature(C),
2607 ((('a', ..., ..., "positional_or_keyword"),),
2608 ...))
2609
2610 class CM(type):
2611 def __call__(cls, a):
2612 pass
2613 class C(metaclass=CM):
2614 def __init__(self, b):
2615 pass
2616
2617 self.assertEqual(self.signature(C),
2618 ((('a', ..., ..., "positional_or_keyword"),),
2619 ...))
2620
2621 class CM(type):
2622 def __new__(mcls, name, bases, dct, *, foo=1):
2623 return super().__new__(mcls, name, bases, dct)
2624 class C(metaclass=CM):
2625 def __init__(self, b):
2626 pass
2627
2628 self.assertEqual(self.signature(C),
2629 ((('b', ..., ..., "positional_or_keyword"),),
2630 ...))
2631
2632 self.assertEqual(self.signature(CM),
2633 ((('name', ..., ..., "positional_or_keyword"),
2634 ('bases', ..., ..., "positional_or_keyword"),
2635 ('dct', ..., ..., "positional_or_keyword"),
2636 ('foo', 1, ..., "keyword_only")),
2637 ...))
2638
2639 class CMM(type):
2640 def __new__(mcls, name, bases, dct, *, foo=1):
2641 return super().__new__(mcls, name, bases, dct)
2642 def __call__(cls, nm, bs, dt):
2643 return type(nm, bs, dt)
2644 class CM(type, metaclass=CMM):
2645 def __new__(mcls, name, bases, dct, *, bar=2):
2646 return super().__new__(mcls, name, bases, dct)
2647 class C(metaclass=CM):
2648 def __init__(self, b):
2649 pass
2650
2651 self.assertEqual(self.signature(CMM),
2652 ((('name', ..., ..., "positional_or_keyword"),
2653 ('bases', ..., ..., "positional_or_keyword"),
2654 ('dct', ..., ..., "positional_or_keyword"),
2655 ('foo', 1, ..., "keyword_only")),
2656 ...))
2657
2658 self.assertEqual(self.signature(CM),
2659 ((('nm', ..., ..., "positional_or_keyword"),
2660 ('bs', ..., ..., "positional_or_keyword"),
2661 ('dt', ..., ..., "positional_or_keyword")),
2662 ...))
2663
2664 self.assertEqual(self.signature(C),
2665 ((('b', ..., ..., "positional_or_keyword"),),
2666 ...))
2667
2668 class CM(type):
2669 def __init__(cls, name, bases, dct, *, bar=2):
2670 return super().__init__(name, bases, dct)
2671 class C(metaclass=CM):
2672 def __init__(self, b):
2673 pass
2674
2675 self.assertEqual(self.signature(CM),
2676 ((('name', ..., ..., "positional_or_keyword"),
2677 ('bases', ..., ..., "positional_or_keyword"),
2678 ('dct', ..., ..., "positional_or_keyword"),
2679 ('bar', 2, ..., "keyword_only")),
2680 ...))
2681
Yury Selivanov145dff82014-02-01 13:49:29 -05002682 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2683 "Signature information for builtins requires docstrings")
2684 def test_signature_on_class_without_init(self):
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002685 # Test classes without user-defined __init__ or __new__
2686 class C: pass
2687 self.assertEqual(str(inspect.signature(C)), '()')
2688 class D(C): pass
2689 self.assertEqual(str(inspect.signature(D)), '()')
2690
2691 # Test meta-classes without user-defined __init__ or __new__
2692 class C(type): pass
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002693 class D(C): pass
Larry Hastings2623c8c2014-02-08 22:15:29 -08002694 with self.assertRaisesRegex(ValueError, "callable.*is not supported"):
2695 self.assertEqual(inspect.signature(C), None)
2696 with self.assertRaisesRegex(ValueError, "callable.*is not supported"):
2697 self.assertEqual(inspect.signature(D), None)
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002698
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002699 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2700 "Signature information for builtins requires docstrings")
2701 def test_signature_on_builtin_class(self):
2702 self.assertEqual(str(inspect.signature(_pickle.Pickler)),
2703 '(file, protocol=None, fix_imports=True)')
2704
2705 class P(_pickle.Pickler): pass
2706 class EmptyTrait: pass
2707 class P2(EmptyTrait, P): pass
2708 self.assertEqual(str(inspect.signature(P)),
2709 '(file, protocol=None, fix_imports=True)')
2710 self.assertEqual(str(inspect.signature(P2)),
2711 '(file, protocol=None, fix_imports=True)')
2712
2713 class P3(P2):
2714 def __init__(self, spam):
2715 pass
2716 self.assertEqual(str(inspect.signature(P3)), '(spam)')
2717
2718 class MetaP(type):
2719 def __call__(cls, foo, bar):
2720 pass
2721 class P4(P2, metaclass=MetaP):
2722 pass
2723 self.assertEqual(str(inspect.signature(P4)), '(foo, bar)')
2724
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002725 def test_signature_on_callable_objects(self):
2726 class Foo:
2727 def __call__(self, a):
2728 pass
2729
2730 self.assertEqual(self.signature(Foo()),
2731 ((('a', ..., ..., "positional_or_keyword"),),
2732 ...))
2733
2734 class Spam:
2735 pass
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002736 with self.assertRaisesRegex(TypeError, "is not a callable object"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002737 inspect.signature(Spam())
2738
2739 class Bar(Spam, Foo):
2740 pass
2741
2742 self.assertEqual(self.signature(Bar()),
2743 ((('a', ..., ..., "positional_or_keyword"),),
2744 ...))
2745
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002746 class Wrapped:
2747 pass
2748 Wrapped.__wrapped__ = lambda a: None
2749 self.assertEqual(self.signature(Wrapped),
2750 ((('a', ..., ..., "positional_or_keyword"),),
2751 ...))
Nick Coghlane8c45d62013-07-28 20:00:01 +10002752 # wrapper loop:
2753 Wrapped.__wrapped__ = Wrapped
2754 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
2755 self.signature(Wrapped)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002756
2757 def test_signature_on_lambdas(self):
2758 self.assertEqual(self.signature((lambda a=10: a)),
2759 ((('a', 10, ..., "positional_or_keyword"),),
2760 ...))
2761
2762 def test_signature_equality(self):
2763 def foo(a, *, b:int) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002764 self.assertFalse(inspect.signature(foo) == 42)
2765 self.assertTrue(inspect.signature(foo) != 42)
2766 self.assertTrue(inspect.signature(foo) == EqualsToAll())
2767 self.assertFalse(inspect.signature(foo) != EqualsToAll())
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002768
2769 def bar(a, *, b:int) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002770 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
2771 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002772 self.assertEqual(
2773 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002774
2775 def bar(a, *, b:int) -> int: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002776 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
2777 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002778 self.assertNotEqual(
2779 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002780
2781 def bar(a, *, b:int): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002782 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
2783 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002784 self.assertNotEqual(
2785 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002786
2787 def bar(a, *, b:int=42) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002788 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
2789 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002790 self.assertNotEqual(
2791 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002792
2793 def bar(a, *, c) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002794 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
2795 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002796 self.assertNotEqual(
2797 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002798
2799 def bar(a, b:int) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002800 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
2801 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002802 self.assertNotEqual(
2803 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002804 def spam(b:int, a) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002805 self.assertFalse(inspect.signature(spam) == inspect.signature(bar))
2806 self.assertTrue(inspect.signature(spam) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002807 self.assertNotEqual(
2808 hash(inspect.signature(spam)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002809
2810 def foo(*, a, b, c): pass
2811 def bar(*, c, b, a): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002812 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
2813 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002814 self.assertEqual(
2815 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002816
2817 def foo(*, a=1, b, c): pass
2818 def bar(*, c, b, a=1): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002819 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
2820 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002821 self.assertEqual(
2822 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002823
2824 def foo(pos, *, a=1, b, c): pass
2825 def bar(pos, *, c, b, a=1): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002826 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
2827 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002828 self.assertEqual(
2829 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002830
2831 def foo(pos, *, a, b, c): pass
2832 def bar(pos, *, c, b, a=1): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002833 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
2834 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002835 self.assertNotEqual(
2836 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002837
2838 def foo(pos, *args, a=42, b, c, **kwargs:int): pass
2839 def bar(pos, *args, c, b, a=42, **kwargs:int): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002840 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
2841 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002842 self.assertEqual(
2843 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002844
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002845 def test_signature_hashable(self):
2846 S = inspect.Signature
2847 P = inspect.Parameter
2848
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002849 def foo(a): pass
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002850 foo_sig = inspect.signature(foo)
2851
2852 manual_sig = S(parameters=[P('a', P.POSITIONAL_OR_KEYWORD)])
2853
2854 self.assertEqual(hash(foo_sig), hash(manual_sig))
2855 self.assertNotEqual(hash(foo_sig),
2856 hash(manual_sig.replace(return_annotation='spam')))
2857
2858 def bar(a) -> 1: pass
2859 self.assertNotEqual(hash(foo_sig), hash(inspect.signature(bar)))
2860
2861 def foo(a={}): pass
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002862 with self.assertRaisesRegex(TypeError, 'unhashable type'):
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002863 hash(inspect.signature(foo))
2864
2865 def foo(a) -> {}: pass
2866 with self.assertRaisesRegex(TypeError, 'unhashable type'):
2867 hash(inspect.signature(foo))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002868
2869 def test_signature_str(self):
2870 def foo(a:int=1, *, b, c=None, **kwargs) -> 42:
2871 pass
2872 self.assertEqual(str(inspect.signature(foo)),
2873 '(a:int=1, *, b, c=None, **kwargs) -> 42')
2874
2875 def foo(a:int=1, *args, b, c=None, **kwargs) -> 42:
2876 pass
2877 self.assertEqual(str(inspect.signature(foo)),
2878 '(a:int=1, *args, b, c=None, **kwargs) -> 42')
2879
2880 def foo():
2881 pass
2882 self.assertEqual(str(inspect.signature(foo)), '()')
2883
2884 def test_signature_str_positional_only(self):
2885 P = inspect.Parameter
Yury Selivanov2393dca2014-01-27 15:07:58 -05002886 S = inspect.Signature
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002887
2888 def test(a_po, *, b, **kwargs):
2889 return a_po, kwargs
2890
2891 sig = inspect.signature(test)
2892 new_params = list(sig.parameters.values())
2893 new_params[0] = new_params[0].replace(kind=P.POSITIONAL_ONLY)
2894 test.__signature__ = sig.replace(parameters=new_params)
2895
2896 self.assertEqual(str(inspect.signature(test)),
Yury Selivanov2393dca2014-01-27 15:07:58 -05002897 '(a_po, /, *, b, **kwargs)')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002898
Yury Selivanov2393dca2014-01-27 15:07:58 -05002899 self.assertEqual(str(S(parameters=[P('foo', P.POSITIONAL_ONLY)])),
2900 '(foo, /)')
2901
2902 self.assertEqual(str(S(parameters=[
2903 P('foo', P.POSITIONAL_ONLY),
2904 P('bar', P.VAR_KEYWORD)])),
2905 '(foo, /, **bar)')
2906
2907 self.assertEqual(str(S(parameters=[
2908 P('foo', P.POSITIONAL_ONLY),
2909 P('bar', P.VAR_POSITIONAL)])),
2910 '(foo, /, *bar)')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002911
2912 def test_signature_replace_anno(self):
2913 def test() -> 42:
2914 pass
2915
2916 sig = inspect.signature(test)
2917 sig = sig.replace(return_annotation=None)
2918 self.assertIs(sig.return_annotation, None)
2919 sig = sig.replace(return_annotation=sig.empty)
2920 self.assertIs(sig.return_annotation, sig.empty)
2921 sig = sig.replace(return_annotation=42)
2922 self.assertEqual(sig.return_annotation, 42)
2923 self.assertEqual(sig, inspect.signature(test))
2924
Yury Selivanov34ce99f2014-02-18 12:49:41 -05002925 def test_signature_on_mangled_parameters(self):
2926 class Spam:
2927 def foo(self, __p1:1=2, *, __p2:2=3):
2928 pass
2929 class Ham(Spam):
2930 pass
2931
2932 self.assertEqual(self.signature(Spam.foo),
2933 ((('self', ..., ..., "positional_or_keyword"),
2934 ('_Spam__p1', 2, 1, "positional_or_keyword"),
2935 ('_Spam__p2', 3, 2, "keyword_only")),
2936 ...))
2937
2938 self.assertEqual(self.signature(Spam.foo),
2939 self.signature(Ham.foo))
2940
Yury Selivanovda396452014-03-27 12:09:24 -04002941 def test_signature_from_callable_python_obj(self):
2942 class MySignature(inspect.Signature): pass
2943 def foo(a, *, b:1): pass
2944 foo_sig = MySignature.from_callable(foo)
2945 self.assertTrue(isinstance(foo_sig, MySignature))
2946
2947 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2948 "Signature information for builtins requires docstrings")
2949 def test_signature_from_callable_builtin_obj(self):
2950 class MySignature(inspect.Signature): pass
2951 sig = MySignature.from_callable(_pickle.Pickler)
2952 self.assertTrue(isinstance(sig, MySignature))
2953
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002954
2955class TestParameterObject(unittest.TestCase):
2956 def test_signature_parameter_kinds(self):
2957 P = inspect.Parameter
2958 self.assertTrue(P.POSITIONAL_ONLY < P.POSITIONAL_OR_KEYWORD < \
2959 P.VAR_POSITIONAL < P.KEYWORD_ONLY < P.VAR_KEYWORD)
2960
2961 self.assertEqual(str(P.POSITIONAL_ONLY), 'POSITIONAL_ONLY')
2962 self.assertTrue('POSITIONAL_ONLY' in repr(P.POSITIONAL_ONLY))
2963
2964 def test_signature_parameter_object(self):
2965 p = inspect.Parameter('foo', default=10,
2966 kind=inspect.Parameter.POSITIONAL_ONLY)
2967 self.assertEqual(p.name, 'foo')
2968 self.assertEqual(p.default, 10)
2969 self.assertIs(p.annotation, p.empty)
2970 self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY)
2971
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002972 with self.assertRaisesRegex(ValueError, 'invalid value'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002973 inspect.Parameter('foo', default=10, kind='123')
2974
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002975 with self.assertRaisesRegex(ValueError, 'not a valid parameter name'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002976 inspect.Parameter('1', kind=inspect.Parameter.VAR_KEYWORD)
2977
Yury Selivanov2393dca2014-01-27 15:07:58 -05002978 with self.assertRaisesRegex(TypeError, 'name must be a str'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002979 inspect.Parameter(None, kind=inspect.Parameter.VAR_KEYWORD)
2980
Yury Selivanov2393dca2014-01-27 15:07:58 -05002981 with self.assertRaisesRegex(ValueError,
2982 'is not a valid parameter name'):
2983 inspect.Parameter('$', kind=inspect.Parameter.VAR_KEYWORD)
2984
Nick Coghlanb4b966e2016-06-04 14:40:03 -07002985 with self.assertRaisesRegex(ValueError,
2986 'is not a valid parameter name'):
2987 inspect.Parameter('.a', kind=inspect.Parameter.VAR_KEYWORD)
2988
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002989 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002990 inspect.Parameter('a', default=42,
2991 kind=inspect.Parameter.VAR_KEYWORD)
2992
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002993 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002994 inspect.Parameter('a', default=42,
2995 kind=inspect.Parameter.VAR_POSITIONAL)
2996
2997 p = inspect.Parameter('a', default=42,
2998 kind=inspect.Parameter.POSITIONAL_OR_KEYWORD)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002999 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003000 p.replace(kind=inspect.Parameter.VAR_POSITIONAL)
3001
3002 self.assertTrue(repr(p).startswith('<Parameter'))
Yury Selivanov374375d2014-03-27 12:41:53 -04003003 self.assertTrue('"a=42"' in repr(p))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003004
Yury Selivanov67ae50e2014-04-08 11:46:50 -04003005 def test_signature_parameter_hashable(self):
3006 P = inspect.Parameter
3007 foo = P('foo', kind=P.POSITIONAL_ONLY)
3008 self.assertEqual(hash(foo), hash(P('foo', kind=P.POSITIONAL_ONLY)))
3009 self.assertNotEqual(hash(foo), hash(P('foo', kind=P.POSITIONAL_ONLY,
3010 default=42)))
3011 self.assertNotEqual(hash(foo),
3012 hash(foo.replace(kind=P.VAR_POSITIONAL)))
3013
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003014 def test_signature_parameter_equality(self):
3015 P = inspect.Parameter
3016 p = P('foo', default=42, kind=inspect.Parameter.KEYWORD_ONLY)
3017
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003018 self.assertTrue(p == p)
3019 self.assertFalse(p != p)
3020 self.assertFalse(p == 42)
3021 self.assertTrue(p != 42)
3022 self.assertTrue(p == EqualsToAll())
3023 self.assertFalse(p != EqualsToAll())
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003024
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003025 self.assertTrue(p == P('foo', default=42,
3026 kind=inspect.Parameter.KEYWORD_ONLY))
3027 self.assertFalse(p != P('foo', default=42,
3028 kind=inspect.Parameter.KEYWORD_ONLY))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003029
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003030 def test_signature_parameter_replace(self):
3031 p = inspect.Parameter('foo', default=42,
3032 kind=inspect.Parameter.KEYWORD_ONLY)
3033
3034 self.assertIsNot(p, p.replace())
3035 self.assertEqual(p, p.replace())
3036
3037 p2 = p.replace(annotation=1)
3038 self.assertEqual(p2.annotation, 1)
3039 p2 = p2.replace(annotation=p2.empty)
3040 self.assertEqual(p, p2)
3041
3042 p2 = p2.replace(name='bar')
3043 self.assertEqual(p2.name, 'bar')
3044 self.assertNotEqual(p2, p)
3045
Yury Selivanov2393dca2014-01-27 15:07:58 -05003046 with self.assertRaisesRegex(ValueError,
3047 'name is a required attribute'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003048 p2 = p2.replace(name=p2.empty)
3049
3050 p2 = p2.replace(name='foo', default=None)
3051 self.assertIs(p2.default, None)
3052 self.assertNotEqual(p2, p)
3053
3054 p2 = p2.replace(name='foo', default=p2.empty)
3055 self.assertIs(p2.default, p2.empty)
3056
3057
3058 p2 = p2.replace(default=42, kind=p2.POSITIONAL_OR_KEYWORD)
3059 self.assertEqual(p2.kind, p2.POSITIONAL_OR_KEYWORD)
3060 self.assertNotEqual(p2, p)
3061
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003062 with self.assertRaisesRegex(ValueError, 'invalid value for'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003063 p2 = p2.replace(kind=p2.empty)
3064
3065 p2 = p2.replace(kind=p2.KEYWORD_ONLY)
3066 self.assertEqual(p2, p)
3067
3068 def test_signature_parameter_positional_only(self):
Yury Selivanov2393dca2014-01-27 15:07:58 -05003069 with self.assertRaisesRegex(TypeError, 'name must be a str'):
3070 inspect.Parameter(None, kind=inspect.Parameter.POSITIONAL_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003071
Nick Coghlanb4b966e2016-06-04 14:40:03 -07003072 @cpython_only
3073 def test_signature_parameter_implicit(self):
3074 with self.assertRaisesRegex(ValueError,
3075 'implicit arguments must be passed in as'):
3076 inspect.Parameter('.0', kind=inspect.Parameter.POSITIONAL_ONLY)
3077
3078 param = inspect.Parameter(
3079 '.0', kind=inspect.Parameter.POSITIONAL_OR_KEYWORD)
3080 self.assertEqual(param.kind, inspect.Parameter.POSITIONAL_ONLY)
3081 self.assertEqual(param.name, 'implicit0')
3082
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003083 def test_signature_parameter_immutability(self):
Yury Selivanov2393dca2014-01-27 15:07:58 -05003084 p = inspect.Parameter('spam', kind=inspect.Parameter.KEYWORD_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003085
3086 with self.assertRaises(AttributeError):
3087 p.foo = 'bar'
3088
3089 with self.assertRaises(AttributeError):
3090 p.kind = 123
3091
3092
3093class TestSignatureBind(unittest.TestCase):
3094 @staticmethod
3095 def call(func, *args, **kwargs):
3096 sig = inspect.signature(func)
3097 ba = sig.bind(*args, **kwargs)
3098 return func(*ba.args, **ba.kwargs)
3099
3100 def test_signature_bind_empty(self):
3101 def test():
3102 return 42
3103
3104 self.assertEqual(self.call(test), 42)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003105 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003106 self.call(test, 1)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003107 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003108 self.call(test, 1, spam=10)
Yury Selivanov86872752015-05-19 00:27:49 -04003109 with self.assertRaisesRegex(
3110 TypeError, "got an unexpected keyword argument 'spam'"):
3111
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003112 self.call(test, spam=1)
3113
3114 def test_signature_bind_var(self):
3115 def test(*args, **kwargs):
3116 return args, kwargs
3117
3118 self.assertEqual(self.call(test), ((), {}))
3119 self.assertEqual(self.call(test, 1), ((1,), {}))
3120 self.assertEqual(self.call(test, 1, 2), ((1, 2), {}))
3121 self.assertEqual(self.call(test, foo='bar'), ((), {'foo': 'bar'}))
3122 self.assertEqual(self.call(test, 1, foo='bar'), ((1,), {'foo': 'bar'}))
3123 self.assertEqual(self.call(test, args=10), ((), {'args': 10}))
3124 self.assertEqual(self.call(test, 1, 2, foo='bar'),
3125 ((1, 2), {'foo': 'bar'}))
3126
3127 def test_signature_bind_just_args(self):
3128 def test(a, b, c):
3129 return a, b, c
3130
3131 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
3132
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003133 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003134 self.call(test, 1, 2, 3, 4)
3135
Yury Selivanov86872752015-05-19 00:27:49 -04003136 with self.assertRaisesRegex(TypeError,
3137 "missing a required argument: 'b'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003138 self.call(test, 1)
3139
Yury Selivanov86872752015-05-19 00:27:49 -04003140 with self.assertRaisesRegex(TypeError,
3141 "missing a required argument: 'a'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003142 self.call(test)
3143
3144 def test(a, b, c=10):
3145 return a, b, c
3146 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
3147 self.assertEqual(self.call(test, 1, 2), (1, 2, 10))
3148
3149 def test(a=1, b=2, c=3):
3150 return a, b, c
3151 self.assertEqual(self.call(test, a=10, c=13), (10, 2, 13))
3152 self.assertEqual(self.call(test, a=10), (10, 2, 3))
3153 self.assertEqual(self.call(test, b=10), (1, 10, 3))
3154
3155 def test_signature_bind_varargs_order(self):
3156 def test(*args):
3157 return args
3158
3159 self.assertEqual(self.call(test), ())
3160 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
3161
3162 def test_signature_bind_args_and_varargs(self):
3163 def test(a, b, c=3, *args):
3164 return a, b, c, args
3165
3166 self.assertEqual(self.call(test, 1, 2, 3, 4, 5), (1, 2, 3, (4, 5)))
3167 self.assertEqual(self.call(test, 1, 2), (1, 2, 3, ()))
3168 self.assertEqual(self.call(test, b=1, a=2), (2, 1, 3, ()))
3169 self.assertEqual(self.call(test, 1, b=2), (1, 2, 3, ()))
3170
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003171 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003172 "multiple values for argument 'c'"):
3173 self.call(test, 1, 2, 3, c=4)
3174
3175 def test_signature_bind_just_kwargs(self):
3176 def test(**kwargs):
3177 return kwargs
3178
3179 self.assertEqual(self.call(test), {})
3180 self.assertEqual(self.call(test, foo='bar', spam='ham'),
3181 {'foo': 'bar', 'spam': 'ham'})
3182
3183 def test_signature_bind_args_and_kwargs(self):
3184 def test(a, b, c=3, **kwargs):
3185 return a, b, c, kwargs
3186
3187 self.assertEqual(self.call(test, 1, 2), (1, 2, 3, {}))
3188 self.assertEqual(self.call(test, 1, 2, foo='bar', spam='ham'),
3189 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3190 self.assertEqual(self.call(test, b=2, a=1, foo='bar', spam='ham'),
3191 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3192 self.assertEqual(self.call(test, a=1, b=2, foo='bar', spam='ham'),
3193 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3194 self.assertEqual(self.call(test, 1, b=2, foo='bar', spam='ham'),
3195 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3196 self.assertEqual(self.call(test, 1, b=2, c=4, foo='bar', spam='ham'),
3197 (1, 2, 4, {'foo': 'bar', 'spam': 'ham'}))
3198 self.assertEqual(self.call(test, 1, 2, 4, foo='bar'),
3199 (1, 2, 4, {'foo': 'bar'}))
3200 self.assertEqual(self.call(test, c=5, a=4, b=3),
3201 (4, 3, 5, {}))
3202
3203 def test_signature_bind_kwonly(self):
3204 def test(*, foo):
3205 return foo
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003206 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003207 'too many positional arguments'):
3208 self.call(test, 1)
3209 self.assertEqual(self.call(test, foo=1), 1)
3210
3211 def test(a, *, foo=1, bar):
3212 return foo
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003213 with self.assertRaisesRegex(TypeError,
Yury Selivanov86872752015-05-19 00:27:49 -04003214 "missing a required argument: 'bar'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003215 self.call(test, 1)
3216
3217 def test(foo, *, bar):
3218 return foo, bar
3219 self.assertEqual(self.call(test, 1, bar=2), (1, 2))
3220 self.assertEqual(self.call(test, bar=2, foo=1), (1, 2))
3221
Yury Selivanov86872752015-05-19 00:27:49 -04003222 with self.assertRaisesRegex(
3223 TypeError, "got an unexpected keyword argument 'spam'"):
3224
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003225 self.call(test, bar=2, foo=1, spam=10)
3226
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003227 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003228 'too many positional arguments'):
3229 self.call(test, 1, 2)
3230
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003231 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003232 'too many positional arguments'):
3233 self.call(test, 1, 2, bar=2)
3234
Yury Selivanov86872752015-05-19 00:27:49 -04003235 with self.assertRaisesRegex(
3236 TypeError, "got an unexpected keyword argument 'spam'"):
3237
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003238 self.call(test, 1, bar=2, spam='ham')
3239
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003240 with self.assertRaisesRegex(TypeError,
Yury Selivanov86872752015-05-19 00:27:49 -04003241 "missing a required argument: 'bar'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003242 self.call(test, 1)
3243
3244 def test(foo, *, bar, **bin):
3245 return foo, bar, bin
3246 self.assertEqual(self.call(test, 1, bar=2), (1, 2, {}))
3247 self.assertEqual(self.call(test, foo=1, bar=2), (1, 2, {}))
3248 self.assertEqual(self.call(test, 1, bar=2, spam='ham'),
3249 (1, 2, {'spam': 'ham'}))
3250 self.assertEqual(self.call(test, spam='ham', foo=1, bar=2),
3251 (1, 2, {'spam': 'ham'}))
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003252 with self.assertRaisesRegex(TypeError,
Yury Selivanov86872752015-05-19 00:27:49 -04003253 "missing a required argument: 'foo'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003254 self.call(test, spam='ham', bar=2)
3255 self.assertEqual(self.call(test, 1, bar=2, bin=1, spam=10),
3256 (1, 2, {'bin': 1, 'spam': 10}))
3257
3258 def test_signature_bind_arguments(self):
3259 def test(a, *args, b, z=100, **kwargs):
3260 pass
3261 sig = inspect.signature(test)
3262 ba = sig.bind(10, 20, b=30, c=40, args=50, kwargs=60)
3263 # we won't have 'z' argument in the bound arguments object, as we didn't
3264 # pass it to the 'bind'
3265 self.assertEqual(tuple(ba.arguments.items()),
3266 (('a', 10), ('args', (20,)), ('b', 30),
3267 ('kwargs', {'c': 40, 'args': 50, 'kwargs': 60})))
3268 self.assertEqual(ba.kwargs,
3269 {'b': 30, 'c': 40, 'args': 50, 'kwargs': 60})
3270 self.assertEqual(ba.args, (10, 20))
3271
3272 def test_signature_bind_positional_only(self):
3273 P = inspect.Parameter
3274
3275 def test(a_po, b_po, c_po=3, foo=42, *, bar=50, **kwargs):
3276 return a_po, b_po, c_po, foo, bar, kwargs
3277
3278 sig = inspect.signature(test)
3279 new_params = collections.OrderedDict(tuple(sig.parameters.items()))
3280 for name in ('a_po', 'b_po', 'c_po'):
3281 new_params[name] = new_params[name].replace(kind=P.POSITIONAL_ONLY)
3282 new_sig = sig.replace(parameters=new_params.values())
3283 test.__signature__ = new_sig
3284
3285 self.assertEqual(self.call(test, 1, 2, 4, 5, bar=6),
3286 (1, 2, 4, 5, 6, {}))
3287
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05003288 self.assertEqual(self.call(test, 1, 2),
3289 (1, 2, 3, 42, 50, {}))
3290
3291 self.assertEqual(self.call(test, 1, 2, foo=4, bar=5),
3292 (1, 2, 3, 4, 5, {}))
3293
3294 with self.assertRaisesRegex(TypeError, "but was passed as a keyword"):
3295 self.call(test, 1, 2, foo=4, bar=5, c_po=10)
3296
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003297 with self.assertRaisesRegex(TypeError, "parameter is positional only"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003298 self.call(test, 1, 2, c_po=4)
3299
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003300 with self.assertRaisesRegex(TypeError, "parameter is positional only"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003301 self.call(test, a_po=1, b_po=2)
3302
Antoine Pitroubd41d1b2013-01-29 21:20:57 +01003303 def test_signature_bind_with_self_arg(self):
3304 # Issue #17071: one of the parameters is named "self
3305 def test(a, self, b):
3306 pass
3307 sig = inspect.signature(test)
3308 ba = sig.bind(1, 2, 3)
3309 self.assertEqual(ba.args, (1, 2, 3))
3310 ba = sig.bind(1, self=2, b=3)
3311 self.assertEqual(ba.args, (1, 2, 3))
3312
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05003313 def test_signature_bind_vararg_name(self):
3314 def test(a, *args):
3315 return a, args
3316 sig = inspect.signature(test)
3317
Yury Selivanov86872752015-05-19 00:27:49 -04003318 with self.assertRaisesRegex(
3319 TypeError, "got an unexpected keyword argument 'args'"):
3320
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05003321 sig.bind(a=0, args=1)
3322
3323 def test(*args, **kwargs):
3324 return args, kwargs
3325 self.assertEqual(self.call(test, args=1), ((), {'args': 1}))
3326
3327 sig = inspect.signature(test)
3328 ba = sig.bind(args=1)
3329 self.assertEqual(ba.arguments, {'kwargs': {'args': 1}})
3330
Nick Coghlanb4b966e2016-06-04 14:40:03 -07003331 @cpython_only
3332 def test_signature_bind_implicit_arg(self):
3333 # Issue #19611: getcallargs should work with set comprehensions
3334 def make_set():
3335 return {z * z for z in range(5)}
3336 setcomp_code = make_set.__code__.co_consts[1]
3337 setcomp_func = types.FunctionType(setcomp_code, {})
3338
3339 iterator = iter(range(5))
3340 self.assertEqual(self.call(setcomp_func, iterator), {0, 1, 4, 9, 16})
3341
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003342
3343class TestBoundArguments(unittest.TestCase):
3344 def test_signature_bound_arguments_unhashable(self):
3345 def foo(a): pass
3346 ba = inspect.signature(foo).bind(1)
3347
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003348 with self.assertRaisesRegex(TypeError, 'unhashable type'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003349 hash(ba)
3350
3351 def test_signature_bound_arguments_equality(self):
3352 def foo(a): pass
3353 ba = inspect.signature(foo).bind(1)
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003354 self.assertTrue(ba == ba)
3355 self.assertFalse(ba != ba)
3356 self.assertTrue(ba == EqualsToAll())
3357 self.assertFalse(ba != EqualsToAll())
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003358
3359 ba2 = inspect.signature(foo).bind(1)
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003360 self.assertTrue(ba == ba2)
3361 self.assertFalse(ba != ba2)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003362
3363 ba3 = inspect.signature(foo).bind(2)
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003364 self.assertFalse(ba == ba3)
3365 self.assertTrue(ba != ba3)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003366 ba3.arguments['a'] = 1
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003367 self.assertTrue(ba == ba3)
3368 self.assertFalse(ba != ba3)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003369
3370 def bar(b): pass
3371 ba4 = inspect.signature(bar).bind(1)
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003372 self.assertFalse(ba == ba4)
3373 self.assertTrue(ba != ba4)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003374
Yury Selivanov4cfd4ea2015-05-14 18:30:27 -04003375 def foo(*, a, b): pass
3376 sig = inspect.signature(foo)
3377 ba1 = sig.bind(a=1, b=2)
3378 ba2 = sig.bind(b=2, a=1)
Serhiy Storchaka2489bd52015-07-18 23:20:50 +03003379 self.assertTrue(ba1 == ba2)
3380 self.assertFalse(ba1 != ba2)
Yury Selivanov4cfd4ea2015-05-14 18:30:27 -04003381
Yury Selivanova5d63dd2014-03-27 11:31:43 -04003382 def test_signature_bound_arguments_pickle(self):
3383 def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
3384 sig = inspect.signature(foo)
3385 ba = sig.bind(20, 30, z={})
3386
3387 for ver in range(pickle.HIGHEST_PROTOCOL + 1):
3388 with self.subTest(pickle_ver=ver):
3389 ba_pickled = pickle.loads(pickle.dumps(ba, ver))
3390 self.assertEqual(ba, ba_pickled)
3391
Yury Selivanov3f6538f2015-05-14 18:47:17 -04003392 def test_signature_bound_arguments_repr(self):
3393 def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
3394 sig = inspect.signature(foo)
3395 ba = sig.bind(20, 30, z={})
Yury Selivanovf229bc52015-05-15 12:53:56 -04003396 self.assertRegex(repr(ba), r'<BoundArguments \(a=20,.*\}\}\)>')
Yury Selivanov3f6538f2015-05-14 18:47:17 -04003397
Yury Selivanovb907a512015-05-16 13:45:09 -04003398 def test_signature_bound_arguments_apply_defaults(self):
3399 def foo(a, b=1, *args, c:1={}, **kw): pass
3400 sig = inspect.signature(foo)
3401
3402 ba = sig.bind(20)
3403 ba.apply_defaults()
3404 self.assertEqual(
3405 list(ba.arguments.items()),
3406 [('a', 20), ('b', 1), ('args', ()), ('c', {}), ('kw', {})])
3407
3408 # Make sure that we preserve the order:
3409 # i.e. 'c' should be *before* 'kw'.
3410 ba = sig.bind(10, 20, 30, d=1)
3411 ba.apply_defaults()
3412 self.assertEqual(
3413 list(ba.arguments.items()),
3414 [('a', 10), ('b', 20), ('args', (30,)), ('c', {}), ('kw', {'d':1})])
3415
3416 # Make sure that BoundArguments produced by bind_partial()
3417 # are supported.
3418 def foo(a, b): pass
3419 sig = inspect.signature(foo)
3420 ba = sig.bind_partial(20)
3421 ba.apply_defaults()
3422 self.assertEqual(
3423 list(ba.arguments.items()),
3424 [('a', 20)])
3425
3426 # Test no args
3427 def foo(): pass
3428 sig = inspect.signature(foo)
3429 ba = sig.bind()
3430 ba.apply_defaults()
3431 self.assertEqual(list(ba.arguments.items()), [])
3432
Yury Selivanovf9e1f2b2016-03-02 11:07:47 -05003433 # Make sure a no-args binding still acquires proper defaults.
3434 def foo(a='spam'): pass
3435 sig = inspect.signature(foo)
3436 ba = sig.bind()
3437 ba.apply_defaults()
3438 self.assertEqual(list(ba.arguments.items()), [('a', 'spam')])
3439
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003440
Yury Selivanovd82eddc2014-01-29 11:24:39 -05003441class TestSignaturePrivateHelpers(unittest.TestCase):
3442 def test_signature_get_bound_param(self):
3443 getter = inspect._signature_get_bound_param
3444
3445 self.assertEqual(getter('($self)'), 'self')
3446 self.assertEqual(getter('($self, obj)'), 'self')
3447 self.assertEqual(getter('($cls, /, obj)'), 'cls')
3448
Larry Hastings2623c8c2014-02-08 22:15:29 -08003449 def _strip_non_python_syntax(self, input,
3450 clean_signature, self_parameter, last_positional_only):
3451 computed_clean_signature, \
3452 computed_self_parameter, \
3453 computed_last_positional_only = \
3454 inspect._signature_strip_non_python_syntax(input)
3455 self.assertEqual(computed_clean_signature, clean_signature)
3456 self.assertEqual(computed_self_parameter, self_parameter)
3457 self.assertEqual(computed_last_positional_only, last_positional_only)
3458
3459 def test_signature_strip_non_python_syntax(self):
3460 self._strip_non_python_syntax(
3461 "($module, /, path, mode, *, dir_fd=None, " +
3462 "effective_ids=False,\n follow_symlinks=True)",
3463 "(module, path, mode, *, dir_fd=None, " +
3464 "effective_ids=False, follow_symlinks=True)",
3465 0,
3466 0)
3467
3468 self._strip_non_python_syntax(
3469 "($module, word, salt, /)",
3470 "(module, word, salt)",
3471 0,
3472 2)
3473
3474 self._strip_non_python_syntax(
3475 "(x, y=None, z=None, /)",
3476 "(x, y=None, z=None)",
3477 None,
3478 2)
3479
3480 self._strip_non_python_syntax(
3481 "(x, y=None, z=None)",
3482 "(x, y=None, z=None)",
3483 None,
3484 None)
3485
3486 self._strip_non_python_syntax(
3487 "(x,\n y=None,\n z = None )",
3488 "(x, y=None, z=None)",
3489 None,
3490 None)
3491
3492 self._strip_non_python_syntax(
3493 "",
3494 "",
3495 None,
3496 None)
3497
3498 self._strip_non_python_syntax(
3499 None,
3500 None,
3501 None,
3502 None)
3503
Nick Coghlan9c680b02015-04-13 12:54:54 -04003504class TestSignatureDefinitions(unittest.TestCase):
3505 # This test case provides a home for checking that particular APIs
3506 # have signatures available for introspection
3507
3508 @cpython_only
3509 @unittest.skipIf(MISSING_C_DOCSTRINGS,
3510 "Signature information for builtins requires docstrings")
3511 def test_builtins_have_signatures(self):
3512 # This checks all builtin callables in CPython have signatures
3513 # A few have signatures Signature can't yet handle, so we skip those
3514 # since they will have to wait until PEP 457 adds the required
3515 # introspection support to the inspect module
3516 # Some others also haven't been converted yet for various other
3517 # reasons, so we also skip those for the time being, but design
3518 # the test to fail in order to indicate when it needs to be
3519 # updated.
3520 no_signature = set()
3521 # These need PEP 457 groups
3522 needs_groups = {"range", "slice", "dir", "getattr",
3523 "next", "iter", "vars"}
3524 no_signature |= needs_groups
3525 # These need PEP 457 groups or a signature change to accept None
3526 needs_semantic_update = {"round"}
3527 no_signature |= needs_semantic_update
3528 # These need *args support in Argument Clinic
3529 needs_varargs = {"min", "max", "print", "__build_class__"}
3530 no_signature |= needs_varargs
3531 # These simply weren't covered in the initial AC conversion
3532 # for builtin callables
3533 not_converted_yet = {"open", "__import__"}
3534 no_signature |= not_converted_yet
3535 # These builtin types are expected to provide introspection info
3536 types_with_signatures = set()
3537 # Check the signatures we expect to be there
3538 ns = vars(builtins)
3539 for name, obj in sorted(ns.items()):
3540 if not callable(obj):
3541 continue
3542 # The builtin types haven't been converted to AC yet
3543 if isinstance(obj, type) and (name not in types_with_signatures):
3544 # Note that this also skips all the exception types
3545 no_signature.add(name)
3546 if (name in no_signature):
3547 # Not yet converted
3548 continue
3549 with self.subTest(builtin=name):
3550 self.assertIsNotNone(inspect.signature(obj))
3551 # Check callables that haven't been converted don't claim a signature
3552 # This ensures this test will start failing as more signatures are
3553 # added, so the affected items can be moved into the scope of the
3554 # regression test above
3555 for name in no_signature:
3556 with self.subTest(builtin=name):
3557 self.assertIsNone(obj.__text_signature__)
3558
Yury Selivanovd82eddc2014-01-29 11:24:39 -05003559
Nick Coghlane8c45d62013-07-28 20:00:01 +10003560class TestUnwrap(unittest.TestCase):
3561
3562 def test_unwrap_one(self):
3563 def func(a, b):
3564 return a + b
3565 wrapper = functools.lru_cache(maxsize=20)(func)
3566 self.assertIs(inspect.unwrap(wrapper), func)
3567
3568 def test_unwrap_several(self):
3569 def func(a, b):
3570 return a + b
3571 wrapper = func
3572 for __ in range(10):
3573 @functools.wraps(wrapper)
3574 def wrapper():
3575 pass
3576 self.assertIsNot(wrapper.__wrapped__, func)
3577 self.assertIs(inspect.unwrap(wrapper), func)
3578
3579 def test_stop(self):
3580 def func1(a, b):
3581 return a + b
3582 @functools.wraps(func1)
3583 def func2():
3584 pass
3585 @functools.wraps(func2)
3586 def wrapper():
3587 pass
3588 func2.stop_here = 1
3589 unwrapped = inspect.unwrap(wrapper,
3590 stop=(lambda f: hasattr(f, "stop_here")))
3591 self.assertIs(unwrapped, func2)
3592
3593 def test_cycle(self):
3594 def func1(): pass
3595 func1.__wrapped__ = func1
3596 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3597 inspect.unwrap(func1)
3598
3599 def func2(): pass
3600 func2.__wrapped__ = func1
3601 func1.__wrapped__ = func2
3602 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3603 inspect.unwrap(func1)
3604 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3605 inspect.unwrap(func2)
3606
3607 def test_unhashable(self):
3608 def func(): pass
3609 func.__wrapped__ = None
3610 class C:
3611 __hash__ = None
3612 __wrapped__ = func
3613 self.assertIsNone(inspect.unwrap(C()))
3614
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003615class TestMain(unittest.TestCase):
3616 def test_only_source(self):
3617 module = importlib.import_module('unittest')
3618 rc, out, err = assert_python_ok('-m', 'inspect',
3619 'unittest')
3620 lines = out.decode().splitlines()
3621 # ignore the final newline
3622 self.assertEqual(lines[:-1], inspect.getsource(module).splitlines())
3623 self.assertEqual(err, b'')
3624
Yury Selivanov42407ab2014-06-23 10:23:50 -07003625 def test_custom_getattr(self):
3626 def foo():
3627 pass
3628 foo.__signature__ = 42
3629 with self.assertRaises(TypeError):
3630 inspect.signature(foo)
3631
Brett Cannon634a8fc2013-10-02 10:25:42 -04003632 @unittest.skipIf(ThreadPoolExecutor is None,
Brett Cannon0de3f012013-10-02 10:58:58 -04003633 'threads required to test __qualname__ for source files')
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003634 def test_qualname_source(self):
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003635 rc, out, err = assert_python_ok('-m', 'inspect',
3636 'concurrent.futures:ThreadPoolExecutor')
3637 lines = out.decode().splitlines()
3638 # ignore the final newline
3639 self.assertEqual(lines[:-1],
Brett Cannon634a8fc2013-10-02 10:25:42 -04003640 inspect.getsource(ThreadPoolExecutor).splitlines())
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003641 self.assertEqual(err, b'')
3642
3643 def test_builtins(self):
3644 module = importlib.import_module('unittest')
3645 _, out, err = assert_python_failure('-m', 'inspect',
3646 'sys')
3647 lines = err.decode().splitlines()
3648 self.assertEqual(lines, ["Can't get info for builtin modules."])
3649
3650 def test_details(self):
3651 module = importlib.import_module('unittest')
Victor Stinner9def2842016-01-18 12:15:08 +01003652 args = support.optim_args_from_interpreter_flags()
3653 rc, out, err = assert_python_ok(*args, '-m', 'inspect',
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003654 'unittest', '--details')
3655 output = out.decode()
3656 # Just a quick sanity check on the output
3657 self.assertIn(module.__name__, output)
3658 self.assertIn(module.__file__, output)
Victor Stinner9def2842016-01-18 12:15:08 +01003659 self.assertIn(module.__cached__, output)
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003660 self.assertEqual(err, b'')
3661
3662
Yury Selivanovef1e7502014-12-08 16:05:34 -05003663class TestReload(unittest.TestCase):
3664
3665 src_before = textwrap.dedent("""\
3666def foo():
3667 print("Bla")
3668 """)
3669
3670 src_after = textwrap.dedent("""\
3671def foo():
3672 print("Oh no!")
3673 """)
3674
3675 def assertInspectEqual(self, path, source):
3676 inspected_src = inspect.getsource(source)
3677 with open(path) as src:
3678 self.assertEqual(
3679 src.read().splitlines(True),
3680 inspected_src.splitlines(True)
3681 )
3682
3683 def test_getsource_reload(self):
3684 # see issue 1218234
3685 with _ready_to_import('reload_bug', self.src_before) as (name, path):
3686 module = importlib.import_module(name)
3687 self.assertInspectEqual(path, module)
3688 with open(path, 'w') as src:
3689 src.write(self.src_after)
3690 self.assertInspectEqual(path, module)
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003691
Nick Coghlane8c45d62013-07-28 20:00:01 +10003692
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00003693def test_main():
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00003694 run_unittest(
3695 TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBuggyCases,
3696 TestInterpreterStack, TestClassesAndFunctions, TestPredicates,
3697 TestGetcallargsFunctions, TestGetcallargsMethods,
Alexander Belopolskyf546e702010-12-02 00:10:11 +00003698 TestGetcallargsUnboundMethods, TestGetattrStatic, TestGetGeneratorState,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003699 TestNoEOL, TestSignatureObject, TestSignatureBind, TestParameterObject,
Nick Coghlan9c680b02015-04-13 12:54:54 -04003700 TestBoundArguments, TestSignaturePrivateHelpers,
3701 TestSignatureDefinitions,
Yury Selivanov5376ba92015-06-22 12:19:30 -04003702 TestGetClosureVars, TestUnwrap, TestMain, TestReload,
3703 TestGetCoroutineState
Michael Foord95fc51d2010-11-20 15:07:30 +00003704 )
Martin v. Löwis893ffa42003-10-31 15:35:53 +00003705
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00003706if __name__ == "__main__":
3707 test_main()