blob: 1a856f6387e8adaae67d166fb6fe0b9b71cc7eae [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
larryhastingsf36ba122018-01-28 11:13:09 -080060
61def signatures_with_lexicographic_keyword_only_parameters():
62 """
63 Yields a whole bunch of functions with only keyword-only parameters,
64 where those parameters are always in lexicographically sorted order.
65 """
66 parameters = ['a', 'bar', 'c', 'delta', 'ephraim', 'magical', 'yoyo', 'z']
67 for i in range(1, 2**len(parameters)):
68 p = []
69 bit = 1
70 for j in range(len(parameters)):
71 if i & (bit << j):
72 p.append(parameters[j])
73 fn_text = "def foo(*, " + ", ".join(p) + "): pass"
74 symbols = {}
75 exec(fn_text, symbols, symbols)
76 yield symbols['foo']
77
78
79def unsorted_keyword_only_parameters_fn(*, throw, out, the, baby, with_,
80 the_, bathwater):
81 pass
82
83unsorted_keyword_only_parameters = 'throw out the baby with_ the_ bathwater'.split()
84
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000085class IsTestBase(unittest.TestCase):
86 predicates = set([inspect.isbuiltin, inspect.isclass, inspect.iscode,
87 inspect.isframe, inspect.isfunction, inspect.ismethod,
Christian Heimes7131fd92008-02-19 14:21:46 +000088 inspect.ismodule, inspect.istraceback,
Yury Selivanov75445082015-05-11 22:57:16 -040089 inspect.isgenerator, inspect.isgeneratorfunction,
Yury Selivanoveb636452016-09-08 22:01:51 -070090 inspect.iscoroutine, inspect.iscoroutinefunction,
91 inspect.isasyncgen, inspect.isasyncgenfunction])
Tim Peters5a9fb3c2005-01-07 16:01:32 +000092
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000093 def istest(self, predicate, exp):
94 obj = eval(exp)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000095 self.assertTrue(predicate(obj), '%s(%s)' % (predicate.__name__, exp))
Tim Peters5a9fb3c2005-01-07 16:01:32 +000096
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000097 for other in self.predicates - set([predicate]):
Yury Selivanov75445082015-05-11 22:57:16 -040098 if (predicate == inspect.isgeneratorfunction or \
Yury Selivanoveb636452016-09-08 22:01:51 -070099 predicate == inspect.isasyncgenfunction or \
Yury Selivanov75445082015-05-11 22:57:16 -0400100 predicate == inspect.iscoroutinefunction) and \
Christian Heimes7131fd92008-02-19 14:21:46 +0000101 other == inspect.isfunction:
102 continue
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000103 self.assertFalse(other(obj), 'not %s(%s)' % (other.__name__, exp))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000104
Christian Heimes7131fd92008-02-19 14:21:46 +0000105def generator_function_example(self):
106 for i in range(2):
107 yield i
108
Yury Selivanoveb636452016-09-08 22:01:51 -0700109async def async_generator_function_example(self):
110 async for i in range(2):
111 yield i
112
Yury Selivanov75445082015-05-11 22:57:16 -0400113async def coroutine_function_example(self):
114 return 'spam'
115
116@types.coroutine
117def gen_coroutine_function_example(self):
118 yield
119 return 'spam'
120
Serhiy Storchaka3018cc42015-07-18 23:19:05 +0300121class EqualsToAll:
122 def __eq__(self, other):
123 return True
Yury Selivanova5d63dd2014-03-27 11:31:43 -0400124
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000125class TestPredicates(IsTestBase):
Christian Heimes7131fd92008-02-19 14:21:46 +0000126
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000127 def test_excluding_predicates(self):
Antoine Pitroud5a1a212012-06-17 23:18:07 +0200128 global tb
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000129 self.istest(inspect.isbuiltin, 'sys.exit')
130 self.istest(inspect.isbuiltin, '[].append')
Neal Norwitz221085d2007-02-25 20:55:47 +0000131 self.istest(inspect.iscode, 'mod.spam.__code__')
Antoine Pitroud5a1a212012-06-17 23:18:07 +0200132 try:
133 1/0
134 except:
135 tb = sys.exc_info()[2]
136 self.istest(inspect.isframe, 'tb.tb_frame')
137 self.istest(inspect.istraceback, 'tb')
138 if hasattr(types, 'GetSetDescriptorType'):
139 self.istest(inspect.isgetsetdescriptor,
140 'type(tb.tb_frame).f_locals')
141 else:
142 self.assertFalse(inspect.isgetsetdescriptor(type(tb.tb_frame).f_locals))
143 finally:
144 # Clear traceback and all the frames and local variables hanging to it.
145 tb = None
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000146 self.istest(inspect.isfunction, 'mod.spam')
Christian Heimes4a22b5d2007-11-25 09:39:14 +0000147 self.istest(inspect.isfunction, 'mod.StupidGit.abuse')
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000148 self.istest(inspect.ismethod, 'git.argue')
149 self.istest(inspect.ismodule, 'mod')
Guido van Rossum813b0e52007-05-21 18:11:34 +0000150 self.istest(inspect.isdatadescriptor, 'collections.defaultdict.default_factory')
Christian Heimes7131fd92008-02-19 14:21:46 +0000151 self.istest(inspect.isgenerator, '(x for x in range(2))')
152 self.istest(inspect.isgeneratorfunction, 'generator_function_example')
Yury Selivanoveb636452016-09-08 22:01:51 -0700153 self.istest(inspect.isasyncgen,
154 'async_generator_function_example(1)')
155 self.istest(inspect.isasyncgenfunction,
156 'async_generator_function_example')
Yury Selivanov75445082015-05-11 22:57:16 -0400157
158 with warnings.catch_warnings():
159 warnings.simplefilter("ignore")
160 self.istest(inspect.iscoroutine, 'coroutine_function_example(1)')
161 self.istest(inspect.iscoroutinefunction, 'coroutine_function_example')
162
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000163 if hasattr(types, 'MemberDescriptorType'):
164 self.istest(inspect.ismemberdescriptor, 'datetime.timedelta.days')
165 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000166 self.assertFalse(inspect.ismemberdescriptor(datetime.timedelta.days))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000167
Yury Selivanov75445082015-05-11 22:57:16 -0400168 def test_iscoroutine(self):
169 gen_coro = gen_coroutine_function_example(1)
170 coro = coroutine_function_example(1)
171
Yury Selivanov5376ba92015-06-22 12:19:30 -0400172 self.assertFalse(
Yury Selivanov75445082015-05-11 22:57:16 -0400173 inspect.iscoroutinefunction(gen_coroutine_function_example))
Yury Selivanov5376ba92015-06-22 12:19:30 -0400174 self.assertFalse(inspect.iscoroutine(gen_coro))
Yury Selivanov75445082015-05-11 22:57:16 -0400175
176 self.assertTrue(
177 inspect.isgeneratorfunction(gen_coroutine_function_example))
178 self.assertTrue(inspect.isgenerator(gen_coro))
179
180 self.assertTrue(
181 inspect.iscoroutinefunction(coroutine_function_example))
182 self.assertTrue(inspect.iscoroutine(coro))
183
184 self.assertFalse(
185 inspect.isgeneratorfunction(coroutine_function_example))
186 self.assertFalse(inspect.isgenerator(coro))
187
188 coro.close(); gen_coro.close() # silence warnings
189
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -0400190 def test_isawaitable(self):
191 def gen(): yield
192 self.assertFalse(inspect.isawaitable(gen()))
193
194 coro = coroutine_function_example(1)
195 gen_coro = gen_coroutine_function_example(1)
196
197 self.assertTrue(inspect.isawaitable(coro))
198 self.assertTrue(inspect.isawaitable(gen_coro))
199
200 class Future:
201 def __await__():
202 pass
203 self.assertTrue(inspect.isawaitable(Future()))
204 self.assertFalse(inspect.isawaitable(Future))
205
206 class NotFuture: pass
207 not_fut = NotFuture()
208 not_fut.__await__ = lambda: None
209 self.assertFalse(inspect.isawaitable(not_fut))
210
211 coro.close(); gen_coro.close() # silence warnings
212
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000213 def test_isroutine(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000214 self.assertTrue(inspect.isroutine(mod.spam))
215 self.assertTrue(inspect.isroutine([].count))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000216
Benjamin Petersonc4656002009-01-17 22:41:18 +0000217 def test_isclass(self):
218 self.istest(inspect.isclass, 'mod.StupidGit')
219 self.assertTrue(inspect.isclass(list))
220
221 class CustomGetattr(object):
222 def __getattr__(self, attr):
223 return None
224 self.assertFalse(inspect.isclass(CustomGetattr()))
225
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000226 def test_get_slot_members(self):
227 class C(object):
228 __slots__ = ("a", "b")
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000229 x = C()
230 x.a = 42
231 members = dict(inspect.getmembers(x))
Benjamin Peterson577473f2010-01-19 00:09:57 +0000232 self.assertIn('a', members)
233 self.assertNotIn('b', members)
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000234
Benjamin Petersona0dfa822009-11-13 02:25:08 +0000235 def test_isabstract(self):
236 from abc import ABCMeta, abstractmethod
237
238 class AbstractClassExample(metaclass=ABCMeta):
239
240 @abstractmethod
241 def foo(self):
242 pass
243
244 class ClassExample(AbstractClassExample):
245 def foo(self):
246 pass
247
248 a = ClassExample()
249
250 # Test general behaviour.
251 self.assertTrue(inspect.isabstract(AbstractClassExample))
252 self.assertFalse(inspect.isabstract(ClassExample))
253 self.assertFalse(inspect.isabstract(a))
254 self.assertFalse(inspect.isabstract(int))
255 self.assertFalse(inspect.isabstract(5))
256
Natefcfe80e2017-04-24 10:06:15 -0700257 def test_isabstract_during_init_subclass(self):
258 from abc import ABCMeta, abstractmethod
259 isabstract_checks = []
260 class AbstractChecker(metaclass=ABCMeta):
261 def __init_subclass__(cls):
262 isabstract_checks.append(inspect.isabstract(cls))
263 class AbstractClassExample(AbstractChecker):
264 @abstractmethod
265 def foo(self):
266 pass
267 class ClassExample(AbstractClassExample):
268 def foo(self):
269 pass
270 self.assertEqual(isabstract_checks, [True, False])
271
272 isabstract_checks.clear()
273 class AbstractChild(AbstractClassExample):
274 pass
275 class AbstractGrandchild(AbstractChild):
276 pass
277 class ConcreteGrandchild(ClassExample):
278 pass
279 self.assertEqual(isabstract_checks, [True, True, False])
280
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000281
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000282class TestInterpreterStack(IsTestBase):
283 def __init__(self, *args, **kwargs):
284 unittest.TestCase.__init__(self, *args, **kwargs)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000285
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000286 git.abuse(7, 8, 9)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000287
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000288 def test_abuse_done(self):
289 self.istest(inspect.istraceback, 'git.ex[2]')
290 self.istest(inspect.isframe, 'mod.fr')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000291
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000292 def test_stack(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000293 self.assertTrue(len(mod.st) >= 5)
Christian Heimesa3538eb2007-11-06 11:44:48 +0000294 self.assertEqual(revise(*mod.st[0][1:]),
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000295 (modfile, 16, 'eggs', [' st = inspect.stack()\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000296 self.assertEqual(revise(*mod.st[1][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000297 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000298 self.assertEqual(revise(*mod.st[2][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000299 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000300 self.assertEqual(revise(*mod.st[3][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000301 (modfile, 39, 'abuse', [' self.argue(a, b, c)\n'], 0))
Antoine Pitroucdcafb72014-08-24 10:50:28 -0400302 # Test named tuple fields
303 record = mod.st[0]
304 self.assertIs(record.frame, mod.fr)
305 self.assertEqual(record.lineno, 16)
306 self.assertEqual(record.filename, mod.__file__)
307 self.assertEqual(record.function, 'eggs')
308 self.assertIn('inspect.stack()', record.code_context[0])
309 self.assertEqual(record.index, 0)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000310
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000311 def test_trace(self):
312 self.assertEqual(len(git.tr), 3)
Florent Xiclunac8575922010-03-24 17:37:49 +0000313 self.assertEqual(revise(*git.tr[0][1:]),
314 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
315 self.assertEqual(revise(*git.tr[1][1:]),
316 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
317 self.assertEqual(revise(*git.tr[2][1:]),
318 (modfile, 18, 'eggs', [' q = y / 0\n'], 0))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000319
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000320 def test_frame(self):
321 args, varargs, varkw, locals = inspect.getargvalues(mod.fr)
322 self.assertEqual(args, ['x', 'y'])
323 self.assertEqual(varargs, None)
324 self.assertEqual(varkw, None)
325 self.assertEqual(locals, {'x': 11, 'p': 11, 'y': 14})
326 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
327 '(x=11, y=14)')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000328
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000329 def test_previous_frame(self):
330 args, varargs, varkw, locals = inspect.getargvalues(mod.fr.f_back)
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000331 self.assertEqual(args, ['a', 'b', 'c', 'd', 'e', 'f'])
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000332 self.assertEqual(varargs, 'g')
333 self.assertEqual(varkw, 'h')
334 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000335 '(a=7, b=8, c=9, d=3, e=4, f=5, *g=(), **h={})')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000336
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000337class GetSourceBase(unittest.TestCase):
338 # Subclasses must override.
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000339 fodderModule = None
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000340
Yury Selivanov6738b112015-05-16 10:10:21 -0400341 def setUp(self):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000342 with open(inspect.getsourcefile(self.fodderModule)) as fp:
Philip Jenveya27c5bd2009-05-28 06:09:08 +0000343 self.source = fp.read()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000344
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000345 def sourcerange(self, top, bottom):
346 lines = self.source.split("\n")
347 return "\n".join(lines[top-1:bottom]) + "\n"
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000348
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000349 def assertSourceEqual(self, obj, top, bottom):
350 self.assertEqual(inspect.getsource(obj),
351 self.sourcerange(top, bottom))
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000352
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000353class TestRetrievingSourceCode(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000354 fodderModule = mod
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000355
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000356 def test_getclasses(self):
357 classes = inspect.getmembers(mod, inspect.isclass)
358 self.assertEqual(classes,
359 [('FesteringGob', mod.FesteringGob),
360 ('MalodorousPervert', mod.MalodorousPervert),
361 ('ParrotDroppings', mod.ParrotDroppings),
Serhiy Storchaka362c1b52013-09-05 17:14:32 +0300362 ('StupidGit', mod.StupidGit),
363 ('Tit', mod.MalodorousPervert),
364 ])
365 tree = inspect.getclasstree([cls[1] for cls in classes])
366 self.assertEqual(tree,
367 [(object, ()),
368 [(mod.ParrotDroppings, (object,)),
369 [(mod.FesteringGob, (mod.MalodorousPervert,
370 mod.ParrotDroppings))
371 ],
372 (mod.StupidGit, (object,)),
373 [(mod.MalodorousPervert, (mod.StupidGit,)),
374 [(mod.FesteringGob, (mod.MalodorousPervert,
375 mod.ParrotDroppings))
376 ]
377 ]
378 ]
379 ])
380 tree = inspect.getclasstree([cls[1] for cls in classes], True)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000381 self.assertEqual(tree,
Thomas Wouters725af872006-04-15 09:13:19 +0000382 [(object, ()),
383 [(mod.ParrotDroppings, (object,)),
384 (mod.StupidGit, (object,)),
385 [(mod.MalodorousPervert, (mod.StupidGit,)),
386 [(mod.FesteringGob, (mod.MalodorousPervert,
387 mod.ParrotDroppings))
388 ]
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000389 ]
390 ]
391 ])
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000392
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000393 def test_getfunctions(self):
394 functions = inspect.getmembers(mod, inspect.isfunction)
395 self.assertEqual(functions, [('eggs', mod.eggs),
Yury Selivanove4e811d2015-07-21 19:01:52 +0300396 ('lobbest', mod.lobbest),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000397 ('spam', mod.spam)])
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000398
R. David Murray378c0cf2010-02-24 01:46:21 +0000399 @unittest.skipIf(sys.flags.optimize >= 2,
400 "Docstrings are omitted with -O2 and above")
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000401 def test_getdoc(self):
402 self.assertEqual(inspect.getdoc(mod), 'A module docstring.')
403 self.assertEqual(inspect.getdoc(mod.StupidGit),
404 'A longer,\n\nindented\n\ndocstring.')
405 self.assertEqual(inspect.getdoc(git.abuse),
406 'Another\n\ndocstring\n\ncontaining\n\ntabs')
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000407
Serhiy Storchaka5cf2b7252015-04-03 22:38:53 +0300408 @unittest.skipIf(sys.flags.optimize >= 2,
409 "Docstrings are omitted with -O2 and above")
410 def test_getdoc_inherited(self):
411 self.assertEqual(inspect.getdoc(mod.FesteringGob),
412 'A longer,\n\nindented\n\ndocstring.')
413 self.assertEqual(inspect.getdoc(mod.FesteringGob.abuse),
414 'Another\n\ndocstring\n\ncontaining\n\ntabs')
415 self.assertEqual(inspect.getdoc(mod.FesteringGob().abuse),
416 'Another\n\ndocstring\n\ncontaining\n\ntabs')
417 self.assertEqual(inspect.getdoc(mod.FesteringGob.contradiction),
418 'The automatic gainsaying.')
419
420 @unittest.skipIf(MISSING_C_DOCSTRINGS, "test requires docstrings")
421 def test_finddoc(self):
422 finddoc = inspect._finddoc
423 self.assertEqual(finddoc(int), int.__doc__)
424 self.assertEqual(finddoc(int.to_bytes), int.to_bytes.__doc__)
425 self.assertEqual(finddoc(int().to_bytes), int.to_bytes.__doc__)
426 self.assertEqual(finddoc(int.from_bytes), int.from_bytes.__doc__)
427 self.assertEqual(finddoc(int.real), int.real.__doc__)
428
Georg Brandl0c77a822008-06-10 16:37:50 +0000429 def test_cleandoc(self):
430 self.assertEqual(inspect.cleandoc('An\n indented\n docstring.'),
431 'An\nindented\ndocstring.')
432
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000433 def test_getcomments(self):
434 self.assertEqual(inspect.getcomments(mod), '# line 1\n')
435 self.assertEqual(inspect.getcomments(mod.StupidGit), '# line 20\n')
Marco Buttu3f2155f2017-03-17 09:50:23 +0100436 # If the object source file is not available, return None.
437 co = compile('x=1', '_non_existing_filename.py', 'exec')
438 self.assertIsNone(inspect.getcomments(co))
439 # If the object has been defined in C, return None.
440 self.assertIsNone(inspect.getcomments(list))
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000441
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000442 def test_getmodule(self):
Thomas Wouters89f507f2006-12-13 04:49:30 +0000443 # Check actual module
444 self.assertEqual(inspect.getmodule(mod), mod)
445 # Check class (uses __module__ attribute)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000446 self.assertEqual(inspect.getmodule(mod.StupidGit), mod)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000447 # Check a method (no __module__ attribute, falls back to filename)
448 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
449 # Do it again (check the caching isn't broken)
450 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
451 # Check a builtin
Georg Brandl1a3284e2007-12-02 09:40:06 +0000452 self.assertEqual(inspect.getmodule(str), sys.modules["builtins"])
Thomas Wouters89f507f2006-12-13 04:49:30 +0000453 # Check filename override
454 self.assertEqual(inspect.getmodule(None, modfile), mod)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000455
Berker Peksagff0e3b72017-01-02 06:57:43 +0300456 def test_getframeinfo_get_first_line(self):
457 frame_info = inspect.getframeinfo(self.fodderModule.fr, 50)
458 self.assertEqual(frame_info.code_context[0], "# line 1\n")
459 self.assertEqual(frame_info.code_context[1], "'A module docstring.'\n")
460
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000461 def test_getsource(self):
462 self.assertSourceEqual(git.abuse, 29, 39)
Serhiy Storchakaac4bdcc2015-10-29 08:15:50 +0200463 self.assertSourceEqual(mod.StupidGit, 21, 51)
464 self.assertSourceEqual(mod.lobbest, 75, 76)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000465
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000466 def test_getsourcefile(self):
Christian Heimesa3538eb2007-11-06 11:44:48 +0000467 self.assertEqual(normcase(inspect.getsourcefile(mod.spam)), modfile)
468 self.assertEqual(normcase(inspect.getsourcefile(git.abuse)), modfile)
R. David Murraya1b37402010-06-17 02:04:29 +0000469 fn = "_non_existing_filename_used_for_sourcefile_test.py"
Victor Stinner51d8c522016-02-08 17:57:02 +0100470 co = compile("x=1", fn, "exec")
R. David Murray4155f972010-06-17 13:23:18 +0000471 self.assertEqual(inspect.getsourcefile(co), None)
R. David Murraya1b37402010-06-17 02:04:29 +0000472 linecache.cache[co.co_filename] = (1, None, "None", co.co_filename)
Antoine Pitrou5d62a612012-07-08 13:48:46 +0200473 try:
474 self.assertEqual(normcase(inspect.getsourcefile(co)), fn)
475 finally:
476 del linecache.cache[co.co_filename]
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000477
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000478 def test_getfile(self):
479 self.assertEqual(inspect.getfile(mod.StupidGit), mod.__file__)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000480
Yury Selivanov2eed8b72014-01-27 13:24:56 -0500481 def test_getfile_class_without_module(self):
482 class CM(type):
483 @property
484 def __module__(cls):
485 raise AttributeError
486 class C(metaclass=CM):
487 pass
488 with self.assertRaises(TypeError):
489 inspect.getfile(C)
490
Thomas Kluyvere968bc732017-10-24 13:42:36 +0100491 def test_getfile_broken_repr(self):
492 class ErrorRepr:
493 def __repr__(self):
494 raise Exception('xyz')
495 er = ErrorRepr()
496 with self.assertRaises(TypeError):
497 inspect.getfile(er)
498
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000499 def test_getmodule_recursion(self):
Christian Heimes45f9af32007-11-27 21:50:00 +0000500 from types import ModuleType
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000501 name = '__inspect_dummy'
Christian Heimes45f9af32007-11-27 21:50:00 +0000502 m = sys.modules[name] = ModuleType(name)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000503 m.__file__ = "<string>" # hopefully not a real filename...
504 m.__loader__ = "dummy" # pretend the filename is understood by a loader
Georg Brandl7cae87c2006-09-06 06:51:57 +0000505 exec("def x(): pass", m.__dict__)
Neal Norwitz221085d2007-02-25 20:55:47 +0000506 self.assertEqual(inspect.getsourcefile(m.x.__code__), '<string>')
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000507 del sys.modules[name]
508 inspect.getmodule(compile('a=10','','single'))
509
Benjamin Peterson9620cc02011-06-11 15:53:11 -0500510 def test_proceed_with_fake_filename(self):
511 '''doctest monkeypatches linecache to enable inspection'''
512 fn, source = '<test>', 'def x(): pass\n'
513 getlines = linecache.getlines
514 def monkey(filename, module_globals=None):
515 if filename == fn:
Ezio Melottid8b509b2011-09-28 17:37:55 +0300516 return source.splitlines(keepends=True)
Benjamin Peterson9620cc02011-06-11 15:53:11 -0500517 else:
518 return getlines(filename, module_globals)
519 linecache.getlines = monkey
520 try:
521 ns = {}
522 exec(compile(source, fn, 'single'), ns)
523 inspect.getsource(ns["x"])
524 finally:
525 linecache.getlines = getlines
526
Antoine Pitroua8723a02015-04-15 00:41:29 +0200527 def test_getsource_on_code_object(self):
528 self.assertSourceEqual(mod.eggs.__code__, 12, 18)
529
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000530class TestDecorators(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000531 fodderModule = mod2
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000532
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000533 def test_wrapped_decorator(self):
Christian Heimes09aaa882008-02-23 15:01:06 +0000534 self.assertSourceEqual(mod2.wrapped, 14, 17)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000535
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000536 def test_replacing_decorator(self):
537 self.assertSourceEqual(mod2.gone, 9, 10)
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000538
Yury Selivanov081bbf62014-09-26 17:34:54 -0400539 def test_getsource_unwrap(self):
Antoine Pitroua8723a02015-04-15 00:41:29 +0200540 self.assertSourceEqual(mod2.real, 130, 132)
541
542 def test_decorator_with_lambda(self):
543 self.assertSourceEqual(mod2.func114, 113, 115)
Yury Selivanov081bbf62014-09-26 17:34:54 -0400544
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000545class TestOneliners(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000546 fodderModule = mod2
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000547 def test_oneline_lambda(self):
548 # Test inspect.getsource with a one-line lambda function.
549 self.assertSourceEqual(mod2.oll, 25, 25)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000550
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000551 def test_threeline_lambda(self):
552 # Test inspect.getsource with a three-line lambda function,
553 # where the second and third lines are _not_ indented.
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000554 self.assertSourceEqual(mod2.tll, 28, 30)
555
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000556 def test_twoline_indented_lambda(self):
557 # Test inspect.getsource with a two-line lambda function,
558 # where the second line _is_ indented.
559 self.assertSourceEqual(mod2.tlli, 33, 34)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000560
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000561 def test_onelinefunc(self):
562 # Test inspect.getsource with a regular one-line function.
563 self.assertSourceEqual(mod2.onelinefunc, 37, 37)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000564
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000565 def test_manyargs(self):
566 # Test inspect.getsource with a regular function where
567 # the arguments are on two lines and _not_ indented and
568 # the body on the second line with the last arguments.
569 self.assertSourceEqual(mod2.manyargs, 40, 41)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000570
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000571 def test_twolinefunc(self):
572 # Test inspect.getsource with a regular function where
573 # the body is on two lines, following the argument list and
574 # continued on the next line by a \\.
575 self.assertSourceEqual(mod2.twolinefunc, 44, 45)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000576
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000577 def test_lambda_in_list(self):
578 # Test inspect.getsource with a one-line lambda function
579 # defined in a list, indented.
580 self.assertSourceEqual(mod2.a[1], 49, 49)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000581
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000582 def test_anonymous(self):
583 # Test inspect.getsource with a lambda function defined
584 # as argument to another function.
585 self.assertSourceEqual(mod2.anonymous, 55, 55)
586
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000587class TestBuggyCases(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000588 fodderModule = mod2
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000589
590 def test_with_comment(self):
591 self.assertSourceEqual(mod2.with_comment, 58, 59)
592
593 def test_multiline_sig(self):
594 self.assertSourceEqual(mod2.multiline_sig[0], 63, 64)
595
Armin Rigodd5c0232005-09-25 11:45:45 +0000596 def test_nested_class(self):
597 self.assertSourceEqual(mod2.func69().func71, 71, 72)
598
599 def test_one_liner_followed_by_non_name(self):
600 self.assertSourceEqual(mod2.func77, 77, 77)
601
602 def test_one_liner_dedent_non_name(self):
603 self.assertSourceEqual(mod2.cls82.func83, 83, 83)
604
605 def test_with_comment_instead_of_docstring(self):
606 self.assertSourceEqual(mod2.func88, 88, 90)
607
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000608 def test_method_in_dynamic_class(self):
609 self.assertSourceEqual(mod2.method_in_dynamic_class, 95, 97)
610
R David Murray32562d72014-10-03 11:15:38 -0400611 # This should not skip for CPython, but might on a repackaged python where
612 # unicodedata is not an external module, or on pypy.
613 @unittest.skipIf(not hasattr(unicodedata, '__file__') or
614 unicodedata.__file__.endswith('.py'),
615 "unicodedata is not an external binary module")
R. David Murray74b89242009-05-13 17:33:03 +0000616 def test_findsource_binary(self):
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200617 self.assertRaises(OSError, inspect.getsource, unicodedata)
618 self.assertRaises(OSError, inspect.findsource, unicodedata)
R. David Murray74b89242009-05-13 17:33:03 +0000619
R. David Murraya1b37402010-06-17 02:04:29 +0000620 def test_findsource_code_in_linecache(self):
621 lines = ["x=1"]
622 co = compile(lines[0], "_dynamically_created_file", "exec")
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200623 self.assertRaises(OSError, inspect.findsource, co)
624 self.assertRaises(OSError, inspect.getsource, co)
R. David Murraya1b37402010-06-17 02:04:29 +0000625 linecache.cache[co.co_filename] = (1, None, lines, co.co_filename)
Antoine Pitrou5d62a612012-07-08 13:48:46 +0200626 try:
627 self.assertEqual(inspect.findsource(co), (lines,0))
628 self.assertEqual(inspect.getsource(co), lines[0])
629 finally:
630 del linecache.cache[co.co_filename]
R. David Murraya1b37402010-06-17 02:04:29 +0000631
Ezio Melotti1b145922013-03-30 05:17:24 +0200632 def test_findsource_without_filename(self):
633 for fname in ['', '<string>']:
634 co = compile('x=1', fname, "exec")
635 self.assertRaises(IOError, inspect.findsource, co)
636 self.assertRaises(IOError, inspect.getsource, co)
637
Antoine Pitroua8723a02015-04-15 00:41:29 +0200638 def test_getsource_on_method(self):
639 self.assertSourceEqual(mod2.ClassWithMethod.method, 118, 119)
640
Yury Selivanov4f4913b2015-07-23 17:10:00 +0300641 def test_nested_func(self):
642 self.assertSourceEqual(mod2.cls135.func136, 136, 139)
643
644
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000645class TestNoEOL(GetSourceBase):
Yury Selivanov6738b112015-05-16 10:10:21 -0400646 def setUp(self):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000647 self.tempdir = TESTFN + '_dir'
648 os.mkdir(self.tempdir)
649 with open(os.path.join(self.tempdir,
650 'inspect_fodder3%spy' % os.extsep), 'w') as f:
651 f.write("class X:\n pass # No EOL")
652 with DirsOnSysPath(self.tempdir):
653 import inspect_fodder3 as mod3
654 self.fodderModule = mod3
Yury Selivanov6738b112015-05-16 10:10:21 -0400655 super().setUp()
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000656
657 def tearDown(self):
658 shutil.rmtree(self.tempdir)
659
660 def test_class(self):
661 self.assertSourceEqual(self.fodderModule.X, 1, 2)
662
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100663
664class _BrokenDataDescriptor(object):
665 """
666 A broken data descriptor. See bug #1785.
667 """
668 def __get__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700669 raise AttributeError("broken data descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100670
671 def __set__(*args):
672 raise RuntimeError
673
674 def __getattr__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700675 raise AttributeError("broken data descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100676
677
678class _BrokenMethodDescriptor(object):
679 """
680 A broken method descriptor. See bug #1785.
681 """
682 def __get__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700683 raise AttributeError("broken method descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100684
685 def __getattr__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700686 raise AttributeError("broken method descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100687
688
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000689# Helper for testing classify_class_attrs.
Tim Peters13b49d32001-09-23 02:00:29 +0000690def attrs_wo_objs(cls):
691 return [t[:3] for t in inspect.classify_class_attrs(cls)]
692
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100693
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000694class TestClassesAndFunctions(unittest.TestCase):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000695 def test_newstyle_mro(self):
696 # The same w/ new-class MRO.
697 class A(object): pass
698 class B(A): pass
699 class C(A): pass
700 class D(B, C): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000701
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000702 expected = (D, B, C, A, object)
703 got = inspect.getmro(D)
704 self.assertEqual(expected, got)
Tim Peters13b49d32001-09-23 02:00:29 +0000705
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500706 def assertArgSpecEquals(self, routine, args_e, varargs_e=None,
707 varkw_e=None, defaults_e=None, formatted=None):
708 with self.assertWarns(DeprecationWarning):
709 args, varargs, varkw, defaults = inspect.getargspec(routine)
710 self.assertEqual(args, args_e)
711 self.assertEqual(varargs, varargs_e)
712 self.assertEqual(varkw, varkw_e)
713 self.assertEqual(defaults, defaults_e)
714 if formatted is not None:
715 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults),
716 formatted)
717
Christian Heimes3795b532007-11-08 13:48:53 +0000718 def assertFullArgSpecEquals(self, routine, args_e, varargs_e=None,
719 varkw_e=None, defaults_e=None,
720 kwonlyargs_e=[], kwonlydefaults_e=None,
721 ann_e={}, formatted=None):
722 args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \
723 inspect.getfullargspec(routine)
724 self.assertEqual(args, args_e)
725 self.assertEqual(varargs, varargs_e)
726 self.assertEqual(varkw, varkw_e)
727 self.assertEqual(defaults, defaults_e)
728 self.assertEqual(kwonlyargs, kwonlyargs_e)
729 self.assertEqual(kwonlydefaults, kwonlydefaults_e)
730 self.assertEqual(ann, ann_e)
731 if formatted is not None:
732 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults,
733 kwonlyargs, kwonlydefaults, ann),
734 formatted)
735
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500736 def test_getargspec(self):
737 self.assertArgSpecEquals(mod.eggs, ['x', 'y'], formatted='(x, y)')
738
739 self.assertArgSpecEquals(mod.spam,
740 ['a', 'b', 'c', 'd', 'e', 'f'],
741 'g', 'h', (3, 4, 5),
742 '(a, b, c, d=3, e=4, f=5, *g, **h)')
743
744 self.assertRaises(ValueError, self.assertArgSpecEquals,
745 mod2.keyworded, [])
746
747 self.assertRaises(ValueError, self.assertArgSpecEquals,
748 mod2.annotated, [])
749 self.assertRaises(ValueError, self.assertArgSpecEquals,
750 mod2.keyword_only_arg, [])
751
752
Christian Heimes3795b532007-11-08 13:48:53 +0000753 def test_getfullargspec(self):
754 self.assertFullArgSpecEquals(mod2.keyworded, [], varargs_e='arg1',
755 kwonlyargs_e=['arg2'],
756 kwonlydefaults_e={'arg2':1},
757 formatted='(*arg1, arg2=1)')
758
759 self.assertFullArgSpecEquals(mod2.annotated, ['arg1'],
Christian Heimesc9543e42007-11-28 08:28:28 +0000760 ann_e={'arg1' : list},
Christian Heimes3795b532007-11-08 13:48:53 +0000761 formatted='(arg1: list)')
Benjamin Peterson9953a8d2009-01-17 04:15:01 +0000762 self.assertFullArgSpecEquals(mod2.keyword_only_arg, [],
763 kwonlyargs_e=['arg'],
764 formatted='(*, arg)')
765
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500766 def test_argspec_api_ignores_wrapped(self):
Yury Selivanov57d240e2014-02-19 16:27:23 -0500767 # Issue 20684: low level introspection API must ignore __wrapped__
768 @functools.wraps(mod.spam)
769 def ham(x, y):
770 pass
771 # Basic check
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500772 self.assertArgSpecEquals(ham, ['x', 'y'], formatted='(x, y)')
Yury Selivanov57d240e2014-02-19 16:27:23 -0500773 self.assertFullArgSpecEquals(ham, ['x', 'y'], formatted='(x, y)')
774 self.assertFullArgSpecEquals(functools.partial(ham),
775 ['x', 'y'], formatted='(x, y)')
776 # Other variants
777 def check_method(f):
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500778 self.assertArgSpecEquals(f, ['self', 'x', 'y'],
779 formatted='(self, x, y)')
Yury Selivanov57d240e2014-02-19 16:27:23 -0500780 class C:
781 @functools.wraps(mod.spam)
782 def ham(self, x, y):
783 pass
784 pham = functools.partialmethod(ham)
785 @functools.wraps(mod.spam)
786 def __call__(self, x, y):
787 pass
788 check_method(C())
789 check_method(C.ham)
790 check_method(C().ham)
791 check_method(C.pham)
792 check_method(C().pham)
793
794 class C_new:
795 @functools.wraps(mod.spam)
796 def __new__(self, x, y):
797 pass
798 check_method(C_new)
799
800 class C_init:
801 @functools.wraps(mod.spam)
802 def __init__(self, x, y):
803 pass
804 check_method(C_init)
805
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500806 def test_getfullargspec_signature_attr(self):
807 def test():
808 pass
809 spam_param = inspect.Parameter('spam', inspect.Parameter.POSITIONAL_ONLY)
810 test.__signature__ = inspect.Signature(parameters=(spam_param,))
811
812 self.assertFullArgSpecEquals(test, args_e=['spam'], formatted='(spam)')
813
Yury Selivanov4cb93912014-01-29 11:54:12 -0500814 def test_getfullargspec_signature_annos(self):
815 def test(a:'spam') -> 'ham': pass
816 spec = inspect.getfullargspec(test)
817 self.assertEqual(test.__annotations__, spec.annotations)
818
819 def test(): pass
820 spec = inspect.getfullargspec(test)
821 self.assertEqual(test.__annotations__, spec.annotations)
822
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500823 @unittest.skipIf(MISSING_C_DOCSTRINGS,
824 "Signature information for builtins requires docstrings")
825 def test_getfullargspec_builtin_methods(self):
826 self.assertFullArgSpecEquals(_pickle.Pickler.dump,
827 args_e=['self', 'obj'], formatted='(self, obj)')
828
829 self.assertFullArgSpecEquals(_pickle.Pickler(io.BytesIO()).dump,
830 args_e=['self', 'obj'], formatted='(self, obj)')
831
Yury Selivanov8c185ee2014-02-21 01:32:42 -0500832 self.assertFullArgSpecEquals(
833 os.stat,
834 args_e=['path'],
835 kwonlyargs_e=['dir_fd', 'follow_symlinks'],
836 kwonlydefaults_e={'dir_fd': None, 'follow_symlinks': True},
837 formatted='(path, *, dir_fd=None, follow_symlinks=True)')
838
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200839 @cpython_only
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500840 @unittest.skipIf(MISSING_C_DOCSTRINGS,
841 "Signature information for builtins requires docstrings")
842 def test_getfullagrspec_builtin_func(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200843 import _testcapi
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500844 builtin = _testcapi.docstring_with_signature_with_defaults
845 spec = inspect.getfullargspec(builtin)
846 self.assertEqual(spec.defaults[0], 'avocado')
847
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200848 @cpython_only
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500849 @unittest.skipIf(MISSING_C_DOCSTRINGS,
850 "Signature information for builtins requires docstrings")
851 def test_getfullagrspec_builtin_func_no_signature(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200852 import _testcapi
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500853 builtin = _testcapi.docstring_no_signature
854 with self.assertRaises(TypeError):
855 inspect.getfullargspec(builtin)
Christian Heimes3795b532007-11-08 13:48:53 +0000856
larryhastingsf36ba122018-01-28 11:13:09 -0800857 def test_getfullargspec_definition_order_preserved_on_kwonly(self):
858 for fn in signatures_with_lexicographic_keyword_only_parameters():
859 signature = inspect.getfullargspec(fn)
860 l = list(signature.kwonlyargs)
861 sorted_l = sorted(l)
862 self.assertTrue(l)
863 self.assertEqual(l, sorted_l)
864 signature = inspect.getfullargspec(unsorted_keyword_only_parameters_fn)
865 l = list(signature.kwonlyargs)
866 self.assertEqual(l, unsorted_keyword_only_parameters)
867
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500868 def test_getargspec_method(self):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000869 class A(object):
870 def m(self):
871 pass
Yury Selivanov37dc2b22016-01-11 15:15:01 -0500872 self.assertArgSpecEquals(A.m, ['self'])
Tim Peters13b49d32001-09-23 02:00:29 +0000873
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000874 def test_classify_newstyle(self):
875 class A(object):
Tim Peters13b49d32001-09-23 02:00:29 +0000876
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000877 def s(): pass
878 s = staticmethod(s)
Tim Peters13b49d32001-09-23 02:00:29 +0000879
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000880 def c(cls): pass
881 c = classmethod(c)
Tim Peters13b49d32001-09-23 02:00:29 +0000882
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000883 def getp(self): pass
884 p = property(getp)
Tim Peters13b49d32001-09-23 02:00:29 +0000885
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000886 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000887
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000888 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000889
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000890 datablob = '1'
Tim Peters13b49d32001-09-23 02:00:29 +0000891
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100892 dd = _BrokenDataDescriptor()
893 md = _BrokenMethodDescriptor()
894
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000895 attrs = attrs_wo_objs(A)
Yury Selivanov0860a0b2014-01-31 14:28:44 -0500896
Serhiy Storchaka3327a2d2017-12-15 14:13:41 +0200897 self.assertIn(('__new__', 'static method', object), attrs,
898 'missing __new__')
Yury Selivanov0860a0b2014-01-31 14:28:44 -0500899 self.assertIn(('__init__', 'method', object), attrs, 'missing __init__')
900
Benjamin Peterson577473f2010-01-19 00:09:57 +0000901 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
902 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
903 self.assertIn(('p', 'property', A), attrs, 'missing property')
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000904 self.assertIn(('m', 'method', A), attrs,
905 'missing plain method: %r' % attrs)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000906 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
907 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100908 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
909 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000910
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000911 class B(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000912
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000913 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000914
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000915 attrs = attrs_wo_objs(B)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000916 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
917 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
918 self.assertIn(('p', 'property', A), attrs, 'missing property')
919 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
920 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
921 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100922 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
923 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000924
925
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000926 class C(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000927
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000928 def m(self): pass
929 def c(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000930
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000931 attrs = attrs_wo_objs(C)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000932 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
933 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
934 self.assertIn(('p', 'property', A), attrs, 'missing property')
935 self.assertIn(('m', 'method', C), attrs, 'missing plain method')
936 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
937 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100938 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
939 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000940
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000941 class D(B, C):
Tim Peters13b49d32001-09-23 02:00:29 +0000942
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000943 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000944
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000945 attrs = attrs_wo_objs(D)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000946 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
947 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
948 self.assertIn(('p', 'property', A), attrs, 'missing property')
949 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
950 self.assertIn(('m1', 'method', D), attrs, 'missing plain method')
951 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100952 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
953 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
954
955 def test_classify_builtin_types(self):
956 # Simple sanity check that all built-in types can have their
957 # attributes classified.
958 for name in dir(__builtins__):
959 builtin = getattr(__builtins__, name)
960 if isinstance(builtin, type):
961 inspect.classify_class_attrs(builtin)
962
Serhiy Storchaka3327a2d2017-12-15 14:13:41 +0200963 attrs = attrs_wo_objs(bool)
964 self.assertIn(('__new__', 'static method', bool), attrs,
965 'missing __new__')
966 self.assertIn(('from_bytes', 'class method', int), attrs,
967 'missing class method')
968 self.assertIn(('to_bytes', 'method', int), attrs,
969 'missing plain method')
970 self.assertIn(('__add__', 'method', int), attrs,
971 'missing plain method')
972 self.assertIn(('__and__', 'method', bool), attrs,
973 'missing plain method')
974
Ethan Furman63c141c2013-10-18 00:27:39 -0700975 def test_classify_DynamicClassAttribute(self):
976 class Meta(type):
977 def __getattr__(self, name):
978 if name == 'ham':
979 return 'spam'
980 return super().__getattr__(name)
981 class VA(metaclass=Meta):
Ethan Furmane03ea372013-09-25 07:14:41 -0700982 @types.DynamicClassAttribute
983 def ham(self):
984 return 'eggs'
Ethan Furman63c141c2013-10-18 00:27:39 -0700985 should_find_dca = inspect.Attribute('ham', 'data', VA, VA.__dict__['ham'])
986 self.assertIn(should_find_dca, inspect.classify_class_attrs(VA))
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700987 should_find_ga = inspect.Attribute('ham', 'data', Meta, 'spam')
Ethan Furman63c141c2013-10-18 00:27:39 -0700988 self.assertIn(should_find_ga, inspect.classify_class_attrs(VA))
989
Yury Selivanovbf341fb2015-05-21 15:41:57 -0400990 def test_classify_overrides_bool(self):
991 class NoBool(object):
992 def __eq__(self, other):
993 return NoBool()
994
995 def __bool__(self):
996 raise NotImplementedError(
997 "This object does not specify a boolean value")
998
999 class HasNB(object):
1000 dd = NoBool()
1001
1002 should_find_attr = inspect.Attribute('dd', 'data', HasNB, HasNB.dd)
1003 self.assertIn(should_find_attr, inspect.classify_class_attrs(HasNB))
1004
Ethan Furmanb0c84cd2013-10-20 22:37:39 -07001005 def test_classify_metaclass_class_attribute(self):
1006 class Meta(type):
1007 fish = 'slap'
1008 def __dir__(self):
Serhiy Storchakaa60c2fe2015-03-12 21:56:08 +02001009 return ['__class__', '__module__', '__name__', 'fish']
Ethan Furmanb0c84cd2013-10-20 22:37:39 -07001010 class Class(metaclass=Meta):
1011 pass
1012 should_find = inspect.Attribute('fish', 'data', Meta, 'slap')
1013 self.assertIn(should_find, inspect.classify_class_attrs(Class))
1014
Ethan Furman63c141c2013-10-18 00:27:39 -07001015 def test_classify_VirtualAttribute(self):
1016 class Meta(type):
1017 def __dir__(cls):
1018 return ['__class__', '__module__', '__name__', 'BOOM']
1019 def __getattr__(self, name):
1020 if name =='BOOM':
1021 return 42
1022 return super().__getattr(name)
1023 class Class(metaclass=Meta):
1024 pass
Ethan Furmanb0c84cd2013-10-20 22:37:39 -07001025 should_find = inspect.Attribute('BOOM', 'data', Meta, 42)
Ethan Furman63c141c2013-10-18 00:27:39 -07001026 self.assertIn(should_find, inspect.classify_class_attrs(Class))
1027
1028 def test_classify_VirtualAttribute_multi_classes(self):
1029 class Meta1(type):
1030 def __dir__(cls):
1031 return ['__class__', '__module__', '__name__', 'one']
1032 def __getattr__(self, name):
1033 if name =='one':
1034 return 1
1035 return super().__getattr__(name)
1036 class Meta2(type):
1037 def __dir__(cls):
1038 return ['__class__', '__module__', '__name__', 'two']
1039 def __getattr__(self, name):
1040 if name =='two':
1041 return 2
1042 return super().__getattr__(name)
1043 class Meta3(Meta1, Meta2):
1044 def __dir__(cls):
1045 return list(sorted(set(['__class__', '__module__', '__name__', 'three'] +
1046 Meta1.__dir__(cls) + Meta2.__dir__(cls))))
1047 def __getattr__(self, name):
1048 if name =='three':
1049 return 3
1050 return super().__getattr__(name)
1051 class Class1(metaclass=Meta1):
1052 pass
1053 class Class2(Class1, metaclass=Meta3):
1054 pass
1055
Ethan Furmanb0c84cd2013-10-20 22:37:39 -07001056 should_find1 = inspect.Attribute('one', 'data', Meta1, 1)
1057 should_find2 = inspect.Attribute('two', 'data', Meta2, 2)
1058 should_find3 = inspect.Attribute('three', 'data', Meta3, 3)
Ethan Furman63c141c2013-10-18 00:27:39 -07001059 cca = inspect.classify_class_attrs(Class2)
1060 for sf in (should_find1, should_find2, should_find3):
1061 self.assertIn(sf, cca)
1062
1063 def test_classify_class_attrs_with_buggy_dir(self):
1064 class M(type):
1065 def __dir__(cls):
1066 return ['__class__', '__name__', 'missing']
1067 class C(metaclass=M):
1068 pass
1069 attrs = [a[0] for a in inspect.classify_class_attrs(C)]
1070 self.assertNotIn('missing', attrs)
Ethan Furmane03ea372013-09-25 07:14:41 -07001071
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +01001072 def test_getmembers_descriptors(self):
1073 class A(object):
1074 dd = _BrokenDataDescriptor()
1075 md = _BrokenMethodDescriptor()
1076
1077 def pred_wrapper(pred):
1078 # A quick'n'dirty way to discard standard attributes of new-style
1079 # classes.
1080 class Empty(object):
1081 pass
1082 def wrapped(x):
1083 if '__name__' in dir(x) and hasattr(Empty, x.__name__):
1084 return False
1085 return pred(x)
1086 return wrapped
1087
1088 ismethoddescriptor = pred_wrapper(inspect.ismethoddescriptor)
1089 isdatadescriptor = pred_wrapper(inspect.isdatadescriptor)
1090
1091 self.assertEqual(inspect.getmembers(A, ismethoddescriptor),
1092 [('md', A.__dict__['md'])])
1093 self.assertEqual(inspect.getmembers(A, isdatadescriptor),
1094 [('dd', A.__dict__['dd'])])
1095
1096 class B(A):
1097 pass
1098
1099 self.assertEqual(inspect.getmembers(B, ismethoddescriptor),
1100 [('md', A.__dict__['md'])])
1101 self.assertEqual(inspect.getmembers(B, isdatadescriptor),
1102 [('dd', A.__dict__['dd'])])
1103
Antoine Pitrou0c603812012-01-18 17:40:18 +01001104 def test_getmembers_method(self):
1105 class B:
1106 def f(self):
1107 pass
1108
1109 self.assertIn(('f', B.f), inspect.getmembers(B))
1110 self.assertNotIn(('f', B.f), inspect.getmembers(B, inspect.ismethod))
1111 b = B()
1112 self.assertIn(('f', b.f), inspect.getmembers(b))
1113 self.assertIn(('f', b.f), inspect.getmembers(b, inspect.ismethod))
1114
Ethan Furmane03ea372013-09-25 07:14:41 -07001115 def test_getmembers_VirtualAttribute(self):
Ethan Furman63c141c2013-10-18 00:27:39 -07001116 class M(type):
1117 def __getattr__(cls, name):
1118 if name == 'eggs':
1119 return 'scrambled'
1120 return super().__getattr__(name)
1121 class A(metaclass=M):
Ethan Furmane03ea372013-09-25 07:14:41 -07001122 @types.DynamicClassAttribute
1123 def eggs(self):
1124 return 'spam'
Ethan Furman63c141c2013-10-18 00:27:39 -07001125 self.assertIn(('eggs', 'scrambled'), inspect.getmembers(A))
1126 self.assertIn(('eggs', 'spam'), inspect.getmembers(A()))
1127
1128 def test_getmembers_with_buggy_dir(self):
1129 class M(type):
1130 def __dir__(cls):
1131 return ['__class__', '__name__', 'missing']
1132 class C(metaclass=M):
1133 pass
1134 attrs = [a[0] for a in inspect.getmembers(C)]
1135 self.assertNotIn('missing', attrs)
Ethan Furmane03ea372013-09-25 07:14:41 -07001136
Jeremy Hyltonc4bf5ed2003-06-27 18:43:12 +00001137
Nick Coghlan2f92e542012-06-23 19:39:55 +10001138_global_ref = object()
1139class TestGetClosureVars(unittest.TestCase):
1140
1141 def test_name_resolution(self):
1142 # Basic test of the 4 different resolution mechanisms
1143 def f(nonlocal_ref):
1144 def g(local_ref):
1145 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
1146 return g
1147 _arg = object()
1148 nonlocal_vars = {"nonlocal_ref": _arg}
1149 global_vars = {"_global_ref": _global_ref}
1150 builtin_vars = {"print": print}
1151 unbound_names = {"unbound_ref"}
1152 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
1153 builtin_vars, unbound_names)
1154 self.assertEqual(inspect.getclosurevars(f(_arg)), expected)
1155
1156 def test_generator_closure(self):
1157 def f(nonlocal_ref):
1158 def g(local_ref):
1159 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
1160 yield
1161 return g
1162 _arg = object()
1163 nonlocal_vars = {"nonlocal_ref": _arg}
1164 global_vars = {"_global_ref": _global_ref}
1165 builtin_vars = {"print": print}
1166 unbound_names = {"unbound_ref"}
1167 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
1168 builtin_vars, unbound_names)
1169 self.assertEqual(inspect.getclosurevars(f(_arg)), expected)
1170
1171 def test_method_closure(self):
1172 class C:
1173 def f(self, nonlocal_ref):
1174 def g(local_ref):
1175 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
1176 return g
1177 _arg = object()
1178 nonlocal_vars = {"nonlocal_ref": _arg}
1179 global_vars = {"_global_ref": _global_ref}
1180 builtin_vars = {"print": print}
1181 unbound_names = {"unbound_ref"}
1182 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
1183 builtin_vars, unbound_names)
1184 self.assertEqual(inspect.getclosurevars(C().f(_arg)), expected)
1185
1186 def test_nonlocal_vars(self):
1187 # More complex tests of nonlocal resolution
1188 def _nonlocal_vars(f):
1189 return inspect.getclosurevars(f).nonlocals
1190
1191 def make_adder(x):
1192 def add(y):
1193 return x + y
1194 return add
1195
1196 def curry(func, arg1):
1197 return lambda arg2: func(arg1, arg2)
1198
1199 def less_than(a, b):
1200 return a < b
1201
1202 # The infamous Y combinator.
1203 def Y(le):
1204 def g(f):
1205 return le(lambda x: f(f)(x))
1206 Y.g_ref = g
1207 return g(g)
1208
1209 def check_y_combinator(func):
1210 self.assertEqual(_nonlocal_vars(func), {'f': Y.g_ref})
1211
1212 inc = make_adder(1)
1213 add_two = make_adder(2)
1214 greater_than_five = curry(less_than, 5)
1215
1216 self.assertEqual(_nonlocal_vars(inc), {'x': 1})
1217 self.assertEqual(_nonlocal_vars(add_two), {'x': 2})
1218 self.assertEqual(_nonlocal_vars(greater_than_five),
1219 {'arg1': 5, 'func': less_than})
1220 self.assertEqual(_nonlocal_vars((lambda x: lambda y: x + y)(3)),
1221 {'x': 3})
1222 Y(check_y_combinator)
1223
1224 def test_getclosurevars_empty(self):
1225 def foo(): pass
1226 _empty = inspect.ClosureVars({}, {}, {}, set())
1227 self.assertEqual(inspect.getclosurevars(lambda: True), _empty)
1228 self.assertEqual(inspect.getclosurevars(foo), _empty)
1229
1230 def test_getclosurevars_error(self):
1231 class T: pass
1232 self.assertRaises(TypeError, inspect.getclosurevars, 1)
1233 self.assertRaises(TypeError, inspect.getclosurevars, list)
1234 self.assertRaises(TypeError, inspect.getclosurevars, {})
1235
Nick Coghlan6c6e2542012-06-23 20:07:39 +10001236 def _private_globals(self):
1237 code = """def f(): print(path)"""
1238 ns = {}
1239 exec(code, ns)
1240 return ns["f"], ns
1241
1242 def test_builtins_fallback(self):
1243 f, ns = self._private_globals()
1244 ns.pop("__builtins__", None)
1245 expected = inspect.ClosureVars({}, {}, {"print":print}, {"path"})
1246 self.assertEqual(inspect.getclosurevars(f), expected)
1247
1248 def test_builtins_as_dict(self):
1249 f, ns = self._private_globals()
1250 ns["__builtins__"] = {"path":1}
1251 expected = inspect.ClosureVars({}, {}, {"path":1}, {"print"})
1252 self.assertEqual(inspect.getclosurevars(f), expected)
1253
1254 def test_builtins_as_module(self):
1255 f, ns = self._private_globals()
1256 ns["__builtins__"] = os
1257 expected = inspect.ClosureVars({}, {}, {"path":os.path}, {"print"})
1258 self.assertEqual(inspect.getclosurevars(f), expected)
1259
Nick Coghlan2f92e542012-06-23 19:39:55 +10001260
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001261class TestGetcallargsFunctions(unittest.TestCase):
1262
1263 def assertEqualCallArgs(self, func, call_params_string, locs=None):
1264 locs = dict(locs or {}, func=func)
1265 r1 = eval('func(%s)' % call_params_string, None, locs)
1266 r2 = eval('inspect.getcallargs(func, %s)' % call_params_string, None,
1267 locs)
1268 self.assertEqual(r1, r2)
1269
1270 def assertEqualException(self, func, call_param_string, locs=None):
1271 locs = dict(locs or {}, func=func)
1272 try:
1273 eval('func(%s)' % call_param_string, None, locs)
1274 except Exception as e:
1275 ex1 = e
1276 else:
1277 self.fail('Exception not raised')
1278 try:
1279 eval('inspect.getcallargs(func, %s)' % call_param_string, None,
1280 locs)
1281 except Exception as e:
1282 ex2 = e
1283 else:
1284 self.fail('Exception not raised')
1285 self.assertIs(type(ex1), type(ex2))
1286 self.assertEqual(str(ex1), str(ex2))
1287 del ex1, ex2
1288
1289 def makeCallable(self, signature):
1290 """Create a function that returns its locals()"""
1291 code = "lambda %s: locals()"
1292 return eval(code % signature)
1293
1294 def test_plain(self):
1295 f = self.makeCallable('a, b=1')
1296 self.assertEqualCallArgs(f, '2')
1297 self.assertEqualCallArgs(f, '2, 3')
1298 self.assertEqualCallArgs(f, 'a=2')
1299 self.assertEqualCallArgs(f, 'b=3, a=2')
1300 self.assertEqualCallArgs(f, '2, b=3')
1301 # expand *iterable / **mapping
1302 self.assertEqualCallArgs(f, '*(2,)')
1303 self.assertEqualCallArgs(f, '*[2]')
1304 self.assertEqualCallArgs(f, '*(2, 3)')
1305 self.assertEqualCallArgs(f, '*[2, 3]')
1306 self.assertEqualCallArgs(f, '**{"a":2}')
1307 self.assertEqualCallArgs(f, 'b=3, **{"a":2}')
1308 self.assertEqualCallArgs(f, '2, **{"b":3}')
1309 self.assertEqualCallArgs(f, '**{"b":3, "a":2}')
1310 # expand UserList / UserDict
1311 self.assertEqualCallArgs(f, '*collections.UserList([2])')
1312 self.assertEqualCallArgs(f, '*collections.UserList([2, 3])')
1313 self.assertEqualCallArgs(f, '**collections.UserDict(a=2)')
1314 self.assertEqualCallArgs(f, '2, **collections.UserDict(b=3)')
1315 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3)')
1316
1317 def test_varargs(self):
1318 f = self.makeCallable('a, b=1, *c')
1319 self.assertEqualCallArgs(f, '2')
1320 self.assertEqualCallArgs(f, '2, 3')
1321 self.assertEqualCallArgs(f, '2, 3, 4')
1322 self.assertEqualCallArgs(f, '*(2,3,4)')
1323 self.assertEqualCallArgs(f, '2, *[3,4]')
1324 self.assertEqualCallArgs(f, '2, 3, *collections.UserList([4])')
1325
1326 def test_varkw(self):
1327 f = self.makeCallable('a, b=1, **c')
1328 self.assertEqualCallArgs(f, 'a=2')
1329 self.assertEqualCallArgs(f, '2, b=3, c=4')
1330 self.assertEqualCallArgs(f, 'b=3, a=2, c=4')
1331 self.assertEqualCallArgs(f, 'c=4, **{"a":2, "b":3}')
1332 self.assertEqualCallArgs(f, '2, c=4, **{"b":3}')
1333 self.assertEqualCallArgs(f, 'b=2, **{"a":3, "c":4}')
1334 self.assertEqualCallArgs(f, '**collections.UserDict(a=2, b=3, c=4)')
1335 self.assertEqualCallArgs(f, '2, c=4, **collections.UserDict(b=3)')
1336 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3, c=4)')
1337
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001338 def test_varkw_only(self):
1339 # issue11256:
1340 f = self.makeCallable('**c')
1341 self.assertEqualCallArgs(f, '')
1342 self.assertEqualCallArgs(f, 'a=1')
1343 self.assertEqualCallArgs(f, 'a=1, b=2')
1344 self.assertEqualCallArgs(f, 'c=3, **{"a": 1, "b": 2}')
1345 self.assertEqualCallArgs(f, '**collections.UserDict(a=1, b=2)')
1346 self.assertEqualCallArgs(f, 'c=3, **collections.UserDict(a=1, b=2)')
1347
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001348 def test_keyword_only(self):
1349 f = self.makeCallable('a=3, *, c, d=2')
1350 self.assertEqualCallArgs(f, 'c=3')
1351 self.assertEqualCallArgs(f, 'c=3, a=3')
1352 self.assertEqualCallArgs(f, 'a=2, c=4')
1353 self.assertEqualCallArgs(f, '4, c=4')
1354 self.assertEqualException(f, '')
1355 self.assertEqualException(f, '3')
1356 self.assertEqualException(f, 'a=3')
1357 self.assertEqualException(f, 'd=4')
1358
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001359 f = self.makeCallable('*, c, d=2')
1360 self.assertEqualCallArgs(f, 'c=3')
1361 self.assertEqualCallArgs(f, 'c=3, d=4')
1362 self.assertEqualCallArgs(f, 'd=4, c=3')
1363
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001364 def test_multiple_features(self):
1365 f = self.makeCallable('a, b=2, *f, **g')
1366 self.assertEqualCallArgs(f, '2, 3, 7')
1367 self.assertEqualCallArgs(f, '2, 3, x=8')
1368 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
1369 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9')
1370 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9')
1371 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
1372 '[2, 3, (4,[5,6])]), **{"y":9, "z":10}')
1373 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
1374 '(4,[5,6])]), **collections.UserDict('
1375 'y=9, z=10)')
1376
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001377 f = self.makeCallable('a, b=2, *f, x, y=99, **g')
1378 self.assertEqualCallArgs(f, '2, 3, x=8')
1379 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
1380 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9, z=10')
1381 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9, z=10')
1382 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
1383 '[2, 3, (4,[5,6])]), q=0, **{"y":9, "z":10}')
1384 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
1385 '(4,[5,6])]), q=0, **collections.UserDict('
1386 'y=9, z=10)')
1387
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001388 def test_errors(self):
1389 f0 = self.makeCallable('')
1390 f1 = self.makeCallable('a, b')
1391 f2 = self.makeCallable('a, b=1')
1392 # f0 takes no arguments
1393 self.assertEqualException(f0, '1')
1394 self.assertEqualException(f0, 'x=1')
1395 self.assertEqualException(f0, '1,x=1')
1396 # f1 takes exactly 2 arguments
1397 self.assertEqualException(f1, '')
1398 self.assertEqualException(f1, '1')
1399 self.assertEqualException(f1, 'a=2')
1400 self.assertEqualException(f1, 'b=3')
1401 # f2 takes at least 1 argument
1402 self.assertEqualException(f2, '')
1403 self.assertEqualException(f2, 'b=3')
1404 for f in f1, f2:
1405 # f1/f2 takes exactly/at most 2 arguments
1406 self.assertEqualException(f, '2, 3, 4')
1407 self.assertEqualException(f, '1, 2, 3, a=1')
1408 self.assertEqualException(f, '2, 3, 4, c=5')
Georg Brandl178e5ea2012-02-21 00:32:36 +01001409 # XXX: success of this one depends on dict order
1410 ## self.assertEqualException(f, '2, 3, 4, a=1, c=5')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001411 # f got an unexpected keyword argument
1412 self.assertEqualException(f, 'c=2')
1413 self.assertEqualException(f, '2, c=3')
1414 self.assertEqualException(f, '2, 3, c=4')
1415 self.assertEqualException(f, '2, c=4, b=3')
1416 self.assertEqualException(f, '**{u"\u03c0\u03b9": 4}')
1417 # f got multiple values for keyword argument
1418 self.assertEqualException(f, '1, a=2')
1419 self.assertEqualException(f, '1, **{"a":2}')
1420 self.assertEqualException(f, '1, 2, b=3')
1421 # XXX: Python inconsistency
1422 # - for functions and bound methods: unexpected keyword 'c'
1423 # - for unbound methods: multiple values for keyword 'a'
1424 #self.assertEqualException(f, '1, c=3, a=2')
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001425 # issue11256:
1426 f3 = self.makeCallable('**c')
1427 self.assertEqualException(f3, '1, 2')
1428 self.assertEqualException(f3, '1, 2, a=1, b=2')
1429 f4 = self.makeCallable('*, a, b=0')
1430 self.assertEqualException(f3, '1, 2')
1431 self.assertEqualException(f3, '1, 2, a=1, b=2')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001432
Yury Selivanov875df202014-03-27 18:23:03 -04001433 # issue #20816: getcallargs() fails to iterate over non-existent
1434 # kwonlydefaults and raises a wrong TypeError
1435 def f5(*, a): pass
1436 with self.assertRaisesRegex(TypeError,
1437 'missing 1 required keyword-only'):
1438 inspect.getcallargs(f5)
1439
1440
Yury Selivanovdccfa132014-03-27 18:42:52 -04001441 # issue20817:
1442 def f6(a, b, c):
1443 pass
1444 with self.assertRaisesRegex(TypeError, "'a', 'b' and 'c'"):
1445 inspect.getcallargs(f6)
1446
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001447class TestGetcallargsMethods(TestGetcallargsFunctions):
1448
1449 def setUp(self):
1450 class Foo(object):
1451 pass
1452 self.cls = Foo
1453 self.inst = Foo()
1454
1455 def makeCallable(self, signature):
1456 assert 'self' not in signature
1457 mk = super(TestGetcallargsMethods, self).makeCallable
1458 self.cls.method = mk('self, ' + signature)
1459 return self.inst.method
1460
1461class TestGetcallargsUnboundMethods(TestGetcallargsMethods):
1462
1463 def makeCallable(self, signature):
1464 super(TestGetcallargsUnboundMethods, self).makeCallable(signature)
1465 return self.cls.method
1466
1467 def assertEqualCallArgs(self, func, call_params_string, locs=None):
1468 return super(TestGetcallargsUnboundMethods, self).assertEqualCallArgs(
1469 *self._getAssertEqualParams(func, call_params_string, locs))
1470
1471 def assertEqualException(self, func, call_params_string, locs=None):
1472 return super(TestGetcallargsUnboundMethods, self).assertEqualException(
1473 *self._getAssertEqualParams(func, call_params_string, locs))
1474
1475 def _getAssertEqualParams(self, func, call_params_string, locs=None):
1476 assert 'inst' not in call_params_string
1477 locs = dict(locs or {}, inst=self.inst)
1478 return (func, 'inst,' + call_params_string, locs)
1479
Michael Foord95fc51d2010-11-20 15:07:30 +00001480
1481class TestGetattrStatic(unittest.TestCase):
1482
1483 def test_basic(self):
1484 class Thing(object):
1485 x = object()
1486
1487 thing = Thing()
1488 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1489 self.assertEqual(inspect.getattr_static(thing, 'x', None), Thing.x)
1490 with self.assertRaises(AttributeError):
1491 inspect.getattr_static(thing, 'y')
1492
1493 self.assertEqual(inspect.getattr_static(thing, 'y', 3), 3)
1494
1495 def test_inherited(self):
1496 class Thing(object):
1497 x = object()
1498 class OtherThing(Thing):
1499 pass
1500
1501 something = OtherThing()
1502 self.assertEqual(inspect.getattr_static(something, 'x'), Thing.x)
1503
1504 def test_instance_attr(self):
1505 class Thing(object):
1506 x = 2
1507 def __init__(self, x):
1508 self.x = x
1509 thing = Thing(3)
1510 self.assertEqual(inspect.getattr_static(thing, 'x'), 3)
1511 del thing.x
1512 self.assertEqual(inspect.getattr_static(thing, 'x'), 2)
1513
1514 def test_property(self):
1515 class Thing(object):
1516 @property
1517 def x(self):
1518 raise AttributeError("I'm pretending not to exist")
1519 thing = Thing()
1520 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1521
Ezio Melotti75cbd732011-04-28 00:59:29 +03001522 def test_descriptor_raises_AttributeError(self):
Michael Foord95fc51d2010-11-20 15:07:30 +00001523 class descriptor(object):
1524 def __get__(*_):
1525 raise AttributeError("I'm pretending not to exist")
1526 desc = descriptor()
1527 class Thing(object):
1528 x = desc
1529 thing = Thing()
1530 self.assertEqual(inspect.getattr_static(thing, 'x'), desc)
1531
1532 def test_classAttribute(self):
1533 class Thing(object):
1534 x = object()
1535
1536 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.x)
1537
Ethan Furmane03ea372013-09-25 07:14:41 -07001538 def test_classVirtualAttribute(self):
1539 class Thing(object):
1540 @types.DynamicClassAttribute
1541 def x(self):
1542 return self._x
1543 _x = object()
1544
1545 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.__dict__['x'])
1546
Michael Foord95fc51d2010-11-20 15:07:30 +00001547 def test_inherited_classattribute(self):
1548 class Thing(object):
1549 x = object()
1550 class OtherThing(Thing):
1551 pass
1552
1553 self.assertEqual(inspect.getattr_static(OtherThing, 'x'), Thing.x)
1554
1555 def test_slots(self):
1556 class Thing(object):
1557 y = 'bar'
1558 __slots__ = ['x']
1559 def __init__(self):
1560 self.x = 'foo'
1561 thing = Thing()
1562 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1563 self.assertEqual(inspect.getattr_static(thing, 'y'), 'bar')
1564
1565 del thing.x
1566 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1567
1568 def test_metaclass(self):
1569 class meta(type):
1570 attr = 'foo'
1571 class Thing(object, metaclass=meta):
1572 pass
1573 self.assertEqual(inspect.getattr_static(Thing, 'attr'), 'foo')
1574
1575 class sub(meta):
1576 pass
1577 class OtherThing(object, metaclass=sub):
1578 x = 3
1579 self.assertEqual(inspect.getattr_static(OtherThing, 'attr'), 'foo')
1580
1581 class OtherOtherThing(OtherThing):
1582 pass
1583 # this test is odd, but it was added as it exposed a bug
1584 self.assertEqual(inspect.getattr_static(OtherOtherThing, 'x'), 3)
1585
1586 def test_no_dict_no_slots(self):
1587 self.assertEqual(inspect.getattr_static(1, 'foo', None), None)
1588 self.assertNotEqual(inspect.getattr_static('foo', 'lower'), None)
1589
1590 def test_no_dict_no_slots_instance_member(self):
1591 # returns descriptor
1592 with open(__file__) as handle:
1593 self.assertEqual(inspect.getattr_static(handle, 'name'), type(handle).name)
1594
1595 def test_inherited_slots(self):
1596 # returns descriptor
1597 class Thing(object):
1598 __slots__ = ['x']
1599 def __init__(self):
1600 self.x = 'foo'
1601
1602 class OtherThing(Thing):
1603 pass
1604 # it would be nice if this worked...
1605 # we get the descriptor instead of the instance attribute
1606 self.assertEqual(inspect.getattr_static(OtherThing(), 'x'), Thing.x)
1607
1608 def test_descriptor(self):
1609 class descriptor(object):
1610 def __get__(self, instance, owner):
1611 return 3
1612 class Foo(object):
1613 d = descriptor()
1614
1615 foo = Foo()
1616
1617 # for a non data descriptor we return the instance attribute
1618 foo.__dict__['d'] = 1
1619 self.assertEqual(inspect.getattr_static(foo, 'd'), 1)
1620
Mike53f7a7c2017-12-14 14:04:53 +03001621 # if the descriptor is a data-descriptor we should return the
Michael Foord95fc51d2010-11-20 15:07:30 +00001622 # descriptor
1623 descriptor.__set__ = lambda s, i, v: None
1624 self.assertEqual(inspect.getattr_static(foo, 'd'), Foo.__dict__['d'])
1625
1626
1627 def test_metaclass_with_descriptor(self):
1628 class descriptor(object):
1629 def __get__(self, instance, owner):
1630 return 3
1631 class meta(type):
1632 d = descriptor()
1633 class Thing(object, metaclass=meta):
1634 pass
1635 self.assertEqual(inspect.getattr_static(Thing, 'd'), meta.__dict__['d'])
1636
1637
Michael Foordcc7ebb82010-11-20 16:20:16 +00001638 def test_class_as_property(self):
1639 class Base(object):
1640 foo = 3
1641
1642 class Something(Base):
Michael Foord35184ed2010-11-20 16:58:30 +00001643 executed = False
Michael Foordcc7ebb82010-11-20 16:20:16 +00001644 @property
1645 def __class__(self):
Michael Foord35184ed2010-11-20 16:58:30 +00001646 self.executed = True
Michael Foordcc7ebb82010-11-20 16:20:16 +00001647 return object
1648
Michael Foord35184ed2010-11-20 16:58:30 +00001649 instance = Something()
1650 self.assertEqual(inspect.getattr_static(instance, 'foo'), 3)
1651 self.assertFalse(instance.executed)
Michael Foordcc7ebb82010-11-20 16:20:16 +00001652 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1653
Michael Foorde5162652010-11-20 16:40:44 +00001654 def test_mro_as_property(self):
1655 class Meta(type):
1656 @property
1657 def __mro__(self):
1658 return (object,)
1659
1660 class Base(object):
1661 foo = 3
1662
1663 class Something(Base, metaclass=Meta):
1664 pass
1665
1666 self.assertEqual(inspect.getattr_static(Something(), 'foo'), 3)
1667 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1668
Michael Foorddcebe0f2011-03-15 19:20:44 -04001669 def test_dict_as_property(self):
1670 test = self
1671 test.called = False
1672
1673 class Foo(dict):
1674 a = 3
1675 @property
1676 def __dict__(self):
1677 test.called = True
1678 return {}
1679
1680 foo = Foo()
1681 foo.a = 4
1682 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1683 self.assertFalse(test.called)
1684
1685 def test_custom_object_dict(self):
1686 test = self
1687 test.called = False
1688
1689 class Custom(dict):
1690 def get(self, key, default=None):
1691 test.called = True
1692 super().get(key, default)
1693
1694 class Foo(object):
1695 a = 3
1696 foo = Foo()
1697 foo.__dict__ = Custom()
1698 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1699 self.assertFalse(test.called)
1700
1701 def test_metaclass_dict_as_property(self):
1702 class Meta(type):
1703 @property
1704 def __dict__(self):
1705 self.executed = True
1706
1707 class Thing(metaclass=Meta):
1708 executed = False
1709
1710 def __init__(self):
1711 self.spam = 42
1712
1713 instance = Thing()
1714 self.assertEqual(inspect.getattr_static(instance, "spam"), 42)
1715 self.assertFalse(Thing.executed)
Michael Foorde5162652010-11-20 16:40:44 +00001716
Michael Foorda51623b2011-12-18 22:01:40 +00001717 def test_module(self):
1718 sentinel = object()
1719 self.assertIsNot(inspect.getattr_static(sys, "version", sentinel),
1720 sentinel)
1721
Michael Foord3ba95f82011-12-22 01:13:37 +00001722 def test_metaclass_with_metaclass_with_dict_as_property(self):
1723 class MetaMeta(type):
1724 @property
1725 def __dict__(self):
1726 self.executed = True
1727 return dict(spam=42)
1728
1729 class Meta(type, metaclass=MetaMeta):
1730 executed = False
1731
1732 class Thing(metaclass=Meta):
1733 pass
1734
1735 with self.assertRaises(AttributeError):
1736 inspect.getattr_static(Thing, "spam")
1737 self.assertFalse(Thing.executed)
1738
Nick Coghlane0f04652010-11-21 03:44:04 +00001739class TestGetGeneratorState(unittest.TestCase):
1740
1741 def setUp(self):
1742 def number_generator():
1743 for number in range(5):
1744 yield number
1745 self.generator = number_generator()
1746
1747 def _generatorstate(self):
1748 return inspect.getgeneratorstate(self.generator)
1749
1750 def test_created(self):
1751 self.assertEqual(self._generatorstate(), inspect.GEN_CREATED)
1752
1753 def test_suspended(self):
1754 next(self.generator)
1755 self.assertEqual(self._generatorstate(), inspect.GEN_SUSPENDED)
1756
1757 def test_closed_after_exhaustion(self):
1758 for i in self.generator:
1759 pass
1760 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1761
1762 def test_closed_after_immediate_exception(self):
1763 with self.assertRaises(RuntimeError):
1764 self.generator.throw(RuntimeError)
1765 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1766
1767 def test_running(self):
1768 # As mentioned on issue #10220, checking for the RUNNING state only
1769 # makes sense inside the generator itself.
1770 # The following generator checks for this by using the closure's
1771 # reference to self and the generator state checking helper method
1772 def running_check_generator():
1773 for number in range(5):
1774 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1775 yield number
1776 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1777 self.generator = running_check_generator()
1778 # Running up to the first yield
1779 next(self.generator)
1780 # Running after the first yield
1781 next(self.generator)
1782
Nick Coghlan7921b9f2010-11-30 06:36:04 +00001783 def test_easy_debugging(self):
1784 # repr() and str() of a generator state should contain the state name
1785 names = 'GEN_CREATED GEN_RUNNING GEN_SUSPENDED GEN_CLOSED'.split()
1786 for name in names:
1787 state = getattr(inspect, name)
1788 self.assertIn(name, repr(state))
1789 self.assertIn(name, str(state))
1790
Nick Coghlan04e2e3f2012-06-23 19:52:05 +10001791 def test_getgeneratorlocals(self):
1792 def each(lst, a=None):
1793 b=(1, 2, 3)
1794 for v in lst:
1795 if v == 3:
1796 c = 12
1797 yield v
1798
1799 numbers = each([1, 2, 3])
1800 self.assertEqual(inspect.getgeneratorlocals(numbers),
1801 {'a': None, 'lst': [1, 2, 3]})
1802 next(numbers)
1803 self.assertEqual(inspect.getgeneratorlocals(numbers),
1804 {'a': None, 'lst': [1, 2, 3], 'v': 1,
1805 'b': (1, 2, 3)})
1806 next(numbers)
1807 self.assertEqual(inspect.getgeneratorlocals(numbers),
1808 {'a': None, 'lst': [1, 2, 3], 'v': 2,
1809 'b': (1, 2, 3)})
1810 next(numbers)
1811 self.assertEqual(inspect.getgeneratorlocals(numbers),
1812 {'a': None, 'lst': [1, 2, 3], 'v': 3,
1813 'b': (1, 2, 3), 'c': 12})
1814 try:
1815 next(numbers)
1816 except StopIteration:
1817 pass
1818 self.assertEqual(inspect.getgeneratorlocals(numbers), {})
1819
1820 def test_getgeneratorlocals_empty(self):
1821 def yield_one():
1822 yield 1
1823 one = yield_one()
1824 self.assertEqual(inspect.getgeneratorlocals(one), {})
1825 try:
1826 next(one)
1827 except StopIteration:
1828 pass
1829 self.assertEqual(inspect.getgeneratorlocals(one), {})
1830
1831 def test_getgeneratorlocals_error(self):
1832 self.assertRaises(TypeError, inspect.getgeneratorlocals, 1)
1833 self.assertRaises(TypeError, inspect.getgeneratorlocals, lambda x: True)
1834 self.assertRaises(TypeError, inspect.getgeneratorlocals, set)
1835 self.assertRaises(TypeError, inspect.getgeneratorlocals, (2,3))
1836
Nick Coghlane0f04652010-11-21 03:44:04 +00001837
Yury Selivanov5376ba92015-06-22 12:19:30 -04001838class TestGetCoroutineState(unittest.TestCase):
1839
1840 def setUp(self):
1841 @types.coroutine
1842 def number_coroutine():
1843 for number in range(5):
1844 yield number
1845 async def coroutine():
1846 await number_coroutine()
1847 self.coroutine = coroutine()
1848
1849 def tearDown(self):
1850 self.coroutine.close()
1851
1852 def _coroutinestate(self):
1853 return inspect.getcoroutinestate(self.coroutine)
1854
1855 def test_created(self):
1856 self.assertEqual(self._coroutinestate(), inspect.CORO_CREATED)
1857
1858 def test_suspended(self):
1859 self.coroutine.send(None)
1860 self.assertEqual(self._coroutinestate(), inspect.CORO_SUSPENDED)
1861
1862 def test_closed_after_exhaustion(self):
1863 while True:
1864 try:
1865 self.coroutine.send(None)
1866 except StopIteration:
1867 break
1868
1869 self.assertEqual(self._coroutinestate(), inspect.CORO_CLOSED)
1870
1871 def test_closed_after_immediate_exception(self):
1872 with self.assertRaises(RuntimeError):
1873 self.coroutine.throw(RuntimeError)
1874 self.assertEqual(self._coroutinestate(), inspect.CORO_CLOSED)
1875
1876 def test_easy_debugging(self):
1877 # repr() and str() of a coroutine state should contain the state name
1878 names = 'CORO_CREATED CORO_RUNNING CORO_SUSPENDED CORO_CLOSED'.split()
1879 for name in names:
1880 state = getattr(inspect, name)
1881 self.assertIn(name, repr(state))
1882 self.assertIn(name, str(state))
1883
1884 def test_getcoroutinelocals(self):
1885 @types.coroutine
1886 def gencoro():
1887 yield
1888
1889 gencoro = gencoro()
1890 async def func(a=None):
1891 b = 'spam'
1892 await gencoro
1893
1894 coro = func()
1895 self.assertEqual(inspect.getcoroutinelocals(coro),
1896 {'a': None, 'gencoro': gencoro})
1897 coro.send(None)
1898 self.assertEqual(inspect.getcoroutinelocals(coro),
1899 {'a': None, 'gencoro': gencoro, 'b': 'spam'})
1900
1901
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001902class MySignature(inspect.Signature):
1903 # Top-level to make it picklable;
1904 # used in test_signature_object_pickle
1905 pass
1906
1907class MyParameter(inspect.Parameter):
1908 # Top-level to make it picklable;
1909 # used in test_signature_object_pickle
1910 pass
1911
Nick Coghlanf9e227e2014-08-17 14:01:19 +10001912
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001913
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001914class TestSignatureObject(unittest.TestCase):
1915 @staticmethod
Yury Selivanovbcd4fc12015-05-20 14:30:08 -04001916 def signature(func, **kw):
1917 sig = inspect.signature(func, **kw)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001918 return (tuple((param.name,
1919 (... if param.default is param.empty else param.default),
1920 (... if param.annotation is param.empty
1921 else param.annotation),
1922 str(param.kind).lower())
1923 for param in sig.parameters.values()),
1924 (... if sig.return_annotation is sig.empty
1925 else sig.return_annotation))
1926
1927 def test_signature_object(self):
1928 S = inspect.Signature
1929 P = inspect.Parameter
1930
1931 self.assertEqual(str(S()), '()')
1932
Yury Selivanov07a9e452014-01-29 10:58:16 -05001933 def test(po, pk, pod=42, pkd=100, *args, ko, **kwargs):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001934 pass
1935 sig = inspect.signature(test)
1936 po = sig.parameters['po'].replace(kind=P.POSITIONAL_ONLY)
Yury Selivanov07a9e452014-01-29 10:58:16 -05001937 pod = sig.parameters['pod'].replace(kind=P.POSITIONAL_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001938 pk = sig.parameters['pk']
Yury Selivanov07a9e452014-01-29 10:58:16 -05001939 pkd = sig.parameters['pkd']
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001940 args = sig.parameters['args']
1941 ko = sig.parameters['ko']
1942 kwargs = sig.parameters['kwargs']
1943
1944 S((po, pk, args, ko, kwargs))
1945
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001946 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001947 S((pk, po, args, ko, kwargs))
1948
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001949 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001950 S((po, args, pk, ko, kwargs))
1951
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001952 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001953 S((args, po, pk, ko, kwargs))
1954
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001955 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001956 S((po, pk, args, kwargs, ko))
1957
1958 kwargs2 = kwargs.replace(name='args')
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001959 with self.assertRaisesRegex(ValueError, 'duplicate parameter name'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001960 S((po, pk, args, kwargs2, ko))
1961
Yury Selivanov07a9e452014-01-29 10:58:16 -05001962 with self.assertRaisesRegex(ValueError, 'follows default argument'):
1963 S((pod, po))
1964
1965 with self.assertRaisesRegex(ValueError, 'follows default argument'):
1966 S((po, pkd, pk))
1967
1968 with self.assertRaisesRegex(ValueError, 'follows default argument'):
1969 S((pkd, pk))
1970
Yury Selivanov374375d2014-03-27 12:41:53 -04001971 self.assertTrue(repr(sig).startswith('<Signature'))
Yury Selivanov0cd2bf42015-05-15 12:55:20 -04001972 self.assertTrue('(po, pk' in repr(sig))
Yury Selivanov374375d2014-03-27 12:41:53 -04001973
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001974 def test_signature_object_pickle(self):
1975 def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
1976 foo_partial = functools.partial(foo, a=1)
1977
1978 sig = inspect.signature(foo_partial)
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001979
1980 for ver in range(pickle.HIGHEST_PROTOCOL + 1):
1981 with self.subTest(pickle_ver=ver, subclass=False):
1982 sig_pickled = pickle.loads(pickle.dumps(sig, ver))
1983 self.assertEqual(sig, sig_pickled)
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001984
1985 # Test that basic sub-classing works
1986 sig = inspect.signature(foo)
1987 myparam = MyParameter(name='z', kind=inspect.Parameter.POSITIONAL_ONLY)
1988 myparams = collections.OrderedDict(sig.parameters, a=myparam)
1989 mysig = MySignature().replace(parameters=myparams.values(),
1990 return_annotation=sig.return_annotation)
1991 self.assertTrue(isinstance(mysig, MySignature))
1992 self.assertTrue(isinstance(mysig.parameters['z'], MyParameter))
1993
1994 for ver in range(pickle.HIGHEST_PROTOCOL + 1):
1995 with self.subTest(pickle_ver=ver, subclass=True):
1996 sig_pickled = pickle.loads(pickle.dumps(mysig, ver))
1997 self.assertEqual(mysig, sig_pickled)
1998 self.assertTrue(isinstance(sig_pickled, MySignature))
1999 self.assertTrue(isinstance(sig_pickled.parameters['z'],
2000 MyParameter))
2001
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002002 def test_signature_immutability(self):
2003 def test(a):
2004 pass
2005 sig = inspect.signature(test)
2006
2007 with self.assertRaises(AttributeError):
2008 sig.foo = 'bar'
2009
2010 with self.assertRaises(TypeError):
2011 sig.parameters['a'] = None
2012
2013 def test_signature_on_noarg(self):
2014 def test():
2015 pass
2016 self.assertEqual(self.signature(test), ((), ...))
2017
2018 def test_signature_on_wargs(self):
2019 def test(a, b:'foo') -> 123:
2020 pass
2021 self.assertEqual(self.signature(test),
2022 ((('a', ..., ..., "positional_or_keyword"),
2023 ('b', ..., 'foo', "positional_or_keyword")),
2024 123))
2025
2026 def test_signature_on_wkwonly(self):
2027 def test(*, a:float, b:str) -> int:
2028 pass
2029 self.assertEqual(self.signature(test),
2030 ((('a', ..., float, "keyword_only"),
2031 ('b', ..., str, "keyword_only")),
2032 int))
2033
2034 def test_signature_on_complex_args(self):
2035 def test(a, b:'foo'=10, *args:'bar', spam:'baz', ham=123, **kwargs:int):
2036 pass
2037 self.assertEqual(self.signature(test),
2038 ((('a', ..., ..., "positional_or_keyword"),
2039 ('b', 10, 'foo', "positional_or_keyword"),
2040 ('args', ..., 'bar', "var_positional"),
2041 ('spam', ..., 'baz', "keyword_only"),
2042 ('ham', 123, ..., "keyword_only"),
2043 ('kwargs', ..., int, "var_keyword")),
2044 ...))
2045
Dong-hee Na378d7062017-05-18 04:00:51 +09002046 def test_signature_without_self(self):
2047 def test_args_only(*args): # NOQA
2048 pass
2049
2050 def test_args_kwargs_only(*args, **kwargs): # NOQA
2051 pass
2052
2053 class A:
2054 @classmethod
2055 def test_classmethod(*args): # NOQA
2056 pass
2057
2058 @staticmethod
2059 def test_staticmethod(*args): # NOQA
2060 pass
2061
2062 f1 = functools.partialmethod((test_classmethod), 1)
2063 f2 = functools.partialmethod((test_args_only), 1)
2064 f3 = functools.partialmethod((test_staticmethod), 1)
2065 f4 = functools.partialmethod((test_args_kwargs_only),1)
2066
2067 self.assertEqual(self.signature(test_args_only),
2068 ((('args', ..., ..., 'var_positional'),), ...))
2069 self.assertEqual(self.signature(test_args_kwargs_only),
2070 ((('args', ..., ..., 'var_positional'),
2071 ('kwargs', ..., ..., 'var_keyword')), ...))
2072 self.assertEqual(self.signature(A.f1),
2073 ((('args', ..., ..., 'var_positional'),), ...))
2074 self.assertEqual(self.signature(A.f2),
2075 ((('args', ..., ..., 'var_positional'),), ...))
2076 self.assertEqual(self.signature(A.f3),
2077 ((('args', ..., ..., 'var_positional'),), ...))
Serhiy Storchaka13ad3b72017-09-14 09:38:36 +03002078 self.assertEqual(self.signature(A.f4),
Dong-hee Na378d7062017-05-18 04:00:51 +09002079 ((('args', ..., ..., 'var_positional'),
2080 ('kwargs', ..., ..., 'var_keyword')), ...))
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002081 @cpython_only
Larry Hastingsfcafe432013-11-23 17:35:48 -08002082 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2083 "Signature information for builtins requires docstrings")
2084 def test_signature_on_builtins(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002085 import _testcapi
Larry Hastings16c51912014-01-07 11:53:01 -08002086
Larry Hastings5c661892014-01-24 06:17:25 -08002087 def test_unbound_method(o):
2088 """Use this to test unbound methods (things that should have a self)"""
2089 signature = inspect.signature(o)
2090 self.assertTrue(isinstance(signature, inspect.Signature))
2091 self.assertEqual(list(signature.parameters.values())[0].name, 'self')
2092 return signature
2093
2094 def test_callable(o):
2095 """Use this to test bound methods or normal callables (things that don't expect self)"""
2096 signature = inspect.signature(o)
2097 self.assertTrue(isinstance(signature, inspect.Signature))
2098 if signature.parameters:
2099 self.assertNotEqual(list(signature.parameters.values())[0].name, 'self')
2100 return signature
2101
2102 signature = test_callable(_testcapi.docstring_with_signature_with_defaults)
Larry Hastings16c51912014-01-07 11:53:01 -08002103 def p(name): return signature.parameters[name].default
2104 self.assertEqual(p('s'), 'avocado')
Larry Hastings2a727912014-01-16 11:32:01 -08002105 self.assertEqual(p('b'), b'bytes')
Larry Hastings16c51912014-01-07 11:53:01 -08002106 self.assertEqual(p('d'), 3.14)
2107 self.assertEqual(p('i'), 35)
Larry Hastings16c51912014-01-07 11:53:01 -08002108 self.assertEqual(p('n'), None)
2109 self.assertEqual(p('t'), True)
2110 self.assertEqual(p('f'), False)
Larry Hastings2a727912014-01-16 11:32:01 -08002111 self.assertEqual(p('local'), 3)
2112 self.assertEqual(p('sys'), sys.maxsize)
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +02002113 self.assertNotIn('exp', signature.parameters)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002114
Larry Hastings5c661892014-01-24 06:17:25 -08002115 test_callable(object)
2116
2117 # normal method
2118 # (PyMethodDescr_Type, "method_descriptor")
2119 test_unbound_method(_pickle.Pickler.dump)
2120 d = _pickle.Pickler(io.StringIO())
2121 test_callable(d.dump)
2122
2123 # static method
2124 test_callable(str.maketrans)
2125 test_callable('abc'.maketrans)
2126
2127 # class method
2128 test_callable(dict.fromkeys)
2129 test_callable({}.fromkeys)
2130
2131 # wrapper around slot (PyWrapperDescr_Type, "wrapper_descriptor")
2132 test_unbound_method(type.__call__)
2133 test_unbound_method(int.__add__)
2134 test_callable((3).__add__)
2135
2136 # _PyMethodWrapper_Type
2137 # support for 'method-wrapper'
2138 test_callable(min.__call__)
2139
Larry Hastings2623c8c2014-02-08 22:15:29 -08002140 # This doesn't work now.
2141 # (We don't have a valid signature for "type" in 3.4)
2142 with self.assertRaisesRegex(ValueError, "no signature found"):
2143 class ThisWorksNow:
2144 __call__ = type
2145 test_callable(ThisWorksNow())
Larry Hastings5c661892014-01-24 06:17:25 -08002146
Yury Selivanov056e2652014-03-02 12:25:27 -05002147 # Regression test for issue #20786
2148 test_unbound_method(dict.__delitem__)
2149 test_unbound_method(property.__delete__)
2150
Zachary Ware8ef887c2015-04-13 18:22:35 -05002151 # Regression test for issue #20586
2152 test_callable(_testcapi.docstring_with_signature_but_no_doc)
2153
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002154 @cpython_only
Yury Selivanov76c6c592014-01-29 10:52:57 -05002155 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2156 "Signature information for builtins requires docstrings")
2157 def test_signature_on_decorated_builtins(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002158 import _testcapi
Yury Selivanov76c6c592014-01-29 10:52:57 -05002159 func = _testcapi.docstring_with_signature_with_defaults
2160
2161 def decorator(func):
2162 @functools.wraps(func)
2163 def wrapper(*args, **kwargs) -> int:
2164 return func(*args, **kwargs)
2165 return wrapper
2166
2167 decorated_func = decorator(func)
2168
2169 self.assertEqual(inspect.signature(func),
2170 inspect.signature(decorated_func))
Larry Hastings5c661892014-01-24 06:17:25 -08002171
Yury Selivanovbcd4fc12015-05-20 14:30:08 -04002172 def wrapper_like(*args, **kwargs) -> int: pass
2173 self.assertEqual(inspect.signature(decorated_func,
2174 follow_wrapped=False),
2175 inspect.signature(wrapper_like))
2176
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002177 @cpython_only
Larry Hastings5c661892014-01-24 06:17:25 -08002178 def test_signature_on_builtins_no_signature(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002179 import _testcapi
Yury Selivanovbf304fc2015-05-30 17:08:36 -04002180 with self.assertRaisesRegex(ValueError,
2181 'no signature found for builtin'):
Larry Hastings5c661892014-01-24 06:17:25 -08002182 inspect.signature(_testcapi.docstring_no_signature)
2183
Yury Selivanovbf304fc2015-05-30 17:08:36 -04002184 with self.assertRaisesRegex(ValueError,
2185 'no signature found for builtin'):
2186 inspect.signature(str)
2187
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002188 def test_signature_on_non_function(self):
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002189 with self.assertRaisesRegex(TypeError, 'is not a callable object'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002190 inspect.signature(42)
2191
Yury Selivanov63da7c72014-01-31 14:48:37 -05002192 def test_signature_from_functionlike_object(self):
2193 def func(a,b, *args, kwonly=True, kwonlyreq, **kwargs):
2194 pass
2195
2196 class funclike:
2197 # Has to be callable, and have correct
2198 # __code__, __annotations__, __defaults__, __name__,
2199 # and __kwdefaults__ attributes
2200
2201 def __init__(self, func):
2202 self.__name__ = func.__name__
2203 self.__code__ = func.__code__
2204 self.__annotations__ = func.__annotations__
2205 self.__defaults__ = func.__defaults__
2206 self.__kwdefaults__ = func.__kwdefaults__
2207 self.func = func
2208
2209 def __call__(self, *args, **kwargs):
2210 return self.func(*args, **kwargs)
2211
Yury Selivanov57c74fc2015-05-20 23:07:02 -04002212 sig_func = inspect.Signature.from_callable(func)
Yury Selivanov63da7c72014-01-31 14:48:37 -05002213
Yury Selivanov57c74fc2015-05-20 23:07:02 -04002214 sig_funclike = inspect.Signature.from_callable(funclike(func))
Yury Selivanov63da7c72014-01-31 14:48:37 -05002215 self.assertEqual(sig_funclike, sig_func)
2216
2217 sig_funclike = inspect.signature(funclike(func))
2218 self.assertEqual(sig_funclike, sig_func)
2219
2220 # If object is not a duck type of function, then
2221 # signature will try to get a signature for its '__call__'
2222 # method
2223 fl = funclike(func)
2224 del fl.__defaults__
2225 self.assertEqual(self.signature(fl),
2226 ((('args', ..., ..., "var_positional"),
2227 ('kwargs', ..., ..., "var_keyword")),
2228 ...))
2229
Yury Selivanova773de02014-02-21 18:30:53 -05002230 # Test with cython-like builtins:
2231 _orig_isdesc = inspect.ismethoddescriptor
2232 def _isdesc(obj):
2233 if hasattr(obj, '_builtinmock'):
2234 return True
2235 return _orig_isdesc(obj)
2236
2237 with unittest.mock.patch('inspect.ismethoddescriptor', _isdesc):
2238 builtin_func = funclike(func)
2239 # Make sure that our mock setup is working
2240 self.assertFalse(inspect.ismethoddescriptor(builtin_func))
2241 builtin_func._builtinmock = True
2242 self.assertTrue(inspect.ismethoddescriptor(builtin_func))
2243 self.assertEqual(inspect.signature(builtin_func), sig_func)
2244
Yury Selivanov63da7c72014-01-31 14:48:37 -05002245 def test_signature_functionlike_class(self):
2246 # We only want to duck type function-like objects,
2247 # not classes.
2248
2249 def func(a,b, *args, kwonly=True, kwonlyreq, **kwargs):
2250 pass
2251
2252 class funclike:
2253 def __init__(self, marker):
2254 pass
2255
2256 __name__ = func.__name__
2257 __code__ = func.__code__
2258 __annotations__ = func.__annotations__
2259 __defaults__ = func.__defaults__
2260 __kwdefaults__ = func.__kwdefaults__
2261
Yury Selivanov63da7c72014-01-31 14:48:37 -05002262 self.assertEqual(str(inspect.signature(funclike)), '(marker)')
2263
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002264 def test_signature_on_method(self):
2265 class Test:
Yury Selivanov62560fb2014-01-28 12:26:24 -05002266 def __init__(*args):
2267 pass
2268 def m1(self, arg1, arg2=1) -> int:
2269 pass
2270 def m2(*args):
2271 pass
2272 def __call__(*, a):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002273 pass
2274
Yury Selivanov62560fb2014-01-28 12:26:24 -05002275 self.assertEqual(self.signature(Test().m1),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002276 ((('arg1', ..., ..., "positional_or_keyword"),
2277 ('arg2', 1, ..., "positional_or_keyword")),
2278 int))
2279
Yury Selivanov62560fb2014-01-28 12:26:24 -05002280 self.assertEqual(self.signature(Test().m2),
2281 ((('args', ..., ..., "var_positional"),),
2282 ...))
2283
2284 self.assertEqual(self.signature(Test),
2285 ((('args', ..., ..., "var_positional"),),
2286 ...))
2287
2288 with self.assertRaisesRegex(ValueError, 'invalid method signature'):
2289 self.signature(Test())
2290
Yury Selivanov46c759d2015-05-27 21:56:53 -04002291 def test_signature_wrapped_bound_method(self):
2292 # Issue 24298
2293 class Test:
2294 def m1(self, arg1, arg2=1) -> int:
2295 pass
2296 @functools.wraps(Test().m1)
2297 def m1d(*args, **kwargs):
2298 pass
2299 self.assertEqual(self.signature(m1d),
2300 ((('arg1', ..., ..., "positional_or_keyword"),
2301 ('arg2', 1, ..., "positional_or_keyword")),
2302 int))
2303
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002304 def test_signature_on_classmethod(self):
2305 class Test:
2306 @classmethod
2307 def foo(cls, arg1, *, arg2=1):
2308 pass
2309
2310 meth = Test().foo
2311 self.assertEqual(self.signature(meth),
2312 ((('arg1', ..., ..., "positional_or_keyword"),
2313 ('arg2', 1, ..., "keyword_only")),
2314 ...))
2315
2316 meth = Test.foo
2317 self.assertEqual(self.signature(meth),
2318 ((('arg1', ..., ..., "positional_or_keyword"),
2319 ('arg2', 1, ..., "keyword_only")),
2320 ...))
2321
2322 def test_signature_on_staticmethod(self):
2323 class Test:
2324 @staticmethod
2325 def foo(cls, *, arg):
2326 pass
2327
2328 meth = Test().foo
2329 self.assertEqual(self.signature(meth),
2330 ((('cls', ..., ..., "positional_or_keyword"),
2331 ('arg', ..., ..., "keyword_only")),
2332 ...))
2333
2334 meth = Test.foo
2335 self.assertEqual(self.signature(meth),
2336 ((('cls', ..., ..., "positional_or_keyword"),
2337 ('arg', ..., ..., "keyword_only")),
2338 ...))
2339
2340 def test_signature_on_partial(self):
2341 from functools import partial
2342
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002343 Parameter = inspect.Parameter
2344
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002345 def test():
2346 pass
2347
2348 self.assertEqual(self.signature(partial(test)), ((), ...))
2349
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002350 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002351 inspect.signature(partial(test, 1))
2352
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002353 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002354 inspect.signature(partial(test, a=1))
2355
2356 def test(a, b, *, c, d):
2357 pass
2358
2359 self.assertEqual(self.signature(partial(test)),
2360 ((('a', ..., ..., "positional_or_keyword"),
2361 ('b', ..., ..., "positional_or_keyword"),
2362 ('c', ..., ..., "keyword_only"),
2363 ('d', ..., ..., "keyword_only")),
2364 ...))
2365
2366 self.assertEqual(self.signature(partial(test, 1)),
2367 ((('b', ..., ..., "positional_or_keyword"),
2368 ('c', ..., ..., "keyword_only"),
2369 ('d', ..., ..., "keyword_only")),
2370 ...))
2371
2372 self.assertEqual(self.signature(partial(test, 1, c=2)),
2373 ((('b', ..., ..., "positional_or_keyword"),
2374 ('c', 2, ..., "keyword_only"),
2375 ('d', ..., ..., "keyword_only")),
2376 ...))
2377
2378 self.assertEqual(self.signature(partial(test, b=1, c=2)),
2379 ((('a', ..., ..., "positional_or_keyword"),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002380 ('b', 1, ..., "keyword_only"),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002381 ('c', 2, ..., "keyword_only"),
2382 ('d', ..., ..., "keyword_only")),
2383 ...))
2384
2385 self.assertEqual(self.signature(partial(test, 0, b=1, c=2)),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002386 ((('b', 1, ..., "keyword_only"),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002387 ('c', 2, ..., "keyword_only"),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002388 ('d', ..., ..., "keyword_only")),
2389 ...))
2390
2391 self.assertEqual(self.signature(partial(test, a=1)),
2392 ((('a', 1, ..., "keyword_only"),
2393 ('b', ..., ..., "keyword_only"),
2394 ('c', ..., ..., "keyword_only"),
2395 ('d', ..., ..., "keyword_only")),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002396 ...))
2397
2398 def test(a, *args, b, **kwargs):
2399 pass
2400
2401 self.assertEqual(self.signature(partial(test, 1)),
2402 ((('args', ..., ..., "var_positional"),
2403 ('b', ..., ..., "keyword_only"),
2404 ('kwargs', ..., ..., "var_keyword")),
2405 ...))
2406
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002407 self.assertEqual(self.signature(partial(test, a=1)),
2408 ((('a', 1, ..., "keyword_only"),
2409 ('b', ..., ..., "keyword_only"),
2410 ('kwargs', ..., ..., "var_keyword")),
2411 ...))
2412
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002413 self.assertEqual(self.signature(partial(test, 1, 2, 3)),
2414 ((('args', ..., ..., "var_positional"),
2415 ('b', ..., ..., "keyword_only"),
2416 ('kwargs', ..., ..., "var_keyword")),
2417 ...))
2418
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002419 self.assertEqual(self.signature(partial(test, 1, 2, 3, test=True)),
2420 ((('args', ..., ..., "var_positional"),
2421 ('b', ..., ..., "keyword_only"),
2422 ('kwargs', ..., ..., "var_keyword")),
2423 ...))
2424
2425 self.assertEqual(self.signature(partial(test, 1, 2, 3, test=1, b=0)),
2426 ((('args', ..., ..., "var_positional"),
2427 ('b', 0, ..., "keyword_only"),
2428 ('kwargs', ..., ..., "var_keyword")),
2429 ...))
2430
2431 self.assertEqual(self.signature(partial(test, b=0)),
2432 ((('a', ..., ..., "positional_or_keyword"),
2433 ('args', ..., ..., "var_positional"),
2434 ('b', 0, ..., "keyword_only"),
2435 ('kwargs', ..., ..., "var_keyword")),
2436 ...))
2437
2438 self.assertEqual(self.signature(partial(test, b=0, test=1)),
2439 ((('a', ..., ..., "positional_or_keyword"),
2440 ('args', ..., ..., "var_positional"),
2441 ('b', 0, ..., "keyword_only"),
2442 ('kwargs', ..., ..., "var_keyword")),
2443 ...))
2444
2445 def test(a, b, c:int) -> 42:
2446 pass
2447
2448 sig = test.__signature__ = inspect.signature(test)
2449
2450 self.assertEqual(self.signature(partial(partial(test, 1))),
2451 ((('b', ..., ..., "positional_or_keyword"),
2452 ('c', ..., int, "positional_or_keyword")),
2453 42))
2454
2455 self.assertEqual(self.signature(partial(partial(test, 1), 2)),
2456 ((('c', ..., int, "positional_or_keyword"),),
2457 42))
2458
2459 psig = inspect.signature(partial(partial(test, 1), 2))
2460
2461 def foo(a):
2462 return a
2463 _foo = partial(partial(foo, a=10), a=20)
2464 self.assertEqual(self.signature(_foo),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002465 ((('a', 20, ..., "keyword_only"),),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002466 ...))
2467 # check that we don't have any side-effects in signature(),
2468 # and the partial object is still functioning
2469 self.assertEqual(_foo(), 20)
2470
2471 def foo(a, b, c):
2472 return a, b, c
2473 _foo = partial(partial(foo, 1, b=20), b=30)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002474
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002475 self.assertEqual(self.signature(_foo),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002476 ((('b', 30, ..., "keyword_only"),
2477 ('c', ..., ..., "keyword_only")),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002478 ...))
2479 self.assertEqual(_foo(c=10), (1, 30, 10))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002480
2481 def foo(a, b, c, *, d):
2482 return a, b, c, d
2483 _foo = partial(partial(foo, d=20, c=20), b=10, d=30)
2484 self.assertEqual(self.signature(_foo),
2485 ((('a', ..., ..., "positional_or_keyword"),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002486 ('b', 10, ..., "keyword_only"),
2487 ('c', 20, ..., "keyword_only"),
2488 ('d', 30, ..., "keyword_only"),
2489 ),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002490 ...))
2491 ba = inspect.signature(_foo).bind(a=200, b=11)
2492 self.assertEqual(_foo(*ba.args, **ba.kwargs), (200, 11, 20, 30))
2493
2494 def foo(a=1, b=2, c=3):
2495 return a, b, c
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002496 _foo = partial(foo, c=13) # (a=1, b=2, *, c=13)
2497
2498 ba = inspect.signature(_foo).bind(a=11)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002499 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 2, 13))
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002500
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002501 ba = inspect.signature(_foo).bind(11, 12)
2502 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002503
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002504 ba = inspect.signature(_foo).bind(11, b=12)
2505 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002506
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002507 ba = inspect.signature(_foo).bind(b=12)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002508 self.assertEqual(_foo(*ba.args, **ba.kwargs), (1, 12, 13))
2509
2510 _foo = partial(_foo, b=10, c=20)
2511 ba = inspect.signature(_foo).bind(12)
2512 self.assertEqual(_foo(*ba.args, **ba.kwargs), (12, 10, 20))
2513
2514
2515 def foo(a, b, c, d, **kwargs):
2516 pass
2517 sig = inspect.signature(foo)
2518 params = sig.parameters.copy()
2519 params['a'] = params['a'].replace(kind=Parameter.POSITIONAL_ONLY)
2520 params['b'] = params['b'].replace(kind=Parameter.POSITIONAL_ONLY)
2521 foo.__signature__ = inspect.Signature(params.values())
2522 sig = inspect.signature(foo)
2523 self.assertEqual(str(sig), '(a, b, /, c, d, **kwargs)')
2524
2525 self.assertEqual(self.signature(partial(foo, 1)),
2526 ((('b', ..., ..., 'positional_only'),
2527 ('c', ..., ..., 'positional_or_keyword'),
2528 ('d', ..., ..., 'positional_or_keyword'),
2529 ('kwargs', ..., ..., 'var_keyword')),
2530 ...))
2531
2532 self.assertEqual(self.signature(partial(foo, 1, 2)),
2533 ((('c', ..., ..., 'positional_or_keyword'),
2534 ('d', ..., ..., 'positional_or_keyword'),
2535 ('kwargs', ..., ..., 'var_keyword')),
2536 ...))
2537
2538 self.assertEqual(self.signature(partial(foo, 1, 2, 3)),
2539 ((('d', ..., ..., 'positional_or_keyword'),
2540 ('kwargs', ..., ..., 'var_keyword')),
2541 ...))
2542
2543 self.assertEqual(self.signature(partial(foo, 1, 2, c=3)),
2544 ((('c', 3, ..., 'keyword_only'),
2545 ('d', ..., ..., 'keyword_only'),
2546 ('kwargs', ..., ..., 'var_keyword')),
2547 ...))
2548
2549 self.assertEqual(self.signature(partial(foo, 1, c=3)),
2550 ((('b', ..., ..., 'positional_only'),
2551 ('c', 3, ..., 'keyword_only'),
2552 ('d', ..., ..., 'keyword_only'),
2553 ('kwargs', ..., ..., 'var_keyword')),
2554 ...))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002555
Yury Selivanovda5fe4f2014-01-27 17:28:37 -05002556 def test_signature_on_partialmethod(self):
2557 from functools import partialmethod
2558
2559 class Spam:
2560 def test():
2561 pass
2562 ham = partialmethod(test)
2563
2564 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
2565 inspect.signature(Spam.ham)
2566
2567 class Spam:
2568 def test(it, a, *, c) -> 'spam':
2569 pass
2570 ham = partialmethod(test, c=1)
2571
2572 self.assertEqual(self.signature(Spam.ham),
2573 ((('it', ..., ..., 'positional_or_keyword'),
2574 ('a', ..., ..., 'positional_or_keyword'),
2575 ('c', 1, ..., 'keyword_only')),
2576 'spam'))
2577
2578 self.assertEqual(self.signature(Spam().ham),
2579 ((('a', ..., ..., 'positional_or_keyword'),
2580 ('c', 1, ..., 'keyword_only')),
2581 'spam'))
2582
Yury Selivanov0486f812014-01-29 12:18:59 -05002583 def test_signature_on_fake_partialmethod(self):
2584 def foo(a): pass
2585 foo._partialmethod = 'spam'
2586 self.assertEqual(str(inspect.signature(foo)), '(a)')
2587
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002588 def test_signature_on_decorated(self):
2589 import functools
2590
2591 def decorator(func):
2592 @functools.wraps(func)
2593 def wrapper(*args, **kwargs) -> int:
2594 return func(*args, **kwargs)
2595 return wrapper
2596
2597 class Foo:
2598 @decorator
2599 def bar(self, a, b):
2600 pass
2601
2602 self.assertEqual(self.signature(Foo.bar),
2603 ((('self', ..., ..., "positional_or_keyword"),
2604 ('a', ..., ..., "positional_or_keyword"),
2605 ('b', ..., ..., "positional_or_keyword")),
2606 ...))
2607
2608 self.assertEqual(self.signature(Foo().bar),
2609 ((('a', ..., ..., "positional_or_keyword"),
2610 ('b', ..., ..., "positional_or_keyword")),
2611 ...))
2612
Yury Selivanovbcd4fc12015-05-20 14:30:08 -04002613 self.assertEqual(self.signature(Foo.bar, follow_wrapped=False),
2614 ((('args', ..., ..., "var_positional"),
2615 ('kwargs', ..., ..., "var_keyword")),
2616 ...)) # functools.wraps will copy __annotations__
2617 # from "func" to "wrapper", hence no
2618 # return_annotation
2619
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002620 # Test that we handle method wrappers correctly
2621 def decorator(func):
2622 @functools.wraps(func)
2623 def wrapper(*args, **kwargs) -> int:
2624 return func(42, *args, **kwargs)
2625 sig = inspect.signature(func)
2626 new_params = tuple(sig.parameters.values())[1:]
2627 wrapper.__signature__ = sig.replace(parameters=new_params)
2628 return wrapper
2629
2630 class Foo:
2631 @decorator
2632 def __call__(self, a, b):
2633 pass
2634
2635 self.assertEqual(self.signature(Foo.__call__),
2636 ((('a', ..., ..., "positional_or_keyword"),
2637 ('b', ..., ..., "positional_or_keyword")),
2638 ...))
2639
2640 self.assertEqual(self.signature(Foo().__call__),
2641 ((('b', ..., ..., "positional_or_keyword"),),
2642 ...))
2643
Nick Coghlane8c45d62013-07-28 20:00:01 +10002644 # Test we handle __signature__ partway down the wrapper stack
2645 def wrapped_foo_call():
2646 pass
2647 wrapped_foo_call.__wrapped__ = Foo.__call__
2648
2649 self.assertEqual(self.signature(wrapped_foo_call),
2650 ((('a', ..., ..., "positional_or_keyword"),
2651 ('b', ..., ..., "positional_or_keyword")),
2652 ...))
2653
2654
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002655 def test_signature_on_class(self):
2656 class C:
2657 def __init__(self, a):
2658 pass
2659
2660 self.assertEqual(self.signature(C),
2661 ((('a', ..., ..., "positional_or_keyword"),),
2662 ...))
2663
2664 class CM(type):
2665 def __call__(cls, a):
2666 pass
2667 class C(metaclass=CM):
2668 def __init__(self, b):
2669 pass
2670
2671 self.assertEqual(self.signature(C),
2672 ((('a', ..., ..., "positional_or_keyword"),),
2673 ...))
2674
2675 class CM(type):
2676 def __new__(mcls, name, bases, dct, *, foo=1):
2677 return super().__new__(mcls, name, bases, dct)
2678 class C(metaclass=CM):
2679 def __init__(self, b):
2680 pass
2681
2682 self.assertEqual(self.signature(C),
2683 ((('b', ..., ..., "positional_or_keyword"),),
2684 ...))
2685
2686 self.assertEqual(self.signature(CM),
2687 ((('name', ..., ..., "positional_or_keyword"),
2688 ('bases', ..., ..., "positional_or_keyword"),
2689 ('dct', ..., ..., "positional_or_keyword"),
2690 ('foo', 1, ..., "keyword_only")),
2691 ...))
2692
2693 class CMM(type):
2694 def __new__(mcls, name, bases, dct, *, foo=1):
2695 return super().__new__(mcls, name, bases, dct)
2696 def __call__(cls, nm, bs, dt):
2697 return type(nm, bs, dt)
2698 class CM(type, metaclass=CMM):
2699 def __new__(mcls, name, bases, dct, *, bar=2):
2700 return super().__new__(mcls, name, bases, dct)
2701 class C(metaclass=CM):
2702 def __init__(self, b):
2703 pass
2704
2705 self.assertEqual(self.signature(CMM),
2706 ((('name', ..., ..., "positional_or_keyword"),
2707 ('bases', ..., ..., "positional_or_keyword"),
2708 ('dct', ..., ..., "positional_or_keyword"),
2709 ('foo', 1, ..., "keyword_only")),
2710 ...))
2711
2712 self.assertEqual(self.signature(CM),
2713 ((('nm', ..., ..., "positional_or_keyword"),
2714 ('bs', ..., ..., "positional_or_keyword"),
2715 ('dt', ..., ..., "positional_or_keyword")),
2716 ...))
2717
2718 self.assertEqual(self.signature(C),
2719 ((('b', ..., ..., "positional_or_keyword"),),
2720 ...))
2721
2722 class CM(type):
2723 def __init__(cls, name, bases, dct, *, bar=2):
2724 return super().__init__(name, bases, dct)
2725 class C(metaclass=CM):
2726 def __init__(self, b):
2727 pass
2728
2729 self.assertEqual(self.signature(CM),
2730 ((('name', ..., ..., "positional_or_keyword"),
2731 ('bases', ..., ..., "positional_or_keyword"),
2732 ('dct', ..., ..., "positional_or_keyword"),
2733 ('bar', 2, ..., "keyword_only")),
2734 ...))
2735
Yury Selivanov145dff82014-02-01 13:49:29 -05002736 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2737 "Signature information for builtins requires docstrings")
2738 def test_signature_on_class_without_init(self):
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002739 # Test classes without user-defined __init__ or __new__
2740 class C: pass
2741 self.assertEqual(str(inspect.signature(C)), '()')
2742 class D(C): pass
2743 self.assertEqual(str(inspect.signature(D)), '()')
2744
2745 # Test meta-classes without user-defined __init__ or __new__
2746 class C(type): pass
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002747 class D(C): pass
Larry Hastings2623c8c2014-02-08 22:15:29 -08002748 with self.assertRaisesRegex(ValueError, "callable.*is not supported"):
2749 self.assertEqual(inspect.signature(C), None)
2750 with self.assertRaisesRegex(ValueError, "callable.*is not supported"):
2751 self.assertEqual(inspect.signature(D), None)
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002752
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002753 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2754 "Signature information for builtins requires docstrings")
2755 def test_signature_on_builtin_class(self):
2756 self.assertEqual(str(inspect.signature(_pickle.Pickler)),
2757 '(file, protocol=None, fix_imports=True)')
2758
2759 class P(_pickle.Pickler): pass
2760 class EmptyTrait: pass
2761 class P2(EmptyTrait, P): pass
2762 self.assertEqual(str(inspect.signature(P)),
2763 '(file, protocol=None, fix_imports=True)')
2764 self.assertEqual(str(inspect.signature(P2)),
2765 '(file, protocol=None, fix_imports=True)')
2766
2767 class P3(P2):
2768 def __init__(self, spam):
2769 pass
2770 self.assertEqual(str(inspect.signature(P3)), '(spam)')
2771
2772 class MetaP(type):
2773 def __call__(cls, foo, bar):
2774 pass
2775 class P4(P2, metaclass=MetaP):
2776 pass
2777 self.assertEqual(str(inspect.signature(P4)), '(foo, bar)')
2778
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002779 def test_signature_on_callable_objects(self):
2780 class Foo:
2781 def __call__(self, a):
2782 pass
2783
2784 self.assertEqual(self.signature(Foo()),
2785 ((('a', ..., ..., "positional_or_keyword"),),
2786 ...))
2787
2788 class Spam:
2789 pass
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002790 with self.assertRaisesRegex(TypeError, "is not a callable object"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002791 inspect.signature(Spam())
2792
2793 class Bar(Spam, Foo):
2794 pass
2795
2796 self.assertEqual(self.signature(Bar()),
2797 ((('a', ..., ..., "positional_or_keyword"),),
2798 ...))
2799
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002800 class Wrapped:
2801 pass
2802 Wrapped.__wrapped__ = lambda a: None
2803 self.assertEqual(self.signature(Wrapped),
2804 ((('a', ..., ..., "positional_or_keyword"),),
2805 ...))
Nick Coghlane8c45d62013-07-28 20:00:01 +10002806 # wrapper loop:
2807 Wrapped.__wrapped__ = Wrapped
2808 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
2809 self.signature(Wrapped)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002810
2811 def test_signature_on_lambdas(self):
2812 self.assertEqual(self.signature((lambda a=10: a)),
2813 ((('a', 10, ..., "positional_or_keyword"),),
2814 ...))
2815
2816 def test_signature_equality(self):
2817 def foo(a, *, b:int) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002818 self.assertFalse(inspect.signature(foo) == 42)
2819 self.assertTrue(inspect.signature(foo) != 42)
2820 self.assertTrue(inspect.signature(foo) == EqualsToAll())
2821 self.assertFalse(inspect.signature(foo) != EqualsToAll())
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002822
2823 def bar(a, *, b:int) -> float: 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 bar(a, *, b:int) -> int: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002830 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
2831 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002832 self.assertNotEqual(
2833 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002834
2835 def bar(a, *, b:int): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002836 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
2837 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002838 self.assertNotEqual(
2839 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002840
2841 def bar(a, *, b:int=42) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002842 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
2843 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002844 self.assertNotEqual(
2845 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002846
2847 def bar(a, *, c) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002848 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
2849 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002850 self.assertNotEqual(
2851 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002852
2853 def bar(a, b:int) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002854 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
2855 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002856 self.assertNotEqual(
2857 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002858 def spam(b:int, a) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002859 self.assertFalse(inspect.signature(spam) == inspect.signature(bar))
2860 self.assertTrue(inspect.signature(spam) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002861 self.assertNotEqual(
2862 hash(inspect.signature(spam)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002863
2864 def foo(*, a, b, c): pass
2865 def bar(*, c, b, a): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002866 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
2867 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002868 self.assertEqual(
2869 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002870
2871 def foo(*, a=1, b, c): pass
2872 def bar(*, c, b, a=1): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002873 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
2874 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002875 self.assertEqual(
2876 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002877
2878 def foo(pos, *, a=1, b, c): pass
2879 def bar(pos, *, c, b, a=1): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002880 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
2881 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002882 self.assertEqual(
2883 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002884
2885 def foo(pos, *, a, b, c): pass
2886 def bar(pos, *, c, b, a=1): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002887 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
2888 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002889 self.assertNotEqual(
2890 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002891
2892 def foo(pos, *args, a=42, b, c, **kwargs:int): pass
2893 def bar(pos, *args, c, b, a=42, **kwargs:int): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002894 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
2895 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002896 self.assertEqual(
2897 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002898
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002899 def test_signature_hashable(self):
2900 S = inspect.Signature
2901 P = inspect.Parameter
2902
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002903 def foo(a): pass
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002904 foo_sig = inspect.signature(foo)
2905
2906 manual_sig = S(parameters=[P('a', P.POSITIONAL_OR_KEYWORD)])
2907
2908 self.assertEqual(hash(foo_sig), hash(manual_sig))
2909 self.assertNotEqual(hash(foo_sig),
2910 hash(manual_sig.replace(return_annotation='spam')))
2911
2912 def bar(a) -> 1: pass
2913 self.assertNotEqual(hash(foo_sig), hash(inspect.signature(bar)))
2914
2915 def foo(a={}): pass
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002916 with self.assertRaisesRegex(TypeError, 'unhashable type'):
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002917 hash(inspect.signature(foo))
2918
2919 def foo(a) -> {}: pass
2920 with self.assertRaisesRegex(TypeError, 'unhashable type'):
2921 hash(inspect.signature(foo))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002922
2923 def test_signature_str(self):
2924 def foo(a:int=1, *, b, c=None, **kwargs) -> 42:
2925 pass
2926 self.assertEqual(str(inspect.signature(foo)),
Dong-hee Na762b9572017-11-16 03:30:59 +09002927 '(a: int = 1, *, b, c=None, **kwargs) -> 42')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002928
2929 def foo(a:int=1, *args, b, c=None, **kwargs) -> 42:
2930 pass
2931 self.assertEqual(str(inspect.signature(foo)),
Dong-hee Na762b9572017-11-16 03:30:59 +09002932 '(a: int = 1, *args, b, c=None, **kwargs) -> 42')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002933
2934 def foo():
2935 pass
2936 self.assertEqual(str(inspect.signature(foo)), '()')
2937
2938 def test_signature_str_positional_only(self):
2939 P = inspect.Parameter
Yury Selivanov2393dca2014-01-27 15:07:58 -05002940 S = inspect.Signature
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002941
2942 def test(a_po, *, b, **kwargs):
2943 return a_po, kwargs
2944
2945 sig = inspect.signature(test)
2946 new_params = list(sig.parameters.values())
2947 new_params[0] = new_params[0].replace(kind=P.POSITIONAL_ONLY)
2948 test.__signature__ = sig.replace(parameters=new_params)
2949
2950 self.assertEqual(str(inspect.signature(test)),
Yury Selivanov2393dca2014-01-27 15:07:58 -05002951 '(a_po, /, *, b, **kwargs)')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002952
Yury Selivanov2393dca2014-01-27 15:07:58 -05002953 self.assertEqual(str(S(parameters=[P('foo', P.POSITIONAL_ONLY)])),
2954 '(foo, /)')
2955
2956 self.assertEqual(str(S(parameters=[
2957 P('foo', P.POSITIONAL_ONLY),
2958 P('bar', P.VAR_KEYWORD)])),
2959 '(foo, /, **bar)')
2960
2961 self.assertEqual(str(S(parameters=[
2962 P('foo', P.POSITIONAL_ONLY),
2963 P('bar', P.VAR_POSITIONAL)])),
2964 '(foo, /, *bar)')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002965
2966 def test_signature_replace_anno(self):
2967 def test() -> 42:
2968 pass
2969
2970 sig = inspect.signature(test)
2971 sig = sig.replace(return_annotation=None)
2972 self.assertIs(sig.return_annotation, None)
2973 sig = sig.replace(return_annotation=sig.empty)
2974 self.assertIs(sig.return_annotation, sig.empty)
2975 sig = sig.replace(return_annotation=42)
2976 self.assertEqual(sig.return_annotation, 42)
2977 self.assertEqual(sig, inspect.signature(test))
2978
Yury Selivanov34ce99f2014-02-18 12:49:41 -05002979 def test_signature_on_mangled_parameters(self):
2980 class Spam:
2981 def foo(self, __p1:1=2, *, __p2:2=3):
2982 pass
2983 class Ham(Spam):
2984 pass
2985
2986 self.assertEqual(self.signature(Spam.foo),
2987 ((('self', ..., ..., "positional_or_keyword"),
2988 ('_Spam__p1', 2, 1, "positional_or_keyword"),
2989 ('_Spam__p2', 3, 2, "keyword_only")),
2990 ...))
2991
2992 self.assertEqual(self.signature(Spam.foo),
2993 self.signature(Ham.foo))
2994
Yury Selivanovda396452014-03-27 12:09:24 -04002995 def test_signature_from_callable_python_obj(self):
2996 class MySignature(inspect.Signature): pass
2997 def foo(a, *, b:1): pass
2998 foo_sig = MySignature.from_callable(foo)
2999 self.assertTrue(isinstance(foo_sig, MySignature))
3000
3001 @unittest.skipIf(MISSING_C_DOCSTRINGS,
3002 "Signature information for builtins requires docstrings")
3003 def test_signature_from_callable_builtin_obj(self):
3004 class MySignature(inspect.Signature): pass
3005 sig = MySignature.from_callable(_pickle.Pickler)
3006 self.assertTrue(isinstance(sig, MySignature))
3007
larryhastingsf36ba122018-01-28 11:13:09 -08003008 def test_signature_definition_order_preserved_on_kwonly(self):
3009 for fn in signatures_with_lexicographic_keyword_only_parameters():
3010 signature = inspect.signature(fn)
3011 l = list(signature.parameters)
3012 sorted_l = sorted(l)
3013 self.assertTrue(l)
3014 self.assertEqual(l, sorted_l)
3015 signature = inspect.signature(unsorted_keyword_only_parameters_fn)
3016 l = list(signature.parameters)
3017 self.assertEqual(l, unsorted_keyword_only_parameters)
3018
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003019
3020class TestParameterObject(unittest.TestCase):
3021 def test_signature_parameter_kinds(self):
3022 P = inspect.Parameter
3023 self.assertTrue(P.POSITIONAL_ONLY < P.POSITIONAL_OR_KEYWORD < \
3024 P.VAR_POSITIONAL < P.KEYWORD_ONLY < P.VAR_KEYWORD)
3025
3026 self.assertEqual(str(P.POSITIONAL_ONLY), 'POSITIONAL_ONLY')
3027 self.assertTrue('POSITIONAL_ONLY' in repr(P.POSITIONAL_ONLY))
3028
3029 def test_signature_parameter_object(self):
3030 p = inspect.Parameter('foo', default=10,
3031 kind=inspect.Parameter.POSITIONAL_ONLY)
3032 self.assertEqual(p.name, 'foo')
3033 self.assertEqual(p.default, 10)
3034 self.assertIs(p.annotation, p.empty)
3035 self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY)
3036
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003037 with self.assertRaisesRegex(ValueError, 'invalid value'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003038 inspect.Parameter('foo', default=10, kind='123')
3039
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003040 with self.assertRaisesRegex(ValueError, 'not a valid parameter name'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003041 inspect.Parameter('1', kind=inspect.Parameter.VAR_KEYWORD)
3042
Yury Selivanov2393dca2014-01-27 15:07:58 -05003043 with self.assertRaisesRegex(TypeError, 'name must be a str'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003044 inspect.Parameter(None, kind=inspect.Parameter.VAR_KEYWORD)
3045
Yury Selivanov2393dca2014-01-27 15:07:58 -05003046 with self.assertRaisesRegex(ValueError,
3047 'is not a valid parameter name'):
3048 inspect.Parameter('$', kind=inspect.Parameter.VAR_KEYWORD)
3049
Nick Coghlanb4b966e2016-06-04 14:40:03 -07003050 with self.assertRaisesRegex(ValueError,
3051 'is not a valid parameter name'):
3052 inspect.Parameter('.a', kind=inspect.Parameter.VAR_KEYWORD)
3053
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003054 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003055 inspect.Parameter('a', default=42,
3056 kind=inspect.Parameter.VAR_KEYWORD)
3057
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003058 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003059 inspect.Parameter('a', default=42,
3060 kind=inspect.Parameter.VAR_POSITIONAL)
3061
3062 p = inspect.Parameter('a', default=42,
3063 kind=inspect.Parameter.POSITIONAL_OR_KEYWORD)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003064 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003065 p.replace(kind=inspect.Parameter.VAR_POSITIONAL)
3066
3067 self.assertTrue(repr(p).startswith('<Parameter'))
Yury Selivanov374375d2014-03-27 12:41:53 -04003068 self.assertTrue('"a=42"' in repr(p))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003069
Yury Selivanov67ae50e2014-04-08 11:46:50 -04003070 def test_signature_parameter_hashable(self):
3071 P = inspect.Parameter
3072 foo = P('foo', kind=P.POSITIONAL_ONLY)
3073 self.assertEqual(hash(foo), hash(P('foo', kind=P.POSITIONAL_ONLY)))
3074 self.assertNotEqual(hash(foo), hash(P('foo', kind=P.POSITIONAL_ONLY,
3075 default=42)))
3076 self.assertNotEqual(hash(foo),
3077 hash(foo.replace(kind=P.VAR_POSITIONAL)))
3078
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003079 def test_signature_parameter_equality(self):
3080 P = inspect.Parameter
3081 p = P('foo', default=42, kind=inspect.Parameter.KEYWORD_ONLY)
3082
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003083 self.assertTrue(p == p)
3084 self.assertFalse(p != p)
3085 self.assertFalse(p == 42)
3086 self.assertTrue(p != 42)
3087 self.assertTrue(p == EqualsToAll())
3088 self.assertFalse(p != EqualsToAll())
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003089
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003090 self.assertTrue(p == P('foo', default=42,
3091 kind=inspect.Parameter.KEYWORD_ONLY))
3092 self.assertFalse(p != P('foo', default=42,
3093 kind=inspect.Parameter.KEYWORD_ONLY))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003094
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003095 def test_signature_parameter_replace(self):
3096 p = inspect.Parameter('foo', default=42,
3097 kind=inspect.Parameter.KEYWORD_ONLY)
3098
3099 self.assertIsNot(p, p.replace())
3100 self.assertEqual(p, p.replace())
3101
3102 p2 = p.replace(annotation=1)
3103 self.assertEqual(p2.annotation, 1)
3104 p2 = p2.replace(annotation=p2.empty)
3105 self.assertEqual(p, p2)
3106
3107 p2 = p2.replace(name='bar')
3108 self.assertEqual(p2.name, 'bar')
3109 self.assertNotEqual(p2, p)
3110
Yury Selivanov2393dca2014-01-27 15:07:58 -05003111 with self.assertRaisesRegex(ValueError,
3112 'name is a required attribute'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003113 p2 = p2.replace(name=p2.empty)
3114
3115 p2 = p2.replace(name='foo', default=None)
3116 self.assertIs(p2.default, None)
3117 self.assertNotEqual(p2, p)
3118
3119 p2 = p2.replace(name='foo', default=p2.empty)
3120 self.assertIs(p2.default, p2.empty)
3121
3122
3123 p2 = p2.replace(default=42, kind=p2.POSITIONAL_OR_KEYWORD)
3124 self.assertEqual(p2.kind, p2.POSITIONAL_OR_KEYWORD)
3125 self.assertNotEqual(p2, p)
3126
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003127 with self.assertRaisesRegex(ValueError, 'invalid value for'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003128 p2 = p2.replace(kind=p2.empty)
3129
3130 p2 = p2.replace(kind=p2.KEYWORD_ONLY)
3131 self.assertEqual(p2, p)
3132
3133 def test_signature_parameter_positional_only(self):
Yury Selivanov2393dca2014-01-27 15:07:58 -05003134 with self.assertRaisesRegex(TypeError, 'name must be a str'):
3135 inspect.Parameter(None, kind=inspect.Parameter.POSITIONAL_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003136
Nick Coghlanb4b966e2016-06-04 14:40:03 -07003137 @cpython_only
3138 def test_signature_parameter_implicit(self):
3139 with self.assertRaisesRegex(ValueError,
3140 'implicit arguments must be passed in as'):
3141 inspect.Parameter('.0', kind=inspect.Parameter.POSITIONAL_ONLY)
3142
3143 param = inspect.Parameter(
3144 '.0', kind=inspect.Parameter.POSITIONAL_OR_KEYWORD)
3145 self.assertEqual(param.kind, inspect.Parameter.POSITIONAL_ONLY)
3146 self.assertEqual(param.name, 'implicit0')
3147
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003148 def test_signature_parameter_immutability(self):
Yury Selivanov2393dca2014-01-27 15:07:58 -05003149 p = inspect.Parameter('spam', kind=inspect.Parameter.KEYWORD_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003150
3151 with self.assertRaises(AttributeError):
3152 p.foo = 'bar'
3153
3154 with self.assertRaises(AttributeError):
3155 p.kind = 123
3156
3157
3158class TestSignatureBind(unittest.TestCase):
3159 @staticmethod
3160 def call(func, *args, **kwargs):
3161 sig = inspect.signature(func)
3162 ba = sig.bind(*args, **kwargs)
3163 return func(*ba.args, **ba.kwargs)
3164
3165 def test_signature_bind_empty(self):
3166 def test():
3167 return 42
3168
3169 self.assertEqual(self.call(test), 42)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003170 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003171 self.call(test, 1)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003172 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003173 self.call(test, 1, spam=10)
Yury Selivanov86872752015-05-19 00:27:49 -04003174 with self.assertRaisesRegex(
3175 TypeError, "got an unexpected keyword argument 'spam'"):
3176
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003177 self.call(test, spam=1)
3178
3179 def test_signature_bind_var(self):
3180 def test(*args, **kwargs):
3181 return args, kwargs
3182
3183 self.assertEqual(self.call(test), ((), {}))
3184 self.assertEqual(self.call(test, 1), ((1,), {}))
3185 self.assertEqual(self.call(test, 1, 2), ((1, 2), {}))
3186 self.assertEqual(self.call(test, foo='bar'), ((), {'foo': 'bar'}))
3187 self.assertEqual(self.call(test, 1, foo='bar'), ((1,), {'foo': 'bar'}))
3188 self.assertEqual(self.call(test, args=10), ((), {'args': 10}))
3189 self.assertEqual(self.call(test, 1, 2, foo='bar'),
3190 ((1, 2), {'foo': 'bar'}))
3191
3192 def test_signature_bind_just_args(self):
3193 def test(a, b, c):
3194 return a, b, c
3195
3196 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
3197
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003198 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003199 self.call(test, 1, 2, 3, 4)
3200
Yury Selivanov86872752015-05-19 00:27:49 -04003201 with self.assertRaisesRegex(TypeError,
3202 "missing a required argument: 'b'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003203 self.call(test, 1)
3204
Yury Selivanov86872752015-05-19 00:27:49 -04003205 with self.assertRaisesRegex(TypeError,
3206 "missing a required argument: 'a'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003207 self.call(test)
3208
3209 def test(a, b, c=10):
3210 return a, b, c
3211 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
3212 self.assertEqual(self.call(test, 1, 2), (1, 2, 10))
3213
3214 def test(a=1, b=2, c=3):
3215 return a, b, c
3216 self.assertEqual(self.call(test, a=10, c=13), (10, 2, 13))
3217 self.assertEqual(self.call(test, a=10), (10, 2, 3))
3218 self.assertEqual(self.call(test, b=10), (1, 10, 3))
3219
3220 def test_signature_bind_varargs_order(self):
3221 def test(*args):
3222 return args
3223
3224 self.assertEqual(self.call(test), ())
3225 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
3226
3227 def test_signature_bind_args_and_varargs(self):
3228 def test(a, b, c=3, *args):
3229 return a, b, c, args
3230
3231 self.assertEqual(self.call(test, 1, 2, 3, 4, 5), (1, 2, 3, (4, 5)))
3232 self.assertEqual(self.call(test, 1, 2), (1, 2, 3, ()))
3233 self.assertEqual(self.call(test, b=1, a=2), (2, 1, 3, ()))
3234 self.assertEqual(self.call(test, 1, b=2), (1, 2, 3, ()))
3235
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003236 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003237 "multiple values for argument 'c'"):
3238 self.call(test, 1, 2, 3, c=4)
3239
3240 def test_signature_bind_just_kwargs(self):
3241 def test(**kwargs):
3242 return kwargs
3243
3244 self.assertEqual(self.call(test), {})
3245 self.assertEqual(self.call(test, foo='bar', spam='ham'),
3246 {'foo': 'bar', 'spam': 'ham'})
3247
3248 def test_signature_bind_args_and_kwargs(self):
3249 def test(a, b, c=3, **kwargs):
3250 return a, b, c, kwargs
3251
3252 self.assertEqual(self.call(test, 1, 2), (1, 2, 3, {}))
3253 self.assertEqual(self.call(test, 1, 2, foo='bar', spam='ham'),
3254 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3255 self.assertEqual(self.call(test, b=2, a=1, foo='bar', spam='ham'),
3256 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3257 self.assertEqual(self.call(test, a=1, b=2, foo='bar', spam='ham'),
3258 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3259 self.assertEqual(self.call(test, 1, b=2, foo='bar', spam='ham'),
3260 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3261 self.assertEqual(self.call(test, 1, b=2, c=4, foo='bar', spam='ham'),
3262 (1, 2, 4, {'foo': 'bar', 'spam': 'ham'}))
3263 self.assertEqual(self.call(test, 1, 2, 4, foo='bar'),
3264 (1, 2, 4, {'foo': 'bar'}))
3265 self.assertEqual(self.call(test, c=5, a=4, b=3),
3266 (4, 3, 5, {}))
3267
3268 def test_signature_bind_kwonly(self):
3269 def test(*, foo):
3270 return foo
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003271 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003272 'too many positional arguments'):
3273 self.call(test, 1)
3274 self.assertEqual(self.call(test, foo=1), 1)
3275
3276 def test(a, *, foo=1, bar):
3277 return foo
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003278 with self.assertRaisesRegex(TypeError,
Yury Selivanov86872752015-05-19 00:27:49 -04003279 "missing a required argument: 'bar'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003280 self.call(test, 1)
3281
3282 def test(foo, *, bar):
3283 return foo, bar
3284 self.assertEqual(self.call(test, 1, bar=2), (1, 2))
3285 self.assertEqual(self.call(test, bar=2, foo=1), (1, 2))
3286
Yury Selivanov86872752015-05-19 00:27:49 -04003287 with self.assertRaisesRegex(
3288 TypeError, "got an unexpected keyword argument 'spam'"):
3289
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003290 self.call(test, bar=2, foo=1, spam=10)
3291
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003292 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003293 'too many positional arguments'):
3294 self.call(test, 1, 2)
3295
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003296 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003297 'too many positional arguments'):
3298 self.call(test, 1, 2, bar=2)
3299
Yury Selivanov86872752015-05-19 00:27:49 -04003300 with self.assertRaisesRegex(
3301 TypeError, "got an unexpected keyword argument 'spam'"):
3302
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003303 self.call(test, 1, bar=2, spam='ham')
3304
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003305 with self.assertRaisesRegex(TypeError,
Yury Selivanov86872752015-05-19 00:27:49 -04003306 "missing a required argument: 'bar'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003307 self.call(test, 1)
3308
3309 def test(foo, *, bar, **bin):
3310 return foo, bar, bin
3311 self.assertEqual(self.call(test, 1, bar=2), (1, 2, {}))
3312 self.assertEqual(self.call(test, foo=1, bar=2), (1, 2, {}))
3313 self.assertEqual(self.call(test, 1, bar=2, spam='ham'),
3314 (1, 2, {'spam': 'ham'}))
3315 self.assertEqual(self.call(test, spam='ham', foo=1, bar=2),
3316 (1, 2, {'spam': 'ham'}))
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003317 with self.assertRaisesRegex(TypeError,
Yury Selivanov86872752015-05-19 00:27:49 -04003318 "missing a required argument: 'foo'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003319 self.call(test, spam='ham', bar=2)
3320 self.assertEqual(self.call(test, 1, bar=2, bin=1, spam=10),
3321 (1, 2, {'bin': 1, 'spam': 10}))
3322
3323 def test_signature_bind_arguments(self):
3324 def test(a, *args, b, z=100, **kwargs):
3325 pass
3326 sig = inspect.signature(test)
3327 ba = sig.bind(10, 20, b=30, c=40, args=50, kwargs=60)
3328 # we won't have 'z' argument in the bound arguments object, as we didn't
3329 # pass it to the 'bind'
3330 self.assertEqual(tuple(ba.arguments.items()),
3331 (('a', 10), ('args', (20,)), ('b', 30),
3332 ('kwargs', {'c': 40, 'args': 50, 'kwargs': 60})))
3333 self.assertEqual(ba.kwargs,
3334 {'b': 30, 'c': 40, 'args': 50, 'kwargs': 60})
3335 self.assertEqual(ba.args, (10, 20))
3336
3337 def test_signature_bind_positional_only(self):
3338 P = inspect.Parameter
3339
3340 def test(a_po, b_po, c_po=3, foo=42, *, bar=50, **kwargs):
3341 return a_po, b_po, c_po, foo, bar, kwargs
3342
3343 sig = inspect.signature(test)
3344 new_params = collections.OrderedDict(tuple(sig.parameters.items()))
3345 for name in ('a_po', 'b_po', 'c_po'):
3346 new_params[name] = new_params[name].replace(kind=P.POSITIONAL_ONLY)
3347 new_sig = sig.replace(parameters=new_params.values())
3348 test.__signature__ = new_sig
3349
3350 self.assertEqual(self.call(test, 1, 2, 4, 5, bar=6),
3351 (1, 2, 4, 5, 6, {}))
3352
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05003353 self.assertEqual(self.call(test, 1, 2),
3354 (1, 2, 3, 42, 50, {}))
3355
3356 self.assertEqual(self.call(test, 1, 2, foo=4, bar=5),
3357 (1, 2, 3, 4, 5, {}))
3358
3359 with self.assertRaisesRegex(TypeError, "but was passed as a keyword"):
3360 self.call(test, 1, 2, foo=4, bar=5, c_po=10)
3361
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003362 with self.assertRaisesRegex(TypeError, "parameter is positional only"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003363 self.call(test, 1, 2, c_po=4)
3364
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003365 with self.assertRaisesRegex(TypeError, "parameter is positional only"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003366 self.call(test, a_po=1, b_po=2)
3367
Antoine Pitroubd41d1b2013-01-29 21:20:57 +01003368 def test_signature_bind_with_self_arg(self):
3369 # Issue #17071: one of the parameters is named "self
3370 def test(a, self, b):
3371 pass
3372 sig = inspect.signature(test)
3373 ba = sig.bind(1, 2, 3)
3374 self.assertEqual(ba.args, (1, 2, 3))
3375 ba = sig.bind(1, self=2, b=3)
3376 self.assertEqual(ba.args, (1, 2, 3))
3377
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05003378 def test_signature_bind_vararg_name(self):
3379 def test(a, *args):
3380 return a, args
3381 sig = inspect.signature(test)
3382
Yury Selivanov86872752015-05-19 00:27:49 -04003383 with self.assertRaisesRegex(
3384 TypeError, "got an unexpected keyword argument 'args'"):
3385
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05003386 sig.bind(a=0, args=1)
3387
3388 def test(*args, **kwargs):
3389 return args, kwargs
3390 self.assertEqual(self.call(test, args=1), ((), {'args': 1}))
3391
3392 sig = inspect.signature(test)
3393 ba = sig.bind(args=1)
3394 self.assertEqual(ba.arguments, {'kwargs': {'args': 1}})
3395
Nick Coghlanb4b966e2016-06-04 14:40:03 -07003396 @cpython_only
3397 def test_signature_bind_implicit_arg(self):
3398 # Issue #19611: getcallargs should work with set comprehensions
3399 def make_set():
3400 return {z * z for z in range(5)}
3401 setcomp_code = make_set.__code__.co_consts[1]
3402 setcomp_func = types.FunctionType(setcomp_code, {})
3403
3404 iterator = iter(range(5))
3405 self.assertEqual(self.call(setcomp_func, iterator), {0, 1, 4, 9, 16})
3406
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003407
3408class TestBoundArguments(unittest.TestCase):
3409 def test_signature_bound_arguments_unhashable(self):
3410 def foo(a): pass
3411 ba = inspect.signature(foo).bind(1)
3412
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003413 with self.assertRaisesRegex(TypeError, 'unhashable type'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003414 hash(ba)
3415
3416 def test_signature_bound_arguments_equality(self):
3417 def foo(a): pass
3418 ba = inspect.signature(foo).bind(1)
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003419 self.assertTrue(ba == ba)
3420 self.assertFalse(ba != ba)
3421 self.assertTrue(ba == EqualsToAll())
3422 self.assertFalse(ba != EqualsToAll())
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003423
3424 ba2 = inspect.signature(foo).bind(1)
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003425 self.assertTrue(ba == ba2)
3426 self.assertFalse(ba != ba2)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003427
3428 ba3 = inspect.signature(foo).bind(2)
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003429 self.assertFalse(ba == ba3)
3430 self.assertTrue(ba != ba3)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003431 ba3.arguments['a'] = 1
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003432 self.assertTrue(ba == ba3)
3433 self.assertFalse(ba != ba3)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003434
3435 def bar(b): pass
3436 ba4 = inspect.signature(bar).bind(1)
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003437 self.assertFalse(ba == ba4)
3438 self.assertTrue(ba != ba4)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003439
Yury Selivanov4cfd4ea2015-05-14 18:30:27 -04003440 def foo(*, a, b): pass
3441 sig = inspect.signature(foo)
3442 ba1 = sig.bind(a=1, b=2)
3443 ba2 = sig.bind(b=2, a=1)
Serhiy Storchaka2489bd52015-07-18 23:20:50 +03003444 self.assertTrue(ba1 == ba2)
3445 self.assertFalse(ba1 != ba2)
Yury Selivanov4cfd4ea2015-05-14 18:30:27 -04003446
Yury Selivanova5d63dd2014-03-27 11:31:43 -04003447 def test_signature_bound_arguments_pickle(self):
3448 def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
3449 sig = inspect.signature(foo)
3450 ba = sig.bind(20, 30, z={})
3451
3452 for ver in range(pickle.HIGHEST_PROTOCOL + 1):
3453 with self.subTest(pickle_ver=ver):
3454 ba_pickled = pickle.loads(pickle.dumps(ba, ver))
3455 self.assertEqual(ba, ba_pickled)
3456
Yury Selivanov3f6538f2015-05-14 18:47:17 -04003457 def test_signature_bound_arguments_repr(self):
3458 def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
3459 sig = inspect.signature(foo)
3460 ba = sig.bind(20, 30, z={})
Yury Selivanovf229bc52015-05-15 12:53:56 -04003461 self.assertRegex(repr(ba), r'<BoundArguments \(a=20,.*\}\}\)>')
Yury Selivanov3f6538f2015-05-14 18:47:17 -04003462
Yury Selivanovb907a512015-05-16 13:45:09 -04003463 def test_signature_bound_arguments_apply_defaults(self):
3464 def foo(a, b=1, *args, c:1={}, **kw): pass
3465 sig = inspect.signature(foo)
3466
3467 ba = sig.bind(20)
3468 ba.apply_defaults()
3469 self.assertEqual(
3470 list(ba.arguments.items()),
3471 [('a', 20), ('b', 1), ('args', ()), ('c', {}), ('kw', {})])
3472
3473 # Make sure that we preserve the order:
3474 # i.e. 'c' should be *before* 'kw'.
3475 ba = sig.bind(10, 20, 30, d=1)
3476 ba.apply_defaults()
3477 self.assertEqual(
3478 list(ba.arguments.items()),
3479 [('a', 10), ('b', 20), ('args', (30,)), ('c', {}), ('kw', {'d':1})])
3480
3481 # Make sure that BoundArguments produced by bind_partial()
3482 # are supported.
3483 def foo(a, b): pass
3484 sig = inspect.signature(foo)
3485 ba = sig.bind_partial(20)
3486 ba.apply_defaults()
3487 self.assertEqual(
3488 list(ba.arguments.items()),
3489 [('a', 20)])
3490
3491 # Test no args
3492 def foo(): pass
3493 sig = inspect.signature(foo)
3494 ba = sig.bind()
3495 ba.apply_defaults()
3496 self.assertEqual(list(ba.arguments.items()), [])
3497
Yury Selivanovf9e1f2b2016-03-02 11:07:47 -05003498 # Make sure a no-args binding still acquires proper defaults.
3499 def foo(a='spam'): pass
3500 sig = inspect.signature(foo)
3501 ba = sig.bind()
3502 ba.apply_defaults()
3503 self.assertEqual(list(ba.arguments.items()), [('a', 'spam')])
3504
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003505
Yury Selivanovd82eddc2014-01-29 11:24:39 -05003506class TestSignaturePrivateHelpers(unittest.TestCase):
3507 def test_signature_get_bound_param(self):
3508 getter = inspect._signature_get_bound_param
3509
3510 self.assertEqual(getter('($self)'), 'self')
3511 self.assertEqual(getter('($self, obj)'), 'self')
3512 self.assertEqual(getter('($cls, /, obj)'), 'cls')
3513
Larry Hastings2623c8c2014-02-08 22:15:29 -08003514 def _strip_non_python_syntax(self, input,
3515 clean_signature, self_parameter, last_positional_only):
3516 computed_clean_signature, \
3517 computed_self_parameter, \
3518 computed_last_positional_only = \
3519 inspect._signature_strip_non_python_syntax(input)
3520 self.assertEqual(computed_clean_signature, clean_signature)
3521 self.assertEqual(computed_self_parameter, self_parameter)
3522 self.assertEqual(computed_last_positional_only, last_positional_only)
3523
3524 def test_signature_strip_non_python_syntax(self):
3525 self._strip_non_python_syntax(
3526 "($module, /, path, mode, *, dir_fd=None, " +
3527 "effective_ids=False,\n follow_symlinks=True)",
3528 "(module, path, mode, *, dir_fd=None, " +
3529 "effective_ids=False, follow_symlinks=True)",
3530 0,
3531 0)
3532
3533 self._strip_non_python_syntax(
3534 "($module, word, salt, /)",
3535 "(module, word, salt)",
3536 0,
3537 2)
3538
3539 self._strip_non_python_syntax(
3540 "(x, y=None, z=None, /)",
3541 "(x, y=None, z=None)",
3542 None,
3543 2)
3544
3545 self._strip_non_python_syntax(
3546 "(x, y=None, z=None)",
3547 "(x, y=None, z=None)",
3548 None,
3549 None)
3550
3551 self._strip_non_python_syntax(
3552 "(x,\n y=None,\n z = None )",
3553 "(x, y=None, z=None)",
3554 None,
3555 None)
3556
3557 self._strip_non_python_syntax(
3558 "",
3559 "",
3560 None,
3561 None)
3562
3563 self._strip_non_python_syntax(
3564 None,
3565 None,
3566 None,
3567 None)
3568
Nick Coghlan9c680b02015-04-13 12:54:54 -04003569class TestSignatureDefinitions(unittest.TestCase):
3570 # This test case provides a home for checking that particular APIs
3571 # have signatures available for introspection
3572
3573 @cpython_only
3574 @unittest.skipIf(MISSING_C_DOCSTRINGS,
3575 "Signature information for builtins requires docstrings")
3576 def test_builtins_have_signatures(self):
3577 # This checks all builtin callables in CPython have signatures
3578 # A few have signatures Signature can't yet handle, so we skip those
3579 # since they will have to wait until PEP 457 adds the required
3580 # introspection support to the inspect module
3581 # Some others also haven't been converted yet for various other
3582 # reasons, so we also skip those for the time being, but design
3583 # the test to fail in order to indicate when it needs to be
3584 # updated.
3585 no_signature = set()
3586 # These need PEP 457 groups
3587 needs_groups = {"range", "slice", "dir", "getattr",
3588 "next", "iter", "vars"}
3589 no_signature |= needs_groups
3590 # These need PEP 457 groups or a signature change to accept None
3591 needs_semantic_update = {"round"}
3592 no_signature |= needs_semantic_update
3593 # These need *args support in Argument Clinic
Barry Warsaw36c1d1f2017-10-05 12:11:18 -04003594 needs_varargs = {"breakpoint", "min", "max", "print",
3595 "__build_class__"}
Nick Coghlan9c680b02015-04-13 12:54:54 -04003596 no_signature |= needs_varargs
3597 # These simply weren't covered in the initial AC conversion
3598 # for builtin callables
3599 not_converted_yet = {"open", "__import__"}
3600 no_signature |= not_converted_yet
3601 # These builtin types are expected to provide introspection info
3602 types_with_signatures = set()
3603 # Check the signatures we expect to be there
3604 ns = vars(builtins)
3605 for name, obj in sorted(ns.items()):
3606 if not callable(obj):
3607 continue
3608 # The builtin types haven't been converted to AC yet
3609 if isinstance(obj, type) and (name not in types_with_signatures):
3610 # Note that this also skips all the exception types
3611 no_signature.add(name)
3612 if (name in no_signature):
3613 # Not yet converted
3614 continue
3615 with self.subTest(builtin=name):
3616 self.assertIsNotNone(inspect.signature(obj))
3617 # Check callables that haven't been converted don't claim a signature
3618 # This ensures this test will start failing as more signatures are
3619 # added, so the affected items can be moved into the scope of the
3620 # regression test above
3621 for name in no_signature:
3622 with self.subTest(builtin=name):
3623 self.assertIsNone(obj.__text_signature__)
3624
Yury Selivanovd82eddc2014-01-29 11:24:39 -05003625
Thomas Kluyverf9169ce2017-05-23 04:27:52 +01003626class NTimesUnwrappable:
3627 def __init__(self, n):
3628 self.n = n
3629 self._next = None
3630
3631 @property
3632 def __wrapped__(self):
3633 if self.n <= 0:
3634 raise Exception("Unwrapped too many times")
3635 if self._next is None:
3636 self._next = NTimesUnwrappable(self.n - 1)
3637 return self._next
3638
Nick Coghlane8c45d62013-07-28 20:00:01 +10003639class TestUnwrap(unittest.TestCase):
3640
3641 def test_unwrap_one(self):
3642 def func(a, b):
3643 return a + b
3644 wrapper = functools.lru_cache(maxsize=20)(func)
3645 self.assertIs(inspect.unwrap(wrapper), func)
3646
3647 def test_unwrap_several(self):
3648 def func(a, b):
3649 return a + b
3650 wrapper = func
3651 for __ in range(10):
3652 @functools.wraps(wrapper)
3653 def wrapper():
3654 pass
3655 self.assertIsNot(wrapper.__wrapped__, func)
3656 self.assertIs(inspect.unwrap(wrapper), func)
3657
3658 def test_stop(self):
3659 def func1(a, b):
3660 return a + b
3661 @functools.wraps(func1)
3662 def func2():
3663 pass
3664 @functools.wraps(func2)
3665 def wrapper():
3666 pass
3667 func2.stop_here = 1
3668 unwrapped = inspect.unwrap(wrapper,
3669 stop=(lambda f: hasattr(f, "stop_here")))
3670 self.assertIs(unwrapped, func2)
3671
3672 def test_cycle(self):
3673 def func1(): pass
3674 func1.__wrapped__ = func1
3675 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3676 inspect.unwrap(func1)
3677
3678 def func2(): pass
3679 func2.__wrapped__ = func1
3680 func1.__wrapped__ = func2
3681 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3682 inspect.unwrap(func1)
3683 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3684 inspect.unwrap(func2)
3685
3686 def test_unhashable(self):
3687 def func(): pass
3688 func.__wrapped__ = None
3689 class C:
3690 __hash__ = None
3691 __wrapped__ = func
3692 self.assertIsNone(inspect.unwrap(C()))
3693
Thomas Kluyverf9169ce2017-05-23 04:27:52 +01003694 def test_recursion_limit(self):
3695 obj = NTimesUnwrappable(sys.getrecursionlimit() + 1)
3696 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3697 inspect.unwrap(obj)
3698
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003699class TestMain(unittest.TestCase):
3700 def test_only_source(self):
3701 module = importlib.import_module('unittest')
3702 rc, out, err = assert_python_ok('-m', 'inspect',
3703 'unittest')
3704 lines = out.decode().splitlines()
3705 # ignore the final newline
3706 self.assertEqual(lines[:-1], inspect.getsource(module).splitlines())
3707 self.assertEqual(err, b'')
3708
Yury Selivanov42407ab2014-06-23 10:23:50 -07003709 def test_custom_getattr(self):
3710 def foo():
3711 pass
3712 foo.__signature__ = 42
3713 with self.assertRaises(TypeError):
3714 inspect.signature(foo)
3715
Brett Cannon634a8fc2013-10-02 10:25:42 -04003716 @unittest.skipIf(ThreadPoolExecutor is None,
Brett Cannon0de3f012013-10-02 10:58:58 -04003717 'threads required to test __qualname__ for source files')
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003718 def test_qualname_source(self):
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003719 rc, out, err = assert_python_ok('-m', 'inspect',
3720 'concurrent.futures:ThreadPoolExecutor')
3721 lines = out.decode().splitlines()
3722 # ignore the final newline
3723 self.assertEqual(lines[:-1],
Brett Cannon634a8fc2013-10-02 10:25:42 -04003724 inspect.getsource(ThreadPoolExecutor).splitlines())
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003725 self.assertEqual(err, b'')
3726
3727 def test_builtins(self):
3728 module = importlib.import_module('unittest')
3729 _, out, err = assert_python_failure('-m', 'inspect',
3730 'sys')
3731 lines = err.decode().splitlines()
3732 self.assertEqual(lines, ["Can't get info for builtin modules."])
3733
3734 def test_details(self):
3735 module = importlib.import_module('unittest')
Victor Stinner9def2842016-01-18 12:15:08 +01003736 args = support.optim_args_from_interpreter_flags()
3737 rc, out, err = assert_python_ok(*args, '-m', 'inspect',
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003738 'unittest', '--details')
3739 output = out.decode()
3740 # Just a quick sanity check on the output
3741 self.assertIn(module.__name__, output)
3742 self.assertIn(module.__file__, output)
Victor Stinner9def2842016-01-18 12:15:08 +01003743 self.assertIn(module.__cached__, output)
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003744 self.assertEqual(err, b'')
3745
3746
Yury Selivanovef1e7502014-12-08 16:05:34 -05003747class TestReload(unittest.TestCase):
3748
3749 src_before = textwrap.dedent("""\
3750def foo():
3751 print("Bla")
3752 """)
3753
3754 src_after = textwrap.dedent("""\
3755def foo():
3756 print("Oh no!")
3757 """)
3758
3759 def assertInspectEqual(self, path, source):
3760 inspected_src = inspect.getsource(source)
3761 with open(path) as src:
3762 self.assertEqual(
3763 src.read().splitlines(True),
3764 inspected_src.splitlines(True)
3765 )
3766
3767 def test_getsource_reload(self):
3768 # see issue 1218234
3769 with _ready_to_import('reload_bug', self.src_before) as (name, path):
3770 module = importlib.import_module(name)
3771 self.assertInspectEqual(path, module)
3772 with open(path, 'w') as src:
3773 src.write(self.src_after)
3774 self.assertInspectEqual(path, module)
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003775
Nick Coghlane8c45d62013-07-28 20:00:01 +10003776
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00003777def test_main():
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00003778 run_unittest(
3779 TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBuggyCases,
3780 TestInterpreterStack, TestClassesAndFunctions, TestPredicates,
3781 TestGetcallargsFunctions, TestGetcallargsMethods,
Alexander Belopolskyf546e702010-12-02 00:10:11 +00003782 TestGetcallargsUnboundMethods, TestGetattrStatic, TestGetGeneratorState,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003783 TestNoEOL, TestSignatureObject, TestSignatureBind, TestParameterObject,
Nick Coghlan9c680b02015-04-13 12:54:54 -04003784 TestBoundArguments, TestSignaturePrivateHelpers,
3785 TestSignatureDefinitions,
Yury Selivanov5376ba92015-06-22 12:19:30 -04003786 TestGetClosureVars, TestUnwrap, TestMain, TestReload,
3787 TestGetCoroutineState
Michael Foord95fc51d2010-11-20 15:07:30 +00003788 )
Martin v. Löwis893ffa42003-10-31 15:35:53 +00003789
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00003790if __name__ == "__main__":
3791 test_main()