blob: 13a86b12dd3d514c02954b6fd78d34bc177d2bde [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 Storchaka5cf2b722015-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 Kluyvere968bc732017-10-24 13:42:36 +0100466 def test_getfile_broken_repr(self):
467 class ErrorRepr:
468 def __repr__(self):
469 raise Exception('xyz')
470 er = ErrorRepr()
471 with self.assertRaises(TypeError):
472 inspect.getfile(er)
473
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000474 def test_getmodule_recursion(self):
Christian Heimes45f9af32007-11-27 21:50:00 +0000475 from types import ModuleType
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000476 name = '__inspect_dummy'
Christian Heimes45f9af32007-11-27 21:50:00 +0000477 m = sys.modules[name] = ModuleType(name)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000478 m.__file__ = "<string>" # hopefully not a real filename...
479 m.__loader__ = "dummy" # pretend the filename is understood by a loader
Georg Brandl7cae87c2006-09-06 06:51:57 +0000480 exec("def x(): pass", m.__dict__)
Neal Norwitz221085d2007-02-25 20:55:47 +0000481 self.assertEqual(inspect.getsourcefile(m.x.__code__), '<string>')
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000482 del sys.modules[name]
483 inspect.getmodule(compile('a=10','','single'))
484
Benjamin Peterson9620cc02011-06-11 15:53:11 -0500485 def test_proceed_with_fake_filename(self):
486 '''doctest monkeypatches linecache to enable inspection'''
487 fn, source = '<test>', 'def x(): pass\n'
488 getlines = linecache.getlines
489 def monkey(filename, module_globals=None):
490 if filename == fn:
Ezio Melottid8b509b2011-09-28 17:37:55 +0300491 return source.splitlines(keepends=True)
Benjamin Peterson9620cc02011-06-11 15:53:11 -0500492 else:
493 return getlines(filename, module_globals)
494 linecache.getlines = monkey
495 try:
496 ns = {}
497 exec(compile(source, fn, 'single'), ns)
498 inspect.getsource(ns["x"])
499 finally:
500 linecache.getlines = getlines
501
Antoine Pitroua8723a02015-04-15 00:41:29 +0200502 def test_getsource_on_code_object(self):
503 self.assertSourceEqual(mod.eggs.__code__, 12, 18)
504
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000505class TestDecorators(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000506 fodderModule = mod2
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000507
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000508 def test_wrapped_decorator(self):
Christian Heimes09aaa882008-02-23 15:01:06 +0000509 self.assertSourceEqual(mod2.wrapped, 14, 17)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000510
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000511 def test_replacing_decorator(self):
512 self.assertSourceEqual(mod2.gone, 9, 10)
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000513
Yury Selivanov081bbf62014-09-26 17:34:54 -0400514 def test_getsource_unwrap(self):
Antoine Pitroua8723a02015-04-15 00:41:29 +0200515 self.assertSourceEqual(mod2.real, 130, 132)
516
517 def test_decorator_with_lambda(self):
518 self.assertSourceEqual(mod2.func114, 113, 115)
Yury Selivanov081bbf62014-09-26 17:34:54 -0400519
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000520class TestOneliners(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000521 fodderModule = mod2
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000522 def test_oneline_lambda(self):
523 # Test inspect.getsource with a one-line lambda function.
524 self.assertSourceEqual(mod2.oll, 25, 25)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000525
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000526 def test_threeline_lambda(self):
527 # Test inspect.getsource with a three-line lambda function,
528 # where the second and third lines are _not_ indented.
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000529 self.assertSourceEqual(mod2.tll, 28, 30)
530
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000531 def test_twoline_indented_lambda(self):
532 # Test inspect.getsource with a two-line lambda function,
533 # where the second line _is_ indented.
534 self.assertSourceEqual(mod2.tlli, 33, 34)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000535
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000536 def test_onelinefunc(self):
537 # Test inspect.getsource with a regular one-line function.
538 self.assertSourceEqual(mod2.onelinefunc, 37, 37)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000539
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000540 def test_manyargs(self):
541 # Test inspect.getsource with a regular function where
542 # the arguments are on two lines and _not_ indented and
543 # the body on the second line with the last arguments.
544 self.assertSourceEqual(mod2.manyargs, 40, 41)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000545
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000546 def test_twolinefunc(self):
547 # Test inspect.getsource with a regular function where
548 # the body is on two lines, following the argument list and
549 # continued on the next line by a \\.
550 self.assertSourceEqual(mod2.twolinefunc, 44, 45)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000551
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000552 def test_lambda_in_list(self):
553 # Test inspect.getsource with a one-line lambda function
554 # defined in a list, indented.
555 self.assertSourceEqual(mod2.a[1], 49, 49)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000556
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000557 def test_anonymous(self):
558 # Test inspect.getsource with a lambda function defined
559 # as argument to another function.
560 self.assertSourceEqual(mod2.anonymous, 55, 55)
561
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000562class TestBuggyCases(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000563 fodderModule = mod2
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000564
565 def test_with_comment(self):
566 self.assertSourceEqual(mod2.with_comment, 58, 59)
567
568 def test_multiline_sig(self):
569 self.assertSourceEqual(mod2.multiline_sig[0], 63, 64)
570
Armin Rigodd5c0232005-09-25 11:45:45 +0000571 def test_nested_class(self):
572 self.assertSourceEqual(mod2.func69().func71, 71, 72)
573
574 def test_one_liner_followed_by_non_name(self):
575 self.assertSourceEqual(mod2.func77, 77, 77)
576
577 def test_one_liner_dedent_non_name(self):
578 self.assertSourceEqual(mod2.cls82.func83, 83, 83)
579
580 def test_with_comment_instead_of_docstring(self):
581 self.assertSourceEqual(mod2.func88, 88, 90)
582
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000583 def test_method_in_dynamic_class(self):
584 self.assertSourceEqual(mod2.method_in_dynamic_class, 95, 97)
585
R David Murray32562d72014-10-03 11:15:38 -0400586 # This should not skip for CPython, but might on a repackaged python where
587 # unicodedata is not an external module, or on pypy.
588 @unittest.skipIf(not hasattr(unicodedata, '__file__') or
589 unicodedata.__file__.endswith('.py'),
590 "unicodedata is not an external binary module")
R. David Murray74b89242009-05-13 17:33:03 +0000591 def test_findsource_binary(self):
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200592 self.assertRaises(OSError, inspect.getsource, unicodedata)
593 self.assertRaises(OSError, inspect.findsource, unicodedata)
R. David Murray74b89242009-05-13 17:33:03 +0000594
R. David Murraya1b37402010-06-17 02:04:29 +0000595 def test_findsource_code_in_linecache(self):
596 lines = ["x=1"]
597 co = compile(lines[0], "_dynamically_created_file", "exec")
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200598 self.assertRaises(OSError, inspect.findsource, co)
599 self.assertRaises(OSError, inspect.getsource, co)
R. David Murraya1b37402010-06-17 02:04:29 +0000600 linecache.cache[co.co_filename] = (1, None, lines, co.co_filename)
Antoine Pitrou5d62a612012-07-08 13:48:46 +0200601 try:
602 self.assertEqual(inspect.findsource(co), (lines,0))
603 self.assertEqual(inspect.getsource(co), lines[0])
604 finally:
605 del linecache.cache[co.co_filename]
R. David Murraya1b37402010-06-17 02:04:29 +0000606
Ezio Melotti1b145922013-03-30 05:17:24 +0200607 def test_findsource_without_filename(self):
608 for fname in ['', '<string>']:
609 co = compile('x=1', fname, "exec")
610 self.assertRaises(IOError, inspect.findsource, co)
611 self.assertRaises(IOError, inspect.getsource, co)
612
Antoine Pitroua8723a02015-04-15 00:41:29 +0200613 def test_getsource_on_method(self):
614 self.assertSourceEqual(mod2.ClassWithMethod.method, 118, 119)
615
Yury Selivanov4f4913b2015-07-23 17:10:00 +0300616 def test_nested_func(self):
617 self.assertSourceEqual(mod2.cls135.func136, 136, 139)
618
619
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000620class TestNoEOL(GetSourceBase):
Yury Selivanov6738b112015-05-16 10:10:21 -0400621 def setUp(self):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000622 self.tempdir = TESTFN + '_dir'
623 os.mkdir(self.tempdir)
624 with open(os.path.join(self.tempdir,
625 'inspect_fodder3%spy' % os.extsep), 'w') as f:
626 f.write("class X:\n pass # No EOL")
627 with DirsOnSysPath(self.tempdir):
628 import inspect_fodder3 as mod3
629 self.fodderModule = mod3
Yury Selivanov6738b112015-05-16 10:10:21 -0400630 super().setUp()
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000631
632 def tearDown(self):
633 shutil.rmtree(self.tempdir)
634
635 def test_class(self):
636 self.assertSourceEqual(self.fodderModule.X, 1, 2)
637
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100638
639class _BrokenDataDescriptor(object):
640 """
641 A broken data descriptor. See bug #1785.
642 """
643 def __get__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700644 raise AttributeError("broken data descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100645
646 def __set__(*args):
647 raise RuntimeError
648
649 def __getattr__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700650 raise AttributeError("broken data descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100651
652
653class _BrokenMethodDescriptor(object):
654 """
655 A broken method descriptor. See bug #1785.
656 """
657 def __get__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700658 raise AttributeError("broken method descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100659
660 def __getattr__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700661 raise AttributeError("broken method descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100662
663
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000664# Helper for testing classify_class_attrs.
Tim Peters13b49d32001-09-23 02:00:29 +0000665def attrs_wo_objs(cls):
666 return [t[:3] for t in inspect.classify_class_attrs(cls)]
667
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100668
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000669class TestClassesAndFunctions(unittest.TestCase):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000670 def test_newstyle_mro(self):
671 # The same w/ new-class MRO.
672 class A(object): pass
673 class B(A): pass
674 class C(A): pass
675 class D(B, C): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000676
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000677 expected = (D, B, C, A, object)
678 got = inspect.getmro(D)
679 self.assertEqual(expected, got)
Tim Peters13b49d32001-09-23 02:00:29 +0000680
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500681 def assertArgSpecEquals(self, routine, args_e, varargs_e=None,
682 varkw_e=None, defaults_e=None, formatted=None):
683 with self.assertWarns(DeprecationWarning):
684 args, varargs, varkw, defaults = inspect.getargspec(routine)
685 self.assertEqual(args, args_e)
686 self.assertEqual(varargs, varargs_e)
687 self.assertEqual(varkw, varkw_e)
688 self.assertEqual(defaults, defaults_e)
689 if formatted is not None:
690 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults),
691 formatted)
692
Christian Heimes3795b532007-11-08 13:48:53 +0000693 def assertFullArgSpecEquals(self, routine, args_e, varargs_e=None,
694 varkw_e=None, defaults_e=None,
695 kwonlyargs_e=[], kwonlydefaults_e=None,
696 ann_e={}, formatted=None):
697 args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \
698 inspect.getfullargspec(routine)
699 self.assertEqual(args, args_e)
700 self.assertEqual(varargs, varargs_e)
701 self.assertEqual(varkw, varkw_e)
702 self.assertEqual(defaults, defaults_e)
703 self.assertEqual(kwonlyargs, kwonlyargs_e)
704 self.assertEqual(kwonlydefaults, kwonlydefaults_e)
705 self.assertEqual(ann, ann_e)
706 if formatted is not None:
707 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults,
708 kwonlyargs, kwonlydefaults, ann),
709 formatted)
710
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500711 def test_getargspec(self):
712 self.assertArgSpecEquals(mod.eggs, ['x', 'y'], formatted='(x, y)')
713
714 self.assertArgSpecEquals(mod.spam,
715 ['a', 'b', 'c', 'd', 'e', 'f'],
716 'g', 'h', (3, 4, 5),
717 '(a, b, c, d=3, e=4, f=5, *g, **h)')
718
719 self.assertRaises(ValueError, self.assertArgSpecEquals,
720 mod2.keyworded, [])
721
722 self.assertRaises(ValueError, self.assertArgSpecEquals,
723 mod2.annotated, [])
724 self.assertRaises(ValueError, self.assertArgSpecEquals,
725 mod2.keyword_only_arg, [])
726
727
Christian Heimes3795b532007-11-08 13:48:53 +0000728 def test_getfullargspec(self):
729 self.assertFullArgSpecEquals(mod2.keyworded, [], varargs_e='arg1',
730 kwonlyargs_e=['arg2'],
731 kwonlydefaults_e={'arg2':1},
732 formatted='(*arg1, arg2=1)')
733
734 self.assertFullArgSpecEquals(mod2.annotated, ['arg1'],
Christian Heimesc9543e42007-11-28 08:28:28 +0000735 ann_e={'arg1' : list},
Christian Heimes3795b532007-11-08 13:48:53 +0000736 formatted='(arg1: list)')
Benjamin Peterson9953a8d2009-01-17 04:15:01 +0000737 self.assertFullArgSpecEquals(mod2.keyword_only_arg, [],
738 kwonlyargs_e=['arg'],
739 formatted='(*, arg)')
740
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500741 def test_argspec_api_ignores_wrapped(self):
Yury Selivanov57d240e2014-02-19 16:27:23 -0500742 # Issue 20684: low level introspection API must ignore __wrapped__
743 @functools.wraps(mod.spam)
744 def ham(x, y):
745 pass
746 # Basic check
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500747 self.assertArgSpecEquals(ham, ['x', 'y'], formatted='(x, y)')
Yury Selivanov57d240e2014-02-19 16:27:23 -0500748 self.assertFullArgSpecEquals(ham, ['x', 'y'], formatted='(x, y)')
749 self.assertFullArgSpecEquals(functools.partial(ham),
750 ['x', 'y'], formatted='(x, y)')
751 # Other variants
752 def check_method(f):
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500753 self.assertArgSpecEquals(f, ['self', 'x', 'y'],
754 formatted='(self, x, y)')
Yury Selivanov57d240e2014-02-19 16:27:23 -0500755 class C:
756 @functools.wraps(mod.spam)
757 def ham(self, x, y):
758 pass
759 pham = functools.partialmethod(ham)
760 @functools.wraps(mod.spam)
761 def __call__(self, x, y):
762 pass
763 check_method(C())
764 check_method(C.ham)
765 check_method(C().ham)
766 check_method(C.pham)
767 check_method(C().pham)
768
769 class C_new:
770 @functools.wraps(mod.spam)
771 def __new__(self, x, y):
772 pass
773 check_method(C_new)
774
775 class C_init:
776 @functools.wraps(mod.spam)
777 def __init__(self, x, y):
778 pass
779 check_method(C_init)
780
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500781 def test_getfullargspec_signature_attr(self):
782 def test():
783 pass
784 spam_param = inspect.Parameter('spam', inspect.Parameter.POSITIONAL_ONLY)
785 test.__signature__ = inspect.Signature(parameters=(spam_param,))
786
787 self.assertFullArgSpecEquals(test, args_e=['spam'], formatted='(spam)')
788
Yury Selivanov4cb93912014-01-29 11:54:12 -0500789 def test_getfullargspec_signature_annos(self):
790 def test(a:'spam') -> 'ham': pass
791 spec = inspect.getfullargspec(test)
792 self.assertEqual(test.__annotations__, spec.annotations)
793
794 def test(): pass
795 spec = inspect.getfullargspec(test)
796 self.assertEqual(test.__annotations__, spec.annotations)
797
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500798 @unittest.skipIf(MISSING_C_DOCSTRINGS,
799 "Signature information for builtins requires docstrings")
800 def test_getfullargspec_builtin_methods(self):
801 self.assertFullArgSpecEquals(_pickle.Pickler.dump,
802 args_e=['self', 'obj'], formatted='(self, obj)')
803
804 self.assertFullArgSpecEquals(_pickle.Pickler(io.BytesIO()).dump,
805 args_e=['self', 'obj'], formatted='(self, obj)')
806
Yury Selivanov8c185ee2014-02-21 01:32:42 -0500807 self.assertFullArgSpecEquals(
808 os.stat,
809 args_e=['path'],
810 kwonlyargs_e=['dir_fd', 'follow_symlinks'],
811 kwonlydefaults_e={'dir_fd': None, 'follow_symlinks': True},
812 formatted='(path, *, dir_fd=None, follow_symlinks=True)')
813
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200814 @cpython_only
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500815 @unittest.skipIf(MISSING_C_DOCSTRINGS,
816 "Signature information for builtins requires docstrings")
817 def test_getfullagrspec_builtin_func(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200818 import _testcapi
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500819 builtin = _testcapi.docstring_with_signature_with_defaults
820 spec = inspect.getfullargspec(builtin)
821 self.assertEqual(spec.defaults[0], 'avocado')
822
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200823 @cpython_only
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500824 @unittest.skipIf(MISSING_C_DOCSTRINGS,
825 "Signature information for builtins requires docstrings")
826 def test_getfullagrspec_builtin_func_no_signature(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200827 import _testcapi
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500828 builtin = _testcapi.docstring_no_signature
829 with self.assertRaises(TypeError):
830 inspect.getfullargspec(builtin)
Christian Heimes3795b532007-11-08 13:48:53 +0000831
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500832 def test_getargspec_method(self):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000833 class A(object):
834 def m(self):
835 pass
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500836 self.assertArgSpecEquals(A.m, ['self'])
Tim Peters13b49d32001-09-23 02:00:29 +0000837
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000838 def test_classify_newstyle(self):
839 class A(object):
Tim Peters13b49d32001-09-23 02:00:29 +0000840
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000841 def s(): pass
842 s = staticmethod(s)
Tim Peters13b49d32001-09-23 02:00:29 +0000843
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000844 def c(cls): pass
845 c = classmethod(c)
Tim Peters13b49d32001-09-23 02:00:29 +0000846
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000847 def getp(self): pass
848 p = property(getp)
Tim Peters13b49d32001-09-23 02:00:29 +0000849
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000850 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000851
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000852 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000853
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000854 datablob = '1'
Tim Peters13b49d32001-09-23 02:00:29 +0000855
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100856 dd = _BrokenDataDescriptor()
857 md = _BrokenMethodDescriptor()
858
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000859 attrs = attrs_wo_objs(A)
Yury Selivanov0860a0b2014-01-31 14:28:44 -0500860
861 self.assertIn(('__new__', 'method', object), attrs, 'missing __new__')
862 self.assertIn(('__init__', 'method', object), attrs, 'missing __init__')
863
Benjamin Peterson577473f2010-01-19 00:09:57 +0000864 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
865 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
866 self.assertIn(('p', 'property', A), attrs, 'missing property')
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000867 self.assertIn(('m', 'method', A), attrs,
868 'missing plain method: %r' % attrs)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000869 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
870 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100871 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
872 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000873
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000874 class B(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000875
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000876 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000877
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000878 attrs = attrs_wo_objs(B)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000879 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
880 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
881 self.assertIn(('p', 'property', A), attrs, 'missing property')
882 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
883 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
884 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100885 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
886 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000887
888
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000889 class C(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000890
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000891 def m(self): pass
892 def c(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000893
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000894 attrs = attrs_wo_objs(C)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000895 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
896 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
897 self.assertIn(('p', 'property', A), attrs, 'missing property')
898 self.assertIn(('m', 'method', C), attrs, 'missing plain method')
899 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
900 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100901 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
902 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000903
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000904 class D(B, C):
Tim Peters13b49d32001-09-23 02:00:29 +0000905
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000906 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000907
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000908 attrs = attrs_wo_objs(D)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000909 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
910 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
911 self.assertIn(('p', 'property', A), attrs, 'missing property')
912 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
913 self.assertIn(('m1', 'method', D), attrs, 'missing plain method')
914 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100915 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
916 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
917
918 def test_classify_builtin_types(self):
919 # Simple sanity check that all built-in types can have their
920 # attributes classified.
921 for name in dir(__builtins__):
922 builtin = getattr(__builtins__, name)
923 if isinstance(builtin, type):
924 inspect.classify_class_attrs(builtin)
925
Ethan Furman63c141c2013-10-18 00:27:39 -0700926 def test_classify_DynamicClassAttribute(self):
927 class Meta(type):
928 def __getattr__(self, name):
929 if name == 'ham':
930 return 'spam'
931 return super().__getattr__(name)
932 class VA(metaclass=Meta):
Ethan Furmane03ea372013-09-25 07:14:41 -0700933 @types.DynamicClassAttribute
934 def ham(self):
935 return 'eggs'
Ethan Furman63c141c2013-10-18 00:27:39 -0700936 should_find_dca = inspect.Attribute('ham', 'data', VA, VA.__dict__['ham'])
937 self.assertIn(should_find_dca, inspect.classify_class_attrs(VA))
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700938 should_find_ga = inspect.Attribute('ham', 'data', Meta, 'spam')
Ethan Furman63c141c2013-10-18 00:27:39 -0700939 self.assertIn(should_find_ga, inspect.classify_class_attrs(VA))
940
Yury Selivanovbf341fb2015-05-21 15:41:57 -0400941 def test_classify_overrides_bool(self):
942 class NoBool(object):
943 def __eq__(self, other):
944 return NoBool()
945
946 def __bool__(self):
947 raise NotImplementedError(
948 "This object does not specify a boolean value")
949
950 class HasNB(object):
951 dd = NoBool()
952
953 should_find_attr = inspect.Attribute('dd', 'data', HasNB, HasNB.dd)
954 self.assertIn(should_find_attr, inspect.classify_class_attrs(HasNB))
955
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700956 def test_classify_metaclass_class_attribute(self):
957 class Meta(type):
958 fish = 'slap'
959 def __dir__(self):
Serhiy Storchakaa60c2fe2015-03-12 21:56:08 +0200960 return ['__class__', '__module__', '__name__', 'fish']
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700961 class Class(metaclass=Meta):
962 pass
963 should_find = inspect.Attribute('fish', 'data', Meta, 'slap')
964 self.assertIn(should_find, inspect.classify_class_attrs(Class))
965
Ethan Furman63c141c2013-10-18 00:27:39 -0700966 def test_classify_VirtualAttribute(self):
967 class Meta(type):
968 def __dir__(cls):
969 return ['__class__', '__module__', '__name__', 'BOOM']
970 def __getattr__(self, name):
971 if name =='BOOM':
972 return 42
973 return super().__getattr(name)
974 class Class(metaclass=Meta):
975 pass
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700976 should_find = inspect.Attribute('BOOM', 'data', Meta, 42)
Ethan Furman63c141c2013-10-18 00:27:39 -0700977 self.assertIn(should_find, inspect.classify_class_attrs(Class))
978
979 def test_classify_VirtualAttribute_multi_classes(self):
980 class Meta1(type):
981 def __dir__(cls):
982 return ['__class__', '__module__', '__name__', 'one']
983 def __getattr__(self, name):
984 if name =='one':
985 return 1
986 return super().__getattr__(name)
987 class Meta2(type):
988 def __dir__(cls):
989 return ['__class__', '__module__', '__name__', 'two']
990 def __getattr__(self, name):
991 if name =='two':
992 return 2
993 return super().__getattr__(name)
994 class Meta3(Meta1, Meta2):
995 def __dir__(cls):
996 return list(sorted(set(['__class__', '__module__', '__name__', 'three'] +
997 Meta1.__dir__(cls) + Meta2.__dir__(cls))))
998 def __getattr__(self, name):
999 if name =='three':
1000 return 3
1001 return super().__getattr__(name)
1002 class Class1(metaclass=Meta1):
1003 pass
1004 class Class2(Class1, metaclass=Meta3):
1005 pass
1006
Ethan Furmanb0c84cd2013-10-20 22:37:39 -07001007 should_find1 = inspect.Attribute('one', 'data', Meta1, 1)
1008 should_find2 = inspect.Attribute('two', 'data', Meta2, 2)
1009 should_find3 = inspect.Attribute('three', 'data', Meta3, 3)
Ethan Furman63c141c2013-10-18 00:27:39 -07001010 cca = inspect.classify_class_attrs(Class2)
1011 for sf in (should_find1, should_find2, should_find3):
1012 self.assertIn(sf, cca)
1013
1014 def test_classify_class_attrs_with_buggy_dir(self):
1015 class M(type):
1016 def __dir__(cls):
1017 return ['__class__', '__name__', 'missing']
1018 class C(metaclass=M):
1019 pass
1020 attrs = [a[0] for a in inspect.classify_class_attrs(C)]
1021 self.assertNotIn('missing', attrs)
Ethan Furmane03ea372013-09-25 07:14:41 -07001022
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +01001023 def test_getmembers_descriptors(self):
1024 class A(object):
1025 dd = _BrokenDataDescriptor()
1026 md = _BrokenMethodDescriptor()
1027
1028 def pred_wrapper(pred):
1029 # A quick'n'dirty way to discard standard attributes of new-style
1030 # classes.
1031 class Empty(object):
1032 pass
1033 def wrapped(x):
1034 if '__name__' in dir(x) and hasattr(Empty, x.__name__):
1035 return False
1036 return pred(x)
1037 return wrapped
1038
1039 ismethoddescriptor = pred_wrapper(inspect.ismethoddescriptor)
1040 isdatadescriptor = pred_wrapper(inspect.isdatadescriptor)
1041
1042 self.assertEqual(inspect.getmembers(A, ismethoddescriptor),
1043 [('md', A.__dict__['md'])])
1044 self.assertEqual(inspect.getmembers(A, isdatadescriptor),
1045 [('dd', A.__dict__['dd'])])
1046
1047 class B(A):
1048 pass
1049
1050 self.assertEqual(inspect.getmembers(B, ismethoddescriptor),
1051 [('md', A.__dict__['md'])])
1052 self.assertEqual(inspect.getmembers(B, isdatadescriptor),
1053 [('dd', A.__dict__['dd'])])
1054
Antoine Pitrou0c603812012-01-18 17:40:18 +01001055 def test_getmembers_method(self):
1056 class B:
1057 def f(self):
1058 pass
1059
1060 self.assertIn(('f', B.f), inspect.getmembers(B))
1061 self.assertNotIn(('f', B.f), inspect.getmembers(B, inspect.ismethod))
1062 b = B()
1063 self.assertIn(('f', b.f), inspect.getmembers(b))
1064 self.assertIn(('f', b.f), inspect.getmembers(b, inspect.ismethod))
1065
Ethan Furmane03ea372013-09-25 07:14:41 -07001066 def test_getmembers_VirtualAttribute(self):
Ethan Furman63c141c2013-10-18 00:27:39 -07001067 class M(type):
1068 def __getattr__(cls, name):
1069 if name == 'eggs':
1070 return 'scrambled'
1071 return super().__getattr__(name)
1072 class A(metaclass=M):
Ethan Furmane03ea372013-09-25 07:14:41 -07001073 @types.DynamicClassAttribute
1074 def eggs(self):
1075 return 'spam'
Ethan Furman63c141c2013-10-18 00:27:39 -07001076 self.assertIn(('eggs', 'scrambled'), inspect.getmembers(A))
1077 self.assertIn(('eggs', 'spam'), inspect.getmembers(A()))
1078
1079 def test_getmembers_with_buggy_dir(self):
1080 class M(type):
1081 def __dir__(cls):
1082 return ['__class__', '__name__', 'missing']
1083 class C(metaclass=M):
1084 pass
1085 attrs = [a[0] for a in inspect.getmembers(C)]
1086 self.assertNotIn('missing', attrs)
Ethan Furmane03ea372013-09-25 07:14:41 -07001087
Jeremy Hyltonc4bf5ed2003-06-27 18:43:12 +00001088
Nick Coghlan2f92e542012-06-23 19:39:55 +10001089_global_ref = object()
1090class TestGetClosureVars(unittest.TestCase):
1091
1092 def test_name_resolution(self):
1093 # Basic test of the 4 different resolution mechanisms
1094 def f(nonlocal_ref):
1095 def g(local_ref):
1096 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
1097 return g
1098 _arg = object()
1099 nonlocal_vars = {"nonlocal_ref": _arg}
1100 global_vars = {"_global_ref": _global_ref}
1101 builtin_vars = {"print": print}
1102 unbound_names = {"unbound_ref"}
1103 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
1104 builtin_vars, unbound_names)
1105 self.assertEqual(inspect.getclosurevars(f(_arg)), expected)
1106
1107 def test_generator_closure(self):
1108 def f(nonlocal_ref):
1109 def g(local_ref):
1110 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
1111 yield
1112 return g
1113 _arg = object()
1114 nonlocal_vars = {"nonlocal_ref": _arg}
1115 global_vars = {"_global_ref": _global_ref}
1116 builtin_vars = {"print": print}
1117 unbound_names = {"unbound_ref"}
1118 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
1119 builtin_vars, unbound_names)
1120 self.assertEqual(inspect.getclosurevars(f(_arg)), expected)
1121
1122 def test_method_closure(self):
1123 class C:
1124 def f(self, nonlocal_ref):
1125 def g(local_ref):
1126 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
1127 return g
1128 _arg = object()
1129 nonlocal_vars = {"nonlocal_ref": _arg}
1130 global_vars = {"_global_ref": _global_ref}
1131 builtin_vars = {"print": print}
1132 unbound_names = {"unbound_ref"}
1133 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
1134 builtin_vars, unbound_names)
1135 self.assertEqual(inspect.getclosurevars(C().f(_arg)), expected)
1136
1137 def test_nonlocal_vars(self):
1138 # More complex tests of nonlocal resolution
1139 def _nonlocal_vars(f):
1140 return inspect.getclosurevars(f).nonlocals
1141
1142 def make_adder(x):
1143 def add(y):
1144 return x + y
1145 return add
1146
1147 def curry(func, arg1):
1148 return lambda arg2: func(arg1, arg2)
1149
1150 def less_than(a, b):
1151 return a < b
1152
1153 # The infamous Y combinator.
1154 def Y(le):
1155 def g(f):
1156 return le(lambda x: f(f)(x))
1157 Y.g_ref = g
1158 return g(g)
1159
1160 def check_y_combinator(func):
1161 self.assertEqual(_nonlocal_vars(func), {'f': Y.g_ref})
1162
1163 inc = make_adder(1)
1164 add_two = make_adder(2)
1165 greater_than_five = curry(less_than, 5)
1166
1167 self.assertEqual(_nonlocal_vars(inc), {'x': 1})
1168 self.assertEqual(_nonlocal_vars(add_two), {'x': 2})
1169 self.assertEqual(_nonlocal_vars(greater_than_five),
1170 {'arg1': 5, 'func': less_than})
1171 self.assertEqual(_nonlocal_vars((lambda x: lambda y: x + y)(3)),
1172 {'x': 3})
1173 Y(check_y_combinator)
1174
1175 def test_getclosurevars_empty(self):
1176 def foo(): pass
1177 _empty = inspect.ClosureVars({}, {}, {}, set())
1178 self.assertEqual(inspect.getclosurevars(lambda: True), _empty)
1179 self.assertEqual(inspect.getclosurevars(foo), _empty)
1180
1181 def test_getclosurevars_error(self):
1182 class T: pass
1183 self.assertRaises(TypeError, inspect.getclosurevars, 1)
1184 self.assertRaises(TypeError, inspect.getclosurevars, list)
1185 self.assertRaises(TypeError, inspect.getclosurevars, {})
1186
Nick Coghlan6c6e2542012-06-23 20:07:39 +10001187 def _private_globals(self):
1188 code = """def f(): print(path)"""
1189 ns = {}
1190 exec(code, ns)
1191 return ns["f"], ns
1192
1193 def test_builtins_fallback(self):
1194 f, ns = self._private_globals()
1195 ns.pop("__builtins__", None)
1196 expected = inspect.ClosureVars({}, {}, {"print":print}, {"path"})
1197 self.assertEqual(inspect.getclosurevars(f), expected)
1198
1199 def test_builtins_as_dict(self):
1200 f, ns = self._private_globals()
1201 ns["__builtins__"] = {"path":1}
1202 expected = inspect.ClosureVars({}, {}, {"path":1}, {"print"})
1203 self.assertEqual(inspect.getclosurevars(f), expected)
1204
1205 def test_builtins_as_module(self):
1206 f, ns = self._private_globals()
1207 ns["__builtins__"] = os
1208 expected = inspect.ClosureVars({}, {}, {"path":os.path}, {"print"})
1209 self.assertEqual(inspect.getclosurevars(f), expected)
1210
Nick Coghlan2f92e542012-06-23 19:39:55 +10001211
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001212class TestGetcallargsFunctions(unittest.TestCase):
1213
1214 def assertEqualCallArgs(self, func, call_params_string, locs=None):
1215 locs = dict(locs or {}, func=func)
1216 r1 = eval('func(%s)' % call_params_string, None, locs)
1217 r2 = eval('inspect.getcallargs(func, %s)' % call_params_string, None,
1218 locs)
1219 self.assertEqual(r1, r2)
1220
1221 def assertEqualException(self, func, call_param_string, locs=None):
1222 locs = dict(locs or {}, func=func)
1223 try:
1224 eval('func(%s)' % call_param_string, None, locs)
1225 except Exception as e:
1226 ex1 = e
1227 else:
1228 self.fail('Exception not raised')
1229 try:
1230 eval('inspect.getcallargs(func, %s)' % call_param_string, None,
1231 locs)
1232 except Exception as e:
1233 ex2 = e
1234 else:
1235 self.fail('Exception not raised')
1236 self.assertIs(type(ex1), type(ex2))
1237 self.assertEqual(str(ex1), str(ex2))
1238 del ex1, ex2
1239
1240 def makeCallable(self, signature):
1241 """Create a function that returns its locals()"""
1242 code = "lambda %s: locals()"
1243 return eval(code % signature)
1244
1245 def test_plain(self):
1246 f = self.makeCallable('a, b=1')
1247 self.assertEqualCallArgs(f, '2')
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 # expand *iterable / **mapping
1253 self.assertEqualCallArgs(f, '*(2,)')
1254 self.assertEqualCallArgs(f, '*[2]')
1255 self.assertEqualCallArgs(f, '*(2, 3)')
1256 self.assertEqualCallArgs(f, '*[2, 3]')
1257 self.assertEqualCallArgs(f, '**{"a":2}')
1258 self.assertEqualCallArgs(f, 'b=3, **{"a":2}')
1259 self.assertEqualCallArgs(f, '2, **{"b":3}')
1260 self.assertEqualCallArgs(f, '**{"b":3, "a":2}')
1261 # expand UserList / UserDict
1262 self.assertEqualCallArgs(f, '*collections.UserList([2])')
1263 self.assertEqualCallArgs(f, '*collections.UserList([2, 3])')
1264 self.assertEqualCallArgs(f, '**collections.UserDict(a=2)')
1265 self.assertEqualCallArgs(f, '2, **collections.UserDict(b=3)')
1266 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3)')
1267
1268 def test_varargs(self):
1269 f = self.makeCallable('a, b=1, *c')
1270 self.assertEqualCallArgs(f, '2')
1271 self.assertEqualCallArgs(f, '2, 3')
1272 self.assertEqualCallArgs(f, '2, 3, 4')
1273 self.assertEqualCallArgs(f, '*(2,3,4)')
1274 self.assertEqualCallArgs(f, '2, *[3,4]')
1275 self.assertEqualCallArgs(f, '2, 3, *collections.UserList([4])')
1276
1277 def test_varkw(self):
1278 f = self.makeCallable('a, b=1, **c')
1279 self.assertEqualCallArgs(f, 'a=2')
1280 self.assertEqualCallArgs(f, '2, b=3, c=4')
1281 self.assertEqualCallArgs(f, 'b=3, a=2, c=4')
1282 self.assertEqualCallArgs(f, 'c=4, **{"a":2, "b":3}')
1283 self.assertEqualCallArgs(f, '2, c=4, **{"b":3}')
1284 self.assertEqualCallArgs(f, 'b=2, **{"a":3, "c":4}')
1285 self.assertEqualCallArgs(f, '**collections.UserDict(a=2, b=3, c=4)')
1286 self.assertEqualCallArgs(f, '2, c=4, **collections.UserDict(b=3)')
1287 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3, c=4)')
1288
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001289 def test_varkw_only(self):
1290 # issue11256:
1291 f = self.makeCallable('**c')
1292 self.assertEqualCallArgs(f, '')
1293 self.assertEqualCallArgs(f, 'a=1')
1294 self.assertEqualCallArgs(f, 'a=1, b=2')
1295 self.assertEqualCallArgs(f, 'c=3, **{"a": 1, "b": 2}')
1296 self.assertEqualCallArgs(f, '**collections.UserDict(a=1, b=2)')
1297 self.assertEqualCallArgs(f, 'c=3, **collections.UserDict(a=1, b=2)')
1298
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001299 def test_keyword_only(self):
1300 f = self.makeCallable('a=3, *, c, d=2')
1301 self.assertEqualCallArgs(f, 'c=3')
1302 self.assertEqualCallArgs(f, 'c=3, a=3')
1303 self.assertEqualCallArgs(f, 'a=2, c=4')
1304 self.assertEqualCallArgs(f, '4, c=4')
1305 self.assertEqualException(f, '')
1306 self.assertEqualException(f, '3')
1307 self.assertEqualException(f, 'a=3')
1308 self.assertEqualException(f, 'd=4')
1309
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001310 f = self.makeCallable('*, c, d=2')
1311 self.assertEqualCallArgs(f, 'c=3')
1312 self.assertEqualCallArgs(f, 'c=3, d=4')
1313 self.assertEqualCallArgs(f, 'd=4, c=3')
1314
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001315 def test_multiple_features(self):
1316 f = self.makeCallable('a, b=2, *f, **g')
1317 self.assertEqualCallArgs(f, '2, 3, 7')
1318 self.assertEqualCallArgs(f, '2, 3, x=8')
1319 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
1320 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9')
1321 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9')
1322 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
1323 '[2, 3, (4,[5,6])]), **{"y":9, "z":10}')
1324 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
1325 '(4,[5,6])]), **collections.UserDict('
1326 'y=9, z=10)')
1327
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001328 f = self.makeCallable('a, b=2, *f, x, y=99, **g')
1329 self.assertEqualCallArgs(f, '2, 3, x=8')
1330 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
1331 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9, z=10')
1332 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9, z=10')
1333 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
1334 '[2, 3, (4,[5,6])]), q=0, **{"y":9, "z":10}')
1335 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
1336 '(4,[5,6])]), q=0, **collections.UserDict('
1337 'y=9, z=10)')
1338
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001339 def test_errors(self):
1340 f0 = self.makeCallable('')
1341 f1 = self.makeCallable('a, b')
1342 f2 = self.makeCallable('a, b=1')
1343 # f0 takes no arguments
1344 self.assertEqualException(f0, '1')
1345 self.assertEqualException(f0, 'x=1')
1346 self.assertEqualException(f0, '1,x=1')
1347 # f1 takes exactly 2 arguments
1348 self.assertEqualException(f1, '')
1349 self.assertEqualException(f1, '1')
1350 self.assertEqualException(f1, 'a=2')
1351 self.assertEqualException(f1, 'b=3')
1352 # f2 takes at least 1 argument
1353 self.assertEqualException(f2, '')
1354 self.assertEqualException(f2, 'b=3')
1355 for f in f1, f2:
1356 # f1/f2 takes exactly/at most 2 arguments
1357 self.assertEqualException(f, '2, 3, 4')
1358 self.assertEqualException(f, '1, 2, 3, a=1')
1359 self.assertEqualException(f, '2, 3, 4, c=5')
Georg Brandl178e5ea2012-02-21 00:32:36 +01001360 # XXX: success of this one depends on dict order
1361 ## self.assertEqualException(f, '2, 3, 4, a=1, c=5')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001362 # f got an unexpected keyword argument
1363 self.assertEqualException(f, 'c=2')
1364 self.assertEqualException(f, '2, c=3')
1365 self.assertEqualException(f, '2, 3, c=4')
1366 self.assertEqualException(f, '2, c=4, b=3')
1367 self.assertEqualException(f, '**{u"\u03c0\u03b9": 4}')
1368 # f got multiple values for keyword argument
1369 self.assertEqualException(f, '1, a=2')
1370 self.assertEqualException(f, '1, **{"a":2}')
1371 self.assertEqualException(f, '1, 2, b=3')
1372 # XXX: Python inconsistency
1373 # - for functions and bound methods: unexpected keyword 'c'
1374 # - for unbound methods: multiple values for keyword 'a'
1375 #self.assertEqualException(f, '1, c=3, a=2')
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001376 # issue11256:
1377 f3 = self.makeCallable('**c')
1378 self.assertEqualException(f3, '1, 2')
1379 self.assertEqualException(f3, '1, 2, a=1, b=2')
1380 f4 = self.makeCallable('*, a, b=0')
1381 self.assertEqualException(f3, '1, 2')
1382 self.assertEqualException(f3, '1, 2, a=1, b=2')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001383
Yury Selivanov875df202014-03-27 18:23:03 -04001384 # issue #20816: getcallargs() fails to iterate over non-existent
1385 # kwonlydefaults and raises a wrong TypeError
1386 def f5(*, a): pass
1387 with self.assertRaisesRegex(TypeError,
1388 'missing 1 required keyword-only'):
1389 inspect.getcallargs(f5)
1390
1391
Yury Selivanovdccfa132014-03-27 18:42:52 -04001392 # issue20817:
1393 def f6(a, b, c):
1394 pass
1395 with self.assertRaisesRegex(TypeError, "'a', 'b' and 'c'"):
1396 inspect.getcallargs(f6)
1397
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001398class TestGetcallargsMethods(TestGetcallargsFunctions):
1399
1400 def setUp(self):
1401 class Foo(object):
1402 pass
1403 self.cls = Foo
1404 self.inst = Foo()
1405
1406 def makeCallable(self, signature):
1407 assert 'self' not in signature
1408 mk = super(TestGetcallargsMethods, self).makeCallable
1409 self.cls.method = mk('self, ' + signature)
1410 return self.inst.method
1411
1412class TestGetcallargsUnboundMethods(TestGetcallargsMethods):
1413
1414 def makeCallable(self, signature):
1415 super(TestGetcallargsUnboundMethods, self).makeCallable(signature)
1416 return self.cls.method
1417
1418 def assertEqualCallArgs(self, func, call_params_string, locs=None):
1419 return super(TestGetcallargsUnboundMethods, self).assertEqualCallArgs(
1420 *self._getAssertEqualParams(func, call_params_string, locs))
1421
1422 def assertEqualException(self, func, call_params_string, locs=None):
1423 return super(TestGetcallargsUnboundMethods, self).assertEqualException(
1424 *self._getAssertEqualParams(func, call_params_string, locs))
1425
1426 def _getAssertEqualParams(self, func, call_params_string, locs=None):
1427 assert 'inst' not in call_params_string
1428 locs = dict(locs or {}, inst=self.inst)
1429 return (func, 'inst,' + call_params_string, locs)
1430
Michael Foord95fc51d2010-11-20 15:07:30 +00001431
1432class TestGetattrStatic(unittest.TestCase):
1433
1434 def test_basic(self):
1435 class Thing(object):
1436 x = object()
1437
1438 thing = Thing()
1439 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1440 self.assertEqual(inspect.getattr_static(thing, 'x', None), Thing.x)
1441 with self.assertRaises(AttributeError):
1442 inspect.getattr_static(thing, 'y')
1443
1444 self.assertEqual(inspect.getattr_static(thing, 'y', 3), 3)
1445
1446 def test_inherited(self):
1447 class Thing(object):
1448 x = object()
1449 class OtherThing(Thing):
1450 pass
1451
1452 something = OtherThing()
1453 self.assertEqual(inspect.getattr_static(something, 'x'), Thing.x)
1454
1455 def test_instance_attr(self):
1456 class Thing(object):
1457 x = 2
1458 def __init__(self, x):
1459 self.x = x
1460 thing = Thing(3)
1461 self.assertEqual(inspect.getattr_static(thing, 'x'), 3)
1462 del thing.x
1463 self.assertEqual(inspect.getattr_static(thing, 'x'), 2)
1464
1465 def test_property(self):
1466 class Thing(object):
1467 @property
1468 def x(self):
1469 raise AttributeError("I'm pretending not to exist")
1470 thing = Thing()
1471 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1472
Ezio Melotti75cbd732011-04-28 00:59:29 +03001473 def test_descriptor_raises_AttributeError(self):
Michael Foord95fc51d2010-11-20 15:07:30 +00001474 class descriptor(object):
1475 def __get__(*_):
1476 raise AttributeError("I'm pretending not to exist")
1477 desc = descriptor()
1478 class Thing(object):
1479 x = desc
1480 thing = Thing()
1481 self.assertEqual(inspect.getattr_static(thing, 'x'), desc)
1482
1483 def test_classAttribute(self):
1484 class Thing(object):
1485 x = object()
1486
1487 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.x)
1488
Ethan Furmane03ea372013-09-25 07:14:41 -07001489 def test_classVirtualAttribute(self):
1490 class Thing(object):
1491 @types.DynamicClassAttribute
1492 def x(self):
1493 return self._x
1494 _x = object()
1495
1496 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.__dict__['x'])
1497
Michael Foord95fc51d2010-11-20 15:07:30 +00001498 def test_inherited_classattribute(self):
1499 class Thing(object):
1500 x = object()
1501 class OtherThing(Thing):
1502 pass
1503
1504 self.assertEqual(inspect.getattr_static(OtherThing, 'x'), Thing.x)
1505
1506 def test_slots(self):
1507 class Thing(object):
1508 y = 'bar'
1509 __slots__ = ['x']
1510 def __init__(self):
1511 self.x = 'foo'
1512 thing = Thing()
1513 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1514 self.assertEqual(inspect.getattr_static(thing, 'y'), 'bar')
1515
1516 del thing.x
1517 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1518
1519 def test_metaclass(self):
1520 class meta(type):
1521 attr = 'foo'
1522 class Thing(object, metaclass=meta):
1523 pass
1524 self.assertEqual(inspect.getattr_static(Thing, 'attr'), 'foo')
1525
1526 class sub(meta):
1527 pass
1528 class OtherThing(object, metaclass=sub):
1529 x = 3
1530 self.assertEqual(inspect.getattr_static(OtherThing, 'attr'), 'foo')
1531
1532 class OtherOtherThing(OtherThing):
1533 pass
1534 # this test is odd, but it was added as it exposed a bug
1535 self.assertEqual(inspect.getattr_static(OtherOtherThing, 'x'), 3)
1536
1537 def test_no_dict_no_slots(self):
1538 self.assertEqual(inspect.getattr_static(1, 'foo', None), None)
1539 self.assertNotEqual(inspect.getattr_static('foo', 'lower'), None)
1540
1541 def test_no_dict_no_slots_instance_member(self):
1542 # returns descriptor
1543 with open(__file__) as handle:
1544 self.assertEqual(inspect.getattr_static(handle, 'name'), type(handle).name)
1545
1546 def test_inherited_slots(self):
1547 # returns descriptor
1548 class Thing(object):
1549 __slots__ = ['x']
1550 def __init__(self):
1551 self.x = 'foo'
1552
1553 class OtherThing(Thing):
1554 pass
1555 # it would be nice if this worked...
1556 # we get the descriptor instead of the instance attribute
1557 self.assertEqual(inspect.getattr_static(OtherThing(), 'x'), Thing.x)
1558
1559 def test_descriptor(self):
1560 class descriptor(object):
1561 def __get__(self, instance, owner):
1562 return 3
1563 class Foo(object):
1564 d = descriptor()
1565
1566 foo = Foo()
1567
1568 # for a non data descriptor we return the instance attribute
1569 foo.__dict__['d'] = 1
1570 self.assertEqual(inspect.getattr_static(foo, 'd'), 1)
1571
1572 # if the descriptor is a data-desciptor we should return the
1573 # descriptor
1574 descriptor.__set__ = lambda s, i, v: None
1575 self.assertEqual(inspect.getattr_static(foo, 'd'), Foo.__dict__['d'])
1576
1577
1578 def test_metaclass_with_descriptor(self):
1579 class descriptor(object):
1580 def __get__(self, instance, owner):
1581 return 3
1582 class meta(type):
1583 d = descriptor()
1584 class Thing(object, metaclass=meta):
1585 pass
1586 self.assertEqual(inspect.getattr_static(Thing, 'd'), meta.__dict__['d'])
1587
1588
Michael Foordcc7ebb82010-11-20 16:20:16 +00001589 def test_class_as_property(self):
1590 class Base(object):
1591 foo = 3
1592
1593 class Something(Base):
Michael Foord35184ed2010-11-20 16:58:30 +00001594 executed = False
Michael Foordcc7ebb82010-11-20 16:20:16 +00001595 @property
1596 def __class__(self):
Michael Foord35184ed2010-11-20 16:58:30 +00001597 self.executed = True
Michael Foordcc7ebb82010-11-20 16:20:16 +00001598 return object
1599
Michael Foord35184ed2010-11-20 16:58:30 +00001600 instance = Something()
1601 self.assertEqual(inspect.getattr_static(instance, 'foo'), 3)
1602 self.assertFalse(instance.executed)
Michael Foordcc7ebb82010-11-20 16:20:16 +00001603 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1604
Michael Foorde5162652010-11-20 16:40:44 +00001605 def test_mro_as_property(self):
1606 class Meta(type):
1607 @property
1608 def __mro__(self):
1609 return (object,)
1610
1611 class Base(object):
1612 foo = 3
1613
1614 class Something(Base, metaclass=Meta):
1615 pass
1616
1617 self.assertEqual(inspect.getattr_static(Something(), 'foo'), 3)
1618 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1619
Michael Foorddcebe0f2011-03-15 19:20:44 -04001620 def test_dict_as_property(self):
1621 test = self
1622 test.called = False
1623
1624 class Foo(dict):
1625 a = 3
1626 @property
1627 def __dict__(self):
1628 test.called = True
1629 return {}
1630
1631 foo = Foo()
1632 foo.a = 4
1633 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1634 self.assertFalse(test.called)
1635
1636 def test_custom_object_dict(self):
1637 test = self
1638 test.called = False
1639
1640 class Custom(dict):
1641 def get(self, key, default=None):
1642 test.called = True
1643 super().get(key, default)
1644
1645 class Foo(object):
1646 a = 3
1647 foo = Foo()
1648 foo.__dict__ = Custom()
1649 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1650 self.assertFalse(test.called)
1651
1652 def test_metaclass_dict_as_property(self):
1653 class Meta(type):
1654 @property
1655 def __dict__(self):
1656 self.executed = True
1657
1658 class Thing(metaclass=Meta):
1659 executed = False
1660
1661 def __init__(self):
1662 self.spam = 42
1663
1664 instance = Thing()
1665 self.assertEqual(inspect.getattr_static(instance, "spam"), 42)
1666 self.assertFalse(Thing.executed)
Michael Foorde5162652010-11-20 16:40:44 +00001667
Michael Foorda51623b2011-12-18 22:01:40 +00001668 def test_module(self):
1669 sentinel = object()
1670 self.assertIsNot(inspect.getattr_static(sys, "version", sentinel),
1671 sentinel)
1672
Michael Foord3ba95f82011-12-22 01:13:37 +00001673 def test_metaclass_with_metaclass_with_dict_as_property(self):
1674 class MetaMeta(type):
1675 @property
1676 def __dict__(self):
1677 self.executed = True
1678 return dict(spam=42)
1679
1680 class Meta(type, metaclass=MetaMeta):
1681 executed = False
1682
1683 class Thing(metaclass=Meta):
1684 pass
1685
1686 with self.assertRaises(AttributeError):
1687 inspect.getattr_static(Thing, "spam")
1688 self.assertFalse(Thing.executed)
1689
Nick Coghlane0f04652010-11-21 03:44:04 +00001690class TestGetGeneratorState(unittest.TestCase):
1691
1692 def setUp(self):
1693 def number_generator():
1694 for number in range(5):
1695 yield number
1696 self.generator = number_generator()
1697
1698 def _generatorstate(self):
1699 return inspect.getgeneratorstate(self.generator)
1700
1701 def test_created(self):
1702 self.assertEqual(self._generatorstate(), inspect.GEN_CREATED)
1703
1704 def test_suspended(self):
1705 next(self.generator)
1706 self.assertEqual(self._generatorstate(), inspect.GEN_SUSPENDED)
1707
1708 def test_closed_after_exhaustion(self):
1709 for i in self.generator:
1710 pass
1711 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1712
1713 def test_closed_after_immediate_exception(self):
1714 with self.assertRaises(RuntimeError):
1715 self.generator.throw(RuntimeError)
1716 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1717
1718 def test_running(self):
1719 # As mentioned on issue #10220, checking for the RUNNING state only
1720 # makes sense inside the generator itself.
1721 # The following generator checks for this by using the closure's
1722 # reference to self and the generator state checking helper method
1723 def running_check_generator():
1724 for number in range(5):
1725 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1726 yield number
1727 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1728 self.generator = running_check_generator()
1729 # Running up to the first yield
1730 next(self.generator)
1731 # Running after the first yield
1732 next(self.generator)
1733
Nick Coghlan7921b9f2010-11-30 06:36:04 +00001734 def test_easy_debugging(self):
1735 # repr() and str() of a generator state should contain the state name
1736 names = 'GEN_CREATED GEN_RUNNING GEN_SUSPENDED GEN_CLOSED'.split()
1737 for name in names:
1738 state = getattr(inspect, name)
1739 self.assertIn(name, repr(state))
1740 self.assertIn(name, str(state))
1741
Nick Coghlan04e2e3f2012-06-23 19:52:05 +10001742 def test_getgeneratorlocals(self):
1743 def each(lst, a=None):
1744 b=(1, 2, 3)
1745 for v in lst:
1746 if v == 3:
1747 c = 12
1748 yield v
1749
1750 numbers = each([1, 2, 3])
1751 self.assertEqual(inspect.getgeneratorlocals(numbers),
1752 {'a': None, 'lst': [1, 2, 3]})
1753 next(numbers)
1754 self.assertEqual(inspect.getgeneratorlocals(numbers),
1755 {'a': None, 'lst': [1, 2, 3], 'v': 1,
1756 'b': (1, 2, 3)})
1757 next(numbers)
1758 self.assertEqual(inspect.getgeneratorlocals(numbers),
1759 {'a': None, 'lst': [1, 2, 3], 'v': 2,
1760 'b': (1, 2, 3)})
1761 next(numbers)
1762 self.assertEqual(inspect.getgeneratorlocals(numbers),
1763 {'a': None, 'lst': [1, 2, 3], 'v': 3,
1764 'b': (1, 2, 3), 'c': 12})
1765 try:
1766 next(numbers)
1767 except StopIteration:
1768 pass
1769 self.assertEqual(inspect.getgeneratorlocals(numbers), {})
1770
1771 def test_getgeneratorlocals_empty(self):
1772 def yield_one():
1773 yield 1
1774 one = yield_one()
1775 self.assertEqual(inspect.getgeneratorlocals(one), {})
1776 try:
1777 next(one)
1778 except StopIteration:
1779 pass
1780 self.assertEqual(inspect.getgeneratorlocals(one), {})
1781
1782 def test_getgeneratorlocals_error(self):
1783 self.assertRaises(TypeError, inspect.getgeneratorlocals, 1)
1784 self.assertRaises(TypeError, inspect.getgeneratorlocals, lambda x: True)
1785 self.assertRaises(TypeError, inspect.getgeneratorlocals, set)
1786 self.assertRaises(TypeError, inspect.getgeneratorlocals, (2,3))
1787
Nick Coghlane0f04652010-11-21 03:44:04 +00001788
Yury Selivanov5376ba92015-06-22 12:19:30 -04001789class TestGetCoroutineState(unittest.TestCase):
1790
1791 def setUp(self):
1792 @types.coroutine
1793 def number_coroutine():
1794 for number in range(5):
1795 yield number
1796 async def coroutine():
1797 await number_coroutine()
1798 self.coroutine = coroutine()
1799
1800 def tearDown(self):
1801 self.coroutine.close()
1802
1803 def _coroutinestate(self):
1804 return inspect.getcoroutinestate(self.coroutine)
1805
1806 def test_created(self):
1807 self.assertEqual(self._coroutinestate(), inspect.CORO_CREATED)
1808
1809 def test_suspended(self):
1810 self.coroutine.send(None)
1811 self.assertEqual(self._coroutinestate(), inspect.CORO_SUSPENDED)
1812
1813 def test_closed_after_exhaustion(self):
1814 while True:
1815 try:
1816 self.coroutine.send(None)
1817 except StopIteration:
1818 break
1819
1820 self.assertEqual(self._coroutinestate(), inspect.CORO_CLOSED)
1821
1822 def test_closed_after_immediate_exception(self):
1823 with self.assertRaises(RuntimeError):
1824 self.coroutine.throw(RuntimeError)
1825 self.assertEqual(self._coroutinestate(), inspect.CORO_CLOSED)
1826
1827 def test_easy_debugging(self):
1828 # repr() and str() of a coroutine state should contain the state name
1829 names = 'CORO_CREATED CORO_RUNNING CORO_SUSPENDED CORO_CLOSED'.split()
1830 for name in names:
1831 state = getattr(inspect, name)
1832 self.assertIn(name, repr(state))
1833 self.assertIn(name, str(state))
1834
1835 def test_getcoroutinelocals(self):
1836 @types.coroutine
1837 def gencoro():
1838 yield
1839
1840 gencoro = gencoro()
1841 async def func(a=None):
1842 b = 'spam'
1843 await gencoro
1844
1845 coro = func()
1846 self.assertEqual(inspect.getcoroutinelocals(coro),
1847 {'a': None, 'gencoro': gencoro})
1848 coro.send(None)
1849 self.assertEqual(inspect.getcoroutinelocals(coro),
1850 {'a': None, 'gencoro': gencoro, 'b': 'spam'})
1851
1852
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001853class MySignature(inspect.Signature):
1854 # Top-level to make it picklable;
1855 # used in test_signature_object_pickle
1856 pass
1857
1858class MyParameter(inspect.Parameter):
1859 # Top-level to make it picklable;
1860 # used in test_signature_object_pickle
1861 pass
1862
Nick Coghlanf9e227e2014-08-17 14:01:19 +10001863
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001864
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001865class TestSignatureObject(unittest.TestCase):
1866 @staticmethod
Yury Selivanovbcd4fc12015-05-20 14:30:08 -04001867 def signature(func, **kw):
1868 sig = inspect.signature(func, **kw)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001869 return (tuple((param.name,
1870 (... if param.default is param.empty else param.default),
1871 (... if param.annotation is param.empty
1872 else param.annotation),
1873 str(param.kind).lower())
1874 for param in sig.parameters.values()),
1875 (... if sig.return_annotation is sig.empty
1876 else sig.return_annotation))
1877
1878 def test_signature_object(self):
1879 S = inspect.Signature
1880 P = inspect.Parameter
1881
1882 self.assertEqual(str(S()), '()')
1883
Yury Selivanov07a9e452014-01-29 10:58:16 -05001884 def test(po, pk, pod=42, pkd=100, *args, ko, **kwargs):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001885 pass
1886 sig = inspect.signature(test)
1887 po = sig.parameters['po'].replace(kind=P.POSITIONAL_ONLY)
Yury Selivanov07a9e452014-01-29 10:58:16 -05001888 pod = sig.parameters['pod'].replace(kind=P.POSITIONAL_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001889 pk = sig.parameters['pk']
Yury Selivanov07a9e452014-01-29 10:58:16 -05001890 pkd = sig.parameters['pkd']
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001891 args = sig.parameters['args']
1892 ko = sig.parameters['ko']
1893 kwargs = sig.parameters['kwargs']
1894
1895 S((po, pk, args, ko, kwargs))
1896
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001897 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001898 S((pk, po, args, ko, kwargs))
1899
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001900 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001901 S((po, args, pk, ko, kwargs))
1902
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001903 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001904 S((args, po, pk, ko, kwargs))
1905
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001906 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001907 S((po, pk, args, kwargs, ko))
1908
1909 kwargs2 = kwargs.replace(name='args')
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001910 with self.assertRaisesRegex(ValueError, 'duplicate parameter name'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001911 S((po, pk, args, kwargs2, ko))
1912
Yury Selivanov07a9e452014-01-29 10:58:16 -05001913 with self.assertRaisesRegex(ValueError, 'follows default argument'):
1914 S((pod, po))
1915
1916 with self.assertRaisesRegex(ValueError, 'follows default argument'):
1917 S((po, pkd, pk))
1918
1919 with self.assertRaisesRegex(ValueError, 'follows default argument'):
1920 S((pkd, pk))
1921
Yury Selivanov374375d2014-03-27 12:41:53 -04001922 self.assertTrue(repr(sig).startswith('<Signature'))
Yury Selivanov0cd2bf42015-05-15 12:55:20 -04001923 self.assertTrue('(po, pk' in repr(sig))
Yury Selivanov374375d2014-03-27 12:41:53 -04001924
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001925 def test_signature_object_pickle(self):
1926 def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
1927 foo_partial = functools.partial(foo, a=1)
1928
1929 sig = inspect.signature(foo_partial)
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001930
1931 for ver in range(pickle.HIGHEST_PROTOCOL + 1):
1932 with self.subTest(pickle_ver=ver, subclass=False):
1933 sig_pickled = pickle.loads(pickle.dumps(sig, ver))
1934 self.assertEqual(sig, sig_pickled)
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001935
1936 # Test that basic sub-classing works
1937 sig = inspect.signature(foo)
1938 myparam = MyParameter(name='z', kind=inspect.Parameter.POSITIONAL_ONLY)
1939 myparams = collections.OrderedDict(sig.parameters, a=myparam)
1940 mysig = MySignature().replace(parameters=myparams.values(),
1941 return_annotation=sig.return_annotation)
1942 self.assertTrue(isinstance(mysig, MySignature))
1943 self.assertTrue(isinstance(mysig.parameters['z'], MyParameter))
1944
1945 for ver in range(pickle.HIGHEST_PROTOCOL + 1):
1946 with self.subTest(pickle_ver=ver, subclass=True):
1947 sig_pickled = pickle.loads(pickle.dumps(mysig, ver))
1948 self.assertEqual(mysig, sig_pickled)
1949 self.assertTrue(isinstance(sig_pickled, MySignature))
1950 self.assertTrue(isinstance(sig_pickled.parameters['z'],
1951 MyParameter))
1952
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001953 def test_signature_immutability(self):
1954 def test(a):
1955 pass
1956 sig = inspect.signature(test)
1957
1958 with self.assertRaises(AttributeError):
1959 sig.foo = 'bar'
1960
1961 with self.assertRaises(TypeError):
1962 sig.parameters['a'] = None
1963
1964 def test_signature_on_noarg(self):
1965 def test():
1966 pass
1967 self.assertEqual(self.signature(test), ((), ...))
1968
1969 def test_signature_on_wargs(self):
1970 def test(a, b:'foo') -> 123:
1971 pass
1972 self.assertEqual(self.signature(test),
1973 ((('a', ..., ..., "positional_or_keyword"),
1974 ('b', ..., 'foo', "positional_or_keyword")),
1975 123))
1976
1977 def test_signature_on_wkwonly(self):
1978 def test(*, a:float, b:str) -> int:
1979 pass
1980 self.assertEqual(self.signature(test),
1981 ((('a', ..., float, "keyword_only"),
1982 ('b', ..., str, "keyword_only")),
1983 int))
1984
1985 def test_signature_on_complex_args(self):
1986 def test(a, b:'foo'=10, *args:'bar', spam:'baz', ham=123, **kwargs:int):
1987 pass
1988 self.assertEqual(self.signature(test),
1989 ((('a', ..., ..., "positional_or_keyword"),
1990 ('b', 10, 'foo', "positional_or_keyword"),
1991 ('args', ..., 'bar', "var_positional"),
1992 ('spam', ..., 'baz', "keyword_only"),
1993 ('ham', 123, ..., "keyword_only"),
1994 ('kwargs', ..., int, "var_keyword")),
1995 ...))
1996
Dong-hee Na378d7062017-05-18 04:00:51 +09001997 def test_signature_without_self(self):
1998 def test_args_only(*args): # NOQA
1999 pass
2000
2001 def test_args_kwargs_only(*args, **kwargs): # NOQA
2002 pass
2003
2004 class A:
2005 @classmethod
2006 def test_classmethod(*args): # NOQA
2007 pass
2008
2009 @staticmethod
2010 def test_staticmethod(*args): # NOQA
2011 pass
2012
2013 f1 = functools.partialmethod((test_classmethod), 1)
2014 f2 = functools.partialmethod((test_args_only), 1)
2015 f3 = functools.partialmethod((test_staticmethod), 1)
2016 f4 = functools.partialmethod((test_args_kwargs_only),1)
2017
2018 self.assertEqual(self.signature(test_args_only),
2019 ((('args', ..., ..., 'var_positional'),), ...))
2020 self.assertEqual(self.signature(test_args_kwargs_only),
2021 ((('args', ..., ..., 'var_positional'),
2022 ('kwargs', ..., ..., 'var_keyword')), ...))
2023 self.assertEqual(self.signature(A.f1),
2024 ((('args', ..., ..., 'var_positional'),), ...))
2025 self.assertEqual(self.signature(A.f2),
2026 ((('args', ..., ..., 'var_positional'),), ...))
2027 self.assertEqual(self.signature(A.f3),
2028 ((('args', ..., ..., 'var_positional'),), ...))
Serhiy Storchaka13ad3b72017-09-14 09:38:36 +03002029 self.assertEqual(self.signature(A.f4),
Dong-hee Na378d7062017-05-18 04:00:51 +09002030 ((('args', ..., ..., 'var_positional'),
2031 ('kwargs', ..., ..., 'var_keyword')), ...))
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002032 @cpython_only
Larry Hastingsfcafe432013-11-23 17:35:48 -08002033 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2034 "Signature information for builtins requires docstrings")
2035 def test_signature_on_builtins(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002036 import _testcapi
Larry Hastings16c51912014-01-07 11:53:01 -08002037
Larry Hastings5c661892014-01-24 06:17:25 -08002038 def test_unbound_method(o):
2039 """Use this to test unbound methods (things that should have a self)"""
2040 signature = inspect.signature(o)
2041 self.assertTrue(isinstance(signature, inspect.Signature))
2042 self.assertEqual(list(signature.parameters.values())[0].name, 'self')
2043 return signature
2044
2045 def test_callable(o):
2046 """Use this to test bound methods or normal callables (things that don't expect self)"""
2047 signature = inspect.signature(o)
2048 self.assertTrue(isinstance(signature, inspect.Signature))
2049 if signature.parameters:
2050 self.assertNotEqual(list(signature.parameters.values())[0].name, 'self')
2051 return signature
2052
2053 signature = test_callable(_testcapi.docstring_with_signature_with_defaults)
Larry Hastings16c51912014-01-07 11:53:01 -08002054 def p(name): return signature.parameters[name].default
2055 self.assertEqual(p('s'), 'avocado')
Larry Hastings2a727912014-01-16 11:32:01 -08002056 self.assertEqual(p('b'), b'bytes')
Larry Hastings16c51912014-01-07 11:53:01 -08002057 self.assertEqual(p('d'), 3.14)
2058 self.assertEqual(p('i'), 35)
Larry Hastings16c51912014-01-07 11:53:01 -08002059 self.assertEqual(p('n'), None)
2060 self.assertEqual(p('t'), True)
2061 self.assertEqual(p('f'), False)
Larry Hastings2a727912014-01-16 11:32:01 -08002062 self.assertEqual(p('local'), 3)
2063 self.assertEqual(p('sys'), sys.maxsize)
2064 self.assertEqual(p('exp'), sys.maxsize - 1)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002065
Larry Hastings5c661892014-01-24 06:17:25 -08002066 test_callable(object)
2067
2068 # normal method
2069 # (PyMethodDescr_Type, "method_descriptor")
2070 test_unbound_method(_pickle.Pickler.dump)
2071 d = _pickle.Pickler(io.StringIO())
2072 test_callable(d.dump)
2073
2074 # static method
2075 test_callable(str.maketrans)
2076 test_callable('abc'.maketrans)
2077
2078 # class method
2079 test_callable(dict.fromkeys)
2080 test_callable({}.fromkeys)
2081
2082 # wrapper around slot (PyWrapperDescr_Type, "wrapper_descriptor")
2083 test_unbound_method(type.__call__)
2084 test_unbound_method(int.__add__)
2085 test_callable((3).__add__)
2086
2087 # _PyMethodWrapper_Type
2088 # support for 'method-wrapper'
2089 test_callable(min.__call__)
2090
Larry Hastings2623c8c2014-02-08 22:15:29 -08002091 # This doesn't work now.
2092 # (We don't have a valid signature for "type" in 3.4)
2093 with self.assertRaisesRegex(ValueError, "no signature found"):
2094 class ThisWorksNow:
2095 __call__ = type
2096 test_callable(ThisWorksNow())
Larry Hastings5c661892014-01-24 06:17:25 -08002097
Yury Selivanov056e2652014-03-02 12:25:27 -05002098 # Regression test for issue #20786
2099 test_unbound_method(dict.__delitem__)
2100 test_unbound_method(property.__delete__)
2101
Zachary Ware8ef887c2015-04-13 18:22:35 -05002102 # Regression test for issue #20586
2103 test_callable(_testcapi.docstring_with_signature_but_no_doc)
2104
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002105 @cpython_only
Yury Selivanov76c6c592014-01-29 10:52:57 -05002106 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2107 "Signature information for builtins requires docstrings")
2108 def test_signature_on_decorated_builtins(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002109 import _testcapi
Yury Selivanov76c6c592014-01-29 10:52:57 -05002110 func = _testcapi.docstring_with_signature_with_defaults
2111
2112 def decorator(func):
2113 @functools.wraps(func)
2114 def wrapper(*args, **kwargs) -> int:
2115 return func(*args, **kwargs)
2116 return wrapper
2117
2118 decorated_func = decorator(func)
2119
2120 self.assertEqual(inspect.signature(func),
2121 inspect.signature(decorated_func))
Larry Hastings5c661892014-01-24 06:17:25 -08002122
Yury Selivanovbcd4fc12015-05-20 14:30:08 -04002123 def wrapper_like(*args, **kwargs) -> int: pass
2124 self.assertEqual(inspect.signature(decorated_func,
2125 follow_wrapped=False),
2126 inspect.signature(wrapper_like))
2127
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002128 @cpython_only
Larry Hastings5c661892014-01-24 06:17:25 -08002129 def test_signature_on_builtins_no_signature(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002130 import _testcapi
Yury Selivanovbf304fc2015-05-30 17:08:36 -04002131 with self.assertRaisesRegex(ValueError,
2132 'no signature found for builtin'):
Larry Hastings5c661892014-01-24 06:17:25 -08002133 inspect.signature(_testcapi.docstring_no_signature)
2134
Yury Selivanovbf304fc2015-05-30 17:08:36 -04002135 with self.assertRaisesRegex(ValueError,
2136 'no signature found for builtin'):
2137 inspect.signature(str)
2138
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002139 def test_signature_on_non_function(self):
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002140 with self.assertRaisesRegex(TypeError, 'is not a callable object'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002141 inspect.signature(42)
2142
Yury Selivanov63da7c72014-01-31 14:48:37 -05002143 def test_signature_from_functionlike_object(self):
2144 def func(a,b, *args, kwonly=True, kwonlyreq, **kwargs):
2145 pass
2146
2147 class funclike:
2148 # Has to be callable, and have correct
2149 # __code__, __annotations__, __defaults__, __name__,
2150 # and __kwdefaults__ attributes
2151
2152 def __init__(self, func):
2153 self.__name__ = func.__name__
2154 self.__code__ = func.__code__
2155 self.__annotations__ = func.__annotations__
2156 self.__defaults__ = func.__defaults__
2157 self.__kwdefaults__ = func.__kwdefaults__
2158 self.func = func
2159
2160 def __call__(self, *args, **kwargs):
2161 return self.func(*args, **kwargs)
2162
Yury Selivanov57c74fc2015-05-20 23:07:02 -04002163 sig_func = inspect.Signature.from_callable(func)
Yury Selivanov63da7c72014-01-31 14:48:37 -05002164
Yury Selivanov57c74fc2015-05-20 23:07:02 -04002165 sig_funclike = inspect.Signature.from_callable(funclike(func))
Yury Selivanov63da7c72014-01-31 14:48:37 -05002166 self.assertEqual(sig_funclike, sig_func)
2167
2168 sig_funclike = inspect.signature(funclike(func))
2169 self.assertEqual(sig_funclike, sig_func)
2170
2171 # If object is not a duck type of function, then
2172 # signature will try to get a signature for its '__call__'
2173 # method
2174 fl = funclike(func)
2175 del fl.__defaults__
2176 self.assertEqual(self.signature(fl),
2177 ((('args', ..., ..., "var_positional"),
2178 ('kwargs', ..., ..., "var_keyword")),
2179 ...))
2180
Yury Selivanova773de02014-02-21 18:30:53 -05002181 # Test with cython-like builtins:
2182 _orig_isdesc = inspect.ismethoddescriptor
2183 def _isdesc(obj):
2184 if hasattr(obj, '_builtinmock'):
2185 return True
2186 return _orig_isdesc(obj)
2187
2188 with unittest.mock.patch('inspect.ismethoddescriptor', _isdesc):
2189 builtin_func = funclike(func)
2190 # Make sure that our mock setup is working
2191 self.assertFalse(inspect.ismethoddescriptor(builtin_func))
2192 builtin_func._builtinmock = True
2193 self.assertTrue(inspect.ismethoddescriptor(builtin_func))
2194 self.assertEqual(inspect.signature(builtin_func), sig_func)
2195
Yury Selivanov63da7c72014-01-31 14:48:37 -05002196 def test_signature_functionlike_class(self):
2197 # We only want to duck type function-like objects,
2198 # not classes.
2199
2200 def func(a,b, *args, kwonly=True, kwonlyreq, **kwargs):
2201 pass
2202
2203 class funclike:
2204 def __init__(self, marker):
2205 pass
2206
2207 __name__ = func.__name__
2208 __code__ = func.__code__
2209 __annotations__ = func.__annotations__
2210 __defaults__ = func.__defaults__
2211 __kwdefaults__ = func.__kwdefaults__
2212
Yury Selivanov63da7c72014-01-31 14:48:37 -05002213 self.assertEqual(str(inspect.signature(funclike)), '(marker)')
2214
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002215 def test_signature_on_method(self):
2216 class Test:
Yury Selivanov62560fb2014-01-28 12:26:24 -05002217 def __init__(*args):
2218 pass
2219 def m1(self, arg1, arg2=1) -> int:
2220 pass
2221 def m2(*args):
2222 pass
2223 def __call__(*, a):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002224 pass
2225
Yury Selivanov62560fb2014-01-28 12:26:24 -05002226 self.assertEqual(self.signature(Test().m1),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002227 ((('arg1', ..., ..., "positional_or_keyword"),
2228 ('arg2', 1, ..., "positional_or_keyword")),
2229 int))
2230
Yury Selivanov62560fb2014-01-28 12:26:24 -05002231 self.assertEqual(self.signature(Test().m2),
2232 ((('args', ..., ..., "var_positional"),),
2233 ...))
2234
2235 self.assertEqual(self.signature(Test),
2236 ((('args', ..., ..., "var_positional"),),
2237 ...))
2238
2239 with self.assertRaisesRegex(ValueError, 'invalid method signature'):
2240 self.signature(Test())
2241
Yury Selivanov46c759d2015-05-27 21:56:53 -04002242 def test_signature_wrapped_bound_method(self):
2243 # Issue 24298
2244 class Test:
2245 def m1(self, arg1, arg2=1) -> int:
2246 pass
2247 @functools.wraps(Test().m1)
2248 def m1d(*args, **kwargs):
2249 pass
2250 self.assertEqual(self.signature(m1d),
2251 ((('arg1', ..., ..., "positional_or_keyword"),
2252 ('arg2', 1, ..., "positional_or_keyword")),
2253 int))
2254
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002255 def test_signature_on_classmethod(self):
2256 class Test:
2257 @classmethod
2258 def foo(cls, arg1, *, arg2=1):
2259 pass
2260
2261 meth = Test().foo
2262 self.assertEqual(self.signature(meth),
2263 ((('arg1', ..., ..., "positional_or_keyword"),
2264 ('arg2', 1, ..., "keyword_only")),
2265 ...))
2266
2267 meth = Test.foo
2268 self.assertEqual(self.signature(meth),
2269 ((('arg1', ..., ..., "positional_or_keyword"),
2270 ('arg2', 1, ..., "keyword_only")),
2271 ...))
2272
2273 def test_signature_on_staticmethod(self):
2274 class Test:
2275 @staticmethod
2276 def foo(cls, *, arg):
2277 pass
2278
2279 meth = Test().foo
2280 self.assertEqual(self.signature(meth),
2281 ((('cls', ..., ..., "positional_or_keyword"),
2282 ('arg', ..., ..., "keyword_only")),
2283 ...))
2284
2285 meth = Test.foo
2286 self.assertEqual(self.signature(meth),
2287 ((('cls', ..., ..., "positional_or_keyword"),
2288 ('arg', ..., ..., "keyword_only")),
2289 ...))
2290
2291 def test_signature_on_partial(self):
2292 from functools import partial
2293
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002294 Parameter = inspect.Parameter
2295
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002296 def test():
2297 pass
2298
2299 self.assertEqual(self.signature(partial(test)), ((), ...))
2300
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002301 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002302 inspect.signature(partial(test, 1))
2303
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002304 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002305 inspect.signature(partial(test, a=1))
2306
2307 def test(a, b, *, c, d):
2308 pass
2309
2310 self.assertEqual(self.signature(partial(test)),
2311 ((('a', ..., ..., "positional_or_keyword"),
2312 ('b', ..., ..., "positional_or_keyword"),
2313 ('c', ..., ..., "keyword_only"),
2314 ('d', ..., ..., "keyword_only")),
2315 ...))
2316
2317 self.assertEqual(self.signature(partial(test, 1)),
2318 ((('b', ..., ..., "positional_or_keyword"),
2319 ('c', ..., ..., "keyword_only"),
2320 ('d', ..., ..., "keyword_only")),
2321 ...))
2322
2323 self.assertEqual(self.signature(partial(test, 1, c=2)),
2324 ((('b', ..., ..., "positional_or_keyword"),
2325 ('c', 2, ..., "keyword_only"),
2326 ('d', ..., ..., "keyword_only")),
2327 ...))
2328
2329 self.assertEqual(self.signature(partial(test, b=1, c=2)),
2330 ((('a', ..., ..., "positional_or_keyword"),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002331 ('b', 1, ..., "keyword_only"),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002332 ('c', 2, ..., "keyword_only"),
2333 ('d', ..., ..., "keyword_only")),
2334 ...))
2335
2336 self.assertEqual(self.signature(partial(test, 0, b=1, c=2)),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002337 ((('b', 1, ..., "keyword_only"),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002338 ('c', 2, ..., "keyword_only"),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002339 ('d', ..., ..., "keyword_only")),
2340 ...))
2341
2342 self.assertEqual(self.signature(partial(test, a=1)),
2343 ((('a', 1, ..., "keyword_only"),
2344 ('b', ..., ..., "keyword_only"),
2345 ('c', ..., ..., "keyword_only"),
2346 ('d', ..., ..., "keyword_only")),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002347 ...))
2348
2349 def test(a, *args, b, **kwargs):
2350 pass
2351
2352 self.assertEqual(self.signature(partial(test, 1)),
2353 ((('args', ..., ..., "var_positional"),
2354 ('b', ..., ..., "keyword_only"),
2355 ('kwargs', ..., ..., "var_keyword")),
2356 ...))
2357
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002358 self.assertEqual(self.signature(partial(test, a=1)),
2359 ((('a', 1, ..., "keyword_only"),
2360 ('b', ..., ..., "keyword_only"),
2361 ('kwargs', ..., ..., "var_keyword")),
2362 ...))
2363
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002364 self.assertEqual(self.signature(partial(test, 1, 2, 3)),
2365 ((('args', ..., ..., "var_positional"),
2366 ('b', ..., ..., "keyword_only"),
2367 ('kwargs', ..., ..., "var_keyword")),
2368 ...))
2369
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002370 self.assertEqual(self.signature(partial(test, 1, 2, 3, test=True)),
2371 ((('args', ..., ..., "var_positional"),
2372 ('b', ..., ..., "keyword_only"),
2373 ('kwargs', ..., ..., "var_keyword")),
2374 ...))
2375
2376 self.assertEqual(self.signature(partial(test, 1, 2, 3, test=1, b=0)),
2377 ((('args', ..., ..., "var_positional"),
2378 ('b', 0, ..., "keyword_only"),
2379 ('kwargs', ..., ..., "var_keyword")),
2380 ...))
2381
2382 self.assertEqual(self.signature(partial(test, b=0)),
2383 ((('a', ..., ..., "positional_or_keyword"),
2384 ('args', ..., ..., "var_positional"),
2385 ('b', 0, ..., "keyword_only"),
2386 ('kwargs', ..., ..., "var_keyword")),
2387 ...))
2388
2389 self.assertEqual(self.signature(partial(test, b=0, test=1)),
2390 ((('a', ..., ..., "positional_or_keyword"),
2391 ('args', ..., ..., "var_positional"),
2392 ('b', 0, ..., "keyword_only"),
2393 ('kwargs', ..., ..., "var_keyword")),
2394 ...))
2395
2396 def test(a, b, c:int) -> 42:
2397 pass
2398
2399 sig = test.__signature__ = inspect.signature(test)
2400
2401 self.assertEqual(self.signature(partial(partial(test, 1))),
2402 ((('b', ..., ..., "positional_or_keyword"),
2403 ('c', ..., int, "positional_or_keyword")),
2404 42))
2405
2406 self.assertEqual(self.signature(partial(partial(test, 1), 2)),
2407 ((('c', ..., int, "positional_or_keyword"),),
2408 42))
2409
2410 psig = inspect.signature(partial(partial(test, 1), 2))
2411
2412 def foo(a):
2413 return a
2414 _foo = partial(partial(foo, a=10), a=20)
2415 self.assertEqual(self.signature(_foo),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002416 ((('a', 20, ..., "keyword_only"),),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002417 ...))
2418 # check that we don't have any side-effects in signature(),
2419 # and the partial object is still functioning
2420 self.assertEqual(_foo(), 20)
2421
2422 def foo(a, b, c):
2423 return a, b, c
2424 _foo = partial(partial(foo, 1, b=20), b=30)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002425
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002426 self.assertEqual(self.signature(_foo),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002427 ((('b', 30, ..., "keyword_only"),
2428 ('c', ..., ..., "keyword_only")),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002429 ...))
2430 self.assertEqual(_foo(c=10), (1, 30, 10))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002431
2432 def foo(a, b, c, *, d):
2433 return a, b, c, d
2434 _foo = partial(partial(foo, d=20, c=20), b=10, d=30)
2435 self.assertEqual(self.signature(_foo),
2436 ((('a', ..., ..., "positional_or_keyword"),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002437 ('b', 10, ..., "keyword_only"),
2438 ('c', 20, ..., "keyword_only"),
2439 ('d', 30, ..., "keyword_only"),
2440 ),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002441 ...))
2442 ba = inspect.signature(_foo).bind(a=200, b=11)
2443 self.assertEqual(_foo(*ba.args, **ba.kwargs), (200, 11, 20, 30))
2444
2445 def foo(a=1, b=2, c=3):
2446 return a, b, c
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002447 _foo = partial(foo, c=13) # (a=1, b=2, *, c=13)
2448
2449 ba = inspect.signature(_foo).bind(a=11)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002450 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 2, 13))
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002451
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002452 ba = inspect.signature(_foo).bind(11, 12)
2453 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002454
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002455 ba = inspect.signature(_foo).bind(11, b=12)
2456 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002457
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002458 ba = inspect.signature(_foo).bind(b=12)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002459 self.assertEqual(_foo(*ba.args, **ba.kwargs), (1, 12, 13))
2460
2461 _foo = partial(_foo, b=10, c=20)
2462 ba = inspect.signature(_foo).bind(12)
2463 self.assertEqual(_foo(*ba.args, **ba.kwargs), (12, 10, 20))
2464
2465
2466 def foo(a, b, c, d, **kwargs):
2467 pass
2468 sig = inspect.signature(foo)
2469 params = sig.parameters.copy()
2470 params['a'] = params['a'].replace(kind=Parameter.POSITIONAL_ONLY)
2471 params['b'] = params['b'].replace(kind=Parameter.POSITIONAL_ONLY)
2472 foo.__signature__ = inspect.Signature(params.values())
2473 sig = inspect.signature(foo)
2474 self.assertEqual(str(sig), '(a, b, /, c, d, **kwargs)')
2475
2476 self.assertEqual(self.signature(partial(foo, 1)),
2477 ((('b', ..., ..., 'positional_only'),
2478 ('c', ..., ..., 'positional_or_keyword'),
2479 ('d', ..., ..., 'positional_or_keyword'),
2480 ('kwargs', ..., ..., 'var_keyword')),
2481 ...))
2482
2483 self.assertEqual(self.signature(partial(foo, 1, 2)),
2484 ((('c', ..., ..., 'positional_or_keyword'),
2485 ('d', ..., ..., 'positional_or_keyword'),
2486 ('kwargs', ..., ..., 'var_keyword')),
2487 ...))
2488
2489 self.assertEqual(self.signature(partial(foo, 1, 2, 3)),
2490 ((('d', ..., ..., 'positional_or_keyword'),
2491 ('kwargs', ..., ..., 'var_keyword')),
2492 ...))
2493
2494 self.assertEqual(self.signature(partial(foo, 1, 2, c=3)),
2495 ((('c', 3, ..., 'keyword_only'),
2496 ('d', ..., ..., 'keyword_only'),
2497 ('kwargs', ..., ..., 'var_keyword')),
2498 ...))
2499
2500 self.assertEqual(self.signature(partial(foo, 1, c=3)),
2501 ((('b', ..., ..., 'positional_only'),
2502 ('c', 3, ..., 'keyword_only'),
2503 ('d', ..., ..., 'keyword_only'),
2504 ('kwargs', ..., ..., 'var_keyword')),
2505 ...))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002506
Yury Selivanovda5fe4f2014-01-27 17:28:37 -05002507 def test_signature_on_partialmethod(self):
2508 from functools import partialmethod
2509
2510 class Spam:
2511 def test():
2512 pass
2513 ham = partialmethod(test)
2514
2515 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
2516 inspect.signature(Spam.ham)
2517
2518 class Spam:
2519 def test(it, a, *, c) -> 'spam':
2520 pass
2521 ham = partialmethod(test, c=1)
2522
2523 self.assertEqual(self.signature(Spam.ham),
2524 ((('it', ..., ..., 'positional_or_keyword'),
2525 ('a', ..., ..., 'positional_or_keyword'),
2526 ('c', 1, ..., 'keyword_only')),
2527 'spam'))
2528
2529 self.assertEqual(self.signature(Spam().ham),
2530 ((('a', ..., ..., 'positional_or_keyword'),
2531 ('c', 1, ..., 'keyword_only')),
2532 'spam'))
2533
Yury Selivanov0486f812014-01-29 12:18:59 -05002534 def test_signature_on_fake_partialmethod(self):
2535 def foo(a): pass
2536 foo._partialmethod = 'spam'
2537 self.assertEqual(str(inspect.signature(foo)), '(a)')
2538
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002539 def test_signature_on_decorated(self):
2540 import functools
2541
2542 def decorator(func):
2543 @functools.wraps(func)
2544 def wrapper(*args, **kwargs) -> int:
2545 return func(*args, **kwargs)
2546 return wrapper
2547
2548 class Foo:
2549 @decorator
2550 def bar(self, a, b):
2551 pass
2552
2553 self.assertEqual(self.signature(Foo.bar),
2554 ((('self', ..., ..., "positional_or_keyword"),
2555 ('a', ..., ..., "positional_or_keyword"),
2556 ('b', ..., ..., "positional_or_keyword")),
2557 ...))
2558
2559 self.assertEqual(self.signature(Foo().bar),
2560 ((('a', ..., ..., "positional_or_keyword"),
2561 ('b', ..., ..., "positional_or_keyword")),
2562 ...))
2563
Yury Selivanovbcd4fc12015-05-20 14:30:08 -04002564 self.assertEqual(self.signature(Foo.bar, follow_wrapped=False),
2565 ((('args', ..., ..., "var_positional"),
2566 ('kwargs', ..., ..., "var_keyword")),
2567 ...)) # functools.wraps will copy __annotations__
2568 # from "func" to "wrapper", hence no
2569 # return_annotation
2570
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002571 # Test that we handle method wrappers correctly
2572 def decorator(func):
2573 @functools.wraps(func)
2574 def wrapper(*args, **kwargs) -> int:
2575 return func(42, *args, **kwargs)
2576 sig = inspect.signature(func)
2577 new_params = tuple(sig.parameters.values())[1:]
2578 wrapper.__signature__ = sig.replace(parameters=new_params)
2579 return wrapper
2580
2581 class Foo:
2582 @decorator
2583 def __call__(self, a, b):
2584 pass
2585
2586 self.assertEqual(self.signature(Foo.__call__),
2587 ((('a', ..., ..., "positional_or_keyword"),
2588 ('b', ..., ..., "positional_or_keyword")),
2589 ...))
2590
2591 self.assertEqual(self.signature(Foo().__call__),
2592 ((('b', ..., ..., "positional_or_keyword"),),
2593 ...))
2594
Nick Coghlane8c45d62013-07-28 20:00:01 +10002595 # Test we handle __signature__ partway down the wrapper stack
2596 def wrapped_foo_call():
2597 pass
2598 wrapped_foo_call.__wrapped__ = Foo.__call__
2599
2600 self.assertEqual(self.signature(wrapped_foo_call),
2601 ((('a', ..., ..., "positional_or_keyword"),
2602 ('b', ..., ..., "positional_or_keyword")),
2603 ...))
2604
2605
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002606 def test_signature_on_class(self):
2607 class C:
2608 def __init__(self, a):
2609 pass
2610
2611 self.assertEqual(self.signature(C),
2612 ((('a', ..., ..., "positional_or_keyword"),),
2613 ...))
2614
2615 class CM(type):
2616 def __call__(cls, a):
2617 pass
2618 class C(metaclass=CM):
2619 def __init__(self, b):
2620 pass
2621
2622 self.assertEqual(self.signature(C),
2623 ((('a', ..., ..., "positional_or_keyword"),),
2624 ...))
2625
2626 class CM(type):
2627 def __new__(mcls, name, bases, dct, *, foo=1):
2628 return super().__new__(mcls, name, bases, dct)
2629 class C(metaclass=CM):
2630 def __init__(self, b):
2631 pass
2632
2633 self.assertEqual(self.signature(C),
2634 ((('b', ..., ..., "positional_or_keyword"),),
2635 ...))
2636
2637 self.assertEqual(self.signature(CM),
2638 ((('name', ..., ..., "positional_or_keyword"),
2639 ('bases', ..., ..., "positional_or_keyword"),
2640 ('dct', ..., ..., "positional_or_keyword"),
2641 ('foo', 1, ..., "keyword_only")),
2642 ...))
2643
2644 class CMM(type):
2645 def __new__(mcls, name, bases, dct, *, foo=1):
2646 return super().__new__(mcls, name, bases, dct)
2647 def __call__(cls, nm, bs, dt):
2648 return type(nm, bs, dt)
2649 class CM(type, metaclass=CMM):
2650 def __new__(mcls, name, bases, dct, *, bar=2):
2651 return super().__new__(mcls, name, bases, dct)
2652 class C(metaclass=CM):
2653 def __init__(self, b):
2654 pass
2655
2656 self.assertEqual(self.signature(CMM),
2657 ((('name', ..., ..., "positional_or_keyword"),
2658 ('bases', ..., ..., "positional_or_keyword"),
2659 ('dct', ..., ..., "positional_or_keyword"),
2660 ('foo', 1, ..., "keyword_only")),
2661 ...))
2662
2663 self.assertEqual(self.signature(CM),
2664 ((('nm', ..., ..., "positional_or_keyword"),
2665 ('bs', ..., ..., "positional_or_keyword"),
2666 ('dt', ..., ..., "positional_or_keyword")),
2667 ...))
2668
2669 self.assertEqual(self.signature(C),
2670 ((('b', ..., ..., "positional_or_keyword"),),
2671 ...))
2672
2673 class CM(type):
2674 def __init__(cls, name, bases, dct, *, bar=2):
2675 return super().__init__(name, bases, dct)
2676 class C(metaclass=CM):
2677 def __init__(self, b):
2678 pass
2679
2680 self.assertEqual(self.signature(CM),
2681 ((('name', ..., ..., "positional_or_keyword"),
2682 ('bases', ..., ..., "positional_or_keyword"),
2683 ('dct', ..., ..., "positional_or_keyword"),
2684 ('bar', 2, ..., "keyword_only")),
2685 ...))
2686
Yury Selivanov145dff82014-02-01 13:49:29 -05002687 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2688 "Signature information for builtins requires docstrings")
2689 def test_signature_on_class_without_init(self):
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002690 # Test classes without user-defined __init__ or __new__
2691 class C: pass
2692 self.assertEqual(str(inspect.signature(C)), '()')
2693 class D(C): pass
2694 self.assertEqual(str(inspect.signature(D)), '()')
2695
2696 # Test meta-classes without user-defined __init__ or __new__
2697 class C(type): pass
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002698 class D(C): pass
Larry Hastings2623c8c2014-02-08 22:15:29 -08002699 with self.assertRaisesRegex(ValueError, "callable.*is not supported"):
2700 self.assertEqual(inspect.signature(C), None)
2701 with self.assertRaisesRegex(ValueError, "callable.*is not supported"):
2702 self.assertEqual(inspect.signature(D), None)
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002703
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002704 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2705 "Signature information for builtins requires docstrings")
2706 def test_signature_on_builtin_class(self):
2707 self.assertEqual(str(inspect.signature(_pickle.Pickler)),
2708 '(file, protocol=None, fix_imports=True)')
2709
2710 class P(_pickle.Pickler): pass
2711 class EmptyTrait: pass
2712 class P2(EmptyTrait, P): pass
2713 self.assertEqual(str(inspect.signature(P)),
2714 '(file, protocol=None, fix_imports=True)')
2715 self.assertEqual(str(inspect.signature(P2)),
2716 '(file, protocol=None, fix_imports=True)')
2717
2718 class P3(P2):
2719 def __init__(self, spam):
2720 pass
2721 self.assertEqual(str(inspect.signature(P3)), '(spam)')
2722
2723 class MetaP(type):
2724 def __call__(cls, foo, bar):
2725 pass
2726 class P4(P2, metaclass=MetaP):
2727 pass
2728 self.assertEqual(str(inspect.signature(P4)), '(foo, bar)')
2729
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002730 def test_signature_on_callable_objects(self):
2731 class Foo:
2732 def __call__(self, a):
2733 pass
2734
2735 self.assertEqual(self.signature(Foo()),
2736 ((('a', ..., ..., "positional_or_keyword"),),
2737 ...))
2738
2739 class Spam:
2740 pass
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002741 with self.assertRaisesRegex(TypeError, "is not a callable object"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002742 inspect.signature(Spam())
2743
2744 class Bar(Spam, Foo):
2745 pass
2746
2747 self.assertEqual(self.signature(Bar()),
2748 ((('a', ..., ..., "positional_or_keyword"),),
2749 ...))
2750
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002751 class Wrapped:
2752 pass
2753 Wrapped.__wrapped__ = lambda a: None
2754 self.assertEqual(self.signature(Wrapped),
2755 ((('a', ..., ..., "positional_or_keyword"),),
2756 ...))
Nick Coghlane8c45d62013-07-28 20:00:01 +10002757 # wrapper loop:
2758 Wrapped.__wrapped__ = Wrapped
2759 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
2760 self.signature(Wrapped)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002761
2762 def test_signature_on_lambdas(self):
2763 self.assertEqual(self.signature((lambda a=10: a)),
2764 ((('a', 10, ..., "positional_or_keyword"),),
2765 ...))
2766
2767 def test_signature_equality(self):
2768 def foo(a, *, b:int) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002769 self.assertFalse(inspect.signature(foo) == 42)
2770 self.assertTrue(inspect.signature(foo) != 42)
2771 self.assertTrue(inspect.signature(foo) == EqualsToAll())
2772 self.assertFalse(inspect.signature(foo) != EqualsToAll())
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002773
2774 def bar(a, *, b:int) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002775 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
2776 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002777 self.assertEqual(
2778 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002779
2780 def bar(a, *, b:int) -> int: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002781 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
2782 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002783 self.assertNotEqual(
2784 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002785
2786 def bar(a, *, b:int): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002787 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
2788 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002789 self.assertNotEqual(
2790 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002791
2792 def bar(a, *, b:int=42) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002793 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
2794 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002795 self.assertNotEqual(
2796 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002797
2798 def bar(a, *, c) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002799 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
2800 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002801 self.assertNotEqual(
2802 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002803
2804 def bar(a, b:int) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002805 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
2806 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002807 self.assertNotEqual(
2808 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002809 def spam(b:int, a) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002810 self.assertFalse(inspect.signature(spam) == inspect.signature(bar))
2811 self.assertTrue(inspect.signature(spam) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002812 self.assertNotEqual(
2813 hash(inspect.signature(spam)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002814
2815 def foo(*, a, b, c): pass
2816 def bar(*, c, b, a): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002817 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
2818 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002819 self.assertEqual(
2820 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002821
2822 def foo(*, a=1, b, c): pass
2823 def bar(*, c, b, a=1): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002824 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
2825 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002826 self.assertEqual(
2827 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002828
2829 def foo(pos, *, a=1, b, c): pass
2830 def bar(pos, *, c, b, a=1): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002831 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
2832 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002833 self.assertEqual(
2834 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002835
2836 def foo(pos, *, a, b, c): pass
2837 def bar(pos, *, c, b, a=1): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002838 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
2839 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002840 self.assertNotEqual(
2841 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002842
2843 def foo(pos, *args, a=42, b, c, **kwargs:int): pass
2844 def bar(pos, *args, c, b, a=42, **kwargs:int): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002845 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
2846 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002847 self.assertEqual(
2848 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002849
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002850 def test_signature_hashable(self):
2851 S = inspect.Signature
2852 P = inspect.Parameter
2853
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002854 def foo(a): pass
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002855 foo_sig = inspect.signature(foo)
2856
2857 manual_sig = S(parameters=[P('a', P.POSITIONAL_OR_KEYWORD)])
2858
2859 self.assertEqual(hash(foo_sig), hash(manual_sig))
2860 self.assertNotEqual(hash(foo_sig),
2861 hash(manual_sig.replace(return_annotation='spam')))
2862
2863 def bar(a) -> 1: pass
2864 self.assertNotEqual(hash(foo_sig), hash(inspect.signature(bar)))
2865
2866 def foo(a={}): pass
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002867 with self.assertRaisesRegex(TypeError, 'unhashable type'):
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002868 hash(inspect.signature(foo))
2869
2870 def foo(a) -> {}: pass
2871 with self.assertRaisesRegex(TypeError, 'unhashable type'):
2872 hash(inspect.signature(foo))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002873
2874 def test_signature_str(self):
2875 def foo(a:int=1, *, b, c=None, **kwargs) -> 42:
2876 pass
2877 self.assertEqual(str(inspect.signature(foo)),
Dong-hee Na762b9572017-11-16 03:30:59 +09002878 '(a: int = 1, *, b, c=None, **kwargs) -> 42')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002879
2880 def foo(a:int=1, *args, b, c=None, **kwargs) -> 42:
2881 pass
2882 self.assertEqual(str(inspect.signature(foo)),
Dong-hee Na762b9572017-11-16 03:30:59 +09002883 '(a: int = 1, *args, b, c=None, **kwargs) -> 42')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002884
2885 def foo():
2886 pass
2887 self.assertEqual(str(inspect.signature(foo)), '()')
2888
2889 def test_signature_str_positional_only(self):
2890 P = inspect.Parameter
Yury Selivanov2393dca2014-01-27 15:07:58 -05002891 S = inspect.Signature
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002892
2893 def test(a_po, *, b, **kwargs):
2894 return a_po, kwargs
2895
2896 sig = inspect.signature(test)
2897 new_params = list(sig.parameters.values())
2898 new_params[0] = new_params[0].replace(kind=P.POSITIONAL_ONLY)
2899 test.__signature__ = sig.replace(parameters=new_params)
2900
2901 self.assertEqual(str(inspect.signature(test)),
Yury Selivanov2393dca2014-01-27 15:07:58 -05002902 '(a_po, /, *, b, **kwargs)')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002903
Yury Selivanov2393dca2014-01-27 15:07:58 -05002904 self.assertEqual(str(S(parameters=[P('foo', P.POSITIONAL_ONLY)])),
2905 '(foo, /)')
2906
2907 self.assertEqual(str(S(parameters=[
2908 P('foo', P.POSITIONAL_ONLY),
2909 P('bar', P.VAR_KEYWORD)])),
2910 '(foo, /, **bar)')
2911
2912 self.assertEqual(str(S(parameters=[
2913 P('foo', P.POSITIONAL_ONLY),
2914 P('bar', P.VAR_POSITIONAL)])),
2915 '(foo, /, *bar)')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002916
2917 def test_signature_replace_anno(self):
2918 def test() -> 42:
2919 pass
2920
2921 sig = inspect.signature(test)
2922 sig = sig.replace(return_annotation=None)
2923 self.assertIs(sig.return_annotation, None)
2924 sig = sig.replace(return_annotation=sig.empty)
2925 self.assertIs(sig.return_annotation, sig.empty)
2926 sig = sig.replace(return_annotation=42)
2927 self.assertEqual(sig.return_annotation, 42)
2928 self.assertEqual(sig, inspect.signature(test))
2929
Yury Selivanov34ce99f2014-02-18 12:49:41 -05002930 def test_signature_on_mangled_parameters(self):
2931 class Spam:
2932 def foo(self, __p1:1=2, *, __p2:2=3):
2933 pass
2934 class Ham(Spam):
2935 pass
2936
2937 self.assertEqual(self.signature(Spam.foo),
2938 ((('self', ..., ..., "positional_or_keyword"),
2939 ('_Spam__p1', 2, 1, "positional_or_keyword"),
2940 ('_Spam__p2', 3, 2, "keyword_only")),
2941 ...))
2942
2943 self.assertEqual(self.signature(Spam.foo),
2944 self.signature(Ham.foo))
2945
Yury Selivanovda396452014-03-27 12:09:24 -04002946 def test_signature_from_callable_python_obj(self):
2947 class MySignature(inspect.Signature): pass
2948 def foo(a, *, b:1): pass
2949 foo_sig = MySignature.from_callable(foo)
2950 self.assertTrue(isinstance(foo_sig, MySignature))
2951
2952 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2953 "Signature information for builtins requires docstrings")
2954 def test_signature_from_callable_builtin_obj(self):
2955 class MySignature(inspect.Signature): pass
2956 sig = MySignature.from_callable(_pickle.Pickler)
2957 self.assertTrue(isinstance(sig, MySignature))
2958
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002959
2960class TestParameterObject(unittest.TestCase):
2961 def test_signature_parameter_kinds(self):
2962 P = inspect.Parameter
2963 self.assertTrue(P.POSITIONAL_ONLY < P.POSITIONAL_OR_KEYWORD < \
2964 P.VAR_POSITIONAL < P.KEYWORD_ONLY < P.VAR_KEYWORD)
2965
2966 self.assertEqual(str(P.POSITIONAL_ONLY), 'POSITIONAL_ONLY')
2967 self.assertTrue('POSITIONAL_ONLY' in repr(P.POSITIONAL_ONLY))
2968
2969 def test_signature_parameter_object(self):
2970 p = inspect.Parameter('foo', default=10,
2971 kind=inspect.Parameter.POSITIONAL_ONLY)
2972 self.assertEqual(p.name, 'foo')
2973 self.assertEqual(p.default, 10)
2974 self.assertIs(p.annotation, p.empty)
2975 self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY)
2976
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002977 with self.assertRaisesRegex(ValueError, 'invalid value'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002978 inspect.Parameter('foo', default=10, kind='123')
2979
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002980 with self.assertRaisesRegex(ValueError, 'not a valid parameter name'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002981 inspect.Parameter('1', kind=inspect.Parameter.VAR_KEYWORD)
2982
Yury Selivanov2393dca2014-01-27 15:07:58 -05002983 with self.assertRaisesRegex(TypeError, 'name must be a str'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002984 inspect.Parameter(None, kind=inspect.Parameter.VAR_KEYWORD)
2985
Yury Selivanov2393dca2014-01-27 15:07:58 -05002986 with self.assertRaisesRegex(ValueError,
2987 'is not a valid parameter name'):
2988 inspect.Parameter('$', kind=inspect.Parameter.VAR_KEYWORD)
2989
Nick Coghlanb4b966e2016-06-04 14:40:03 -07002990 with self.assertRaisesRegex(ValueError,
2991 'is not a valid parameter name'):
2992 inspect.Parameter('.a', kind=inspect.Parameter.VAR_KEYWORD)
2993
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002994 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002995 inspect.Parameter('a', default=42,
2996 kind=inspect.Parameter.VAR_KEYWORD)
2997
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002998 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002999 inspect.Parameter('a', default=42,
3000 kind=inspect.Parameter.VAR_POSITIONAL)
3001
3002 p = inspect.Parameter('a', default=42,
3003 kind=inspect.Parameter.POSITIONAL_OR_KEYWORD)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003004 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003005 p.replace(kind=inspect.Parameter.VAR_POSITIONAL)
3006
3007 self.assertTrue(repr(p).startswith('<Parameter'))
Yury Selivanov374375d2014-03-27 12:41:53 -04003008 self.assertTrue('"a=42"' in repr(p))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003009
Yury Selivanov67ae50e2014-04-08 11:46:50 -04003010 def test_signature_parameter_hashable(self):
3011 P = inspect.Parameter
3012 foo = P('foo', kind=P.POSITIONAL_ONLY)
3013 self.assertEqual(hash(foo), hash(P('foo', kind=P.POSITIONAL_ONLY)))
3014 self.assertNotEqual(hash(foo), hash(P('foo', kind=P.POSITIONAL_ONLY,
3015 default=42)))
3016 self.assertNotEqual(hash(foo),
3017 hash(foo.replace(kind=P.VAR_POSITIONAL)))
3018
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003019 def test_signature_parameter_equality(self):
3020 P = inspect.Parameter
3021 p = P('foo', default=42, kind=inspect.Parameter.KEYWORD_ONLY)
3022
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003023 self.assertTrue(p == p)
3024 self.assertFalse(p != p)
3025 self.assertFalse(p == 42)
3026 self.assertTrue(p != 42)
3027 self.assertTrue(p == EqualsToAll())
3028 self.assertFalse(p != EqualsToAll())
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003029
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003030 self.assertTrue(p == P('foo', default=42,
3031 kind=inspect.Parameter.KEYWORD_ONLY))
3032 self.assertFalse(p != P('foo', default=42,
3033 kind=inspect.Parameter.KEYWORD_ONLY))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003034
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003035 def test_signature_parameter_replace(self):
3036 p = inspect.Parameter('foo', default=42,
3037 kind=inspect.Parameter.KEYWORD_ONLY)
3038
3039 self.assertIsNot(p, p.replace())
3040 self.assertEqual(p, p.replace())
3041
3042 p2 = p.replace(annotation=1)
3043 self.assertEqual(p2.annotation, 1)
3044 p2 = p2.replace(annotation=p2.empty)
3045 self.assertEqual(p, p2)
3046
3047 p2 = p2.replace(name='bar')
3048 self.assertEqual(p2.name, 'bar')
3049 self.assertNotEqual(p2, p)
3050
Yury Selivanov2393dca2014-01-27 15:07:58 -05003051 with self.assertRaisesRegex(ValueError,
3052 'name is a required attribute'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003053 p2 = p2.replace(name=p2.empty)
3054
3055 p2 = p2.replace(name='foo', default=None)
3056 self.assertIs(p2.default, None)
3057 self.assertNotEqual(p2, p)
3058
3059 p2 = p2.replace(name='foo', default=p2.empty)
3060 self.assertIs(p2.default, p2.empty)
3061
3062
3063 p2 = p2.replace(default=42, kind=p2.POSITIONAL_OR_KEYWORD)
3064 self.assertEqual(p2.kind, p2.POSITIONAL_OR_KEYWORD)
3065 self.assertNotEqual(p2, p)
3066
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003067 with self.assertRaisesRegex(ValueError, 'invalid value for'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003068 p2 = p2.replace(kind=p2.empty)
3069
3070 p2 = p2.replace(kind=p2.KEYWORD_ONLY)
3071 self.assertEqual(p2, p)
3072
3073 def test_signature_parameter_positional_only(self):
Yury Selivanov2393dca2014-01-27 15:07:58 -05003074 with self.assertRaisesRegex(TypeError, 'name must be a str'):
3075 inspect.Parameter(None, kind=inspect.Parameter.POSITIONAL_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003076
Nick Coghlanb4b966e2016-06-04 14:40:03 -07003077 @cpython_only
3078 def test_signature_parameter_implicit(self):
3079 with self.assertRaisesRegex(ValueError,
3080 'implicit arguments must be passed in as'):
3081 inspect.Parameter('.0', kind=inspect.Parameter.POSITIONAL_ONLY)
3082
3083 param = inspect.Parameter(
3084 '.0', kind=inspect.Parameter.POSITIONAL_OR_KEYWORD)
3085 self.assertEqual(param.kind, inspect.Parameter.POSITIONAL_ONLY)
3086 self.assertEqual(param.name, 'implicit0')
3087
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003088 def test_signature_parameter_immutability(self):
Yury Selivanov2393dca2014-01-27 15:07:58 -05003089 p = inspect.Parameter('spam', kind=inspect.Parameter.KEYWORD_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003090
3091 with self.assertRaises(AttributeError):
3092 p.foo = 'bar'
3093
3094 with self.assertRaises(AttributeError):
3095 p.kind = 123
3096
3097
3098class TestSignatureBind(unittest.TestCase):
3099 @staticmethod
3100 def call(func, *args, **kwargs):
3101 sig = inspect.signature(func)
3102 ba = sig.bind(*args, **kwargs)
3103 return func(*ba.args, **ba.kwargs)
3104
3105 def test_signature_bind_empty(self):
3106 def test():
3107 return 42
3108
3109 self.assertEqual(self.call(test), 42)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003110 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003111 self.call(test, 1)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003112 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003113 self.call(test, 1, spam=10)
Yury Selivanov86872752015-05-19 00:27:49 -04003114 with self.assertRaisesRegex(
3115 TypeError, "got an unexpected keyword argument 'spam'"):
3116
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003117 self.call(test, spam=1)
3118
3119 def test_signature_bind_var(self):
3120 def test(*args, **kwargs):
3121 return args, kwargs
3122
3123 self.assertEqual(self.call(test), ((), {}))
3124 self.assertEqual(self.call(test, 1), ((1,), {}))
3125 self.assertEqual(self.call(test, 1, 2), ((1, 2), {}))
3126 self.assertEqual(self.call(test, foo='bar'), ((), {'foo': 'bar'}))
3127 self.assertEqual(self.call(test, 1, foo='bar'), ((1,), {'foo': 'bar'}))
3128 self.assertEqual(self.call(test, args=10), ((), {'args': 10}))
3129 self.assertEqual(self.call(test, 1, 2, foo='bar'),
3130 ((1, 2), {'foo': 'bar'}))
3131
3132 def test_signature_bind_just_args(self):
3133 def test(a, b, c):
3134 return a, b, c
3135
3136 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
3137
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003138 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003139 self.call(test, 1, 2, 3, 4)
3140
Yury Selivanov86872752015-05-19 00:27:49 -04003141 with self.assertRaisesRegex(TypeError,
3142 "missing a required argument: 'b'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003143 self.call(test, 1)
3144
Yury Selivanov86872752015-05-19 00:27:49 -04003145 with self.assertRaisesRegex(TypeError,
3146 "missing a required argument: 'a'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003147 self.call(test)
3148
3149 def test(a, b, c=10):
3150 return a, b, c
3151 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
3152 self.assertEqual(self.call(test, 1, 2), (1, 2, 10))
3153
3154 def test(a=1, b=2, c=3):
3155 return a, b, c
3156 self.assertEqual(self.call(test, a=10, c=13), (10, 2, 13))
3157 self.assertEqual(self.call(test, a=10), (10, 2, 3))
3158 self.assertEqual(self.call(test, b=10), (1, 10, 3))
3159
3160 def test_signature_bind_varargs_order(self):
3161 def test(*args):
3162 return args
3163
3164 self.assertEqual(self.call(test), ())
3165 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
3166
3167 def test_signature_bind_args_and_varargs(self):
3168 def test(a, b, c=3, *args):
3169 return a, b, c, args
3170
3171 self.assertEqual(self.call(test, 1, 2, 3, 4, 5), (1, 2, 3, (4, 5)))
3172 self.assertEqual(self.call(test, 1, 2), (1, 2, 3, ()))
3173 self.assertEqual(self.call(test, b=1, a=2), (2, 1, 3, ()))
3174 self.assertEqual(self.call(test, 1, b=2), (1, 2, 3, ()))
3175
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003176 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003177 "multiple values for argument 'c'"):
3178 self.call(test, 1, 2, 3, c=4)
3179
3180 def test_signature_bind_just_kwargs(self):
3181 def test(**kwargs):
3182 return kwargs
3183
3184 self.assertEqual(self.call(test), {})
3185 self.assertEqual(self.call(test, foo='bar', spam='ham'),
3186 {'foo': 'bar', 'spam': 'ham'})
3187
3188 def test_signature_bind_args_and_kwargs(self):
3189 def test(a, b, c=3, **kwargs):
3190 return a, b, c, kwargs
3191
3192 self.assertEqual(self.call(test, 1, 2), (1, 2, 3, {}))
3193 self.assertEqual(self.call(test, 1, 2, foo='bar', spam='ham'),
3194 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3195 self.assertEqual(self.call(test, b=2, a=1, foo='bar', spam='ham'),
3196 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3197 self.assertEqual(self.call(test, a=1, b=2, foo='bar', spam='ham'),
3198 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3199 self.assertEqual(self.call(test, 1, b=2, foo='bar', spam='ham'),
3200 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3201 self.assertEqual(self.call(test, 1, b=2, c=4, foo='bar', spam='ham'),
3202 (1, 2, 4, {'foo': 'bar', 'spam': 'ham'}))
3203 self.assertEqual(self.call(test, 1, 2, 4, foo='bar'),
3204 (1, 2, 4, {'foo': 'bar'}))
3205 self.assertEqual(self.call(test, c=5, a=4, b=3),
3206 (4, 3, 5, {}))
3207
3208 def test_signature_bind_kwonly(self):
3209 def test(*, foo):
3210 return foo
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003211 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003212 'too many positional arguments'):
3213 self.call(test, 1)
3214 self.assertEqual(self.call(test, foo=1), 1)
3215
3216 def test(a, *, foo=1, bar):
3217 return foo
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003218 with self.assertRaisesRegex(TypeError,
Yury Selivanov86872752015-05-19 00:27:49 -04003219 "missing a required argument: 'bar'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003220 self.call(test, 1)
3221
3222 def test(foo, *, bar):
3223 return foo, bar
3224 self.assertEqual(self.call(test, 1, bar=2), (1, 2))
3225 self.assertEqual(self.call(test, bar=2, foo=1), (1, 2))
3226
Yury Selivanov86872752015-05-19 00:27:49 -04003227 with self.assertRaisesRegex(
3228 TypeError, "got an unexpected keyword argument 'spam'"):
3229
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003230 self.call(test, bar=2, foo=1, spam=10)
3231
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003232 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003233 'too many positional arguments'):
3234 self.call(test, 1, 2)
3235
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003236 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003237 'too many positional arguments'):
3238 self.call(test, 1, 2, bar=2)
3239
Yury Selivanov86872752015-05-19 00:27:49 -04003240 with self.assertRaisesRegex(
3241 TypeError, "got an unexpected keyword argument 'spam'"):
3242
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003243 self.call(test, 1, bar=2, spam='ham')
3244
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003245 with self.assertRaisesRegex(TypeError,
Yury Selivanov86872752015-05-19 00:27:49 -04003246 "missing a required argument: 'bar'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003247 self.call(test, 1)
3248
3249 def test(foo, *, bar, **bin):
3250 return foo, bar, bin
3251 self.assertEqual(self.call(test, 1, bar=2), (1, 2, {}))
3252 self.assertEqual(self.call(test, foo=1, bar=2), (1, 2, {}))
3253 self.assertEqual(self.call(test, 1, bar=2, spam='ham'),
3254 (1, 2, {'spam': 'ham'}))
3255 self.assertEqual(self.call(test, spam='ham', foo=1, bar=2),
3256 (1, 2, {'spam': 'ham'}))
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003257 with self.assertRaisesRegex(TypeError,
Yury Selivanov86872752015-05-19 00:27:49 -04003258 "missing a required argument: 'foo'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003259 self.call(test, spam='ham', bar=2)
3260 self.assertEqual(self.call(test, 1, bar=2, bin=1, spam=10),
3261 (1, 2, {'bin': 1, 'spam': 10}))
3262
3263 def test_signature_bind_arguments(self):
3264 def test(a, *args, b, z=100, **kwargs):
3265 pass
3266 sig = inspect.signature(test)
3267 ba = sig.bind(10, 20, b=30, c=40, args=50, kwargs=60)
3268 # we won't have 'z' argument in the bound arguments object, as we didn't
3269 # pass it to the 'bind'
3270 self.assertEqual(tuple(ba.arguments.items()),
3271 (('a', 10), ('args', (20,)), ('b', 30),
3272 ('kwargs', {'c': 40, 'args': 50, 'kwargs': 60})))
3273 self.assertEqual(ba.kwargs,
3274 {'b': 30, 'c': 40, 'args': 50, 'kwargs': 60})
3275 self.assertEqual(ba.args, (10, 20))
3276
3277 def test_signature_bind_positional_only(self):
3278 P = inspect.Parameter
3279
3280 def test(a_po, b_po, c_po=3, foo=42, *, bar=50, **kwargs):
3281 return a_po, b_po, c_po, foo, bar, kwargs
3282
3283 sig = inspect.signature(test)
3284 new_params = collections.OrderedDict(tuple(sig.parameters.items()))
3285 for name in ('a_po', 'b_po', 'c_po'):
3286 new_params[name] = new_params[name].replace(kind=P.POSITIONAL_ONLY)
3287 new_sig = sig.replace(parameters=new_params.values())
3288 test.__signature__ = new_sig
3289
3290 self.assertEqual(self.call(test, 1, 2, 4, 5, bar=6),
3291 (1, 2, 4, 5, 6, {}))
3292
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05003293 self.assertEqual(self.call(test, 1, 2),
3294 (1, 2, 3, 42, 50, {}))
3295
3296 self.assertEqual(self.call(test, 1, 2, foo=4, bar=5),
3297 (1, 2, 3, 4, 5, {}))
3298
3299 with self.assertRaisesRegex(TypeError, "but was passed as a keyword"):
3300 self.call(test, 1, 2, foo=4, bar=5, c_po=10)
3301
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003302 with self.assertRaisesRegex(TypeError, "parameter is positional only"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003303 self.call(test, 1, 2, c_po=4)
3304
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003305 with self.assertRaisesRegex(TypeError, "parameter is positional only"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003306 self.call(test, a_po=1, b_po=2)
3307
Antoine Pitroubd41d1b2013-01-29 21:20:57 +01003308 def test_signature_bind_with_self_arg(self):
3309 # Issue #17071: one of the parameters is named "self
3310 def test(a, self, b):
3311 pass
3312 sig = inspect.signature(test)
3313 ba = sig.bind(1, 2, 3)
3314 self.assertEqual(ba.args, (1, 2, 3))
3315 ba = sig.bind(1, self=2, b=3)
3316 self.assertEqual(ba.args, (1, 2, 3))
3317
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05003318 def test_signature_bind_vararg_name(self):
3319 def test(a, *args):
3320 return a, args
3321 sig = inspect.signature(test)
3322
Yury Selivanov86872752015-05-19 00:27:49 -04003323 with self.assertRaisesRegex(
3324 TypeError, "got an unexpected keyword argument 'args'"):
3325
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05003326 sig.bind(a=0, args=1)
3327
3328 def test(*args, **kwargs):
3329 return args, kwargs
3330 self.assertEqual(self.call(test, args=1), ((), {'args': 1}))
3331
3332 sig = inspect.signature(test)
3333 ba = sig.bind(args=1)
3334 self.assertEqual(ba.arguments, {'kwargs': {'args': 1}})
3335
Nick Coghlanb4b966e2016-06-04 14:40:03 -07003336 @cpython_only
3337 def test_signature_bind_implicit_arg(self):
3338 # Issue #19611: getcallargs should work with set comprehensions
3339 def make_set():
3340 return {z * z for z in range(5)}
3341 setcomp_code = make_set.__code__.co_consts[1]
3342 setcomp_func = types.FunctionType(setcomp_code, {})
3343
3344 iterator = iter(range(5))
3345 self.assertEqual(self.call(setcomp_func, iterator), {0, 1, 4, 9, 16})
3346
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003347
3348class TestBoundArguments(unittest.TestCase):
3349 def test_signature_bound_arguments_unhashable(self):
3350 def foo(a): pass
3351 ba = inspect.signature(foo).bind(1)
3352
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003353 with self.assertRaisesRegex(TypeError, 'unhashable type'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003354 hash(ba)
3355
3356 def test_signature_bound_arguments_equality(self):
3357 def foo(a): pass
3358 ba = inspect.signature(foo).bind(1)
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003359 self.assertTrue(ba == ba)
3360 self.assertFalse(ba != ba)
3361 self.assertTrue(ba == EqualsToAll())
3362 self.assertFalse(ba != EqualsToAll())
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003363
3364 ba2 = inspect.signature(foo).bind(1)
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003365 self.assertTrue(ba == ba2)
3366 self.assertFalse(ba != ba2)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003367
3368 ba3 = inspect.signature(foo).bind(2)
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003369 self.assertFalse(ba == ba3)
3370 self.assertTrue(ba != ba3)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003371 ba3.arguments['a'] = 1
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003372 self.assertTrue(ba == ba3)
3373 self.assertFalse(ba != ba3)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003374
3375 def bar(b): pass
3376 ba4 = inspect.signature(bar).bind(1)
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003377 self.assertFalse(ba == ba4)
3378 self.assertTrue(ba != ba4)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003379
Yury Selivanov4cfd4ea2015-05-14 18:30:27 -04003380 def foo(*, a, b): pass
3381 sig = inspect.signature(foo)
3382 ba1 = sig.bind(a=1, b=2)
3383 ba2 = sig.bind(b=2, a=1)
Serhiy Storchaka2489bd52015-07-18 23:20:50 +03003384 self.assertTrue(ba1 == ba2)
3385 self.assertFalse(ba1 != ba2)
Yury Selivanov4cfd4ea2015-05-14 18:30:27 -04003386
Yury Selivanova5d63dd2014-03-27 11:31:43 -04003387 def test_signature_bound_arguments_pickle(self):
3388 def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
3389 sig = inspect.signature(foo)
3390 ba = sig.bind(20, 30, z={})
3391
3392 for ver in range(pickle.HIGHEST_PROTOCOL + 1):
3393 with self.subTest(pickle_ver=ver):
3394 ba_pickled = pickle.loads(pickle.dumps(ba, ver))
3395 self.assertEqual(ba, ba_pickled)
3396
Yury Selivanov3f6538f2015-05-14 18:47:17 -04003397 def test_signature_bound_arguments_repr(self):
3398 def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
3399 sig = inspect.signature(foo)
3400 ba = sig.bind(20, 30, z={})
Yury Selivanovf229bc52015-05-15 12:53:56 -04003401 self.assertRegex(repr(ba), r'<BoundArguments \(a=20,.*\}\}\)>')
Yury Selivanov3f6538f2015-05-14 18:47:17 -04003402
Yury Selivanovb907a512015-05-16 13:45:09 -04003403 def test_signature_bound_arguments_apply_defaults(self):
3404 def foo(a, b=1, *args, c:1={}, **kw): pass
3405 sig = inspect.signature(foo)
3406
3407 ba = sig.bind(20)
3408 ba.apply_defaults()
3409 self.assertEqual(
3410 list(ba.arguments.items()),
3411 [('a', 20), ('b', 1), ('args', ()), ('c', {}), ('kw', {})])
3412
3413 # Make sure that we preserve the order:
3414 # i.e. 'c' should be *before* 'kw'.
3415 ba = sig.bind(10, 20, 30, d=1)
3416 ba.apply_defaults()
3417 self.assertEqual(
3418 list(ba.arguments.items()),
3419 [('a', 10), ('b', 20), ('args', (30,)), ('c', {}), ('kw', {'d':1})])
3420
3421 # Make sure that BoundArguments produced by bind_partial()
3422 # are supported.
3423 def foo(a, b): pass
3424 sig = inspect.signature(foo)
3425 ba = sig.bind_partial(20)
3426 ba.apply_defaults()
3427 self.assertEqual(
3428 list(ba.arguments.items()),
3429 [('a', 20)])
3430
3431 # Test no args
3432 def foo(): pass
3433 sig = inspect.signature(foo)
3434 ba = sig.bind()
3435 ba.apply_defaults()
3436 self.assertEqual(list(ba.arguments.items()), [])
3437
Yury Selivanovf9e1f2b2016-03-02 11:07:47 -05003438 # Make sure a no-args binding still acquires proper defaults.
3439 def foo(a='spam'): pass
3440 sig = inspect.signature(foo)
3441 ba = sig.bind()
3442 ba.apply_defaults()
3443 self.assertEqual(list(ba.arguments.items()), [('a', 'spam')])
3444
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003445
Yury Selivanovd82eddc2014-01-29 11:24:39 -05003446class TestSignaturePrivateHelpers(unittest.TestCase):
3447 def test_signature_get_bound_param(self):
3448 getter = inspect._signature_get_bound_param
3449
3450 self.assertEqual(getter('($self)'), 'self')
3451 self.assertEqual(getter('($self, obj)'), 'self')
3452 self.assertEqual(getter('($cls, /, obj)'), 'cls')
3453
Larry Hastings2623c8c2014-02-08 22:15:29 -08003454 def _strip_non_python_syntax(self, input,
3455 clean_signature, self_parameter, last_positional_only):
3456 computed_clean_signature, \
3457 computed_self_parameter, \
3458 computed_last_positional_only = \
3459 inspect._signature_strip_non_python_syntax(input)
3460 self.assertEqual(computed_clean_signature, clean_signature)
3461 self.assertEqual(computed_self_parameter, self_parameter)
3462 self.assertEqual(computed_last_positional_only, last_positional_only)
3463
3464 def test_signature_strip_non_python_syntax(self):
3465 self._strip_non_python_syntax(
3466 "($module, /, path, mode, *, dir_fd=None, " +
3467 "effective_ids=False,\n follow_symlinks=True)",
3468 "(module, path, mode, *, dir_fd=None, " +
3469 "effective_ids=False, follow_symlinks=True)",
3470 0,
3471 0)
3472
3473 self._strip_non_python_syntax(
3474 "($module, word, salt, /)",
3475 "(module, word, salt)",
3476 0,
3477 2)
3478
3479 self._strip_non_python_syntax(
3480 "(x, y=None, z=None, /)",
3481 "(x, y=None, z=None)",
3482 None,
3483 2)
3484
3485 self._strip_non_python_syntax(
3486 "(x, y=None, z=None)",
3487 "(x, y=None, z=None)",
3488 None,
3489 None)
3490
3491 self._strip_non_python_syntax(
3492 "(x,\n y=None,\n z = None )",
3493 "(x, y=None, z=None)",
3494 None,
3495 None)
3496
3497 self._strip_non_python_syntax(
3498 "",
3499 "",
3500 None,
3501 None)
3502
3503 self._strip_non_python_syntax(
3504 None,
3505 None,
3506 None,
3507 None)
3508
Nick Coghlan9c680b02015-04-13 12:54:54 -04003509class TestSignatureDefinitions(unittest.TestCase):
3510 # This test case provides a home for checking that particular APIs
3511 # have signatures available for introspection
3512
3513 @cpython_only
3514 @unittest.skipIf(MISSING_C_DOCSTRINGS,
3515 "Signature information for builtins requires docstrings")
3516 def test_builtins_have_signatures(self):
3517 # This checks all builtin callables in CPython have signatures
3518 # A few have signatures Signature can't yet handle, so we skip those
3519 # since they will have to wait until PEP 457 adds the required
3520 # introspection support to the inspect module
3521 # Some others also haven't been converted yet for various other
3522 # reasons, so we also skip those for the time being, but design
3523 # the test to fail in order to indicate when it needs to be
3524 # updated.
3525 no_signature = set()
3526 # These need PEP 457 groups
3527 needs_groups = {"range", "slice", "dir", "getattr",
3528 "next", "iter", "vars"}
3529 no_signature |= needs_groups
3530 # These need PEP 457 groups or a signature change to accept None
3531 needs_semantic_update = {"round"}
3532 no_signature |= needs_semantic_update
3533 # These need *args support in Argument Clinic
Barry Warsaw36c1d1f2017-10-05 12:11:18 -04003534 needs_varargs = {"breakpoint", "min", "max", "print",
3535 "__build_class__"}
Nick Coghlan9c680b02015-04-13 12:54:54 -04003536 no_signature |= needs_varargs
3537 # These simply weren't covered in the initial AC conversion
3538 # for builtin callables
3539 not_converted_yet = {"open", "__import__"}
3540 no_signature |= not_converted_yet
3541 # These builtin types are expected to provide introspection info
3542 types_with_signatures = set()
3543 # Check the signatures we expect to be there
3544 ns = vars(builtins)
3545 for name, obj in sorted(ns.items()):
3546 if not callable(obj):
3547 continue
3548 # The builtin types haven't been converted to AC yet
3549 if isinstance(obj, type) and (name not in types_with_signatures):
3550 # Note that this also skips all the exception types
3551 no_signature.add(name)
3552 if (name in no_signature):
3553 # Not yet converted
3554 continue
3555 with self.subTest(builtin=name):
3556 self.assertIsNotNone(inspect.signature(obj))
3557 # Check callables that haven't been converted don't claim a signature
3558 # This ensures this test will start failing as more signatures are
3559 # added, so the affected items can be moved into the scope of the
3560 # regression test above
3561 for name in no_signature:
3562 with self.subTest(builtin=name):
3563 self.assertIsNone(obj.__text_signature__)
3564
Yury Selivanovd82eddc2014-01-29 11:24:39 -05003565
Thomas Kluyverf9169ce2017-05-23 04:27:52 +01003566class NTimesUnwrappable:
3567 def __init__(self, n):
3568 self.n = n
3569 self._next = None
3570
3571 @property
3572 def __wrapped__(self):
3573 if self.n <= 0:
3574 raise Exception("Unwrapped too many times")
3575 if self._next is None:
3576 self._next = NTimesUnwrappable(self.n - 1)
3577 return self._next
3578
Nick Coghlane8c45d62013-07-28 20:00:01 +10003579class TestUnwrap(unittest.TestCase):
3580
3581 def test_unwrap_one(self):
3582 def func(a, b):
3583 return a + b
3584 wrapper = functools.lru_cache(maxsize=20)(func)
3585 self.assertIs(inspect.unwrap(wrapper), func)
3586
3587 def test_unwrap_several(self):
3588 def func(a, b):
3589 return a + b
3590 wrapper = func
3591 for __ in range(10):
3592 @functools.wraps(wrapper)
3593 def wrapper():
3594 pass
3595 self.assertIsNot(wrapper.__wrapped__, func)
3596 self.assertIs(inspect.unwrap(wrapper), func)
3597
3598 def test_stop(self):
3599 def func1(a, b):
3600 return a + b
3601 @functools.wraps(func1)
3602 def func2():
3603 pass
3604 @functools.wraps(func2)
3605 def wrapper():
3606 pass
3607 func2.stop_here = 1
3608 unwrapped = inspect.unwrap(wrapper,
3609 stop=(lambda f: hasattr(f, "stop_here")))
3610 self.assertIs(unwrapped, func2)
3611
3612 def test_cycle(self):
3613 def func1(): pass
3614 func1.__wrapped__ = func1
3615 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3616 inspect.unwrap(func1)
3617
3618 def func2(): pass
3619 func2.__wrapped__ = func1
3620 func1.__wrapped__ = func2
3621 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3622 inspect.unwrap(func1)
3623 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3624 inspect.unwrap(func2)
3625
3626 def test_unhashable(self):
3627 def func(): pass
3628 func.__wrapped__ = None
3629 class C:
3630 __hash__ = None
3631 __wrapped__ = func
3632 self.assertIsNone(inspect.unwrap(C()))
3633
Thomas Kluyverf9169ce2017-05-23 04:27:52 +01003634 def test_recursion_limit(self):
3635 obj = NTimesUnwrappable(sys.getrecursionlimit() + 1)
3636 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3637 inspect.unwrap(obj)
3638
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003639class TestMain(unittest.TestCase):
3640 def test_only_source(self):
3641 module = importlib.import_module('unittest')
3642 rc, out, err = assert_python_ok('-m', 'inspect',
3643 'unittest')
3644 lines = out.decode().splitlines()
3645 # ignore the final newline
3646 self.assertEqual(lines[:-1], inspect.getsource(module).splitlines())
3647 self.assertEqual(err, b'')
3648
Yury Selivanov42407ab2014-06-23 10:23:50 -07003649 def test_custom_getattr(self):
3650 def foo():
3651 pass
3652 foo.__signature__ = 42
3653 with self.assertRaises(TypeError):
3654 inspect.signature(foo)
3655
Brett Cannon634a8fc2013-10-02 10:25:42 -04003656 @unittest.skipIf(ThreadPoolExecutor is None,
Brett Cannon0de3f012013-10-02 10:58:58 -04003657 'threads required to test __qualname__ for source files')
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003658 def test_qualname_source(self):
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003659 rc, out, err = assert_python_ok('-m', 'inspect',
3660 'concurrent.futures:ThreadPoolExecutor')
3661 lines = out.decode().splitlines()
3662 # ignore the final newline
3663 self.assertEqual(lines[:-1],
Brett Cannon634a8fc2013-10-02 10:25:42 -04003664 inspect.getsource(ThreadPoolExecutor).splitlines())
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003665 self.assertEqual(err, b'')
3666
3667 def test_builtins(self):
3668 module = importlib.import_module('unittest')
3669 _, out, err = assert_python_failure('-m', 'inspect',
3670 'sys')
3671 lines = err.decode().splitlines()
3672 self.assertEqual(lines, ["Can't get info for builtin modules."])
3673
3674 def test_details(self):
3675 module = importlib.import_module('unittest')
Victor Stinner9def2842016-01-18 12:15:08 +01003676 args = support.optim_args_from_interpreter_flags()
3677 rc, out, err = assert_python_ok(*args, '-m', 'inspect',
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003678 'unittest', '--details')
3679 output = out.decode()
3680 # Just a quick sanity check on the output
3681 self.assertIn(module.__name__, output)
3682 self.assertIn(module.__file__, output)
Victor Stinner9def2842016-01-18 12:15:08 +01003683 self.assertIn(module.__cached__, output)
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003684 self.assertEqual(err, b'')
3685
3686
Yury Selivanovef1e7502014-12-08 16:05:34 -05003687class TestReload(unittest.TestCase):
3688
3689 src_before = textwrap.dedent("""\
3690def foo():
3691 print("Bla")
3692 """)
3693
3694 src_after = textwrap.dedent("""\
3695def foo():
3696 print("Oh no!")
3697 """)
3698
3699 def assertInspectEqual(self, path, source):
3700 inspected_src = inspect.getsource(source)
3701 with open(path) as src:
3702 self.assertEqual(
3703 src.read().splitlines(True),
3704 inspected_src.splitlines(True)
3705 )
3706
3707 def test_getsource_reload(self):
3708 # see issue 1218234
3709 with _ready_to_import('reload_bug', self.src_before) as (name, path):
3710 module = importlib.import_module(name)
3711 self.assertInspectEqual(path, module)
3712 with open(path, 'w') as src:
3713 src.write(self.src_after)
3714 self.assertInspectEqual(path, module)
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003715
Nick Coghlane8c45d62013-07-28 20:00:01 +10003716
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00003717def test_main():
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00003718 run_unittest(
3719 TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBuggyCases,
3720 TestInterpreterStack, TestClassesAndFunctions, TestPredicates,
3721 TestGetcallargsFunctions, TestGetcallargsMethods,
Alexander Belopolskyf546e702010-12-02 00:10:11 +00003722 TestGetcallargsUnboundMethods, TestGetattrStatic, TestGetGeneratorState,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003723 TestNoEOL, TestSignatureObject, TestSignatureBind, TestParameterObject,
Nick Coghlan9c680b02015-04-13 12:54:54 -04003724 TestBoundArguments, TestSignaturePrivateHelpers,
3725 TestSignatureDefinitions,
Yury Selivanov5376ba92015-06-22 12:19:30 -04003726 TestGetClosureVars, TestUnwrap, TestMain, TestReload,
3727 TestGetCoroutineState
Michael Foord95fc51d2010-11-20 15:07:30 +00003728 )
Martin v. Löwis893ffa42003-10-31 15:35:53 +00003729
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00003730if __name__ == "__main__":
3731 test_main()