blob: 350d5dbd776ac2ff69499cb927ee104bb160402c [file] [log] [blame]
Nick Coghlanf9e227e2014-08-17 14:01:19 +10001import builtins
Guido van Rossum813b0e52007-05-21 18:11:34 +00002import collections
Larry Hastings5c661892014-01-24 06:17:25 -08003import datetime
Nick Coghlane8c45d62013-07-28 20:00:01 +10004import functools
Nick Coghlanf94a16b2013-09-22 22:46:49 +10005import importlib
Larry Hastings5c661892014-01-24 06:17:25 -08006import inspect
7import io
8import linecache
9import os
Christian Heimesa3538eb2007-11-06 11:44:48 +000010from os.path import normcase
Larry Hastings5c661892014-01-24 06:17:25 -080011import _pickle
Yury Selivanova5d63dd2014-03-27 11:31:43 -040012import pickle
Larry Hastings5c661892014-01-24 06:17:25 -080013import shutil
14import sys
15import types
Yury Selivanovef1e7502014-12-08 16:05:34 -050016import textwrap
Larry Hastings5c661892014-01-24 06:17:25 -080017import unicodedata
18import unittest
Yury Selivanova773de02014-02-21 18:30:53 -050019import unittest.mock
Yury Selivanov75445082015-05-11 22:57:16 -040020import warnings
Larry Hastings5c661892014-01-24 06:17:25 -080021
Brett Cannon634a8fc2013-10-02 10:25:42 -040022try:
23 from concurrent.futures import ThreadPoolExecutor
24except ImportError:
25 ThreadPoolExecutor = None
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000026
Serhiy Storchakaf28ba362014-02-07 10:10:55 +020027from test.support import run_unittest, TESTFN, DirsOnSysPath, cpython_only
Nick Coghlanf9e227e2014-08-17 14:01:19 +100028from test.support import MISSING_C_DOCSTRINGS, cpython_only
Berker Peksagce643912015-05-06 06:33:17 +030029from test.support.script_helper import assert_python_ok, assert_python_failure
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000030from test import inspect_fodder as mod
31from test import inspect_fodder2 as mod2
Victor Stinner9def2842016-01-18 12:15:08 +010032from test import support
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000033
Yury Selivanovef1e7502014-12-08 16:05:34 -050034from test.test_import import _ready_to_import
35
R. David Murray74b89242009-05-13 17:33:03 +000036
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000037# Functions tested in this suite:
38# ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode,
Christian Heimes7131fd92008-02-19 14:21:46 +000039# isbuiltin, isroutine, isgenerator, isgeneratorfunction, getmembers,
40# getdoc, getfile, getmodule, getsourcefile, getcomments, getsource,
Berker Peksagfa3922c2015-07-31 04:11:29 +030041# getclasstree, getargvalues, formatargspec, formatargvalues,
Christian Heimes7131fd92008-02-19 14:21:46 +000042# currentframe, stack, trace, isdatadescriptor
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000043
Nick Coghlanf088e5e2008-12-14 11:50:48 +000044# NOTE: There are some additional tests relating to interaction with
45# zipimport in the test_zipimport_support test module.
46
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000047modfile = mod.__file__
Thomas Wouters0e3f5912006-08-11 14:57:12 +000048if modfile.endswith(('c', 'o')):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000049 modfile = modfile[:-1]
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000050
Christian Heimesa3538eb2007-11-06 11:44:48 +000051# Normalize file names: on Windows, the case of file names of compiled
52# modules depends on the path used to start the python executable.
53modfile = normcase(modfile)
54
55def revise(filename, *args):
56 return (normcase(filename),) + args
57
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000058git = mod.StupidGit()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000059
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000060class IsTestBase(unittest.TestCase):
61 predicates = set([inspect.isbuiltin, inspect.isclass, inspect.iscode,
62 inspect.isframe, inspect.isfunction, inspect.ismethod,
Christian Heimes7131fd92008-02-19 14:21:46 +000063 inspect.ismodule, inspect.istraceback,
Yury Selivanov75445082015-05-11 22:57:16 -040064 inspect.isgenerator, inspect.isgeneratorfunction,
Yury Selivanoveb636452016-09-08 22:01:51 -070065 inspect.iscoroutine, inspect.iscoroutinefunction,
66 inspect.isasyncgen, inspect.isasyncgenfunction])
Tim Peters5a9fb3c2005-01-07 16:01:32 +000067
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000068 def istest(self, predicate, exp):
69 obj = eval(exp)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000070 self.assertTrue(predicate(obj), '%s(%s)' % (predicate.__name__, exp))
Tim Peters5a9fb3c2005-01-07 16:01:32 +000071
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000072 for other in self.predicates - set([predicate]):
Yury Selivanov75445082015-05-11 22:57:16 -040073 if (predicate == inspect.isgeneratorfunction or \
Yury Selivanoveb636452016-09-08 22:01:51 -070074 predicate == inspect.isasyncgenfunction or \
Yury Selivanov75445082015-05-11 22:57:16 -040075 predicate == inspect.iscoroutinefunction) and \
Christian Heimes7131fd92008-02-19 14:21:46 +000076 other == inspect.isfunction:
77 continue
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000078 self.assertFalse(other(obj), 'not %s(%s)' % (other.__name__, exp))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000079
Christian Heimes7131fd92008-02-19 14:21:46 +000080def generator_function_example(self):
81 for i in range(2):
82 yield i
83
Yury Selivanoveb636452016-09-08 22:01:51 -070084async def async_generator_function_example(self):
85 async for i in range(2):
86 yield i
87
Yury Selivanov75445082015-05-11 22:57:16 -040088async def coroutine_function_example(self):
89 return 'spam'
90
91@types.coroutine
92def gen_coroutine_function_example(self):
93 yield
94 return 'spam'
95
Serhiy Storchaka3018cc42015-07-18 23:19:05 +030096class EqualsToAll:
97 def __eq__(self, other):
98 return True
Yury Selivanova5d63dd2014-03-27 11:31:43 -040099
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000100class TestPredicates(IsTestBase):
Christian Heimes7131fd92008-02-19 14:21:46 +0000101
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000102 def test_excluding_predicates(self):
Antoine Pitroud5a1a212012-06-17 23:18:07 +0200103 global tb
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000104 self.istest(inspect.isbuiltin, 'sys.exit')
105 self.istest(inspect.isbuiltin, '[].append')
Neal Norwitz221085d2007-02-25 20:55:47 +0000106 self.istest(inspect.iscode, 'mod.spam.__code__')
Antoine Pitroud5a1a212012-06-17 23:18:07 +0200107 try:
108 1/0
109 except:
110 tb = sys.exc_info()[2]
111 self.istest(inspect.isframe, 'tb.tb_frame')
112 self.istest(inspect.istraceback, 'tb')
113 if hasattr(types, 'GetSetDescriptorType'):
114 self.istest(inspect.isgetsetdescriptor,
115 'type(tb.tb_frame).f_locals')
116 else:
117 self.assertFalse(inspect.isgetsetdescriptor(type(tb.tb_frame).f_locals))
118 finally:
119 # Clear traceback and all the frames and local variables hanging to it.
120 tb = None
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000121 self.istest(inspect.isfunction, 'mod.spam')
Christian Heimes4a22b5d2007-11-25 09:39:14 +0000122 self.istest(inspect.isfunction, 'mod.StupidGit.abuse')
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000123 self.istest(inspect.ismethod, 'git.argue')
124 self.istest(inspect.ismodule, 'mod')
Guido van Rossum813b0e52007-05-21 18:11:34 +0000125 self.istest(inspect.isdatadescriptor, 'collections.defaultdict.default_factory')
Christian Heimes7131fd92008-02-19 14:21:46 +0000126 self.istest(inspect.isgenerator, '(x for x in range(2))')
127 self.istest(inspect.isgeneratorfunction, 'generator_function_example')
Yury Selivanoveb636452016-09-08 22:01:51 -0700128 self.istest(inspect.isasyncgen,
129 'async_generator_function_example(1)')
130 self.istest(inspect.isasyncgenfunction,
131 'async_generator_function_example')
Yury Selivanov75445082015-05-11 22:57:16 -0400132
133 with warnings.catch_warnings():
134 warnings.simplefilter("ignore")
135 self.istest(inspect.iscoroutine, 'coroutine_function_example(1)')
136 self.istest(inspect.iscoroutinefunction, 'coroutine_function_example')
137
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000138 if hasattr(types, 'MemberDescriptorType'):
139 self.istest(inspect.ismemberdescriptor, 'datetime.timedelta.days')
140 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000141 self.assertFalse(inspect.ismemberdescriptor(datetime.timedelta.days))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000142
Yury Selivanov75445082015-05-11 22:57:16 -0400143 def test_iscoroutine(self):
144 gen_coro = gen_coroutine_function_example(1)
145 coro = coroutine_function_example(1)
146
Yury Selivanov5376ba92015-06-22 12:19:30 -0400147 self.assertFalse(
Yury Selivanov75445082015-05-11 22:57:16 -0400148 inspect.iscoroutinefunction(gen_coroutine_function_example))
Yury Selivanov5376ba92015-06-22 12:19:30 -0400149 self.assertFalse(inspect.iscoroutine(gen_coro))
Yury Selivanov75445082015-05-11 22:57:16 -0400150
151 self.assertTrue(
152 inspect.isgeneratorfunction(gen_coroutine_function_example))
153 self.assertTrue(inspect.isgenerator(gen_coro))
154
155 self.assertTrue(
156 inspect.iscoroutinefunction(coroutine_function_example))
157 self.assertTrue(inspect.iscoroutine(coro))
158
159 self.assertFalse(
160 inspect.isgeneratorfunction(coroutine_function_example))
161 self.assertFalse(inspect.isgenerator(coro))
162
163 coro.close(); gen_coro.close() # silence warnings
164
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -0400165 def test_isawaitable(self):
166 def gen(): yield
167 self.assertFalse(inspect.isawaitable(gen()))
168
169 coro = coroutine_function_example(1)
170 gen_coro = gen_coroutine_function_example(1)
171
172 self.assertTrue(inspect.isawaitable(coro))
173 self.assertTrue(inspect.isawaitable(gen_coro))
174
175 class Future:
176 def __await__():
177 pass
178 self.assertTrue(inspect.isawaitable(Future()))
179 self.assertFalse(inspect.isawaitable(Future))
180
181 class NotFuture: pass
182 not_fut = NotFuture()
183 not_fut.__await__ = lambda: None
184 self.assertFalse(inspect.isawaitable(not_fut))
185
186 coro.close(); gen_coro.close() # silence warnings
187
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000188 def test_isroutine(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000189 self.assertTrue(inspect.isroutine(mod.spam))
190 self.assertTrue(inspect.isroutine([].count))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000191
Benjamin Petersonc4656002009-01-17 22:41:18 +0000192 def test_isclass(self):
193 self.istest(inspect.isclass, 'mod.StupidGit')
194 self.assertTrue(inspect.isclass(list))
195
196 class CustomGetattr(object):
197 def __getattr__(self, attr):
198 return None
199 self.assertFalse(inspect.isclass(CustomGetattr()))
200
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000201 def test_get_slot_members(self):
202 class C(object):
203 __slots__ = ("a", "b")
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000204 x = C()
205 x.a = 42
206 members = dict(inspect.getmembers(x))
Benjamin Peterson577473f2010-01-19 00:09:57 +0000207 self.assertIn('a', members)
208 self.assertNotIn('b', members)
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000209
Benjamin Petersona0dfa822009-11-13 02:25:08 +0000210 def test_isabstract(self):
211 from abc import ABCMeta, abstractmethod
212
213 class AbstractClassExample(metaclass=ABCMeta):
214
215 @abstractmethod
216 def foo(self):
217 pass
218
219 class ClassExample(AbstractClassExample):
220 def foo(self):
221 pass
222
223 a = ClassExample()
224
225 # Test general behaviour.
226 self.assertTrue(inspect.isabstract(AbstractClassExample))
227 self.assertFalse(inspect.isabstract(ClassExample))
228 self.assertFalse(inspect.isabstract(a))
229 self.assertFalse(inspect.isabstract(int))
230 self.assertFalse(inspect.isabstract(5))
231
Natefcfe80e2017-04-24 10:06:15 -0700232 def test_isabstract_during_init_subclass(self):
233 from abc import ABCMeta, abstractmethod
234 isabstract_checks = []
235 class AbstractChecker(metaclass=ABCMeta):
236 def __init_subclass__(cls):
237 isabstract_checks.append(inspect.isabstract(cls))
238 class AbstractClassExample(AbstractChecker):
239 @abstractmethod
240 def foo(self):
241 pass
242 class ClassExample(AbstractClassExample):
243 def foo(self):
244 pass
245 self.assertEqual(isabstract_checks, [True, False])
246
247 isabstract_checks.clear()
248 class AbstractChild(AbstractClassExample):
249 pass
250 class AbstractGrandchild(AbstractChild):
251 pass
252 class ConcreteGrandchild(ClassExample):
253 pass
254 self.assertEqual(isabstract_checks, [True, True, False])
255
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000256
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000257class TestInterpreterStack(IsTestBase):
258 def __init__(self, *args, **kwargs):
259 unittest.TestCase.__init__(self, *args, **kwargs)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000260
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000261 git.abuse(7, 8, 9)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000262
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000263 def test_abuse_done(self):
264 self.istest(inspect.istraceback, 'git.ex[2]')
265 self.istest(inspect.isframe, 'mod.fr')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000266
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000267 def test_stack(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000268 self.assertTrue(len(mod.st) >= 5)
Christian Heimesa3538eb2007-11-06 11:44:48 +0000269 self.assertEqual(revise(*mod.st[0][1:]),
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000270 (modfile, 16, 'eggs', [' st = inspect.stack()\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000271 self.assertEqual(revise(*mod.st[1][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000272 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000273 self.assertEqual(revise(*mod.st[2][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000274 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000275 self.assertEqual(revise(*mod.st[3][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000276 (modfile, 39, 'abuse', [' self.argue(a, b, c)\n'], 0))
Antoine Pitroucdcafb72014-08-24 10:50:28 -0400277 # Test named tuple fields
278 record = mod.st[0]
279 self.assertIs(record.frame, mod.fr)
280 self.assertEqual(record.lineno, 16)
281 self.assertEqual(record.filename, mod.__file__)
282 self.assertEqual(record.function, 'eggs')
283 self.assertIn('inspect.stack()', record.code_context[0])
284 self.assertEqual(record.index, 0)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000285
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000286 def test_trace(self):
287 self.assertEqual(len(git.tr), 3)
Florent Xiclunac8575922010-03-24 17:37:49 +0000288 self.assertEqual(revise(*git.tr[0][1:]),
289 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
290 self.assertEqual(revise(*git.tr[1][1:]),
291 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
292 self.assertEqual(revise(*git.tr[2][1:]),
293 (modfile, 18, 'eggs', [' q = y / 0\n'], 0))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000294
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000295 def test_frame(self):
296 args, varargs, varkw, locals = inspect.getargvalues(mod.fr)
297 self.assertEqual(args, ['x', 'y'])
298 self.assertEqual(varargs, None)
299 self.assertEqual(varkw, None)
300 self.assertEqual(locals, {'x': 11, 'p': 11, 'y': 14})
301 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
302 '(x=11, y=14)')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000303
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000304 def test_previous_frame(self):
305 args, varargs, varkw, locals = inspect.getargvalues(mod.fr.f_back)
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000306 self.assertEqual(args, ['a', 'b', 'c', 'd', 'e', 'f'])
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000307 self.assertEqual(varargs, 'g')
308 self.assertEqual(varkw, 'h')
309 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000310 '(a=7, b=8, c=9, d=3, e=4, f=5, *g=(), **h={})')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000311
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000312class GetSourceBase(unittest.TestCase):
313 # Subclasses must override.
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000314 fodderModule = None
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000315
Yury Selivanov6738b112015-05-16 10:10:21 -0400316 def setUp(self):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000317 with open(inspect.getsourcefile(self.fodderModule)) as fp:
Philip Jenveya27c5bd2009-05-28 06:09:08 +0000318 self.source = fp.read()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000319
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000320 def sourcerange(self, top, bottom):
321 lines = self.source.split("\n")
322 return "\n".join(lines[top-1:bottom]) + "\n"
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000323
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000324 def assertSourceEqual(self, obj, top, bottom):
325 self.assertEqual(inspect.getsource(obj),
326 self.sourcerange(top, bottom))
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000327
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000328class TestRetrievingSourceCode(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000329 fodderModule = mod
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000330
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000331 def test_getclasses(self):
332 classes = inspect.getmembers(mod, inspect.isclass)
333 self.assertEqual(classes,
334 [('FesteringGob', mod.FesteringGob),
335 ('MalodorousPervert', mod.MalodorousPervert),
336 ('ParrotDroppings', mod.ParrotDroppings),
Serhiy Storchaka362c1b52013-09-05 17:14:32 +0300337 ('StupidGit', mod.StupidGit),
338 ('Tit', mod.MalodorousPervert),
339 ])
340 tree = inspect.getclasstree([cls[1] for cls in classes])
341 self.assertEqual(tree,
342 [(object, ()),
343 [(mod.ParrotDroppings, (object,)),
344 [(mod.FesteringGob, (mod.MalodorousPervert,
345 mod.ParrotDroppings))
346 ],
347 (mod.StupidGit, (object,)),
348 [(mod.MalodorousPervert, (mod.StupidGit,)),
349 [(mod.FesteringGob, (mod.MalodorousPervert,
350 mod.ParrotDroppings))
351 ]
352 ]
353 ]
354 ])
355 tree = inspect.getclasstree([cls[1] for cls in classes], True)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000356 self.assertEqual(tree,
Thomas Wouters725af872006-04-15 09:13:19 +0000357 [(object, ()),
358 [(mod.ParrotDroppings, (object,)),
359 (mod.StupidGit, (object,)),
360 [(mod.MalodorousPervert, (mod.StupidGit,)),
361 [(mod.FesteringGob, (mod.MalodorousPervert,
362 mod.ParrotDroppings))
363 ]
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000364 ]
365 ]
366 ])
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000367
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000368 def test_getfunctions(self):
369 functions = inspect.getmembers(mod, inspect.isfunction)
370 self.assertEqual(functions, [('eggs', mod.eggs),
Yury Selivanove4e811d2015-07-21 19:01:52 +0300371 ('lobbest', mod.lobbest),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000372 ('spam', mod.spam)])
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000373
R. David Murray378c0cf2010-02-24 01:46:21 +0000374 @unittest.skipIf(sys.flags.optimize >= 2,
375 "Docstrings are omitted with -O2 and above")
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000376 def test_getdoc(self):
377 self.assertEqual(inspect.getdoc(mod), 'A module docstring.')
378 self.assertEqual(inspect.getdoc(mod.StupidGit),
379 'A longer,\n\nindented\n\ndocstring.')
380 self.assertEqual(inspect.getdoc(git.abuse),
381 'Another\n\ndocstring\n\ncontaining\n\ntabs')
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000382
Serhiy Storchaka5cf2b7252015-04-03 22:38:53 +0300383 @unittest.skipIf(sys.flags.optimize >= 2,
384 "Docstrings are omitted with -O2 and above")
385 def test_getdoc_inherited(self):
386 self.assertEqual(inspect.getdoc(mod.FesteringGob),
387 'A longer,\n\nindented\n\ndocstring.')
388 self.assertEqual(inspect.getdoc(mod.FesteringGob.abuse),
389 'Another\n\ndocstring\n\ncontaining\n\ntabs')
390 self.assertEqual(inspect.getdoc(mod.FesteringGob().abuse),
391 'Another\n\ndocstring\n\ncontaining\n\ntabs')
392 self.assertEqual(inspect.getdoc(mod.FesteringGob.contradiction),
393 'The automatic gainsaying.')
394
395 @unittest.skipIf(MISSING_C_DOCSTRINGS, "test requires docstrings")
396 def test_finddoc(self):
397 finddoc = inspect._finddoc
398 self.assertEqual(finddoc(int), int.__doc__)
399 self.assertEqual(finddoc(int.to_bytes), int.to_bytes.__doc__)
400 self.assertEqual(finddoc(int().to_bytes), int.to_bytes.__doc__)
401 self.assertEqual(finddoc(int.from_bytes), int.from_bytes.__doc__)
402 self.assertEqual(finddoc(int.real), int.real.__doc__)
403
Georg Brandl0c77a822008-06-10 16:37:50 +0000404 def test_cleandoc(self):
405 self.assertEqual(inspect.cleandoc('An\n indented\n docstring.'),
406 'An\nindented\ndocstring.')
407
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000408 def test_getcomments(self):
409 self.assertEqual(inspect.getcomments(mod), '# line 1\n')
410 self.assertEqual(inspect.getcomments(mod.StupidGit), '# line 20\n')
Marco Buttu3f2155f2017-03-17 09:50:23 +0100411 # If the object source file is not available, return None.
412 co = compile('x=1', '_non_existing_filename.py', 'exec')
413 self.assertIsNone(inspect.getcomments(co))
414 # If the object has been defined in C, return None.
415 self.assertIsNone(inspect.getcomments(list))
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000416
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000417 def test_getmodule(self):
Thomas Wouters89f507f2006-12-13 04:49:30 +0000418 # Check actual module
419 self.assertEqual(inspect.getmodule(mod), mod)
420 # Check class (uses __module__ attribute)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000421 self.assertEqual(inspect.getmodule(mod.StupidGit), mod)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000422 # Check a method (no __module__ attribute, falls back to filename)
423 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
424 # Do it again (check the caching isn't broken)
425 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
426 # Check a builtin
Georg Brandl1a3284e2007-12-02 09:40:06 +0000427 self.assertEqual(inspect.getmodule(str), sys.modules["builtins"])
Thomas Wouters89f507f2006-12-13 04:49:30 +0000428 # Check filename override
429 self.assertEqual(inspect.getmodule(None, modfile), mod)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000430
Berker Peksagff0e3b72017-01-02 06:57:43 +0300431 def test_getframeinfo_get_first_line(self):
432 frame_info = inspect.getframeinfo(self.fodderModule.fr, 50)
433 self.assertEqual(frame_info.code_context[0], "# line 1\n")
434 self.assertEqual(frame_info.code_context[1], "'A module docstring.'\n")
435
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000436 def test_getsource(self):
437 self.assertSourceEqual(git.abuse, 29, 39)
Serhiy Storchakaac4bdcc2015-10-29 08:15:50 +0200438 self.assertSourceEqual(mod.StupidGit, 21, 51)
439 self.assertSourceEqual(mod.lobbest, 75, 76)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000440
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000441 def test_getsourcefile(self):
Christian Heimesa3538eb2007-11-06 11:44:48 +0000442 self.assertEqual(normcase(inspect.getsourcefile(mod.spam)), modfile)
443 self.assertEqual(normcase(inspect.getsourcefile(git.abuse)), modfile)
R. David Murraya1b37402010-06-17 02:04:29 +0000444 fn = "_non_existing_filename_used_for_sourcefile_test.py"
Victor Stinner51d8c522016-02-08 17:57:02 +0100445 co = compile("x=1", fn, "exec")
R. David Murray4155f972010-06-17 13:23:18 +0000446 self.assertEqual(inspect.getsourcefile(co), None)
R. David Murraya1b37402010-06-17 02:04:29 +0000447 linecache.cache[co.co_filename] = (1, None, "None", co.co_filename)
Antoine Pitrou5d62a612012-07-08 13:48:46 +0200448 try:
449 self.assertEqual(normcase(inspect.getsourcefile(co)), fn)
450 finally:
451 del linecache.cache[co.co_filename]
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000452
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000453 def test_getfile(self):
454 self.assertEqual(inspect.getfile(mod.StupidGit), mod.__file__)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000455
Yury Selivanov2eed8b72014-01-27 13:24:56 -0500456 def test_getfile_class_without_module(self):
457 class CM(type):
458 @property
459 def __module__(cls):
460 raise AttributeError
461 class C(metaclass=CM):
462 pass
463 with self.assertRaises(TypeError):
464 inspect.getfile(C)
465
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000466 def test_getmodule_recursion(self):
Christian Heimes45f9af32007-11-27 21:50:00 +0000467 from types import ModuleType
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000468 name = '__inspect_dummy'
Christian Heimes45f9af32007-11-27 21:50:00 +0000469 m = sys.modules[name] = ModuleType(name)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000470 m.__file__ = "<string>" # hopefully not a real filename...
471 m.__loader__ = "dummy" # pretend the filename is understood by a loader
Georg Brandl7cae87c2006-09-06 06:51:57 +0000472 exec("def x(): pass", m.__dict__)
Neal Norwitz221085d2007-02-25 20:55:47 +0000473 self.assertEqual(inspect.getsourcefile(m.x.__code__), '<string>')
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000474 del sys.modules[name]
475 inspect.getmodule(compile('a=10','','single'))
476
Benjamin Peterson9620cc02011-06-11 15:53:11 -0500477 def test_proceed_with_fake_filename(self):
478 '''doctest monkeypatches linecache to enable inspection'''
479 fn, source = '<test>', 'def x(): pass\n'
480 getlines = linecache.getlines
481 def monkey(filename, module_globals=None):
482 if filename == fn:
Ezio Melottid8b509b2011-09-28 17:37:55 +0300483 return source.splitlines(keepends=True)
Benjamin Peterson9620cc02011-06-11 15:53:11 -0500484 else:
485 return getlines(filename, module_globals)
486 linecache.getlines = monkey
487 try:
488 ns = {}
489 exec(compile(source, fn, 'single'), ns)
490 inspect.getsource(ns["x"])
491 finally:
492 linecache.getlines = getlines
493
Antoine Pitroua8723a02015-04-15 00:41:29 +0200494 def test_getsource_on_code_object(self):
495 self.assertSourceEqual(mod.eggs.__code__, 12, 18)
496
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000497class TestDecorators(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000498 fodderModule = mod2
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000499
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000500 def test_wrapped_decorator(self):
Christian Heimes09aaa882008-02-23 15:01:06 +0000501 self.assertSourceEqual(mod2.wrapped, 14, 17)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000502
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000503 def test_replacing_decorator(self):
504 self.assertSourceEqual(mod2.gone, 9, 10)
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000505
Yury Selivanov081bbf62014-09-26 17:34:54 -0400506 def test_getsource_unwrap(self):
Antoine Pitroua8723a02015-04-15 00:41:29 +0200507 self.assertSourceEqual(mod2.real, 130, 132)
508
509 def test_decorator_with_lambda(self):
510 self.assertSourceEqual(mod2.func114, 113, 115)
Yury Selivanov081bbf62014-09-26 17:34:54 -0400511
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000512class TestOneliners(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000513 fodderModule = mod2
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000514 def test_oneline_lambda(self):
515 # Test inspect.getsource with a one-line lambda function.
516 self.assertSourceEqual(mod2.oll, 25, 25)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000517
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000518 def test_threeline_lambda(self):
519 # Test inspect.getsource with a three-line lambda function,
520 # where the second and third lines are _not_ indented.
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000521 self.assertSourceEqual(mod2.tll, 28, 30)
522
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000523 def test_twoline_indented_lambda(self):
524 # Test inspect.getsource with a two-line lambda function,
525 # where the second line _is_ indented.
526 self.assertSourceEqual(mod2.tlli, 33, 34)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000527
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000528 def test_onelinefunc(self):
529 # Test inspect.getsource with a regular one-line function.
530 self.assertSourceEqual(mod2.onelinefunc, 37, 37)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000531
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000532 def test_manyargs(self):
533 # Test inspect.getsource with a regular function where
534 # the arguments are on two lines and _not_ indented and
535 # the body on the second line with the last arguments.
536 self.assertSourceEqual(mod2.manyargs, 40, 41)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000537
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000538 def test_twolinefunc(self):
539 # Test inspect.getsource with a regular function where
540 # the body is on two lines, following the argument list and
541 # continued on the next line by a \\.
542 self.assertSourceEqual(mod2.twolinefunc, 44, 45)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000543
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000544 def test_lambda_in_list(self):
545 # Test inspect.getsource with a one-line lambda function
546 # defined in a list, indented.
547 self.assertSourceEqual(mod2.a[1], 49, 49)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000548
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000549 def test_anonymous(self):
550 # Test inspect.getsource with a lambda function defined
551 # as argument to another function.
552 self.assertSourceEqual(mod2.anonymous, 55, 55)
553
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000554class TestBuggyCases(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000555 fodderModule = mod2
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000556
557 def test_with_comment(self):
558 self.assertSourceEqual(mod2.with_comment, 58, 59)
559
560 def test_multiline_sig(self):
561 self.assertSourceEqual(mod2.multiline_sig[0], 63, 64)
562
Armin Rigodd5c0232005-09-25 11:45:45 +0000563 def test_nested_class(self):
564 self.assertSourceEqual(mod2.func69().func71, 71, 72)
565
566 def test_one_liner_followed_by_non_name(self):
567 self.assertSourceEqual(mod2.func77, 77, 77)
568
569 def test_one_liner_dedent_non_name(self):
570 self.assertSourceEqual(mod2.cls82.func83, 83, 83)
571
572 def test_with_comment_instead_of_docstring(self):
573 self.assertSourceEqual(mod2.func88, 88, 90)
574
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000575 def test_method_in_dynamic_class(self):
576 self.assertSourceEqual(mod2.method_in_dynamic_class, 95, 97)
577
R David Murray32562d72014-10-03 11:15:38 -0400578 # This should not skip for CPython, but might on a repackaged python where
579 # unicodedata is not an external module, or on pypy.
580 @unittest.skipIf(not hasattr(unicodedata, '__file__') or
581 unicodedata.__file__.endswith('.py'),
582 "unicodedata is not an external binary module")
R. David Murray74b89242009-05-13 17:33:03 +0000583 def test_findsource_binary(self):
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200584 self.assertRaises(OSError, inspect.getsource, unicodedata)
585 self.assertRaises(OSError, inspect.findsource, unicodedata)
R. David Murray74b89242009-05-13 17:33:03 +0000586
R. David Murraya1b37402010-06-17 02:04:29 +0000587 def test_findsource_code_in_linecache(self):
588 lines = ["x=1"]
589 co = compile(lines[0], "_dynamically_created_file", "exec")
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200590 self.assertRaises(OSError, inspect.findsource, co)
591 self.assertRaises(OSError, inspect.getsource, co)
R. David Murraya1b37402010-06-17 02:04:29 +0000592 linecache.cache[co.co_filename] = (1, None, lines, co.co_filename)
Antoine Pitrou5d62a612012-07-08 13:48:46 +0200593 try:
594 self.assertEqual(inspect.findsource(co), (lines,0))
595 self.assertEqual(inspect.getsource(co), lines[0])
596 finally:
597 del linecache.cache[co.co_filename]
R. David Murraya1b37402010-06-17 02:04:29 +0000598
Ezio Melotti1b145922013-03-30 05:17:24 +0200599 def test_findsource_without_filename(self):
600 for fname in ['', '<string>']:
601 co = compile('x=1', fname, "exec")
602 self.assertRaises(IOError, inspect.findsource, co)
603 self.assertRaises(IOError, inspect.getsource, co)
604
Antoine Pitroua8723a02015-04-15 00:41:29 +0200605 def test_getsource_on_method(self):
606 self.assertSourceEqual(mod2.ClassWithMethod.method, 118, 119)
607
Yury Selivanov4f4913b2015-07-23 17:10:00 +0300608 def test_nested_func(self):
609 self.assertSourceEqual(mod2.cls135.func136, 136, 139)
610
611
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000612class TestNoEOL(GetSourceBase):
Yury Selivanov6738b112015-05-16 10:10:21 -0400613 def setUp(self):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000614 self.tempdir = TESTFN + '_dir'
615 os.mkdir(self.tempdir)
616 with open(os.path.join(self.tempdir,
617 'inspect_fodder3%spy' % os.extsep), 'w') as f:
618 f.write("class X:\n pass # No EOL")
619 with DirsOnSysPath(self.tempdir):
620 import inspect_fodder3 as mod3
621 self.fodderModule = mod3
Yury Selivanov6738b112015-05-16 10:10:21 -0400622 super().setUp()
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000623
624 def tearDown(self):
625 shutil.rmtree(self.tempdir)
626
627 def test_class(self):
628 self.assertSourceEqual(self.fodderModule.X, 1, 2)
629
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100630
631class _BrokenDataDescriptor(object):
632 """
633 A broken data descriptor. See bug #1785.
634 """
635 def __get__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700636 raise AttributeError("broken data descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100637
638 def __set__(*args):
639 raise RuntimeError
640
641 def __getattr__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700642 raise AttributeError("broken data descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100643
644
645class _BrokenMethodDescriptor(object):
646 """
647 A broken method descriptor. See bug #1785.
648 """
649 def __get__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700650 raise AttributeError("broken method descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100651
652 def __getattr__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700653 raise AttributeError("broken method descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100654
655
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000656# Helper for testing classify_class_attrs.
Tim Peters13b49d32001-09-23 02:00:29 +0000657def attrs_wo_objs(cls):
658 return [t[:3] for t in inspect.classify_class_attrs(cls)]
659
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100660
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000661class TestClassesAndFunctions(unittest.TestCase):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000662 def test_newstyle_mro(self):
663 # The same w/ new-class MRO.
664 class A(object): pass
665 class B(A): pass
666 class C(A): pass
667 class D(B, C): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000668
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000669 expected = (D, B, C, A, object)
670 got = inspect.getmro(D)
671 self.assertEqual(expected, got)
Tim Peters13b49d32001-09-23 02:00:29 +0000672
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500673 def assertArgSpecEquals(self, routine, args_e, varargs_e=None,
674 varkw_e=None, defaults_e=None, formatted=None):
675 with self.assertWarns(DeprecationWarning):
676 args, varargs, varkw, defaults = inspect.getargspec(routine)
677 self.assertEqual(args, args_e)
678 self.assertEqual(varargs, varargs_e)
679 self.assertEqual(varkw, varkw_e)
680 self.assertEqual(defaults, defaults_e)
681 if formatted is not None:
682 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults),
683 formatted)
684
Christian Heimes3795b532007-11-08 13:48:53 +0000685 def assertFullArgSpecEquals(self, routine, args_e, varargs_e=None,
686 varkw_e=None, defaults_e=None,
687 kwonlyargs_e=[], kwonlydefaults_e=None,
688 ann_e={}, formatted=None):
689 args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \
690 inspect.getfullargspec(routine)
691 self.assertEqual(args, args_e)
692 self.assertEqual(varargs, varargs_e)
693 self.assertEqual(varkw, varkw_e)
694 self.assertEqual(defaults, defaults_e)
695 self.assertEqual(kwonlyargs, kwonlyargs_e)
696 self.assertEqual(kwonlydefaults, kwonlydefaults_e)
697 self.assertEqual(ann, ann_e)
698 if formatted is not None:
699 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults,
700 kwonlyargs, kwonlydefaults, ann),
701 formatted)
702
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500703 def test_getargspec(self):
704 self.assertArgSpecEquals(mod.eggs, ['x', 'y'], formatted='(x, y)')
705
706 self.assertArgSpecEquals(mod.spam,
707 ['a', 'b', 'c', 'd', 'e', 'f'],
708 'g', 'h', (3, 4, 5),
709 '(a, b, c, d=3, e=4, f=5, *g, **h)')
710
711 self.assertRaises(ValueError, self.assertArgSpecEquals,
712 mod2.keyworded, [])
713
714 self.assertRaises(ValueError, self.assertArgSpecEquals,
715 mod2.annotated, [])
716 self.assertRaises(ValueError, self.assertArgSpecEquals,
717 mod2.keyword_only_arg, [])
718
719
Christian Heimes3795b532007-11-08 13:48:53 +0000720 def test_getfullargspec(self):
721 self.assertFullArgSpecEquals(mod2.keyworded, [], varargs_e='arg1',
722 kwonlyargs_e=['arg2'],
723 kwonlydefaults_e={'arg2':1},
724 formatted='(*arg1, arg2=1)')
725
726 self.assertFullArgSpecEquals(mod2.annotated, ['arg1'],
Christian Heimesc9543e42007-11-28 08:28:28 +0000727 ann_e={'arg1' : list},
Christian Heimes3795b532007-11-08 13:48:53 +0000728 formatted='(arg1: list)')
Benjamin Peterson9953a8d2009-01-17 04:15:01 +0000729 self.assertFullArgSpecEquals(mod2.keyword_only_arg, [],
730 kwonlyargs_e=['arg'],
731 formatted='(*, arg)')
732
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500733 def test_argspec_api_ignores_wrapped(self):
Yury Selivanov57d240e2014-02-19 16:27:23 -0500734 # Issue 20684: low level introspection API must ignore __wrapped__
735 @functools.wraps(mod.spam)
736 def ham(x, y):
737 pass
738 # Basic check
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500739 self.assertArgSpecEquals(ham, ['x', 'y'], formatted='(x, y)')
Yury Selivanov57d240e2014-02-19 16:27:23 -0500740 self.assertFullArgSpecEquals(ham, ['x', 'y'], formatted='(x, y)')
741 self.assertFullArgSpecEquals(functools.partial(ham),
742 ['x', 'y'], formatted='(x, y)')
743 # Other variants
744 def check_method(f):
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500745 self.assertArgSpecEquals(f, ['self', 'x', 'y'],
746 formatted='(self, x, y)')
Yury Selivanov57d240e2014-02-19 16:27:23 -0500747 class C:
748 @functools.wraps(mod.spam)
749 def ham(self, x, y):
750 pass
751 pham = functools.partialmethod(ham)
752 @functools.wraps(mod.spam)
753 def __call__(self, x, y):
754 pass
755 check_method(C())
756 check_method(C.ham)
757 check_method(C().ham)
758 check_method(C.pham)
759 check_method(C().pham)
760
761 class C_new:
762 @functools.wraps(mod.spam)
763 def __new__(self, x, y):
764 pass
765 check_method(C_new)
766
767 class C_init:
768 @functools.wraps(mod.spam)
769 def __init__(self, x, y):
770 pass
771 check_method(C_init)
772
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500773 def test_getfullargspec_signature_attr(self):
774 def test():
775 pass
776 spam_param = inspect.Parameter('spam', inspect.Parameter.POSITIONAL_ONLY)
777 test.__signature__ = inspect.Signature(parameters=(spam_param,))
778
779 self.assertFullArgSpecEquals(test, args_e=['spam'], formatted='(spam)')
780
Yury Selivanov4cb93912014-01-29 11:54:12 -0500781 def test_getfullargspec_signature_annos(self):
782 def test(a:'spam') -> 'ham': pass
783 spec = inspect.getfullargspec(test)
784 self.assertEqual(test.__annotations__, spec.annotations)
785
786 def test(): pass
787 spec = inspect.getfullargspec(test)
788 self.assertEqual(test.__annotations__, spec.annotations)
789
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500790 @unittest.skipIf(MISSING_C_DOCSTRINGS,
791 "Signature information for builtins requires docstrings")
792 def test_getfullargspec_builtin_methods(self):
793 self.assertFullArgSpecEquals(_pickle.Pickler.dump,
794 args_e=['self', 'obj'], formatted='(self, obj)')
795
796 self.assertFullArgSpecEquals(_pickle.Pickler(io.BytesIO()).dump,
797 args_e=['self', 'obj'], formatted='(self, obj)')
798
Yury Selivanov8c185ee2014-02-21 01:32:42 -0500799 self.assertFullArgSpecEquals(
800 os.stat,
801 args_e=['path'],
802 kwonlyargs_e=['dir_fd', 'follow_symlinks'],
803 kwonlydefaults_e={'dir_fd': None, 'follow_symlinks': True},
804 formatted='(path, *, dir_fd=None, follow_symlinks=True)')
805
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200806 @cpython_only
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500807 @unittest.skipIf(MISSING_C_DOCSTRINGS,
808 "Signature information for builtins requires docstrings")
809 def test_getfullagrspec_builtin_func(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200810 import _testcapi
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500811 builtin = _testcapi.docstring_with_signature_with_defaults
812 spec = inspect.getfullargspec(builtin)
813 self.assertEqual(spec.defaults[0], 'avocado')
814
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200815 @cpython_only
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500816 @unittest.skipIf(MISSING_C_DOCSTRINGS,
817 "Signature information for builtins requires docstrings")
818 def test_getfullagrspec_builtin_func_no_signature(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200819 import _testcapi
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500820 builtin = _testcapi.docstring_no_signature
821 with self.assertRaises(TypeError):
822 inspect.getfullargspec(builtin)
Christian Heimes3795b532007-11-08 13:48:53 +0000823
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500824 def test_getargspec_method(self):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000825 class A(object):
826 def m(self):
827 pass
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500828 self.assertArgSpecEquals(A.m, ['self'])
Tim Peters13b49d32001-09-23 02:00:29 +0000829
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000830 def test_classify_newstyle(self):
831 class A(object):
Tim Peters13b49d32001-09-23 02:00:29 +0000832
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000833 def s(): pass
834 s = staticmethod(s)
Tim Peters13b49d32001-09-23 02:00:29 +0000835
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000836 def c(cls): pass
837 c = classmethod(c)
Tim Peters13b49d32001-09-23 02:00:29 +0000838
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000839 def getp(self): pass
840 p = property(getp)
Tim Peters13b49d32001-09-23 02:00:29 +0000841
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000842 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000843
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000844 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000845
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000846 datablob = '1'
Tim Peters13b49d32001-09-23 02:00:29 +0000847
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100848 dd = _BrokenDataDescriptor()
849 md = _BrokenMethodDescriptor()
850
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000851 attrs = attrs_wo_objs(A)
Yury Selivanov0860a0b2014-01-31 14:28:44 -0500852
853 self.assertIn(('__new__', 'method', object), attrs, 'missing __new__')
854 self.assertIn(('__init__', 'method', object), attrs, 'missing __init__')
855
Benjamin Peterson577473f2010-01-19 00:09:57 +0000856 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
857 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
858 self.assertIn(('p', 'property', A), attrs, 'missing property')
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000859 self.assertIn(('m', 'method', A), attrs,
860 'missing plain method: %r' % attrs)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000861 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
862 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100863 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
864 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000865
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000866 class B(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000867
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000868 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000869
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000870 attrs = attrs_wo_objs(B)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000871 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
872 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
873 self.assertIn(('p', 'property', A), attrs, 'missing property')
874 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
875 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
876 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100877 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
878 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000879
880
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000881 class C(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000882
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000883 def m(self): pass
884 def c(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000885
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000886 attrs = attrs_wo_objs(C)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000887 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
888 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
889 self.assertIn(('p', 'property', A), attrs, 'missing property')
890 self.assertIn(('m', 'method', C), attrs, 'missing plain method')
891 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
892 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100893 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
894 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000895
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000896 class D(B, C):
Tim Peters13b49d32001-09-23 02:00:29 +0000897
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000898 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000899
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000900 attrs = attrs_wo_objs(D)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000901 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
902 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
903 self.assertIn(('p', 'property', A), attrs, 'missing property')
904 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
905 self.assertIn(('m1', 'method', D), attrs, 'missing plain method')
906 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100907 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
908 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
909
910 def test_classify_builtin_types(self):
911 # Simple sanity check that all built-in types can have their
912 # attributes classified.
913 for name in dir(__builtins__):
914 builtin = getattr(__builtins__, name)
915 if isinstance(builtin, type):
916 inspect.classify_class_attrs(builtin)
917
Ethan Furman63c141c2013-10-18 00:27:39 -0700918 def test_classify_DynamicClassAttribute(self):
919 class Meta(type):
920 def __getattr__(self, name):
921 if name == 'ham':
922 return 'spam'
923 return super().__getattr__(name)
924 class VA(metaclass=Meta):
Ethan Furmane03ea372013-09-25 07:14:41 -0700925 @types.DynamicClassAttribute
926 def ham(self):
927 return 'eggs'
Ethan Furman63c141c2013-10-18 00:27:39 -0700928 should_find_dca = inspect.Attribute('ham', 'data', VA, VA.__dict__['ham'])
929 self.assertIn(should_find_dca, inspect.classify_class_attrs(VA))
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700930 should_find_ga = inspect.Attribute('ham', 'data', Meta, 'spam')
Ethan Furman63c141c2013-10-18 00:27:39 -0700931 self.assertIn(should_find_ga, inspect.classify_class_attrs(VA))
932
Yury Selivanovbf341fb2015-05-21 15:41:57 -0400933 def test_classify_overrides_bool(self):
934 class NoBool(object):
935 def __eq__(self, other):
936 return NoBool()
937
938 def __bool__(self):
939 raise NotImplementedError(
940 "This object does not specify a boolean value")
941
942 class HasNB(object):
943 dd = NoBool()
944
945 should_find_attr = inspect.Attribute('dd', 'data', HasNB, HasNB.dd)
946 self.assertIn(should_find_attr, inspect.classify_class_attrs(HasNB))
947
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700948 def test_classify_metaclass_class_attribute(self):
949 class Meta(type):
950 fish = 'slap'
951 def __dir__(self):
Serhiy Storchakaa60c2fe2015-03-12 21:56:08 +0200952 return ['__class__', '__module__', '__name__', 'fish']
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700953 class Class(metaclass=Meta):
954 pass
955 should_find = inspect.Attribute('fish', 'data', Meta, 'slap')
956 self.assertIn(should_find, inspect.classify_class_attrs(Class))
957
Ethan Furman63c141c2013-10-18 00:27:39 -0700958 def test_classify_VirtualAttribute(self):
959 class Meta(type):
960 def __dir__(cls):
961 return ['__class__', '__module__', '__name__', 'BOOM']
962 def __getattr__(self, name):
963 if name =='BOOM':
964 return 42
965 return super().__getattr(name)
966 class Class(metaclass=Meta):
967 pass
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700968 should_find = inspect.Attribute('BOOM', 'data', Meta, 42)
Ethan Furman63c141c2013-10-18 00:27:39 -0700969 self.assertIn(should_find, inspect.classify_class_attrs(Class))
970
971 def test_classify_VirtualAttribute_multi_classes(self):
972 class Meta1(type):
973 def __dir__(cls):
974 return ['__class__', '__module__', '__name__', 'one']
975 def __getattr__(self, name):
976 if name =='one':
977 return 1
978 return super().__getattr__(name)
979 class Meta2(type):
980 def __dir__(cls):
981 return ['__class__', '__module__', '__name__', 'two']
982 def __getattr__(self, name):
983 if name =='two':
984 return 2
985 return super().__getattr__(name)
986 class Meta3(Meta1, Meta2):
987 def __dir__(cls):
988 return list(sorted(set(['__class__', '__module__', '__name__', 'three'] +
989 Meta1.__dir__(cls) + Meta2.__dir__(cls))))
990 def __getattr__(self, name):
991 if name =='three':
992 return 3
993 return super().__getattr__(name)
994 class Class1(metaclass=Meta1):
995 pass
996 class Class2(Class1, metaclass=Meta3):
997 pass
998
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700999 should_find1 = inspect.Attribute('one', 'data', Meta1, 1)
1000 should_find2 = inspect.Attribute('two', 'data', Meta2, 2)
1001 should_find3 = inspect.Attribute('three', 'data', Meta3, 3)
Ethan Furman63c141c2013-10-18 00:27:39 -07001002 cca = inspect.classify_class_attrs(Class2)
1003 for sf in (should_find1, should_find2, should_find3):
1004 self.assertIn(sf, cca)
1005
1006 def test_classify_class_attrs_with_buggy_dir(self):
1007 class M(type):
1008 def __dir__(cls):
1009 return ['__class__', '__name__', 'missing']
1010 class C(metaclass=M):
1011 pass
1012 attrs = [a[0] for a in inspect.classify_class_attrs(C)]
1013 self.assertNotIn('missing', attrs)
Ethan Furmane03ea372013-09-25 07:14:41 -07001014
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +01001015 def test_getmembers_descriptors(self):
1016 class A(object):
1017 dd = _BrokenDataDescriptor()
1018 md = _BrokenMethodDescriptor()
1019
1020 def pred_wrapper(pred):
1021 # A quick'n'dirty way to discard standard attributes of new-style
1022 # classes.
1023 class Empty(object):
1024 pass
1025 def wrapped(x):
1026 if '__name__' in dir(x) and hasattr(Empty, x.__name__):
1027 return False
1028 return pred(x)
1029 return wrapped
1030
1031 ismethoddescriptor = pred_wrapper(inspect.ismethoddescriptor)
1032 isdatadescriptor = pred_wrapper(inspect.isdatadescriptor)
1033
1034 self.assertEqual(inspect.getmembers(A, ismethoddescriptor),
1035 [('md', A.__dict__['md'])])
1036 self.assertEqual(inspect.getmembers(A, isdatadescriptor),
1037 [('dd', A.__dict__['dd'])])
1038
1039 class B(A):
1040 pass
1041
1042 self.assertEqual(inspect.getmembers(B, ismethoddescriptor),
1043 [('md', A.__dict__['md'])])
1044 self.assertEqual(inspect.getmembers(B, isdatadescriptor),
1045 [('dd', A.__dict__['dd'])])
1046
Antoine Pitrou0c603812012-01-18 17:40:18 +01001047 def test_getmembers_method(self):
1048 class B:
1049 def f(self):
1050 pass
1051
1052 self.assertIn(('f', B.f), inspect.getmembers(B))
1053 self.assertNotIn(('f', B.f), inspect.getmembers(B, inspect.ismethod))
1054 b = B()
1055 self.assertIn(('f', b.f), inspect.getmembers(b))
1056 self.assertIn(('f', b.f), inspect.getmembers(b, inspect.ismethod))
1057
Ethan Furmane03ea372013-09-25 07:14:41 -07001058 def test_getmembers_VirtualAttribute(self):
Ethan Furman63c141c2013-10-18 00:27:39 -07001059 class M(type):
1060 def __getattr__(cls, name):
1061 if name == 'eggs':
1062 return 'scrambled'
1063 return super().__getattr__(name)
1064 class A(metaclass=M):
Ethan Furmane03ea372013-09-25 07:14:41 -07001065 @types.DynamicClassAttribute
1066 def eggs(self):
1067 return 'spam'
Ethan Furman63c141c2013-10-18 00:27:39 -07001068 self.assertIn(('eggs', 'scrambled'), inspect.getmembers(A))
1069 self.assertIn(('eggs', 'spam'), inspect.getmembers(A()))
1070
1071 def test_getmembers_with_buggy_dir(self):
1072 class M(type):
1073 def __dir__(cls):
1074 return ['__class__', '__name__', 'missing']
1075 class C(metaclass=M):
1076 pass
1077 attrs = [a[0] for a in inspect.getmembers(C)]
1078 self.assertNotIn('missing', attrs)
Ethan Furmane03ea372013-09-25 07:14:41 -07001079
Jeremy Hyltonc4bf5ed2003-06-27 18:43:12 +00001080
Nick Coghlan2f92e542012-06-23 19:39:55 +10001081_global_ref = object()
1082class TestGetClosureVars(unittest.TestCase):
1083
1084 def test_name_resolution(self):
1085 # Basic test of the 4 different resolution mechanisms
1086 def f(nonlocal_ref):
1087 def g(local_ref):
1088 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
1089 return g
1090 _arg = object()
1091 nonlocal_vars = {"nonlocal_ref": _arg}
1092 global_vars = {"_global_ref": _global_ref}
1093 builtin_vars = {"print": print}
1094 unbound_names = {"unbound_ref"}
1095 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
1096 builtin_vars, unbound_names)
1097 self.assertEqual(inspect.getclosurevars(f(_arg)), expected)
1098
1099 def test_generator_closure(self):
1100 def f(nonlocal_ref):
1101 def g(local_ref):
1102 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
1103 yield
1104 return g
1105 _arg = object()
1106 nonlocal_vars = {"nonlocal_ref": _arg}
1107 global_vars = {"_global_ref": _global_ref}
1108 builtin_vars = {"print": print}
1109 unbound_names = {"unbound_ref"}
1110 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
1111 builtin_vars, unbound_names)
1112 self.assertEqual(inspect.getclosurevars(f(_arg)), expected)
1113
1114 def test_method_closure(self):
1115 class C:
1116 def f(self, nonlocal_ref):
1117 def g(local_ref):
1118 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
1119 return g
1120 _arg = object()
1121 nonlocal_vars = {"nonlocal_ref": _arg}
1122 global_vars = {"_global_ref": _global_ref}
1123 builtin_vars = {"print": print}
1124 unbound_names = {"unbound_ref"}
1125 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
1126 builtin_vars, unbound_names)
1127 self.assertEqual(inspect.getclosurevars(C().f(_arg)), expected)
1128
1129 def test_nonlocal_vars(self):
1130 # More complex tests of nonlocal resolution
1131 def _nonlocal_vars(f):
1132 return inspect.getclosurevars(f).nonlocals
1133
1134 def make_adder(x):
1135 def add(y):
1136 return x + y
1137 return add
1138
1139 def curry(func, arg1):
1140 return lambda arg2: func(arg1, arg2)
1141
1142 def less_than(a, b):
1143 return a < b
1144
1145 # The infamous Y combinator.
1146 def Y(le):
1147 def g(f):
1148 return le(lambda x: f(f)(x))
1149 Y.g_ref = g
1150 return g(g)
1151
1152 def check_y_combinator(func):
1153 self.assertEqual(_nonlocal_vars(func), {'f': Y.g_ref})
1154
1155 inc = make_adder(1)
1156 add_two = make_adder(2)
1157 greater_than_five = curry(less_than, 5)
1158
1159 self.assertEqual(_nonlocal_vars(inc), {'x': 1})
1160 self.assertEqual(_nonlocal_vars(add_two), {'x': 2})
1161 self.assertEqual(_nonlocal_vars(greater_than_five),
1162 {'arg1': 5, 'func': less_than})
1163 self.assertEqual(_nonlocal_vars((lambda x: lambda y: x + y)(3)),
1164 {'x': 3})
1165 Y(check_y_combinator)
1166
1167 def test_getclosurevars_empty(self):
1168 def foo(): pass
1169 _empty = inspect.ClosureVars({}, {}, {}, set())
1170 self.assertEqual(inspect.getclosurevars(lambda: True), _empty)
1171 self.assertEqual(inspect.getclosurevars(foo), _empty)
1172
1173 def test_getclosurevars_error(self):
1174 class T: pass
1175 self.assertRaises(TypeError, inspect.getclosurevars, 1)
1176 self.assertRaises(TypeError, inspect.getclosurevars, list)
1177 self.assertRaises(TypeError, inspect.getclosurevars, {})
1178
Nick Coghlan6c6e2542012-06-23 20:07:39 +10001179 def _private_globals(self):
1180 code = """def f(): print(path)"""
1181 ns = {}
1182 exec(code, ns)
1183 return ns["f"], ns
1184
1185 def test_builtins_fallback(self):
1186 f, ns = self._private_globals()
1187 ns.pop("__builtins__", None)
1188 expected = inspect.ClosureVars({}, {}, {"print":print}, {"path"})
1189 self.assertEqual(inspect.getclosurevars(f), expected)
1190
1191 def test_builtins_as_dict(self):
1192 f, ns = self._private_globals()
1193 ns["__builtins__"] = {"path":1}
1194 expected = inspect.ClosureVars({}, {}, {"path":1}, {"print"})
1195 self.assertEqual(inspect.getclosurevars(f), expected)
1196
1197 def test_builtins_as_module(self):
1198 f, ns = self._private_globals()
1199 ns["__builtins__"] = os
1200 expected = inspect.ClosureVars({}, {}, {"path":os.path}, {"print"})
1201 self.assertEqual(inspect.getclosurevars(f), expected)
1202
Nick Coghlan2f92e542012-06-23 19:39:55 +10001203
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001204class TestGetcallargsFunctions(unittest.TestCase):
1205
1206 def assertEqualCallArgs(self, func, call_params_string, locs=None):
1207 locs = dict(locs or {}, func=func)
1208 r1 = eval('func(%s)' % call_params_string, None, locs)
1209 r2 = eval('inspect.getcallargs(func, %s)' % call_params_string, None,
1210 locs)
1211 self.assertEqual(r1, r2)
1212
1213 def assertEqualException(self, func, call_param_string, locs=None):
1214 locs = dict(locs or {}, func=func)
1215 try:
1216 eval('func(%s)' % call_param_string, None, locs)
1217 except Exception as e:
1218 ex1 = e
1219 else:
1220 self.fail('Exception not raised')
1221 try:
1222 eval('inspect.getcallargs(func, %s)' % call_param_string, None,
1223 locs)
1224 except Exception as e:
1225 ex2 = e
1226 else:
1227 self.fail('Exception not raised')
1228 self.assertIs(type(ex1), type(ex2))
1229 self.assertEqual(str(ex1), str(ex2))
1230 del ex1, ex2
1231
1232 def makeCallable(self, signature):
1233 """Create a function that returns its locals()"""
1234 code = "lambda %s: locals()"
1235 return eval(code % signature)
1236
1237 def test_plain(self):
1238 f = self.makeCallable('a, b=1')
1239 self.assertEqualCallArgs(f, '2')
1240 self.assertEqualCallArgs(f, '2, 3')
1241 self.assertEqualCallArgs(f, 'a=2')
1242 self.assertEqualCallArgs(f, 'b=3, a=2')
1243 self.assertEqualCallArgs(f, '2, b=3')
1244 # expand *iterable / **mapping
1245 self.assertEqualCallArgs(f, '*(2,)')
1246 self.assertEqualCallArgs(f, '*[2]')
1247 self.assertEqualCallArgs(f, '*(2, 3)')
1248 self.assertEqualCallArgs(f, '*[2, 3]')
1249 self.assertEqualCallArgs(f, '**{"a":2}')
1250 self.assertEqualCallArgs(f, 'b=3, **{"a":2}')
1251 self.assertEqualCallArgs(f, '2, **{"b":3}')
1252 self.assertEqualCallArgs(f, '**{"b":3, "a":2}')
1253 # expand UserList / UserDict
1254 self.assertEqualCallArgs(f, '*collections.UserList([2])')
1255 self.assertEqualCallArgs(f, '*collections.UserList([2, 3])')
1256 self.assertEqualCallArgs(f, '**collections.UserDict(a=2)')
1257 self.assertEqualCallArgs(f, '2, **collections.UserDict(b=3)')
1258 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3)')
1259
1260 def test_varargs(self):
1261 f = self.makeCallable('a, b=1, *c')
1262 self.assertEqualCallArgs(f, '2')
1263 self.assertEqualCallArgs(f, '2, 3')
1264 self.assertEqualCallArgs(f, '2, 3, 4')
1265 self.assertEqualCallArgs(f, '*(2,3,4)')
1266 self.assertEqualCallArgs(f, '2, *[3,4]')
1267 self.assertEqualCallArgs(f, '2, 3, *collections.UserList([4])')
1268
1269 def test_varkw(self):
1270 f = self.makeCallable('a, b=1, **c')
1271 self.assertEqualCallArgs(f, 'a=2')
1272 self.assertEqualCallArgs(f, '2, b=3, c=4')
1273 self.assertEqualCallArgs(f, 'b=3, a=2, c=4')
1274 self.assertEqualCallArgs(f, 'c=4, **{"a":2, "b":3}')
1275 self.assertEqualCallArgs(f, '2, c=4, **{"b":3}')
1276 self.assertEqualCallArgs(f, 'b=2, **{"a":3, "c":4}')
1277 self.assertEqualCallArgs(f, '**collections.UserDict(a=2, b=3, c=4)')
1278 self.assertEqualCallArgs(f, '2, c=4, **collections.UserDict(b=3)')
1279 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3, c=4)')
1280
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001281 def test_varkw_only(self):
1282 # issue11256:
1283 f = self.makeCallable('**c')
1284 self.assertEqualCallArgs(f, '')
1285 self.assertEqualCallArgs(f, 'a=1')
1286 self.assertEqualCallArgs(f, 'a=1, b=2')
1287 self.assertEqualCallArgs(f, 'c=3, **{"a": 1, "b": 2}')
1288 self.assertEqualCallArgs(f, '**collections.UserDict(a=1, b=2)')
1289 self.assertEqualCallArgs(f, 'c=3, **collections.UserDict(a=1, b=2)')
1290
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001291 def test_keyword_only(self):
1292 f = self.makeCallable('a=3, *, c, d=2')
1293 self.assertEqualCallArgs(f, 'c=3')
1294 self.assertEqualCallArgs(f, 'c=3, a=3')
1295 self.assertEqualCallArgs(f, 'a=2, c=4')
1296 self.assertEqualCallArgs(f, '4, c=4')
1297 self.assertEqualException(f, '')
1298 self.assertEqualException(f, '3')
1299 self.assertEqualException(f, 'a=3')
1300 self.assertEqualException(f, 'd=4')
1301
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001302 f = self.makeCallable('*, c, d=2')
1303 self.assertEqualCallArgs(f, 'c=3')
1304 self.assertEqualCallArgs(f, 'c=3, d=4')
1305 self.assertEqualCallArgs(f, 'd=4, c=3')
1306
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001307 def test_multiple_features(self):
1308 f = self.makeCallable('a, b=2, *f, **g')
1309 self.assertEqualCallArgs(f, '2, 3, 7')
1310 self.assertEqualCallArgs(f, '2, 3, x=8')
1311 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
1312 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9')
1313 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9')
1314 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
1315 '[2, 3, (4,[5,6])]), **{"y":9, "z":10}')
1316 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
1317 '(4,[5,6])]), **collections.UserDict('
1318 'y=9, z=10)')
1319
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001320 f = self.makeCallable('a, b=2, *f, x, y=99, **g')
1321 self.assertEqualCallArgs(f, '2, 3, x=8')
1322 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
1323 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9, z=10')
1324 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9, z=10')
1325 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
1326 '[2, 3, (4,[5,6])]), q=0, **{"y":9, "z":10}')
1327 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
1328 '(4,[5,6])]), q=0, **collections.UserDict('
1329 'y=9, z=10)')
1330
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001331 def test_errors(self):
1332 f0 = self.makeCallable('')
1333 f1 = self.makeCallable('a, b')
1334 f2 = self.makeCallable('a, b=1')
1335 # f0 takes no arguments
1336 self.assertEqualException(f0, '1')
1337 self.assertEqualException(f0, 'x=1')
1338 self.assertEqualException(f0, '1,x=1')
1339 # f1 takes exactly 2 arguments
1340 self.assertEqualException(f1, '')
1341 self.assertEqualException(f1, '1')
1342 self.assertEqualException(f1, 'a=2')
1343 self.assertEqualException(f1, 'b=3')
1344 # f2 takes at least 1 argument
1345 self.assertEqualException(f2, '')
1346 self.assertEqualException(f2, 'b=3')
1347 for f in f1, f2:
1348 # f1/f2 takes exactly/at most 2 arguments
1349 self.assertEqualException(f, '2, 3, 4')
1350 self.assertEqualException(f, '1, 2, 3, a=1')
1351 self.assertEqualException(f, '2, 3, 4, c=5')
Georg Brandl178e5ea2012-02-21 00:32:36 +01001352 # XXX: success of this one depends on dict order
1353 ## self.assertEqualException(f, '2, 3, 4, a=1, c=5')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001354 # f got an unexpected keyword argument
1355 self.assertEqualException(f, 'c=2')
1356 self.assertEqualException(f, '2, c=3')
1357 self.assertEqualException(f, '2, 3, c=4')
1358 self.assertEqualException(f, '2, c=4, b=3')
1359 self.assertEqualException(f, '**{u"\u03c0\u03b9": 4}')
1360 # f got multiple values for keyword argument
1361 self.assertEqualException(f, '1, a=2')
1362 self.assertEqualException(f, '1, **{"a":2}')
1363 self.assertEqualException(f, '1, 2, b=3')
1364 # XXX: Python inconsistency
1365 # - for functions and bound methods: unexpected keyword 'c'
1366 # - for unbound methods: multiple values for keyword 'a'
1367 #self.assertEqualException(f, '1, c=3, a=2')
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001368 # issue11256:
1369 f3 = self.makeCallable('**c')
1370 self.assertEqualException(f3, '1, 2')
1371 self.assertEqualException(f3, '1, 2, a=1, b=2')
1372 f4 = self.makeCallable('*, a, b=0')
1373 self.assertEqualException(f3, '1, 2')
1374 self.assertEqualException(f3, '1, 2, a=1, b=2')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001375
Yury Selivanov875df202014-03-27 18:23:03 -04001376 # issue #20816: getcallargs() fails to iterate over non-existent
1377 # kwonlydefaults and raises a wrong TypeError
1378 def f5(*, a): pass
1379 with self.assertRaisesRegex(TypeError,
1380 'missing 1 required keyword-only'):
1381 inspect.getcallargs(f5)
1382
1383
Yury Selivanovdccfa132014-03-27 18:42:52 -04001384 # issue20817:
1385 def f6(a, b, c):
1386 pass
1387 with self.assertRaisesRegex(TypeError, "'a', 'b' and 'c'"):
1388 inspect.getcallargs(f6)
1389
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001390class TestGetcallargsMethods(TestGetcallargsFunctions):
1391
1392 def setUp(self):
1393 class Foo(object):
1394 pass
1395 self.cls = Foo
1396 self.inst = Foo()
1397
1398 def makeCallable(self, signature):
1399 assert 'self' not in signature
1400 mk = super(TestGetcallargsMethods, self).makeCallable
1401 self.cls.method = mk('self, ' + signature)
1402 return self.inst.method
1403
1404class TestGetcallargsUnboundMethods(TestGetcallargsMethods):
1405
1406 def makeCallable(self, signature):
1407 super(TestGetcallargsUnboundMethods, self).makeCallable(signature)
1408 return self.cls.method
1409
1410 def assertEqualCallArgs(self, func, call_params_string, locs=None):
1411 return super(TestGetcallargsUnboundMethods, self).assertEqualCallArgs(
1412 *self._getAssertEqualParams(func, call_params_string, locs))
1413
1414 def assertEqualException(self, func, call_params_string, locs=None):
1415 return super(TestGetcallargsUnboundMethods, self).assertEqualException(
1416 *self._getAssertEqualParams(func, call_params_string, locs))
1417
1418 def _getAssertEqualParams(self, func, call_params_string, locs=None):
1419 assert 'inst' not in call_params_string
1420 locs = dict(locs or {}, inst=self.inst)
1421 return (func, 'inst,' + call_params_string, locs)
1422
Michael Foord95fc51d2010-11-20 15:07:30 +00001423
1424class TestGetattrStatic(unittest.TestCase):
1425
1426 def test_basic(self):
1427 class Thing(object):
1428 x = object()
1429
1430 thing = Thing()
1431 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1432 self.assertEqual(inspect.getattr_static(thing, 'x', None), Thing.x)
1433 with self.assertRaises(AttributeError):
1434 inspect.getattr_static(thing, 'y')
1435
1436 self.assertEqual(inspect.getattr_static(thing, 'y', 3), 3)
1437
1438 def test_inherited(self):
1439 class Thing(object):
1440 x = object()
1441 class OtherThing(Thing):
1442 pass
1443
1444 something = OtherThing()
1445 self.assertEqual(inspect.getattr_static(something, 'x'), Thing.x)
1446
1447 def test_instance_attr(self):
1448 class Thing(object):
1449 x = 2
1450 def __init__(self, x):
1451 self.x = x
1452 thing = Thing(3)
1453 self.assertEqual(inspect.getattr_static(thing, 'x'), 3)
1454 del thing.x
1455 self.assertEqual(inspect.getattr_static(thing, 'x'), 2)
1456
1457 def test_property(self):
1458 class Thing(object):
1459 @property
1460 def x(self):
1461 raise AttributeError("I'm pretending not to exist")
1462 thing = Thing()
1463 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1464
Ezio Melotti75cbd732011-04-28 00:59:29 +03001465 def test_descriptor_raises_AttributeError(self):
Michael Foord95fc51d2010-11-20 15:07:30 +00001466 class descriptor(object):
1467 def __get__(*_):
1468 raise AttributeError("I'm pretending not to exist")
1469 desc = descriptor()
1470 class Thing(object):
1471 x = desc
1472 thing = Thing()
1473 self.assertEqual(inspect.getattr_static(thing, 'x'), desc)
1474
1475 def test_classAttribute(self):
1476 class Thing(object):
1477 x = object()
1478
1479 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.x)
1480
Ethan Furmane03ea372013-09-25 07:14:41 -07001481 def test_classVirtualAttribute(self):
1482 class Thing(object):
1483 @types.DynamicClassAttribute
1484 def x(self):
1485 return self._x
1486 _x = object()
1487
1488 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.__dict__['x'])
1489
Michael Foord95fc51d2010-11-20 15:07:30 +00001490 def test_inherited_classattribute(self):
1491 class Thing(object):
1492 x = object()
1493 class OtherThing(Thing):
1494 pass
1495
1496 self.assertEqual(inspect.getattr_static(OtherThing, 'x'), Thing.x)
1497
1498 def test_slots(self):
1499 class Thing(object):
1500 y = 'bar'
1501 __slots__ = ['x']
1502 def __init__(self):
1503 self.x = 'foo'
1504 thing = Thing()
1505 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1506 self.assertEqual(inspect.getattr_static(thing, 'y'), 'bar')
1507
1508 del thing.x
1509 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1510
1511 def test_metaclass(self):
1512 class meta(type):
1513 attr = 'foo'
1514 class Thing(object, metaclass=meta):
1515 pass
1516 self.assertEqual(inspect.getattr_static(Thing, 'attr'), 'foo')
1517
1518 class sub(meta):
1519 pass
1520 class OtherThing(object, metaclass=sub):
1521 x = 3
1522 self.assertEqual(inspect.getattr_static(OtherThing, 'attr'), 'foo')
1523
1524 class OtherOtherThing(OtherThing):
1525 pass
1526 # this test is odd, but it was added as it exposed a bug
1527 self.assertEqual(inspect.getattr_static(OtherOtherThing, 'x'), 3)
1528
1529 def test_no_dict_no_slots(self):
1530 self.assertEqual(inspect.getattr_static(1, 'foo', None), None)
1531 self.assertNotEqual(inspect.getattr_static('foo', 'lower'), None)
1532
1533 def test_no_dict_no_slots_instance_member(self):
1534 # returns descriptor
1535 with open(__file__) as handle:
1536 self.assertEqual(inspect.getattr_static(handle, 'name'), type(handle).name)
1537
1538 def test_inherited_slots(self):
1539 # returns descriptor
1540 class Thing(object):
1541 __slots__ = ['x']
1542 def __init__(self):
1543 self.x = 'foo'
1544
1545 class OtherThing(Thing):
1546 pass
1547 # it would be nice if this worked...
1548 # we get the descriptor instead of the instance attribute
1549 self.assertEqual(inspect.getattr_static(OtherThing(), 'x'), Thing.x)
1550
1551 def test_descriptor(self):
1552 class descriptor(object):
1553 def __get__(self, instance, owner):
1554 return 3
1555 class Foo(object):
1556 d = descriptor()
1557
1558 foo = Foo()
1559
1560 # for a non data descriptor we return the instance attribute
1561 foo.__dict__['d'] = 1
1562 self.assertEqual(inspect.getattr_static(foo, 'd'), 1)
1563
1564 # if the descriptor is a data-desciptor we should return the
1565 # descriptor
1566 descriptor.__set__ = lambda s, i, v: None
1567 self.assertEqual(inspect.getattr_static(foo, 'd'), Foo.__dict__['d'])
1568
1569
1570 def test_metaclass_with_descriptor(self):
1571 class descriptor(object):
1572 def __get__(self, instance, owner):
1573 return 3
1574 class meta(type):
1575 d = descriptor()
1576 class Thing(object, metaclass=meta):
1577 pass
1578 self.assertEqual(inspect.getattr_static(Thing, 'd'), meta.__dict__['d'])
1579
1580
Michael Foordcc7ebb82010-11-20 16:20:16 +00001581 def test_class_as_property(self):
1582 class Base(object):
1583 foo = 3
1584
1585 class Something(Base):
Michael Foord35184ed2010-11-20 16:58:30 +00001586 executed = False
Michael Foordcc7ebb82010-11-20 16:20:16 +00001587 @property
1588 def __class__(self):
Michael Foord35184ed2010-11-20 16:58:30 +00001589 self.executed = True
Michael Foordcc7ebb82010-11-20 16:20:16 +00001590 return object
1591
Michael Foord35184ed2010-11-20 16:58:30 +00001592 instance = Something()
1593 self.assertEqual(inspect.getattr_static(instance, 'foo'), 3)
1594 self.assertFalse(instance.executed)
Michael Foordcc7ebb82010-11-20 16:20:16 +00001595 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1596
Michael Foorde5162652010-11-20 16:40:44 +00001597 def test_mro_as_property(self):
1598 class Meta(type):
1599 @property
1600 def __mro__(self):
1601 return (object,)
1602
1603 class Base(object):
1604 foo = 3
1605
1606 class Something(Base, metaclass=Meta):
1607 pass
1608
1609 self.assertEqual(inspect.getattr_static(Something(), 'foo'), 3)
1610 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1611
Michael Foorddcebe0f2011-03-15 19:20:44 -04001612 def test_dict_as_property(self):
1613 test = self
1614 test.called = False
1615
1616 class Foo(dict):
1617 a = 3
1618 @property
1619 def __dict__(self):
1620 test.called = True
1621 return {}
1622
1623 foo = Foo()
1624 foo.a = 4
1625 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1626 self.assertFalse(test.called)
1627
1628 def test_custom_object_dict(self):
1629 test = self
1630 test.called = False
1631
1632 class Custom(dict):
1633 def get(self, key, default=None):
1634 test.called = True
1635 super().get(key, default)
1636
1637 class Foo(object):
1638 a = 3
1639 foo = Foo()
1640 foo.__dict__ = Custom()
1641 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1642 self.assertFalse(test.called)
1643
1644 def test_metaclass_dict_as_property(self):
1645 class Meta(type):
1646 @property
1647 def __dict__(self):
1648 self.executed = True
1649
1650 class Thing(metaclass=Meta):
1651 executed = False
1652
1653 def __init__(self):
1654 self.spam = 42
1655
1656 instance = Thing()
1657 self.assertEqual(inspect.getattr_static(instance, "spam"), 42)
1658 self.assertFalse(Thing.executed)
Michael Foorde5162652010-11-20 16:40:44 +00001659
Michael Foorda51623b2011-12-18 22:01:40 +00001660 def test_module(self):
1661 sentinel = object()
1662 self.assertIsNot(inspect.getattr_static(sys, "version", sentinel),
1663 sentinel)
1664
Michael Foord3ba95f82011-12-22 01:13:37 +00001665 def test_metaclass_with_metaclass_with_dict_as_property(self):
1666 class MetaMeta(type):
1667 @property
1668 def __dict__(self):
1669 self.executed = True
1670 return dict(spam=42)
1671
1672 class Meta(type, metaclass=MetaMeta):
1673 executed = False
1674
1675 class Thing(metaclass=Meta):
1676 pass
1677
1678 with self.assertRaises(AttributeError):
1679 inspect.getattr_static(Thing, "spam")
1680 self.assertFalse(Thing.executed)
1681
Nick Coghlane0f04652010-11-21 03:44:04 +00001682class TestGetGeneratorState(unittest.TestCase):
1683
1684 def setUp(self):
1685 def number_generator():
1686 for number in range(5):
1687 yield number
1688 self.generator = number_generator()
1689
1690 def _generatorstate(self):
1691 return inspect.getgeneratorstate(self.generator)
1692
1693 def test_created(self):
1694 self.assertEqual(self._generatorstate(), inspect.GEN_CREATED)
1695
1696 def test_suspended(self):
1697 next(self.generator)
1698 self.assertEqual(self._generatorstate(), inspect.GEN_SUSPENDED)
1699
1700 def test_closed_after_exhaustion(self):
1701 for i in self.generator:
1702 pass
1703 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1704
1705 def test_closed_after_immediate_exception(self):
1706 with self.assertRaises(RuntimeError):
1707 self.generator.throw(RuntimeError)
1708 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1709
1710 def test_running(self):
1711 # As mentioned on issue #10220, checking for the RUNNING state only
1712 # makes sense inside the generator itself.
1713 # The following generator checks for this by using the closure's
1714 # reference to self and the generator state checking helper method
1715 def running_check_generator():
1716 for number in range(5):
1717 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1718 yield number
1719 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1720 self.generator = running_check_generator()
1721 # Running up to the first yield
1722 next(self.generator)
1723 # Running after the first yield
1724 next(self.generator)
1725
Nick Coghlan7921b9f2010-11-30 06:36:04 +00001726 def test_easy_debugging(self):
1727 # repr() and str() of a generator state should contain the state name
1728 names = 'GEN_CREATED GEN_RUNNING GEN_SUSPENDED GEN_CLOSED'.split()
1729 for name in names:
1730 state = getattr(inspect, name)
1731 self.assertIn(name, repr(state))
1732 self.assertIn(name, str(state))
1733
Nick Coghlan04e2e3f2012-06-23 19:52:05 +10001734 def test_getgeneratorlocals(self):
1735 def each(lst, a=None):
1736 b=(1, 2, 3)
1737 for v in lst:
1738 if v == 3:
1739 c = 12
1740 yield v
1741
1742 numbers = each([1, 2, 3])
1743 self.assertEqual(inspect.getgeneratorlocals(numbers),
1744 {'a': None, 'lst': [1, 2, 3]})
1745 next(numbers)
1746 self.assertEqual(inspect.getgeneratorlocals(numbers),
1747 {'a': None, 'lst': [1, 2, 3], 'v': 1,
1748 'b': (1, 2, 3)})
1749 next(numbers)
1750 self.assertEqual(inspect.getgeneratorlocals(numbers),
1751 {'a': None, 'lst': [1, 2, 3], 'v': 2,
1752 'b': (1, 2, 3)})
1753 next(numbers)
1754 self.assertEqual(inspect.getgeneratorlocals(numbers),
1755 {'a': None, 'lst': [1, 2, 3], 'v': 3,
1756 'b': (1, 2, 3), 'c': 12})
1757 try:
1758 next(numbers)
1759 except StopIteration:
1760 pass
1761 self.assertEqual(inspect.getgeneratorlocals(numbers), {})
1762
1763 def test_getgeneratorlocals_empty(self):
1764 def yield_one():
1765 yield 1
1766 one = yield_one()
1767 self.assertEqual(inspect.getgeneratorlocals(one), {})
1768 try:
1769 next(one)
1770 except StopIteration:
1771 pass
1772 self.assertEqual(inspect.getgeneratorlocals(one), {})
1773
1774 def test_getgeneratorlocals_error(self):
1775 self.assertRaises(TypeError, inspect.getgeneratorlocals, 1)
1776 self.assertRaises(TypeError, inspect.getgeneratorlocals, lambda x: True)
1777 self.assertRaises(TypeError, inspect.getgeneratorlocals, set)
1778 self.assertRaises(TypeError, inspect.getgeneratorlocals, (2,3))
1779
Nick Coghlane0f04652010-11-21 03:44:04 +00001780
Yury Selivanov5376ba92015-06-22 12:19:30 -04001781class TestGetCoroutineState(unittest.TestCase):
1782
1783 def setUp(self):
1784 @types.coroutine
1785 def number_coroutine():
1786 for number in range(5):
1787 yield number
1788 async def coroutine():
1789 await number_coroutine()
1790 self.coroutine = coroutine()
1791
1792 def tearDown(self):
1793 self.coroutine.close()
1794
1795 def _coroutinestate(self):
1796 return inspect.getcoroutinestate(self.coroutine)
1797
1798 def test_created(self):
1799 self.assertEqual(self._coroutinestate(), inspect.CORO_CREATED)
1800
1801 def test_suspended(self):
1802 self.coroutine.send(None)
1803 self.assertEqual(self._coroutinestate(), inspect.CORO_SUSPENDED)
1804
1805 def test_closed_after_exhaustion(self):
1806 while True:
1807 try:
1808 self.coroutine.send(None)
1809 except StopIteration:
1810 break
1811
1812 self.assertEqual(self._coroutinestate(), inspect.CORO_CLOSED)
1813
1814 def test_closed_after_immediate_exception(self):
1815 with self.assertRaises(RuntimeError):
1816 self.coroutine.throw(RuntimeError)
1817 self.assertEqual(self._coroutinestate(), inspect.CORO_CLOSED)
1818
1819 def test_easy_debugging(self):
1820 # repr() and str() of a coroutine state should contain the state name
1821 names = 'CORO_CREATED CORO_RUNNING CORO_SUSPENDED CORO_CLOSED'.split()
1822 for name in names:
1823 state = getattr(inspect, name)
1824 self.assertIn(name, repr(state))
1825 self.assertIn(name, str(state))
1826
1827 def test_getcoroutinelocals(self):
1828 @types.coroutine
1829 def gencoro():
1830 yield
1831
1832 gencoro = gencoro()
1833 async def func(a=None):
1834 b = 'spam'
1835 await gencoro
1836
1837 coro = func()
1838 self.assertEqual(inspect.getcoroutinelocals(coro),
1839 {'a': None, 'gencoro': gencoro})
1840 coro.send(None)
1841 self.assertEqual(inspect.getcoroutinelocals(coro),
1842 {'a': None, 'gencoro': gencoro, 'b': 'spam'})
1843
1844
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001845class MySignature(inspect.Signature):
1846 # Top-level to make it picklable;
1847 # used in test_signature_object_pickle
1848 pass
1849
1850class MyParameter(inspect.Parameter):
1851 # Top-level to make it picklable;
1852 # used in test_signature_object_pickle
1853 pass
1854
Nick Coghlanf9e227e2014-08-17 14:01:19 +10001855
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001856
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001857class TestSignatureObject(unittest.TestCase):
1858 @staticmethod
Yury Selivanovbcd4fc12015-05-20 14:30:08 -04001859 def signature(func, **kw):
1860 sig = inspect.signature(func, **kw)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001861 return (tuple((param.name,
1862 (... if param.default is param.empty else param.default),
1863 (... if param.annotation is param.empty
1864 else param.annotation),
1865 str(param.kind).lower())
1866 for param in sig.parameters.values()),
1867 (... if sig.return_annotation is sig.empty
1868 else sig.return_annotation))
1869
1870 def test_signature_object(self):
1871 S = inspect.Signature
1872 P = inspect.Parameter
1873
1874 self.assertEqual(str(S()), '()')
1875
Yury Selivanov07a9e452014-01-29 10:58:16 -05001876 def test(po, pk, pod=42, pkd=100, *args, ko, **kwargs):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001877 pass
1878 sig = inspect.signature(test)
1879 po = sig.parameters['po'].replace(kind=P.POSITIONAL_ONLY)
Yury Selivanov07a9e452014-01-29 10:58:16 -05001880 pod = sig.parameters['pod'].replace(kind=P.POSITIONAL_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001881 pk = sig.parameters['pk']
Yury Selivanov07a9e452014-01-29 10:58:16 -05001882 pkd = sig.parameters['pkd']
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001883 args = sig.parameters['args']
1884 ko = sig.parameters['ko']
1885 kwargs = sig.parameters['kwargs']
1886
1887 S((po, pk, args, ko, kwargs))
1888
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001889 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001890 S((pk, po, 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((po, args, pk, 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((args, po, 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((po, pk, args, kwargs, ko))
1900
1901 kwargs2 = kwargs.replace(name='args')
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001902 with self.assertRaisesRegex(ValueError, 'duplicate parameter name'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001903 S((po, pk, args, kwargs2, ko))
1904
Yury Selivanov07a9e452014-01-29 10:58:16 -05001905 with self.assertRaisesRegex(ValueError, 'follows default argument'):
1906 S((pod, po))
1907
1908 with self.assertRaisesRegex(ValueError, 'follows default argument'):
1909 S((po, pkd, pk))
1910
1911 with self.assertRaisesRegex(ValueError, 'follows default argument'):
1912 S((pkd, pk))
1913
Yury Selivanov374375d2014-03-27 12:41:53 -04001914 self.assertTrue(repr(sig).startswith('<Signature'))
Yury Selivanov0cd2bf42015-05-15 12:55:20 -04001915 self.assertTrue('(po, pk' in repr(sig))
Yury Selivanov374375d2014-03-27 12:41:53 -04001916
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001917 def test_signature_object_pickle(self):
1918 def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
1919 foo_partial = functools.partial(foo, a=1)
1920
1921 sig = inspect.signature(foo_partial)
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001922
1923 for ver in range(pickle.HIGHEST_PROTOCOL + 1):
1924 with self.subTest(pickle_ver=ver, subclass=False):
1925 sig_pickled = pickle.loads(pickle.dumps(sig, ver))
1926 self.assertEqual(sig, sig_pickled)
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001927
1928 # Test that basic sub-classing works
1929 sig = inspect.signature(foo)
1930 myparam = MyParameter(name='z', kind=inspect.Parameter.POSITIONAL_ONLY)
1931 myparams = collections.OrderedDict(sig.parameters, a=myparam)
1932 mysig = MySignature().replace(parameters=myparams.values(),
1933 return_annotation=sig.return_annotation)
1934 self.assertTrue(isinstance(mysig, MySignature))
1935 self.assertTrue(isinstance(mysig.parameters['z'], MyParameter))
1936
1937 for ver in range(pickle.HIGHEST_PROTOCOL + 1):
1938 with self.subTest(pickle_ver=ver, subclass=True):
1939 sig_pickled = pickle.loads(pickle.dumps(mysig, ver))
1940 self.assertEqual(mysig, sig_pickled)
1941 self.assertTrue(isinstance(sig_pickled, MySignature))
1942 self.assertTrue(isinstance(sig_pickled.parameters['z'],
1943 MyParameter))
1944
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001945 def test_signature_immutability(self):
1946 def test(a):
1947 pass
1948 sig = inspect.signature(test)
1949
1950 with self.assertRaises(AttributeError):
1951 sig.foo = 'bar'
1952
1953 with self.assertRaises(TypeError):
1954 sig.parameters['a'] = None
1955
1956 def test_signature_on_noarg(self):
1957 def test():
1958 pass
1959 self.assertEqual(self.signature(test), ((), ...))
1960
1961 def test_signature_on_wargs(self):
1962 def test(a, b:'foo') -> 123:
1963 pass
1964 self.assertEqual(self.signature(test),
1965 ((('a', ..., ..., "positional_or_keyword"),
1966 ('b', ..., 'foo', "positional_or_keyword")),
1967 123))
1968
1969 def test_signature_on_wkwonly(self):
1970 def test(*, a:float, b:str) -> int:
1971 pass
1972 self.assertEqual(self.signature(test),
1973 ((('a', ..., float, "keyword_only"),
1974 ('b', ..., str, "keyword_only")),
1975 int))
1976
1977 def test_signature_on_complex_args(self):
1978 def test(a, b:'foo'=10, *args:'bar', spam:'baz', ham=123, **kwargs:int):
1979 pass
1980 self.assertEqual(self.signature(test),
1981 ((('a', ..., ..., "positional_or_keyword"),
1982 ('b', 10, 'foo', "positional_or_keyword"),
1983 ('args', ..., 'bar', "var_positional"),
1984 ('spam', ..., 'baz', "keyword_only"),
1985 ('ham', 123, ..., "keyword_only"),
1986 ('kwargs', ..., int, "var_keyword")),
1987 ...))
1988
Dong-hee Na378d7062017-05-18 04:00:51 +09001989 def test_signature_without_self(self):
1990 def test_args_only(*args): # NOQA
1991 pass
1992
1993 def test_args_kwargs_only(*args, **kwargs): # NOQA
1994 pass
1995
1996 class A:
1997 @classmethod
1998 def test_classmethod(*args): # NOQA
1999 pass
2000
2001 @staticmethod
2002 def test_staticmethod(*args): # NOQA
2003 pass
2004
2005 f1 = functools.partialmethod((test_classmethod), 1)
2006 f2 = functools.partialmethod((test_args_only), 1)
2007 f3 = functools.partialmethod((test_staticmethod), 1)
2008 f4 = functools.partialmethod((test_args_kwargs_only),1)
2009
2010 self.assertEqual(self.signature(test_args_only),
2011 ((('args', ..., ..., 'var_positional'),), ...))
2012 self.assertEqual(self.signature(test_args_kwargs_only),
2013 ((('args', ..., ..., 'var_positional'),
2014 ('kwargs', ..., ..., 'var_keyword')), ...))
2015 self.assertEqual(self.signature(A.f1),
2016 ((('args', ..., ..., 'var_positional'),), ...))
2017 self.assertEqual(self.signature(A.f2),
2018 ((('args', ..., ..., 'var_positional'),), ...))
2019 self.assertEqual(self.signature(A.f3),
2020 ((('args', ..., ..., 'var_positional'),), ...))
2021 self.assertEqual(self.signature(A.f4),
2022 ((('args', ..., ..., 'var_positional'),
2023 ('kwargs', ..., ..., 'var_keyword')), ...))
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002024 @cpython_only
Larry Hastingsfcafe432013-11-23 17:35:48 -08002025 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2026 "Signature information for builtins requires docstrings")
2027 def test_signature_on_builtins(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002028 import _testcapi
Larry Hastings16c51912014-01-07 11:53:01 -08002029
Larry Hastings5c661892014-01-24 06:17:25 -08002030 def test_unbound_method(o):
2031 """Use this to test unbound methods (things that should have a self)"""
2032 signature = inspect.signature(o)
2033 self.assertTrue(isinstance(signature, inspect.Signature))
2034 self.assertEqual(list(signature.parameters.values())[0].name, 'self')
2035 return signature
2036
2037 def test_callable(o):
2038 """Use this to test bound methods or normal callables (things that don't expect self)"""
2039 signature = inspect.signature(o)
2040 self.assertTrue(isinstance(signature, inspect.Signature))
2041 if signature.parameters:
2042 self.assertNotEqual(list(signature.parameters.values())[0].name, 'self')
2043 return signature
2044
2045 signature = test_callable(_testcapi.docstring_with_signature_with_defaults)
Larry Hastings16c51912014-01-07 11:53:01 -08002046 def p(name): return signature.parameters[name].default
2047 self.assertEqual(p('s'), 'avocado')
Larry Hastings2a727912014-01-16 11:32:01 -08002048 self.assertEqual(p('b'), b'bytes')
Larry Hastings16c51912014-01-07 11:53:01 -08002049 self.assertEqual(p('d'), 3.14)
2050 self.assertEqual(p('i'), 35)
Larry Hastings16c51912014-01-07 11:53:01 -08002051 self.assertEqual(p('n'), None)
2052 self.assertEqual(p('t'), True)
2053 self.assertEqual(p('f'), False)
Larry Hastings2a727912014-01-16 11:32:01 -08002054 self.assertEqual(p('local'), 3)
2055 self.assertEqual(p('sys'), sys.maxsize)
2056 self.assertEqual(p('exp'), sys.maxsize - 1)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002057
Larry Hastings5c661892014-01-24 06:17:25 -08002058 test_callable(object)
2059
2060 # normal method
2061 # (PyMethodDescr_Type, "method_descriptor")
2062 test_unbound_method(_pickle.Pickler.dump)
2063 d = _pickle.Pickler(io.StringIO())
2064 test_callable(d.dump)
2065
2066 # static method
2067 test_callable(str.maketrans)
2068 test_callable('abc'.maketrans)
2069
2070 # class method
2071 test_callable(dict.fromkeys)
2072 test_callable({}.fromkeys)
2073
2074 # wrapper around slot (PyWrapperDescr_Type, "wrapper_descriptor")
2075 test_unbound_method(type.__call__)
2076 test_unbound_method(int.__add__)
2077 test_callable((3).__add__)
2078
2079 # _PyMethodWrapper_Type
2080 # support for 'method-wrapper'
2081 test_callable(min.__call__)
2082
Larry Hastings2623c8c2014-02-08 22:15:29 -08002083 # This doesn't work now.
2084 # (We don't have a valid signature for "type" in 3.4)
2085 with self.assertRaisesRegex(ValueError, "no signature found"):
2086 class ThisWorksNow:
2087 __call__ = type
2088 test_callable(ThisWorksNow())
Larry Hastings5c661892014-01-24 06:17:25 -08002089
Yury Selivanov056e2652014-03-02 12:25:27 -05002090 # Regression test for issue #20786
2091 test_unbound_method(dict.__delitem__)
2092 test_unbound_method(property.__delete__)
2093
Zachary Ware8ef887c2015-04-13 18:22:35 -05002094 # Regression test for issue #20586
2095 test_callable(_testcapi.docstring_with_signature_but_no_doc)
2096
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002097 @cpython_only
Yury Selivanov76c6c592014-01-29 10:52:57 -05002098 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2099 "Signature information for builtins requires docstrings")
2100 def test_signature_on_decorated_builtins(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002101 import _testcapi
Yury Selivanov76c6c592014-01-29 10:52:57 -05002102 func = _testcapi.docstring_with_signature_with_defaults
2103
2104 def decorator(func):
2105 @functools.wraps(func)
2106 def wrapper(*args, **kwargs) -> int:
2107 return func(*args, **kwargs)
2108 return wrapper
2109
2110 decorated_func = decorator(func)
2111
2112 self.assertEqual(inspect.signature(func),
2113 inspect.signature(decorated_func))
Larry Hastings5c661892014-01-24 06:17:25 -08002114
Yury Selivanovbcd4fc12015-05-20 14:30:08 -04002115 def wrapper_like(*args, **kwargs) -> int: pass
2116 self.assertEqual(inspect.signature(decorated_func,
2117 follow_wrapped=False),
2118 inspect.signature(wrapper_like))
2119
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002120 @cpython_only
Larry Hastings5c661892014-01-24 06:17:25 -08002121 def test_signature_on_builtins_no_signature(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002122 import _testcapi
Yury Selivanovbf304fc2015-05-30 17:08:36 -04002123 with self.assertRaisesRegex(ValueError,
2124 'no signature found for builtin'):
Larry Hastings5c661892014-01-24 06:17:25 -08002125 inspect.signature(_testcapi.docstring_no_signature)
2126
Yury Selivanovbf304fc2015-05-30 17:08:36 -04002127 with self.assertRaisesRegex(ValueError,
2128 'no signature found for builtin'):
2129 inspect.signature(str)
2130
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002131 def test_signature_on_non_function(self):
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002132 with self.assertRaisesRegex(TypeError, 'is not a callable object'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002133 inspect.signature(42)
2134
Yury Selivanov63da7c72014-01-31 14:48:37 -05002135 def test_signature_from_functionlike_object(self):
2136 def func(a,b, *args, kwonly=True, kwonlyreq, **kwargs):
2137 pass
2138
2139 class funclike:
2140 # Has to be callable, and have correct
2141 # __code__, __annotations__, __defaults__, __name__,
2142 # and __kwdefaults__ attributes
2143
2144 def __init__(self, func):
2145 self.__name__ = func.__name__
2146 self.__code__ = func.__code__
2147 self.__annotations__ = func.__annotations__
2148 self.__defaults__ = func.__defaults__
2149 self.__kwdefaults__ = func.__kwdefaults__
2150 self.func = func
2151
2152 def __call__(self, *args, **kwargs):
2153 return self.func(*args, **kwargs)
2154
Yury Selivanov57c74fc2015-05-20 23:07:02 -04002155 sig_func = inspect.Signature.from_callable(func)
Yury Selivanov63da7c72014-01-31 14:48:37 -05002156
Yury Selivanov57c74fc2015-05-20 23:07:02 -04002157 sig_funclike = inspect.Signature.from_callable(funclike(func))
Yury Selivanov63da7c72014-01-31 14:48:37 -05002158 self.assertEqual(sig_funclike, sig_func)
2159
2160 sig_funclike = inspect.signature(funclike(func))
2161 self.assertEqual(sig_funclike, sig_func)
2162
2163 # If object is not a duck type of function, then
2164 # signature will try to get a signature for its '__call__'
2165 # method
2166 fl = funclike(func)
2167 del fl.__defaults__
2168 self.assertEqual(self.signature(fl),
2169 ((('args', ..., ..., "var_positional"),
2170 ('kwargs', ..., ..., "var_keyword")),
2171 ...))
2172
Yury Selivanova773de02014-02-21 18:30:53 -05002173 # Test with cython-like builtins:
2174 _orig_isdesc = inspect.ismethoddescriptor
2175 def _isdesc(obj):
2176 if hasattr(obj, '_builtinmock'):
2177 return True
2178 return _orig_isdesc(obj)
2179
2180 with unittest.mock.patch('inspect.ismethoddescriptor', _isdesc):
2181 builtin_func = funclike(func)
2182 # Make sure that our mock setup is working
2183 self.assertFalse(inspect.ismethoddescriptor(builtin_func))
2184 builtin_func._builtinmock = True
2185 self.assertTrue(inspect.ismethoddescriptor(builtin_func))
2186 self.assertEqual(inspect.signature(builtin_func), sig_func)
2187
Yury Selivanov63da7c72014-01-31 14:48:37 -05002188 def test_signature_functionlike_class(self):
2189 # We only want to duck type function-like objects,
2190 # not classes.
2191
2192 def func(a,b, *args, kwonly=True, kwonlyreq, **kwargs):
2193 pass
2194
2195 class funclike:
2196 def __init__(self, marker):
2197 pass
2198
2199 __name__ = func.__name__
2200 __code__ = func.__code__
2201 __annotations__ = func.__annotations__
2202 __defaults__ = func.__defaults__
2203 __kwdefaults__ = func.__kwdefaults__
2204
Yury Selivanov63da7c72014-01-31 14:48:37 -05002205 self.assertEqual(str(inspect.signature(funclike)), '(marker)')
2206
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002207 def test_signature_on_method(self):
2208 class Test:
Yury Selivanov62560fb2014-01-28 12:26:24 -05002209 def __init__(*args):
2210 pass
2211 def m1(self, arg1, arg2=1) -> int:
2212 pass
2213 def m2(*args):
2214 pass
2215 def __call__(*, a):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002216 pass
2217
Yury Selivanov62560fb2014-01-28 12:26:24 -05002218 self.assertEqual(self.signature(Test().m1),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002219 ((('arg1', ..., ..., "positional_or_keyword"),
2220 ('arg2', 1, ..., "positional_or_keyword")),
2221 int))
2222
Yury Selivanov62560fb2014-01-28 12:26:24 -05002223 self.assertEqual(self.signature(Test().m2),
2224 ((('args', ..., ..., "var_positional"),),
2225 ...))
2226
2227 self.assertEqual(self.signature(Test),
2228 ((('args', ..., ..., "var_positional"),),
2229 ...))
2230
2231 with self.assertRaisesRegex(ValueError, 'invalid method signature'):
2232 self.signature(Test())
2233
Yury Selivanov46c759d2015-05-27 21:56:53 -04002234 def test_signature_wrapped_bound_method(self):
2235 # Issue 24298
2236 class Test:
2237 def m1(self, arg1, arg2=1) -> int:
2238 pass
2239 @functools.wraps(Test().m1)
2240 def m1d(*args, **kwargs):
2241 pass
2242 self.assertEqual(self.signature(m1d),
2243 ((('arg1', ..., ..., "positional_or_keyword"),
2244 ('arg2', 1, ..., "positional_or_keyword")),
2245 int))
2246
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002247 def test_signature_on_classmethod(self):
2248 class Test:
2249 @classmethod
2250 def foo(cls, arg1, *, arg2=1):
2251 pass
2252
2253 meth = Test().foo
2254 self.assertEqual(self.signature(meth),
2255 ((('arg1', ..., ..., "positional_or_keyword"),
2256 ('arg2', 1, ..., "keyword_only")),
2257 ...))
2258
2259 meth = Test.foo
2260 self.assertEqual(self.signature(meth),
2261 ((('arg1', ..., ..., "positional_or_keyword"),
2262 ('arg2', 1, ..., "keyword_only")),
2263 ...))
2264
2265 def test_signature_on_staticmethod(self):
2266 class Test:
2267 @staticmethod
2268 def foo(cls, *, arg):
2269 pass
2270
2271 meth = Test().foo
2272 self.assertEqual(self.signature(meth),
2273 ((('cls', ..., ..., "positional_or_keyword"),
2274 ('arg', ..., ..., "keyword_only")),
2275 ...))
2276
2277 meth = Test.foo
2278 self.assertEqual(self.signature(meth),
2279 ((('cls', ..., ..., "positional_or_keyword"),
2280 ('arg', ..., ..., "keyword_only")),
2281 ...))
2282
2283 def test_signature_on_partial(self):
2284 from functools import partial
2285
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002286 Parameter = inspect.Parameter
2287
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002288 def test():
2289 pass
2290
2291 self.assertEqual(self.signature(partial(test)), ((), ...))
2292
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002293 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002294 inspect.signature(partial(test, 1))
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, a=1))
2298
2299 def test(a, b, *, c, d):
2300 pass
2301
2302 self.assertEqual(self.signature(partial(test)),
2303 ((('a', ..., ..., "positional_or_keyword"),
2304 ('b', ..., ..., "positional_or_keyword"),
2305 ('c', ..., ..., "keyword_only"),
2306 ('d', ..., ..., "keyword_only")),
2307 ...))
2308
2309 self.assertEqual(self.signature(partial(test, 1)),
2310 ((('b', ..., ..., "positional_or_keyword"),
2311 ('c', ..., ..., "keyword_only"),
2312 ('d', ..., ..., "keyword_only")),
2313 ...))
2314
2315 self.assertEqual(self.signature(partial(test, 1, c=2)),
2316 ((('b', ..., ..., "positional_or_keyword"),
2317 ('c', 2, ..., "keyword_only"),
2318 ('d', ..., ..., "keyword_only")),
2319 ...))
2320
2321 self.assertEqual(self.signature(partial(test, b=1, c=2)),
2322 ((('a', ..., ..., "positional_or_keyword"),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002323 ('b', 1, ..., "keyword_only"),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002324 ('c', 2, ..., "keyword_only"),
2325 ('d', ..., ..., "keyword_only")),
2326 ...))
2327
2328 self.assertEqual(self.signature(partial(test, 0, b=1, c=2)),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002329 ((('b', 1, ..., "keyword_only"),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002330 ('c', 2, ..., "keyword_only"),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002331 ('d', ..., ..., "keyword_only")),
2332 ...))
2333
2334 self.assertEqual(self.signature(partial(test, a=1)),
2335 ((('a', 1, ..., "keyword_only"),
2336 ('b', ..., ..., "keyword_only"),
2337 ('c', ..., ..., "keyword_only"),
2338 ('d', ..., ..., "keyword_only")),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002339 ...))
2340
2341 def test(a, *args, b, **kwargs):
2342 pass
2343
2344 self.assertEqual(self.signature(partial(test, 1)),
2345 ((('args', ..., ..., "var_positional"),
2346 ('b', ..., ..., "keyword_only"),
2347 ('kwargs', ..., ..., "var_keyword")),
2348 ...))
2349
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002350 self.assertEqual(self.signature(partial(test, a=1)),
2351 ((('a', 1, ..., "keyword_only"),
2352 ('b', ..., ..., "keyword_only"),
2353 ('kwargs', ..., ..., "var_keyword")),
2354 ...))
2355
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002356 self.assertEqual(self.signature(partial(test, 1, 2, 3)),
2357 ((('args', ..., ..., "var_positional"),
2358 ('b', ..., ..., "keyword_only"),
2359 ('kwargs', ..., ..., "var_keyword")),
2360 ...))
2361
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002362 self.assertEqual(self.signature(partial(test, 1, 2, 3, test=True)),
2363 ((('args', ..., ..., "var_positional"),
2364 ('b', ..., ..., "keyword_only"),
2365 ('kwargs', ..., ..., "var_keyword")),
2366 ...))
2367
2368 self.assertEqual(self.signature(partial(test, 1, 2, 3, test=1, b=0)),
2369 ((('args', ..., ..., "var_positional"),
2370 ('b', 0, ..., "keyword_only"),
2371 ('kwargs', ..., ..., "var_keyword")),
2372 ...))
2373
2374 self.assertEqual(self.signature(partial(test, b=0)),
2375 ((('a', ..., ..., "positional_or_keyword"),
2376 ('args', ..., ..., "var_positional"),
2377 ('b', 0, ..., "keyword_only"),
2378 ('kwargs', ..., ..., "var_keyword")),
2379 ...))
2380
2381 self.assertEqual(self.signature(partial(test, b=0, test=1)),
2382 ((('a', ..., ..., "positional_or_keyword"),
2383 ('args', ..., ..., "var_positional"),
2384 ('b', 0, ..., "keyword_only"),
2385 ('kwargs', ..., ..., "var_keyword")),
2386 ...))
2387
2388 def test(a, b, c:int) -> 42:
2389 pass
2390
2391 sig = test.__signature__ = inspect.signature(test)
2392
2393 self.assertEqual(self.signature(partial(partial(test, 1))),
2394 ((('b', ..., ..., "positional_or_keyword"),
2395 ('c', ..., int, "positional_or_keyword")),
2396 42))
2397
2398 self.assertEqual(self.signature(partial(partial(test, 1), 2)),
2399 ((('c', ..., int, "positional_or_keyword"),),
2400 42))
2401
2402 psig = inspect.signature(partial(partial(test, 1), 2))
2403
2404 def foo(a):
2405 return a
2406 _foo = partial(partial(foo, a=10), a=20)
2407 self.assertEqual(self.signature(_foo),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002408 ((('a', 20, ..., "keyword_only"),),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002409 ...))
2410 # check that we don't have any side-effects in signature(),
2411 # and the partial object is still functioning
2412 self.assertEqual(_foo(), 20)
2413
2414 def foo(a, b, c):
2415 return a, b, c
2416 _foo = partial(partial(foo, 1, b=20), b=30)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002417
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002418 self.assertEqual(self.signature(_foo),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002419 ((('b', 30, ..., "keyword_only"),
2420 ('c', ..., ..., "keyword_only")),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002421 ...))
2422 self.assertEqual(_foo(c=10), (1, 30, 10))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002423
2424 def foo(a, b, c, *, d):
2425 return a, b, c, d
2426 _foo = partial(partial(foo, d=20, c=20), b=10, d=30)
2427 self.assertEqual(self.signature(_foo),
2428 ((('a', ..., ..., "positional_or_keyword"),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002429 ('b', 10, ..., "keyword_only"),
2430 ('c', 20, ..., "keyword_only"),
2431 ('d', 30, ..., "keyword_only"),
2432 ),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002433 ...))
2434 ba = inspect.signature(_foo).bind(a=200, b=11)
2435 self.assertEqual(_foo(*ba.args, **ba.kwargs), (200, 11, 20, 30))
2436
2437 def foo(a=1, b=2, c=3):
2438 return a, b, c
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002439 _foo = partial(foo, c=13) # (a=1, b=2, *, c=13)
2440
2441 ba = inspect.signature(_foo).bind(a=11)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002442 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 2, 13))
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002443
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002444 ba = inspect.signature(_foo).bind(11, 12)
2445 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002446
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002447 ba = inspect.signature(_foo).bind(11, b=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(b=12)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002451 self.assertEqual(_foo(*ba.args, **ba.kwargs), (1, 12, 13))
2452
2453 _foo = partial(_foo, b=10, c=20)
2454 ba = inspect.signature(_foo).bind(12)
2455 self.assertEqual(_foo(*ba.args, **ba.kwargs), (12, 10, 20))
2456
2457
2458 def foo(a, b, c, d, **kwargs):
2459 pass
2460 sig = inspect.signature(foo)
2461 params = sig.parameters.copy()
2462 params['a'] = params['a'].replace(kind=Parameter.POSITIONAL_ONLY)
2463 params['b'] = params['b'].replace(kind=Parameter.POSITIONAL_ONLY)
2464 foo.__signature__ = inspect.Signature(params.values())
2465 sig = inspect.signature(foo)
2466 self.assertEqual(str(sig), '(a, b, /, c, d, **kwargs)')
2467
2468 self.assertEqual(self.signature(partial(foo, 1)),
2469 ((('b', ..., ..., 'positional_only'),
2470 ('c', ..., ..., 'positional_or_keyword'),
2471 ('d', ..., ..., 'positional_or_keyword'),
2472 ('kwargs', ..., ..., 'var_keyword')),
2473 ...))
2474
2475 self.assertEqual(self.signature(partial(foo, 1, 2)),
2476 ((('c', ..., ..., 'positional_or_keyword'),
2477 ('d', ..., ..., 'positional_or_keyword'),
2478 ('kwargs', ..., ..., 'var_keyword')),
2479 ...))
2480
2481 self.assertEqual(self.signature(partial(foo, 1, 2, 3)),
2482 ((('d', ..., ..., 'positional_or_keyword'),
2483 ('kwargs', ..., ..., 'var_keyword')),
2484 ...))
2485
2486 self.assertEqual(self.signature(partial(foo, 1, 2, c=3)),
2487 ((('c', 3, ..., 'keyword_only'),
2488 ('d', ..., ..., 'keyword_only'),
2489 ('kwargs', ..., ..., 'var_keyword')),
2490 ...))
2491
2492 self.assertEqual(self.signature(partial(foo, 1, c=3)),
2493 ((('b', ..., ..., 'positional_only'),
2494 ('c', 3, ..., 'keyword_only'),
2495 ('d', ..., ..., 'keyword_only'),
2496 ('kwargs', ..., ..., 'var_keyword')),
2497 ...))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002498
Yury Selivanovda5fe4f2014-01-27 17:28:37 -05002499 def test_signature_on_partialmethod(self):
2500 from functools import partialmethod
2501
2502 class Spam:
2503 def test():
2504 pass
2505 ham = partialmethod(test)
2506
2507 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
2508 inspect.signature(Spam.ham)
2509
2510 class Spam:
2511 def test(it, a, *, c) -> 'spam':
2512 pass
2513 ham = partialmethod(test, c=1)
2514
2515 self.assertEqual(self.signature(Spam.ham),
2516 ((('it', ..., ..., 'positional_or_keyword'),
2517 ('a', ..., ..., 'positional_or_keyword'),
2518 ('c', 1, ..., 'keyword_only')),
2519 'spam'))
2520
2521 self.assertEqual(self.signature(Spam().ham),
2522 ((('a', ..., ..., 'positional_or_keyword'),
2523 ('c', 1, ..., 'keyword_only')),
2524 'spam'))
2525
Yury Selivanov0486f812014-01-29 12:18:59 -05002526 def test_signature_on_fake_partialmethod(self):
2527 def foo(a): pass
2528 foo._partialmethod = 'spam'
2529 self.assertEqual(str(inspect.signature(foo)), '(a)')
2530
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002531 def test_signature_on_decorated(self):
2532 import functools
2533
2534 def decorator(func):
2535 @functools.wraps(func)
2536 def wrapper(*args, **kwargs) -> int:
2537 return func(*args, **kwargs)
2538 return wrapper
2539
2540 class Foo:
2541 @decorator
2542 def bar(self, a, b):
2543 pass
2544
2545 self.assertEqual(self.signature(Foo.bar),
2546 ((('self', ..., ..., "positional_or_keyword"),
2547 ('a', ..., ..., "positional_or_keyword"),
2548 ('b', ..., ..., "positional_or_keyword")),
2549 ...))
2550
2551 self.assertEqual(self.signature(Foo().bar),
2552 ((('a', ..., ..., "positional_or_keyword"),
2553 ('b', ..., ..., "positional_or_keyword")),
2554 ...))
2555
Yury Selivanovbcd4fc12015-05-20 14:30:08 -04002556 self.assertEqual(self.signature(Foo.bar, follow_wrapped=False),
2557 ((('args', ..., ..., "var_positional"),
2558 ('kwargs', ..., ..., "var_keyword")),
2559 ...)) # functools.wraps will copy __annotations__
2560 # from "func" to "wrapper", hence no
2561 # return_annotation
2562
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002563 # Test that we handle method wrappers correctly
2564 def decorator(func):
2565 @functools.wraps(func)
2566 def wrapper(*args, **kwargs) -> int:
2567 return func(42, *args, **kwargs)
2568 sig = inspect.signature(func)
2569 new_params = tuple(sig.parameters.values())[1:]
2570 wrapper.__signature__ = sig.replace(parameters=new_params)
2571 return wrapper
2572
2573 class Foo:
2574 @decorator
2575 def __call__(self, a, b):
2576 pass
2577
2578 self.assertEqual(self.signature(Foo.__call__),
2579 ((('a', ..., ..., "positional_or_keyword"),
2580 ('b', ..., ..., "positional_or_keyword")),
2581 ...))
2582
2583 self.assertEqual(self.signature(Foo().__call__),
2584 ((('b', ..., ..., "positional_or_keyword"),),
2585 ...))
2586
Nick Coghlane8c45d62013-07-28 20:00:01 +10002587 # Test we handle __signature__ partway down the wrapper stack
2588 def wrapped_foo_call():
2589 pass
2590 wrapped_foo_call.__wrapped__ = Foo.__call__
2591
2592 self.assertEqual(self.signature(wrapped_foo_call),
2593 ((('a', ..., ..., "positional_or_keyword"),
2594 ('b', ..., ..., "positional_or_keyword")),
2595 ...))
2596
2597
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002598 def test_signature_on_class(self):
2599 class C:
2600 def __init__(self, a):
2601 pass
2602
2603 self.assertEqual(self.signature(C),
2604 ((('a', ..., ..., "positional_or_keyword"),),
2605 ...))
2606
2607 class CM(type):
2608 def __call__(cls, a):
2609 pass
2610 class C(metaclass=CM):
2611 def __init__(self, b):
2612 pass
2613
2614 self.assertEqual(self.signature(C),
2615 ((('a', ..., ..., "positional_or_keyword"),),
2616 ...))
2617
2618 class CM(type):
2619 def __new__(mcls, name, bases, dct, *, foo=1):
2620 return super().__new__(mcls, name, bases, dct)
2621 class C(metaclass=CM):
2622 def __init__(self, b):
2623 pass
2624
2625 self.assertEqual(self.signature(C),
2626 ((('b', ..., ..., "positional_or_keyword"),),
2627 ...))
2628
2629 self.assertEqual(self.signature(CM),
2630 ((('name', ..., ..., "positional_or_keyword"),
2631 ('bases', ..., ..., "positional_or_keyword"),
2632 ('dct', ..., ..., "positional_or_keyword"),
2633 ('foo', 1, ..., "keyword_only")),
2634 ...))
2635
2636 class CMM(type):
2637 def __new__(mcls, name, bases, dct, *, foo=1):
2638 return super().__new__(mcls, name, bases, dct)
2639 def __call__(cls, nm, bs, dt):
2640 return type(nm, bs, dt)
2641 class CM(type, metaclass=CMM):
2642 def __new__(mcls, name, bases, dct, *, bar=2):
2643 return super().__new__(mcls, name, bases, dct)
2644 class C(metaclass=CM):
2645 def __init__(self, b):
2646 pass
2647
2648 self.assertEqual(self.signature(CMM),
2649 ((('name', ..., ..., "positional_or_keyword"),
2650 ('bases', ..., ..., "positional_or_keyword"),
2651 ('dct', ..., ..., "positional_or_keyword"),
2652 ('foo', 1, ..., "keyword_only")),
2653 ...))
2654
2655 self.assertEqual(self.signature(CM),
2656 ((('nm', ..., ..., "positional_or_keyword"),
2657 ('bs', ..., ..., "positional_or_keyword"),
2658 ('dt', ..., ..., "positional_or_keyword")),
2659 ...))
2660
2661 self.assertEqual(self.signature(C),
2662 ((('b', ..., ..., "positional_or_keyword"),),
2663 ...))
2664
2665 class CM(type):
2666 def __init__(cls, name, bases, dct, *, bar=2):
2667 return super().__init__(name, bases, dct)
2668 class C(metaclass=CM):
2669 def __init__(self, b):
2670 pass
2671
2672 self.assertEqual(self.signature(CM),
2673 ((('name', ..., ..., "positional_or_keyword"),
2674 ('bases', ..., ..., "positional_or_keyword"),
2675 ('dct', ..., ..., "positional_or_keyword"),
2676 ('bar', 2, ..., "keyword_only")),
2677 ...))
2678
Yury Selivanov145dff82014-02-01 13:49:29 -05002679 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2680 "Signature information for builtins requires docstrings")
2681 def test_signature_on_class_without_init(self):
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002682 # Test classes without user-defined __init__ or __new__
2683 class C: pass
2684 self.assertEqual(str(inspect.signature(C)), '()')
2685 class D(C): pass
2686 self.assertEqual(str(inspect.signature(D)), '()')
2687
2688 # Test meta-classes without user-defined __init__ or __new__
2689 class C(type): pass
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002690 class D(C): pass
Larry Hastings2623c8c2014-02-08 22:15:29 -08002691 with self.assertRaisesRegex(ValueError, "callable.*is not supported"):
2692 self.assertEqual(inspect.signature(C), None)
2693 with self.assertRaisesRegex(ValueError, "callable.*is not supported"):
2694 self.assertEqual(inspect.signature(D), None)
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002695
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002696 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2697 "Signature information for builtins requires docstrings")
2698 def test_signature_on_builtin_class(self):
2699 self.assertEqual(str(inspect.signature(_pickle.Pickler)),
2700 '(file, protocol=None, fix_imports=True)')
2701
2702 class P(_pickle.Pickler): pass
2703 class EmptyTrait: pass
2704 class P2(EmptyTrait, P): pass
2705 self.assertEqual(str(inspect.signature(P)),
2706 '(file, protocol=None, fix_imports=True)')
2707 self.assertEqual(str(inspect.signature(P2)),
2708 '(file, protocol=None, fix_imports=True)')
2709
2710 class P3(P2):
2711 def __init__(self, spam):
2712 pass
2713 self.assertEqual(str(inspect.signature(P3)), '(spam)')
2714
2715 class MetaP(type):
2716 def __call__(cls, foo, bar):
2717 pass
2718 class P4(P2, metaclass=MetaP):
2719 pass
2720 self.assertEqual(str(inspect.signature(P4)), '(foo, bar)')
2721
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002722 def test_signature_on_callable_objects(self):
2723 class Foo:
2724 def __call__(self, a):
2725 pass
2726
2727 self.assertEqual(self.signature(Foo()),
2728 ((('a', ..., ..., "positional_or_keyword"),),
2729 ...))
2730
2731 class Spam:
2732 pass
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002733 with self.assertRaisesRegex(TypeError, "is not a callable object"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002734 inspect.signature(Spam())
2735
2736 class Bar(Spam, Foo):
2737 pass
2738
2739 self.assertEqual(self.signature(Bar()),
2740 ((('a', ..., ..., "positional_or_keyword"),),
2741 ...))
2742
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002743 class Wrapped:
2744 pass
2745 Wrapped.__wrapped__ = lambda a: None
2746 self.assertEqual(self.signature(Wrapped),
2747 ((('a', ..., ..., "positional_or_keyword"),),
2748 ...))
Nick Coghlane8c45d62013-07-28 20:00:01 +10002749 # wrapper loop:
2750 Wrapped.__wrapped__ = Wrapped
2751 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
2752 self.signature(Wrapped)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002753
2754 def test_signature_on_lambdas(self):
2755 self.assertEqual(self.signature((lambda a=10: a)),
2756 ((('a', 10, ..., "positional_or_keyword"),),
2757 ...))
2758
2759 def test_signature_equality(self):
2760 def foo(a, *, b:int) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002761 self.assertFalse(inspect.signature(foo) == 42)
2762 self.assertTrue(inspect.signature(foo) != 42)
2763 self.assertTrue(inspect.signature(foo) == EqualsToAll())
2764 self.assertFalse(inspect.signature(foo) != EqualsToAll())
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002765
2766 def bar(a, *, b:int) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002767 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
2768 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002769 self.assertEqual(
2770 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002771
2772 def bar(a, *, b:int) -> int: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002773 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
2774 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002775 self.assertNotEqual(
2776 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002777
2778 def bar(a, *, b:int): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002779 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
2780 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002781 self.assertNotEqual(
2782 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002783
2784 def bar(a, *, b:int=42) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002785 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
2786 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002787 self.assertNotEqual(
2788 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002789
2790 def bar(a, *, c) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002791 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
2792 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002793 self.assertNotEqual(
2794 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002795
2796 def bar(a, b:int) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002797 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
2798 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002799 self.assertNotEqual(
2800 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002801 def spam(b:int, a) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002802 self.assertFalse(inspect.signature(spam) == inspect.signature(bar))
2803 self.assertTrue(inspect.signature(spam) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002804 self.assertNotEqual(
2805 hash(inspect.signature(spam)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002806
2807 def foo(*, a, b, c): pass
2808 def bar(*, c, b, a): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002809 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
2810 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002811 self.assertEqual(
2812 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002813
2814 def foo(*, a=1, b, c): pass
2815 def bar(*, c, b, a=1): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002816 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
2817 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002818 self.assertEqual(
2819 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002820
2821 def foo(pos, *, a=1, b, c): pass
2822 def bar(pos, *, c, b, a=1): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002823 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
2824 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002825 self.assertEqual(
2826 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002827
2828 def foo(pos, *, a, b, c): pass
2829 def bar(pos, *, c, b, a=1): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002830 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
2831 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002832 self.assertNotEqual(
2833 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002834
2835 def foo(pos, *args, a=42, b, c, **kwargs:int): pass
2836 def bar(pos, *args, c, b, a=42, **kwargs:int): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002837 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
2838 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002839 self.assertEqual(
2840 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002841
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002842 def test_signature_hashable(self):
2843 S = inspect.Signature
2844 P = inspect.Parameter
2845
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002846 def foo(a): pass
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002847 foo_sig = inspect.signature(foo)
2848
2849 manual_sig = S(parameters=[P('a', P.POSITIONAL_OR_KEYWORD)])
2850
2851 self.assertEqual(hash(foo_sig), hash(manual_sig))
2852 self.assertNotEqual(hash(foo_sig),
2853 hash(manual_sig.replace(return_annotation='spam')))
2854
2855 def bar(a) -> 1: pass
2856 self.assertNotEqual(hash(foo_sig), hash(inspect.signature(bar)))
2857
2858 def foo(a={}): pass
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002859 with self.assertRaisesRegex(TypeError, 'unhashable type'):
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002860 hash(inspect.signature(foo))
2861
2862 def foo(a) -> {}: pass
2863 with self.assertRaisesRegex(TypeError, 'unhashable type'):
2864 hash(inspect.signature(foo))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002865
2866 def test_signature_str(self):
2867 def foo(a:int=1, *, b, c=None, **kwargs) -> 42:
2868 pass
2869 self.assertEqual(str(inspect.signature(foo)),
2870 '(a:int=1, *, b, c=None, **kwargs) -> 42')
2871
2872 def foo(a:int=1, *args, b, c=None, **kwargs) -> 42:
2873 pass
2874 self.assertEqual(str(inspect.signature(foo)),
2875 '(a:int=1, *args, b, c=None, **kwargs) -> 42')
2876
2877 def foo():
2878 pass
2879 self.assertEqual(str(inspect.signature(foo)), '()')
2880
2881 def test_signature_str_positional_only(self):
2882 P = inspect.Parameter
Yury Selivanov2393dca2014-01-27 15:07:58 -05002883 S = inspect.Signature
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002884
2885 def test(a_po, *, b, **kwargs):
2886 return a_po, kwargs
2887
2888 sig = inspect.signature(test)
2889 new_params = list(sig.parameters.values())
2890 new_params[0] = new_params[0].replace(kind=P.POSITIONAL_ONLY)
2891 test.__signature__ = sig.replace(parameters=new_params)
2892
2893 self.assertEqual(str(inspect.signature(test)),
Yury Selivanov2393dca2014-01-27 15:07:58 -05002894 '(a_po, /, *, b, **kwargs)')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002895
Yury Selivanov2393dca2014-01-27 15:07:58 -05002896 self.assertEqual(str(S(parameters=[P('foo', P.POSITIONAL_ONLY)])),
2897 '(foo, /)')
2898
2899 self.assertEqual(str(S(parameters=[
2900 P('foo', P.POSITIONAL_ONLY),
2901 P('bar', P.VAR_KEYWORD)])),
2902 '(foo, /, **bar)')
2903
2904 self.assertEqual(str(S(parameters=[
2905 P('foo', P.POSITIONAL_ONLY),
2906 P('bar', P.VAR_POSITIONAL)])),
2907 '(foo, /, *bar)')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002908
2909 def test_signature_replace_anno(self):
2910 def test() -> 42:
2911 pass
2912
2913 sig = inspect.signature(test)
2914 sig = sig.replace(return_annotation=None)
2915 self.assertIs(sig.return_annotation, None)
2916 sig = sig.replace(return_annotation=sig.empty)
2917 self.assertIs(sig.return_annotation, sig.empty)
2918 sig = sig.replace(return_annotation=42)
2919 self.assertEqual(sig.return_annotation, 42)
2920 self.assertEqual(sig, inspect.signature(test))
2921
Yury Selivanov34ce99f2014-02-18 12:49:41 -05002922 def test_signature_on_mangled_parameters(self):
2923 class Spam:
2924 def foo(self, __p1:1=2, *, __p2:2=3):
2925 pass
2926 class Ham(Spam):
2927 pass
2928
2929 self.assertEqual(self.signature(Spam.foo),
2930 ((('self', ..., ..., "positional_or_keyword"),
2931 ('_Spam__p1', 2, 1, "positional_or_keyword"),
2932 ('_Spam__p2', 3, 2, "keyword_only")),
2933 ...))
2934
2935 self.assertEqual(self.signature(Spam.foo),
2936 self.signature(Ham.foo))
2937
Yury Selivanovda396452014-03-27 12:09:24 -04002938 def test_signature_from_callable_python_obj(self):
2939 class MySignature(inspect.Signature): pass
2940 def foo(a, *, b:1): pass
2941 foo_sig = MySignature.from_callable(foo)
2942 self.assertTrue(isinstance(foo_sig, MySignature))
2943
2944 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2945 "Signature information for builtins requires docstrings")
2946 def test_signature_from_callable_builtin_obj(self):
2947 class MySignature(inspect.Signature): pass
2948 sig = MySignature.from_callable(_pickle.Pickler)
2949 self.assertTrue(isinstance(sig, MySignature))
2950
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002951
2952class TestParameterObject(unittest.TestCase):
2953 def test_signature_parameter_kinds(self):
2954 P = inspect.Parameter
2955 self.assertTrue(P.POSITIONAL_ONLY < P.POSITIONAL_OR_KEYWORD < \
2956 P.VAR_POSITIONAL < P.KEYWORD_ONLY < P.VAR_KEYWORD)
2957
2958 self.assertEqual(str(P.POSITIONAL_ONLY), 'POSITIONAL_ONLY')
2959 self.assertTrue('POSITIONAL_ONLY' in repr(P.POSITIONAL_ONLY))
2960
2961 def test_signature_parameter_object(self):
2962 p = inspect.Parameter('foo', default=10,
2963 kind=inspect.Parameter.POSITIONAL_ONLY)
2964 self.assertEqual(p.name, 'foo')
2965 self.assertEqual(p.default, 10)
2966 self.assertIs(p.annotation, p.empty)
2967 self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY)
2968
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002969 with self.assertRaisesRegex(ValueError, 'invalid value'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002970 inspect.Parameter('foo', default=10, kind='123')
2971
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002972 with self.assertRaisesRegex(ValueError, 'not a valid parameter name'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002973 inspect.Parameter('1', kind=inspect.Parameter.VAR_KEYWORD)
2974
Yury Selivanov2393dca2014-01-27 15:07:58 -05002975 with self.assertRaisesRegex(TypeError, 'name must be a str'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002976 inspect.Parameter(None, kind=inspect.Parameter.VAR_KEYWORD)
2977
Yury Selivanov2393dca2014-01-27 15:07:58 -05002978 with self.assertRaisesRegex(ValueError,
2979 'is not a valid parameter name'):
2980 inspect.Parameter('$', kind=inspect.Parameter.VAR_KEYWORD)
2981
Nick Coghlanb4b966e2016-06-04 14:40:03 -07002982 with self.assertRaisesRegex(ValueError,
2983 'is not a valid parameter name'):
2984 inspect.Parameter('.a', kind=inspect.Parameter.VAR_KEYWORD)
2985
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002986 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002987 inspect.Parameter('a', default=42,
2988 kind=inspect.Parameter.VAR_KEYWORD)
2989
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002990 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002991 inspect.Parameter('a', default=42,
2992 kind=inspect.Parameter.VAR_POSITIONAL)
2993
2994 p = inspect.Parameter('a', default=42,
2995 kind=inspect.Parameter.POSITIONAL_OR_KEYWORD)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002996 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002997 p.replace(kind=inspect.Parameter.VAR_POSITIONAL)
2998
2999 self.assertTrue(repr(p).startswith('<Parameter'))
Yury Selivanov374375d2014-03-27 12:41:53 -04003000 self.assertTrue('"a=42"' in repr(p))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003001
Yury Selivanov67ae50e2014-04-08 11:46:50 -04003002 def test_signature_parameter_hashable(self):
3003 P = inspect.Parameter
3004 foo = P('foo', kind=P.POSITIONAL_ONLY)
3005 self.assertEqual(hash(foo), hash(P('foo', kind=P.POSITIONAL_ONLY)))
3006 self.assertNotEqual(hash(foo), hash(P('foo', kind=P.POSITIONAL_ONLY,
3007 default=42)))
3008 self.assertNotEqual(hash(foo),
3009 hash(foo.replace(kind=P.VAR_POSITIONAL)))
3010
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003011 def test_signature_parameter_equality(self):
3012 P = inspect.Parameter
3013 p = P('foo', default=42, kind=inspect.Parameter.KEYWORD_ONLY)
3014
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003015 self.assertTrue(p == p)
3016 self.assertFalse(p != p)
3017 self.assertFalse(p == 42)
3018 self.assertTrue(p != 42)
3019 self.assertTrue(p == EqualsToAll())
3020 self.assertFalse(p != EqualsToAll())
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003021
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003022 self.assertTrue(p == P('foo', default=42,
3023 kind=inspect.Parameter.KEYWORD_ONLY))
3024 self.assertFalse(p != P('foo', default=42,
3025 kind=inspect.Parameter.KEYWORD_ONLY))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003026
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003027 def test_signature_parameter_replace(self):
3028 p = inspect.Parameter('foo', default=42,
3029 kind=inspect.Parameter.KEYWORD_ONLY)
3030
3031 self.assertIsNot(p, p.replace())
3032 self.assertEqual(p, p.replace())
3033
3034 p2 = p.replace(annotation=1)
3035 self.assertEqual(p2.annotation, 1)
3036 p2 = p2.replace(annotation=p2.empty)
3037 self.assertEqual(p, p2)
3038
3039 p2 = p2.replace(name='bar')
3040 self.assertEqual(p2.name, 'bar')
3041 self.assertNotEqual(p2, p)
3042
Yury Selivanov2393dca2014-01-27 15:07:58 -05003043 with self.assertRaisesRegex(ValueError,
3044 'name is a required attribute'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003045 p2 = p2.replace(name=p2.empty)
3046
3047 p2 = p2.replace(name='foo', default=None)
3048 self.assertIs(p2.default, None)
3049 self.assertNotEqual(p2, p)
3050
3051 p2 = p2.replace(name='foo', default=p2.empty)
3052 self.assertIs(p2.default, p2.empty)
3053
3054
3055 p2 = p2.replace(default=42, kind=p2.POSITIONAL_OR_KEYWORD)
3056 self.assertEqual(p2.kind, p2.POSITIONAL_OR_KEYWORD)
3057 self.assertNotEqual(p2, p)
3058
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003059 with self.assertRaisesRegex(ValueError, 'invalid value for'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003060 p2 = p2.replace(kind=p2.empty)
3061
3062 p2 = p2.replace(kind=p2.KEYWORD_ONLY)
3063 self.assertEqual(p2, p)
3064
3065 def test_signature_parameter_positional_only(self):
Yury Selivanov2393dca2014-01-27 15:07:58 -05003066 with self.assertRaisesRegex(TypeError, 'name must be a str'):
3067 inspect.Parameter(None, kind=inspect.Parameter.POSITIONAL_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003068
Nick Coghlanb4b966e2016-06-04 14:40:03 -07003069 @cpython_only
3070 def test_signature_parameter_implicit(self):
3071 with self.assertRaisesRegex(ValueError,
3072 'implicit arguments must be passed in as'):
3073 inspect.Parameter('.0', kind=inspect.Parameter.POSITIONAL_ONLY)
3074
3075 param = inspect.Parameter(
3076 '.0', kind=inspect.Parameter.POSITIONAL_OR_KEYWORD)
3077 self.assertEqual(param.kind, inspect.Parameter.POSITIONAL_ONLY)
3078 self.assertEqual(param.name, 'implicit0')
3079
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003080 def test_signature_parameter_immutability(self):
Yury Selivanov2393dca2014-01-27 15:07:58 -05003081 p = inspect.Parameter('spam', kind=inspect.Parameter.KEYWORD_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003082
3083 with self.assertRaises(AttributeError):
3084 p.foo = 'bar'
3085
3086 with self.assertRaises(AttributeError):
3087 p.kind = 123
3088
3089
3090class TestSignatureBind(unittest.TestCase):
3091 @staticmethod
3092 def call(func, *args, **kwargs):
3093 sig = inspect.signature(func)
3094 ba = sig.bind(*args, **kwargs)
3095 return func(*ba.args, **ba.kwargs)
3096
3097 def test_signature_bind_empty(self):
3098 def test():
3099 return 42
3100
3101 self.assertEqual(self.call(test), 42)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003102 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003103 self.call(test, 1)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003104 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003105 self.call(test, 1, spam=10)
Yury Selivanov86872752015-05-19 00:27:49 -04003106 with self.assertRaisesRegex(
3107 TypeError, "got an unexpected keyword argument 'spam'"):
3108
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003109 self.call(test, spam=1)
3110
3111 def test_signature_bind_var(self):
3112 def test(*args, **kwargs):
3113 return args, kwargs
3114
3115 self.assertEqual(self.call(test), ((), {}))
3116 self.assertEqual(self.call(test, 1), ((1,), {}))
3117 self.assertEqual(self.call(test, 1, 2), ((1, 2), {}))
3118 self.assertEqual(self.call(test, foo='bar'), ((), {'foo': 'bar'}))
3119 self.assertEqual(self.call(test, 1, foo='bar'), ((1,), {'foo': 'bar'}))
3120 self.assertEqual(self.call(test, args=10), ((), {'args': 10}))
3121 self.assertEqual(self.call(test, 1, 2, foo='bar'),
3122 ((1, 2), {'foo': 'bar'}))
3123
3124 def test_signature_bind_just_args(self):
3125 def test(a, b, c):
3126 return a, b, c
3127
3128 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
3129
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003130 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003131 self.call(test, 1, 2, 3, 4)
3132
Yury Selivanov86872752015-05-19 00:27:49 -04003133 with self.assertRaisesRegex(TypeError,
3134 "missing a required argument: 'b'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003135 self.call(test, 1)
3136
Yury Selivanov86872752015-05-19 00:27:49 -04003137 with self.assertRaisesRegex(TypeError,
3138 "missing a required argument: 'a'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003139 self.call(test)
3140
3141 def test(a, b, c=10):
3142 return a, b, c
3143 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
3144 self.assertEqual(self.call(test, 1, 2), (1, 2, 10))
3145
3146 def test(a=1, b=2, c=3):
3147 return a, b, c
3148 self.assertEqual(self.call(test, a=10, c=13), (10, 2, 13))
3149 self.assertEqual(self.call(test, a=10), (10, 2, 3))
3150 self.assertEqual(self.call(test, b=10), (1, 10, 3))
3151
3152 def test_signature_bind_varargs_order(self):
3153 def test(*args):
3154 return args
3155
3156 self.assertEqual(self.call(test), ())
3157 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
3158
3159 def test_signature_bind_args_and_varargs(self):
3160 def test(a, b, c=3, *args):
3161 return a, b, c, args
3162
3163 self.assertEqual(self.call(test, 1, 2, 3, 4, 5), (1, 2, 3, (4, 5)))
3164 self.assertEqual(self.call(test, 1, 2), (1, 2, 3, ()))
3165 self.assertEqual(self.call(test, b=1, a=2), (2, 1, 3, ()))
3166 self.assertEqual(self.call(test, 1, b=2), (1, 2, 3, ()))
3167
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003168 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003169 "multiple values for argument 'c'"):
3170 self.call(test, 1, 2, 3, c=4)
3171
3172 def test_signature_bind_just_kwargs(self):
3173 def test(**kwargs):
3174 return kwargs
3175
3176 self.assertEqual(self.call(test), {})
3177 self.assertEqual(self.call(test, foo='bar', spam='ham'),
3178 {'foo': 'bar', 'spam': 'ham'})
3179
3180 def test_signature_bind_args_and_kwargs(self):
3181 def test(a, b, c=3, **kwargs):
3182 return a, b, c, kwargs
3183
3184 self.assertEqual(self.call(test, 1, 2), (1, 2, 3, {}))
3185 self.assertEqual(self.call(test, 1, 2, foo='bar', spam='ham'),
3186 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3187 self.assertEqual(self.call(test, b=2, a=1, foo='bar', spam='ham'),
3188 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3189 self.assertEqual(self.call(test, a=1, b=2, foo='bar', spam='ham'),
3190 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3191 self.assertEqual(self.call(test, 1, b=2, foo='bar', spam='ham'),
3192 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3193 self.assertEqual(self.call(test, 1, b=2, c=4, foo='bar', spam='ham'),
3194 (1, 2, 4, {'foo': 'bar', 'spam': 'ham'}))
3195 self.assertEqual(self.call(test, 1, 2, 4, foo='bar'),
3196 (1, 2, 4, {'foo': 'bar'}))
3197 self.assertEqual(self.call(test, c=5, a=4, b=3),
3198 (4, 3, 5, {}))
3199
3200 def test_signature_bind_kwonly(self):
3201 def test(*, foo):
3202 return foo
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003203 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003204 'too many positional arguments'):
3205 self.call(test, 1)
3206 self.assertEqual(self.call(test, foo=1), 1)
3207
3208 def test(a, *, foo=1, bar):
3209 return foo
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003210 with self.assertRaisesRegex(TypeError,
Yury Selivanov86872752015-05-19 00:27:49 -04003211 "missing a required argument: 'bar'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003212 self.call(test, 1)
3213
3214 def test(foo, *, bar):
3215 return foo, bar
3216 self.assertEqual(self.call(test, 1, bar=2), (1, 2))
3217 self.assertEqual(self.call(test, bar=2, foo=1), (1, 2))
3218
Yury Selivanov86872752015-05-19 00:27:49 -04003219 with self.assertRaisesRegex(
3220 TypeError, "got an unexpected keyword argument 'spam'"):
3221
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003222 self.call(test, bar=2, foo=1, spam=10)
3223
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003224 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003225 'too many positional arguments'):
3226 self.call(test, 1, 2)
3227
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003228 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003229 'too many positional arguments'):
3230 self.call(test, 1, 2, bar=2)
3231
Yury Selivanov86872752015-05-19 00:27:49 -04003232 with self.assertRaisesRegex(
3233 TypeError, "got an unexpected keyword argument 'spam'"):
3234
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003235 self.call(test, 1, bar=2, spam='ham')
3236
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003237 with self.assertRaisesRegex(TypeError,
Yury Selivanov86872752015-05-19 00:27:49 -04003238 "missing a required argument: 'bar'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003239 self.call(test, 1)
3240
3241 def test(foo, *, bar, **bin):
3242 return foo, bar, bin
3243 self.assertEqual(self.call(test, 1, bar=2), (1, 2, {}))
3244 self.assertEqual(self.call(test, foo=1, bar=2), (1, 2, {}))
3245 self.assertEqual(self.call(test, 1, bar=2, spam='ham'),
3246 (1, 2, {'spam': 'ham'}))
3247 self.assertEqual(self.call(test, spam='ham', foo=1, bar=2),
3248 (1, 2, {'spam': 'ham'}))
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003249 with self.assertRaisesRegex(TypeError,
Yury Selivanov86872752015-05-19 00:27:49 -04003250 "missing a required argument: 'foo'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003251 self.call(test, spam='ham', bar=2)
3252 self.assertEqual(self.call(test, 1, bar=2, bin=1, spam=10),
3253 (1, 2, {'bin': 1, 'spam': 10}))
3254
3255 def test_signature_bind_arguments(self):
3256 def test(a, *args, b, z=100, **kwargs):
3257 pass
3258 sig = inspect.signature(test)
3259 ba = sig.bind(10, 20, b=30, c=40, args=50, kwargs=60)
3260 # we won't have 'z' argument in the bound arguments object, as we didn't
3261 # pass it to the 'bind'
3262 self.assertEqual(tuple(ba.arguments.items()),
3263 (('a', 10), ('args', (20,)), ('b', 30),
3264 ('kwargs', {'c': 40, 'args': 50, 'kwargs': 60})))
3265 self.assertEqual(ba.kwargs,
3266 {'b': 30, 'c': 40, 'args': 50, 'kwargs': 60})
3267 self.assertEqual(ba.args, (10, 20))
3268
3269 def test_signature_bind_positional_only(self):
3270 P = inspect.Parameter
3271
3272 def test(a_po, b_po, c_po=3, foo=42, *, bar=50, **kwargs):
3273 return a_po, b_po, c_po, foo, bar, kwargs
3274
3275 sig = inspect.signature(test)
3276 new_params = collections.OrderedDict(tuple(sig.parameters.items()))
3277 for name in ('a_po', 'b_po', 'c_po'):
3278 new_params[name] = new_params[name].replace(kind=P.POSITIONAL_ONLY)
3279 new_sig = sig.replace(parameters=new_params.values())
3280 test.__signature__ = new_sig
3281
3282 self.assertEqual(self.call(test, 1, 2, 4, 5, bar=6),
3283 (1, 2, 4, 5, 6, {}))
3284
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05003285 self.assertEqual(self.call(test, 1, 2),
3286 (1, 2, 3, 42, 50, {}))
3287
3288 self.assertEqual(self.call(test, 1, 2, foo=4, bar=5),
3289 (1, 2, 3, 4, 5, {}))
3290
3291 with self.assertRaisesRegex(TypeError, "but was passed as a keyword"):
3292 self.call(test, 1, 2, foo=4, bar=5, c_po=10)
3293
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003294 with self.assertRaisesRegex(TypeError, "parameter is positional only"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003295 self.call(test, 1, 2, c_po=4)
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, a_po=1, b_po=2)
3299
Antoine Pitroubd41d1b2013-01-29 21:20:57 +01003300 def test_signature_bind_with_self_arg(self):
3301 # Issue #17071: one of the parameters is named "self
3302 def test(a, self, b):
3303 pass
3304 sig = inspect.signature(test)
3305 ba = sig.bind(1, 2, 3)
3306 self.assertEqual(ba.args, (1, 2, 3))
3307 ba = sig.bind(1, self=2, b=3)
3308 self.assertEqual(ba.args, (1, 2, 3))
3309
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05003310 def test_signature_bind_vararg_name(self):
3311 def test(a, *args):
3312 return a, args
3313 sig = inspect.signature(test)
3314
Yury Selivanov86872752015-05-19 00:27:49 -04003315 with self.assertRaisesRegex(
3316 TypeError, "got an unexpected keyword argument 'args'"):
3317
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05003318 sig.bind(a=0, args=1)
3319
3320 def test(*args, **kwargs):
3321 return args, kwargs
3322 self.assertEqual(self.call(test, args=1), ((), {'args': 1}))
3323
3324 sig = inspect.signature(test)
3325 ba = sig.bind(args=1)
3326 self.assertEqual(ba.arguments, {'kwargs': {'args': 1}})
3327
Nick Coghlanb4b966e2016-06-04 14:40:03 -07003328 @cpython_only
3329 def test_signature_bind_implicit_arg(self):
3330 # Issue #19611: getcallargs should work with set comprehensions
3331 def make_set():
3332 return {z * z for z in range(5)}
3333 setcomp_code = make_set.__code__.co_consts[1]
3334 setcomp_func = types.FunctionType(setcomp_code, {})
3335
3336 iterator = iter(range(5))
3337 self.assertEqual(self.call(setcomp_func, iterator), {0, 1, 4, 9, 16})
3338
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003339
3340class TestBoundArguments(unittest.TestCase):
3341 def test_signature_bound_arguments_unhashable(self):
3342 def foo(a): pass
3343 ba = inspect.signature(foo).bind(1)
3344
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003345 with self.assertRaisesRegex(TypeError, 'unhashable type'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003346 hash(ba)
3347
3348 def test_signature_bound_arguments_equality(self):
3349 def foo(a): pass
3350 ba = inspect.signature(foo).bind(1)
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003351 self.assertTrue(ba == ba)
3352 self.assertFalse(ba != ba)
3353 self.assertTrue(ba == EqualsToAll())
3354 self.assertFalse(ba != EqualsToAll())
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003355
3356 ba2 = inspect.signature(foo).bind(1)
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003357 self.assertTrue(ba == ba2)
3358 self.assertFalse(ba != ba2)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003359
3360 ba3 = inspect.signature(foo).bind(2)
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003361 self.assertFalse(ba == ba3)
3362 self.assertTrue(ba != ba3)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003363 ba3.arguments['a'] = 1
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003364 self.assertTrue(ba == ba3)
3365 self.assertFalse(ba != ba3)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003366
3367 def bar(b): pass
3368 ba4 = inspect.signature(bar).bind(1)
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003369 self.assertFalse(ba == ba4)
3370 self.assertTrue(ba != ba4)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003371
Yury Selivanov4cfd4ea2015-05-14 18:30:27 -04003372 def foo(*, a, b): pass
3373 sig = inspect.signature(foo)
3374 ba1 = sig.bind(a=1, b=2)
3375 ba2 = sig.bind(b=2, a=1)
Serhiy Storchaka2489bd52015-07-18 23:20:50 +03003376 self.assertTrue(ba1 == ba2)
3377 self.assertFalse(ba1 != ba2)
Yury Selivanov4cfd4ea2015-05-14 18:30:27 -04003378
Yury Selivanova5d63dd2014-03-27 11:31:43 -04003379 def test_signature_bound_arguments_pickle(self):
3380 def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
3381 sig = inspect.signature(foo)
3382 ba = sig.bind(20, 30, z={})
3383
3384 for ver in range(pickle.HIGHEST_PROTOCOL + 1):
3385 with self.subTest(pickle_ver=ver):
3386 ba_pickled = pickle.loads(pickle.dumps(ba, ver))
3387 self.assertEqual(ba, ba_pickled)
3388
Yury Selivanov3f6538f2015-05-14 18:47:17 -04003389 def test_signature_bound_arguments_repr(self):
3390 def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
3391 sig = inspect.signature(foo)
3392 ba = sig.bind(20, 30, z={})
Yury Selivanovf229bc52015-05-15 12:53:56 -04003393 self.assertRegex(repr(ba), r'<BoundArguments \(a=20,.*\}\}\)>')
Yury Selivanov3f6538f2015-05-14 18:47:17 -04003394
Yury Selivanovb907a512015-05-16 13:45:09 -04003395 def test_signature_bound_arguments_apply_defaults(self):
3396 def foo(a, b=1, *args, c:1={}, **kw): pass
3397 sig = inspect.signature(foo)
3398
3399 ba = sig.bind(20)
3400 ba.apply_defaults()
3401 self.assertEqual(
3402 list(ba.arguments.items()),
3403 [('a', 20), ('b', 1), ('args', ()), ('c', {}), ('kw', {})])
3404
3405 # Make sure that we preserve the order:
3406 # i.e. 'c' should be *before* 'kw'.
3407 ba = sig.bind(10, 20, 30, d=1)
3408 ba.apply_defaults()
3409 self.assertEqual(
3410 list(ba.arguments.items()),
3411 [('a', 10), ('b', 20), ('args', (30,)), ('c', {}), ('kw', {'d':1})])
3412
3413 # Make sure that BoundArguments produced by bind_partial()
3414 # are supported.
3415 def foo(a, b): pass
3416 sig = inspect.signature(foo)
3417 ba = sig.bind_partial(20)
3418 ba.apply_defaults()
3419 self.assertEqual(
3420 list(ba.arguments.items()),
3421 [('a', 20)])
3422
3423 # Test no args
3424 def foo(): pass
3425 sig = inspect.signature(foo)
3426 ba = sig.bind()
3427 ba.apply_defaults()
3428 self.assertEqual(list(ba.arguments.items()), [])
3429
Yury Selivanovf9e1f2b2016-03-02 11:07:47 -05003430 # Make sure a no-args binding still acquires proper defaults.
3431 def foo(a='spam'): pass
3432 sig = inspect.signature(foo)
3433 ba = sig.bind()
3434 ba.apply_defaults()
3435 self.assertEqual(list(ba.arguments.items()), [('a', 'spam')])
3436
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003437
Yury Selivanovd82eddc2014-01-29 11:24:39 -05003438class TestSignaturePrivateHelpers(unittest.TestCase):
3439 def test_signature_get_bound_param(self):
3440 getter = inspect._signature_get_bound_param
3441
3442 self.assertEqual(getter('($self)'), 'self')
3443 self.assertEqual(getter('($self, obj)'), 'self')
3444 self.assertEqual(getter('($cls, /, obj)'), 'cls')
3445
Larry Hastings2623c8c2014-02-08 22:15:29 -08003446 def _strip_non_python_syntax(self, input,
3447 clean_signature, self_parameter, last_positional_only):
3448 computed_clean_signature, \
3449 computed_self_parameter, \
3450 computed_last_positional_only = \
3451 inspect._signature_strip_non_python_syntax(input)
3452 self.assertEqual(computed_clean_signature, clean_signature)
3453 self.assertEqual(computed_self_parameter, self_parameter)
3454 self.assertEqual(computed_last_positional_only, last_positional_only)
3455
3456 def test_signature_strip_non_python_syntax(self):
3457 self._strip_non_python_syntax(
3458 "($module, /, path, mode, *, dir_fd=None, " +
3459 "effective_ids=False,\n follow_symlinks=True)",
3460 "(module, path, mode, *, dir_fd=None, " +
3461 "effective_ids=False, follow_symlinks=True)",
3462 0,
3463 0)
3464
3465 self._strip_non_python_syntax(
3466 "($module, word, salt, /)",
3467 "(module, word, salt)",
3468 0,
3469 2)
3470
3471 self._strip_non_python_syntax(
3472 "(x, y=None, z=None, /)",
3473 "(x, y=None, z=None)",
3474 None,
3475 2)
3476
3477 self._strip_non_python_syntax(
3478 "(x, y=None, z=None)",
3479 "(x, y=None, z=None)",
3480 None,
3481 None)
3482
3483 self._strip_non_python_syntax(
3484 "(x,\n y=None,\n z = None )",
3485 "(x, y=None, z=None)",
3486 None,
3487 None)
3488
3489 self._strip_non_python_syntax(
3490 "",
3491 "",
3492 None,
3493 None)
3494
3495 self._strip_non_python_syntax(
3496 None,
3497 None,
3498 None,
3499 None)
3500
Nick Coghlan9c680b02015-04-13 12:54:54 -04003501class TestSignatureDefinitions(unittest.TestCase):
3502 # This test case provides a home for checking that particular APIs
3503 # have signatures available for introspection
3504
3505 @cpython_only
3506 @unittest.skipIf(MISSING_C_DOCSTRINGS,
3507 "Signature information for builtins requires docstrings")
3508 def test_builtins_have_signatures(self):
3509 # This checks all builtin callables in CPython have signatures
3510 # A few have signatures Signature can't yet handle, so we skip those
3511 # since they will have to wait until PEP 457 adds the required
3512 # introspection support to the inspect module
3513 # Some others also haven't been converted yet for various other
3514 # reasons, so we also skip those for the time being, but design
3515 # the test to fail in order to indicate when it needs to be
3516 # updated.
3517 no_signature = set()
3518 # These need PEP 457 groups
3519 needs_groups = {"range", "slice", "dir", "getattr",
3520 "next", "iter", "vars"}
3521 no_signature |= needs_groups
3522 # These need PEP 457 groups or a signature change to accept None
3523 needs_semantic_update = {"round"}
3524 no_signature |= needs_semantic_update
3525 # These need *args support in Argument Clinic
3526 needs_varargs = {"min", "max", "print", "__build_class__"}
3527 no_signature |= needs_varargs
3528 # These simply weren't covered in the initial AC conversion
3529 # for builtin callables
3530 not_converted_yet = {"open", "__import__"}
3531 no_signature |= not_converted_yet
3532 # These builtin types are expected to provide introspection info
3533 types_with_signatures = set()
3534 # Check the signatures we expect to be there
3535 ns = vars(builtins)
3536 for name, obj in sorted(ns.items()):
3537 if not callable(obj):
3538 continue
3539 # The builtin types haven't been converted to AC yet
3540 if isinstance(obj, type) and (name not in types_with_signatures):
3541 # Note that this also skips all the exception types
3542 no_signature.add(name)
3543 if (name in no_signature):
3544 # Not yet converted
3545 continue
3546 with self.subTest(builtin=name):
3547 self.assertIsNotNone(inspect.signature(obj))
3548 # Check callables that haven't been converted don't claim a signature
3549 # This ensures this test will start failing as more signatures are
3550 # added, so the affected items can be moved into the scope of the
3551 # regression test above
3552 for name in no_signature:
3553 with self.subTest(builtin=name):
3554 self.assertIsNone(obj.__text_signature__)
3555
Yury Selivanovd82eddc2014-01-29 11:24:39 -05003556
Thomas Kluyverf9169ce2017-05-23 04:27:52 +01003557class NTimesUnwrappable:
3558 def __init__(self, n):
3559 self.n = n
3560 self._next = None
3561
3562 @property
3563 def __wrapped__(self):
3564 if self.n <= 0:
3565 raise Exception("Unwrapped too many times")
3566 if self._next is None:
3567 self._next = NTimesUnwrappable(self.n - 1)
3568 return self._next
3569
Nick Coghlane8c45d62013-07-28 20:00:01 +10003570class TestUnwrap(unittest.TestCase):
3571
3572 def test_unwrap_one(self):
3573 def func(a, b):
3574 return a + b
3575 wrapper = functools.lru_cache(maxsize=20)(func)
3576 self.assertIs(inspect.unwrap(wrapper), func)
3577
3578 def test_unwrap_several(self):
3579 def func(a, b):
3580 return a + b
3581 wrapper = func
3582 for __ in range(10):
3583 @functools.wraps(wrapper)
3584 def wrapper():
3585 pass
3586 self.assertIsNot(wrapper.__wrapped__, func)
3587 self.assertIs(inspect.unwrap(wrapper), func)
3588
3589 def test_stop(self):
3590 def func1(a, b):
3591 return a + b
3592 @functools.wraps(func1)
3593 def func2():
3594 pass
3595 @functools.wraps(func2)
3596 def wrapper():
3597 pass
3598 func2.stop_here = 1
3599 unwrapped = inspect.unwrap(wrapper,
3600 stop=(lambda f: hasattr(f, "stop_here")))
3601 self.assertIs(unwrapped, func2)
3602
3603 def test_cycle(self):
3604 def func1(): pass
3605 func1.__wrapped__ = func1
3606 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3607 inspect.unwrap(func1)
3608
3609 def func2(): pass
3610 func2.__wrapped__ = func1
3611 func1.__wrapped__ = func2
3612 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3613 inspect.unwrap(func1)
3614 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3615 inspect.unwrap(func2)
3616
3617 def test_unhashable(self):
3618 def func(): pass
3619 func.__wrapped__ = None
3620 class C:
3621 __hash__ = None
3622 __wrapped__ = func
3623 self.assertIsNone(inspect.unwrap(C()))
3624
Thomas Kluyverf9169ce2017-05-23 04:27:52 +01003625 def test_recursion_limit(self):
3626 obj = NTimesUnwrappable(sys.getrecursionlimit() + 1)
3627 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3628 inspect.unwrap(obj)
3629
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003630class TestMain(unittest.TestCase):
3631 def test_only_source(self):
3632 module = importlib.import_module('unittest')
3633 rc, out, err = assert_python_ok('-m', 'inspect',
3634 'unittest')
3635 lines = out.decode().splitlines()
3636 # ignore the final newline
3637 self.assertEqual(lines[:-1], inspect.getsource(module).splitlines())
3638 self.assertEqual(err, b'')
3639
Yury Selivanov42407ab2014-06-23 10:23:50 -07003640 def test_custom_getattr(self):
3641 def foo():
3642 pass
3643 foo.__signature__ = 42
3644 with self.assertRaises(TypeError):
3645 inspect.signature(foo)
3646
Brett Cannon634a8fc2013-10-02 10:25:42 -04003647 @unittest.skipIf(ThreadPoolExecutor is None,
Brett Cannon0de3f012013-10-02 10:58:58 -04003648 'threads required to test __qualname__ for source files')
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003649 def test_qualname_source(self):
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003650 rc, out, err = assert_python_ok('-m', 'inspect',
3651 'concurrent.futures:ThreadPoolExecutor')
3652 lines = out.decode().splitlines()
3653 # ignore the final newline
3654 self.assertEqual(lines[:-1],
Brett Cannon634a8fc2013-10-02 10:25:42 -04003655 inspect.getsource(ThreadPoolExecutor).splitlines())
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003656 self.assertEqual(err, b'')
3657
3658 def test_builtins(self):
3659 module = importlib.import_module('unittest')
3660 _, out, err = assert_python_failure('-m', 'inspect',
3661 'sys')
3662 lines = err.decode().splitlines()
3663 self.assertEqual(lines, ["Can't get info for builtin modules."])
3664
3665 def test_details(self):
3666 module = importlib.import_module('unittest')
Victor Stinner9def2842016-01-18 12:15:08 +01003667 args = support.optim_args_from_interpreter_flags()
3668 rc, out, err = assert_python_ok(*args, '-m', 'inspect',
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003669 'unittest', '--details')
3670 output = out.decode()
3671 # Just a quick sanity check on the output
3672 self.assertIn(module.__name__, output)
3673 self.assertIn(module.__file__, output)
Victor Stinner9def2842016-01-18 12:15:08 +01003674 self.assertIn(module.__cached__, output)
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003675 self.assertEqual(err, b'')
3676
3677
Yury Selivanovef1e7502014-12-08 16:05:34 -05003678class TestReload(unittest.TestCase):
3679
3680 src_before = textwrap.dedent("""\
3681def foo():
3682 print("Bla")
3683 """)
3684
3685 src_after = textwrap.dedent("""\
3686def foo():
3687 print("Oh no!")
3688 """)
3689
3690 def assertInspectEqual(self, path, source):
3691 inspected_src = inspect.getsource(source)
3692 with open(path) as src:
3693 self.assertEqual(
3694 src.read().splitlines(True),
3695 inspected_src.splitlines(True)
3696 )
3697
3698 def test_getsource_reload(self):
3699 # see issue 1218234
3700 with _ready_to_import('reload_bug', self.src_before) as (name, path):
3701 module = importlib.import_module(name)
3702 self.assertInspectEqual(path, module)
3703 with open(path, 'w') as src:
3704 src.write(self.src_after)
3705 self.assertInspectEqual(path, module)
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003706
Nick Coghlane8c45d62013-07-28 20:00:01 +10003707
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00003708def test_main():
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00003709 run_unittest(
3710 TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBuggyCases,
3711 TestInterpreterStack, TestClassesAndFunctions, TestPredicates,
3712 TestGetcallargsFunctions, TestGetcallargsMethods,
Alexander Belopolskyf546e702010-12-02 00:10:11 +00003713 TestGetcallargsUnboundMethods, TestGetattrStatic, TestGetGeneratorState,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003714 TestNoEOL, TestSignatureObject, TestSignatureBind, TestParameterObject,
Nick Coghlan9c680b02015-04-13 12:54:54 -04003715 TestBoundArguments, TestSignaturePrivateHelpers,
3716 TestSignatureDefinitions,
Yury Selivanov5376ba92015-06-22 12:19:30 -04003717 TestGetClosureVars, TestUnwrap, TestMain, TestReload,
3718 TestGetCoroutineState
Michael Foord95fc51d2010-11-20 15:07:30 +00003719 )
Martin v. Löwis893ffa42003-10-31 15:35:53 +00003720
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00003721if __name__ == "__main__":
3722 test_main()