blob: ff6f0145451387ab0ff98f8659a867fbeb27b6d0 [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
Miss Islington (bot)cb055bc2018-05-29 08:43:54 -07001447 # bpo-33197
1448 with self.assertRaisesRegex(ValueError,
1449 'variadic keyword parameters cannot'
1450 ' have default values'):
1451 inspect.Parameter("foo", kind=inspect.Parameter.VAR_KEYWORD,
1452 default=42)
1453 with self.assertRaisesRegex(ValueError,
1454 "value 5 is not a valid Parameter.kind"):
1455 inspect.Parameter("bar", kind=5, default=42)
1456
1457 with self.assertRaisesRegex(TypeError,
1458 'name must be a str, not a int'):
1459 inspect.Parameter(123, kind=4)
1460
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001461class TestGetcallargsMethods(TestGetcallargsFunctions):
1462
1463 def setUp(self):
1464 class Foo(object):
1465 pass
1466 self.cls = Foo
1467 self.inst = Foo()
1468
1469 def makeCallable(self, signature):
1470 assert 'self' not in signature
1471 mk = super(TestGetcallargsMethods, self).makeCallable
1472 self.cls.method = mk('self, ' + signature)
1473 return self.inst.method
1474
1475class TestGetcallargsUnboundMethods(TestGetcallargsMethods):
1476
1477 def makeCallable(self, signature):
1478 super(TestGetcallargsUnboundMethods, self).makeCallable(signature)
1479 return self.cls.method
1480
1481 def assertEqualCallArgs(self, func, call_params_string, locs=None):
1482 return super(TestGetcallargsUnboundMethods, self).assertEqualCallArgs(
1483 *self._getAssertEqualParams(func, call_params_string, locs))
1484
1485 def assertEqualException(self, func, call_params_string, locs=None):
1486 return super(TestGetcallargsUnboundMethods, self).assertEqualException(
1487 *self._getAssertEqualParams(func, call_params_string, locs))
1488
1489 def _getAssertEqualParams(self, func, call_params_string, locs=None):
1490 assert 'inst' not in call_params_string
1491 locs = dict(locs or {}, inst=self.inst)
1492 return (func, 'inst,' + call_params_string, locs)
1493
Michael Foord95fc51d2010-11-20 15:07:30 +00001494
1495class TestGetattrStatic(unittest.TestCase):
1496
1497 def test_basic(self):
1498 class Thing(object):
1499 x = object()
1500
1501 thing = Thing()
1502 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1503 self.assertEqual(inspect.getattr_static(thing, 'x', None), Thing.x)
1504 with self.assertRaises(AttributeError):
1505 inspect.getattr_static(thing, 'y')
1506
1507 self.assertEqual(inspect.getattr_static(thing, 'y', 3), 3)
1508
1509 def test_inherited(self):
1510 class Thing(object):
1511 x = object()
1512 class OtherThing(Thing):
1513 pass
1514
1515 something = OtherThing()
1516 self.assertEqual(inspect.getattr_static(something, 'x'), Thing.x)
1517
1518 def test_instance_attr(self):
1519 class Thing(object):
1520 x = 2
1521 def __init__(self, x):
1522 self.x = x
1523 thing = Thing(3)
1524 self.assertEqual(inspect.getattr_static(thing, 'x'), 3)
1525 del thing.x
1526 self.assertEqual(inspect.getattr_static(thing, 'x'), 2)
1527
1528 def test_property(self):
1529 class Thing(object):
1530 @property
1531 def x(self):
1532 raise AttributeError("I'm pretending not to exist")
1533 thing = Thing()
1534 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1535
Ezio Melotti75cbd732011-04-28 00:59:29 +03001536 def test_descriptor_raises_AttributeError(self):
Michael Foord95fc51d2010-11-20 15:07:30 +00001537 class descriptor(object):
1538 def __get__(*_):
1539 raise AttributeError("I'm pretending not to exist")
1540 desc = descriptor()
1541 class Thing(object):
1542 x = desc
1543 thing = Thing()
1544 self.assertEqual(inspect.getattr_static(thing, 'x'), desc)
1545
1546 def test_classAttribute(self):
1547 class Thing(object):
1548 x = object()
1549
1550 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.x)
1551
Ethan Furmane03ea372013-09-25 07:14:41 -07001552 def test_classVirtualAttribute(self):
1553 class Thing(object):
1554 @types.DynamicClassAttribute
1555 def x(self):
1556 return self._x
1557 _x = object()
1558
1559 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.__dict__['x'])
1560
Michael Foord95fc51d2010-11-20 15:07:30 +00001561 def test_inherited_classattribute(self):
1562 class Thing(object):
1563 x = object()
1564 class OtherThing(Thing):
1565 pass
1566
1567 self.assertEqual(inspect.getattr_static(OtherThing, 'x'), Thing.x)
1568
1569 def test_slots(self):
1570 class Thing(object):
1571 y = 'bar'
1572 __slots__ = ['x']
1573 def __init__(self):
1574 self.x = 'foo'
1575 thing = Thing()
1576 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1577 self.assertEqual(inspect.getattr_static(thing, 'y'), 'bar')
1578
1579 del thing.x
1580 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1581
1582 def test_metaclass(self):
1583 class meta(type):
1584 attr = 'foo'
1585 class Thing(object, metaclass=meta):
1586 pass
1587 self.assertEqual(inspect.getattr_static(Thing, 'attr'), 'foo')
1588
1589 class sub(meta):
1590 pass
1591 class OtherThing(object, metaclass=sub):
1592 x = 3
1593 self.assertEqual(inspect.getattr_static(OtherThing, 'attr'), 'foo')
1594
1595 class OtherOtherThing(OtherThing):
1596 pass
1597 # this test is odd, but it was added as it exposed a bug
1598 self.assertEqual(inspect.getattr_static(OtherOtherThing, 'x'), 3)
1599
1600 def test_no_dict_no_slots(self):
1601 self.assertEqual(inspect.getattr_static(1, 'foo', None), None)
1602 self.assertNotEqual(inspect.getattr_static('foo', 'lower'), None)
1603
1604 def test_no_dict_no_slots_instance_member(self):
1605 # returns descriptor
1606 with open(__file__) as handle:
1607 self.assertEqual(inspect.getattr_static(handle, 'name'), type(handle).name)
1608
1609 def test_inherited_slots(self):
1610 # returns descriptor
1611 class Thing(object):
1612 __slots__ = ['x']
1613 def __init__(self):
1614 self.x = 'foo'
1615
1616 class OtherThing(Thing):
1617 pass
1618 # it would be nice if this worked...
1619 # we get the descriptor instead of the instance attribute
1620 self.assertEqual(inspect.getattr_static(OtherThing(), 'x'), Thing.x)
1621
1622 def test_descriptor(self):
1623 class descriptor(object):
1624 def __get__(self, instance, owner):
1625 return 3
1626 class Foo(object):
1627 d = descriptor()
1628
1629 foo = Foo()
1630
1631 # for a non data descriptor we return the instance attribute
1632 foo.__dict__['d'] = 1
1633 self.assertEqual(inspect.getattr_static(foo, 'd'), 1)
1634
Mike53f7a7c2017-12-14 14:04:53 +03001635 # if the descriptor is a data-descriptor we should return the
Michael Foord95fc51d2010-11-20 15:07:30 +00001636 # descriptor
1637 descriptor.__set__ = lambda s, i, v: None
1638 self.assertEqual(inspect.getattr_static(foo, 'd'), Foo.__dict__['d'])
1639
1640
1641 def test_metaclass_with_descriptor(self):
1642 class descriptor(object):
1643 def __get__(self, instance, owner):
1644 return 3
1645 class meta(type):
1646 d = descriptor()
1647 class Thing(object, metaclass=meta):
1648 pass
1649 self.assertEqual(inspect.getattr_static(Thing, 'd'), meta.__dict__['d'])
1650
1651
Michael Foordcc7ebb82010-11-20 16:20:16 +00001652 def test_class_as_property(self):
1653 class Base(object):
1654 foo = 3
1655
1656 class Something(Base):
Michael Foord35184ed2010-11-20 16:58:30 +00001657 executed = False
Michael Foordcc7ebb82010-11-20 16:20:16 +00001658 @property
1659 def __class__(self):
Michael Foord35184ed2010-11-20 16:58:30 +00001660 self.executed = True
Michael Foordcc7ebb82010-11-20 16:20:16 +00001661 return object
1662
Michael Foord35184ed2010-11-20 16:58:30 +00001663 instance = Something()
1664 self.assertEqual(inspect.getattr_static(instance, 'foo'), 3)
1665 self.assertFalse(instance.executed)
Michael Foordcc7ebb82010-11-20 16:20:16 +00001666 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1667
Michael Foorde5162652010-11-20 16:40:44 +00001668 def test_mro_as_property(self):
1669 class Meta(type):
1670 @property
1671 def __mro__(self):
1672 return (object,)
1673
1674 class Base(object):
1675 foo = 3
1676
1677 class Something(Base, metaclass=Meta):
1678 pass
1679
1680 self.assertEqual(inspect.getattr_static(Something(), 'foo'), 3)
1681 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1682
Michael Foorddcebe0f2011-03-15 19:20:44 -04001683 def test_dict_as_property(self):
1684 test = self
1685 test.called = False
1686
1687 class Foo(dict):
1688 a = 3
1689 @property
1690 def __dict__(self):
1691 test.called = True
1692 return {}
1693
1694 foo = Foo()
1695 foo.a = 4
1696 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1697 self.assertFalse(test.called)
1698
1699 def test_custom_object_dict(self):
1700 test = self
1701 test.called = False
1702
1703 class Custom(dict):
1704 def get(self, key, default=None):
1705 test.called = True
1706 super().get(key, default)
1707
1708 class Foo(object):
1709 a = 3
1710 foo = Foo()
1711 foo.__dict__ = Custom()
1712 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1713 self.assertFalse(test.called)
1714
1715 def test_metaclass_dict_as_property(self):
1716 class Meta(type):
1717 @property
1718 def __dict__(self):
1719 self.executed = True
1720
1721 class Thing(metaclass=Meta):
1722 executed = False
1723
1724 def __init__(self):
1725 self.spam = 42
1726
1727 instance = Thing()
1728 self.assertEqual(inspect.getattr_static(instance, "spam"), 42)
1729 self.assertFalse(Thing.executed)
Michael Foorde5162652010-11-20 16:40:44 +00001730
Michael Foorda51623b2011-12-18 22:01:40 +00001731 def test_module(self):
1732 sentinel = object()
1733 self.assertIsNot(inspect.getattr_static(sys, "version", sentinel),
1734 sentinel)
1735
Michael Foord3ba95f82011-12-22 01:13:37 +00001736 def test_metaclass_with_metaclass_with_dict_as_property(self):
1737 class MetaMeta(type):
1738 @property
1739 def __dict__(self):
1740 self.executed = True
1741 return dict(spam=42)
1742
1743 class Meta(type, metaclass=MetaMeta):
1744 executed = False
1745
1746 class Thing(metaclass=Meta):
1747 pass
1748
1749 with self.assertRaises(AttributeError):
1750 inspect.getattr_static(Thing, "spam")
1751 self.assertFalse(Thing.executed)
1752
Nick Coghlane0f04652010-11-21 03:44:04 +00001753class TestGetGeneratorState(unittest.TestCase):
1754
1755 def setUp(self):
1756 def number_generator():
1757 for number in range(5):
1758 yield number
1759 self.generator = number_generator()
1760
1761 def _generatorstate(self):
1762 return inspect.getgeneratorstate(self.generator)
1763
1764 def test_created(self):
1765 self.assertEqual(self._generatorstate(), inspect.GEN_CREATED)
1766
1767 def test_suspended(self):
1768 next(self.generator)
1769 self.assertEqual(self._generatorstate(), inspect.GEN_SUSPENDED)
1770
1771 def test_closed_after_exhaustion(self):
1772 for i in self.generator:
1773 pass
1774 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1775
1776 def test_closed_after_immediate_exception(self):
1777 with self.assertRaises(RuntimeError):
1778 self.generator.throw(RuntimeError)
1779 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1780
1781 def test_running(self):
1782 # As mentioned on issue #10220, checking for the RUNNING state only
1783 # makes sense inside the generator itself.
1784 # The following generator checks for this by using the closure's
1785 # reference to self and the generator state checking helper method
1786 def running_check_generator():
1787 for number in range(5):
1788 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1789 yield number
1790 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1791 self.generator = running_check_generator()
1792 # Running up to the first yield
1793 next(self.generator)
1794 # Running after the first yield
1795 next(self.generator)
1796
Nick Coghlan7921b9f2010-11-30 06:36:04 +00001797 def test_easy_debugging(self):
1798 # repr() and str() of a generator state should contain the state name
1799 names = 'GEN_CREATED GEN_RUNNING GEN_SUSPENDED GEN_CLOSED'.split()
1800 for name in names:
1801 state = getattr(inspect, name)
1802 self.assertIn(name, repr(state))
1803 self.assertIn(name, str(state))
1804
Nick Coghlan04e2e3f2012-06-23 19:52:05 +10001805 def test_getgeneratorlocals(self):
1806 def each(lst, a=None):
1807 b=(1, 2, 3)
1808 for v in lst:
1809 if v == 3:
1810 c = 12
1811 yield v
1812
1813 numbers = each([1, 2, 3])
1814 self.assertEqual(inspect.getgeneratorlocals(numbers),
1815 {'a': None, 'lst': [1, 2, 3]})
1816 next(numbers)
1817 self.assertEqual(inspect.getgeneratorlocals(numbers),
1818 {'a': None, 'lst': [1, 2, 3], 'v': 1,
1819 'b': (1, 2, 3)})
1820 next(numbers)
1821 self.assertEqual(inspect.getgeneratorlocals(numbers),
1822 {'a': None, 'lst': [1, 2, 3], 'v': 2,
1823 'b': (1, 2, 3)})
1824 next(numbers)
1825 self.assertEqual(inspect.getgeneratorlocals(numbers),
1826 {'a': None, 'lst': [1, 2, 3], 'v': 3,
1827 'b': (1, 2, 3), 'c': 12})
1828 try:
1829 next(numbers)
1830 except StopIteration:
1831 pass
1832 self.assertEqual(inspect.getgeneratorlocals(numbers), {})
1833
1834 def test_getgeneratorlocals_empty(self):
1835 def yield_one():
1836 yield 1
1837 one = yield_one()
1838 self.assertEqual(inspect.getgeneratorlocals(one), {})
1839 try:
1840 next(one)
1841 except StopIteration:
1842 pass
1843 self.assertEqual(inspect.getgeneratorlocals(one), {})
1844
1845 def test_getgeneratorlocals_error(self):
1846 self.assertRaises(TypeError, inspect.getgeneratorlocals, 1)
1847 self.assertRaises(TypeError, inspect.getgeneratorlocals, lambda x: True)
1848 self.assertRaises(TypeError, inspect.getgeneratorlocals, set)
1849 self.assertRaises(TypeError, inspect.getgeneratorlocals, (2,3))
1850
Nick Coghlane0f04652010-11-21 03:44:04 +00001851
Yury Selivanov5376ba92015-06-22 12:19:30 -04001852class TestGetCoroutineState(unittest.TestCase):
1853
1854 def setUp(self):
1855 @types.coroutine
1856 def number_coroutine():
1857 for number in range(5):
1858 yield number
1859 async def coroutine():
1860 await number_coroutine()
1861 self.coroutine = coroutine()
1862
1863 def tearDown(self):
1864 self.coroutine.close()
1865
1866 def _coroutinestate(self):
1867 return inspect.getcoroutinestate(self.coroutine)
1868
1869 def test_created(self):
1870 self.assertEqual(self._coroutinestate(), inspect.CORO_CREATED)
1871
1872 def test_suspended(self):
1873 self.coroutine.send(None)
1874 self.assertEqual(self._coroutinestate(), inspect.CORO_SUSPENDED)
1875
1876 def test_closed_after_exhaustion(self):
1877 while True:
1878 try:
1879 self.coroutine.send(None)
1880 except StopIteration:
1881 break
1882
1883 self.assertEqual(self._coroutinestate(), inspect.CORO_CLOSED)
1884
1885 def test_closed_after_immediate_exception(self):
1886 with self.assertRaises(RuntimeError):
1887 self.coroutine.throw(RuntimeError)
1888 self.assertEqual(self._coroutinestate(), inspect.CORO_CLOSED)
1889
1890 def test_easy_debugging(self):
1891 # repr() and str() of a coroutine state should contain the state name
1892 names = 'CORO_CREATED CORO_RUNNING CORO_SUSPENDED CORO_CLOSED'.split()
1893 for name in names:
1894 state = getattr(inspect, name)
1895 self.assertIn(name, repr(state))
1896 self.assertIn(name, str(state))
1897
1898 def test_getcoroutinelocals(self):
1899 @types.coroutine
1900 def gencoro():
1901 yield
1902
1903 gencoro = gencoro()
1904 async def func(a=None):
1905 b = 'spam'
1906 await gencoro
1907
1908 coro = func()
1909 self.assertEqual(inspect.getcoroutinelocals(coro),
1910 {'a': None, 'gencoro': gencoro})
1911 coro.send(None)
1912 self.assertEqual(inspect.getcoroutinelocals(coro),
1913 {'a': None, 'gencoro': gencoro, 'b': 'spam'})
1914
1915
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001916class MySignature(inspect.Signature):
1917 # Top-level to make it picklable;
1918 # used in test_signature_object_pickle
1919 pass
1920
1921class MyParameter(inspect.Parameter):
1922 # Top-level to make it picklable;
1923 # used in test_signature_object_pickle
1924 pass
1925
Nick Coghlanf9e227e2014-08-17 14:01:19 +10001926
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001927
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001928class TestSignatureObject(unittest.TestCase):
1929 @staticmethod
Yury Selivanovbcd4fc12015-05-20 14:30:08 -04001930 def signature(func, **kw):
1931 sig = inspect.signature(func, **kw)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001932 return (tuple((param.name,
1933 (... if param.default is param.empty else param.default),
1934 (... if param.annotation is param.empty
1935 else param.annotation),
1936 str(param.kind).lower())
1937 for param in sig.parameters.values()),
1938 (... if sig.return_annotation is sig.empty
1939 else sig.return_annotation))
1940
1941 def test_signature_object(self):
1942 S = inspect.Signature
1943 P = inspect.Parameter
1944
1945 self.assertEqual(str(S()), '()')
1946
Yury Selivanov07a9e452014-01-29 10:58:16 -05001947 def test(po, pk, pod=42, pkd=100, *args, ko, **kwargs):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001948 pass
1949 sig = inspect.signature(test)
1950 po = sig.parameters['po'].replace(kind=P.POSITIONAL_ONLY)
Yury Selivanov07a9e452014-01-29 10:58:16 -05001951 pod = sig.parameters['pod'].replace(kind=P.POSITIONAL_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001952 pk = sig.parameters['pk']
Yury Selivanov07a9e452014-01-29 10:58:16 -05001953 pkd = sig.parameters['pkd']
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001954 args = sig.parameters['args']
1955 ko = sig.parameters['ko']
1956 kwargs = sig.parameters['kwargs']
1957
1958 S((po, pk, args, ko, kwargs))
1959
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001960 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001961 S((pk, po, args, ko, kwargs))
1962
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001963 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001964 S((po, args, pk, ko, kwargs))
1965
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001966 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001967 S((args, po, pk, ko, kwargs))
1968
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001969 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001970 S((po, pk, args, kwargs, ko))
1971
1972 kwargs2 = kwargs.replace(name='args')
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001973 with self.assertRaisesRegex(ValueError, 'duplicate parameter name'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001974 S((po, pk, args, kwargs2, ko))
1975
Yury Selivanov07a9e452014-01-29 10:58:16 -05001976 with self.assertRaisesRegex(ValueError, 'follows default argument'):
1977 S((pod, po))
1978
1979 with self.assertRaisesRegex(ValueError, 'follows default argument'):
1980 S((po, pkd, pk))
1981
1982 with self.assertRaisesRegex(ValueError, 'follows default argument'):
1983 S((pkd, pk))
1984
Yury Selivanov374375d2014-03-27 12:41:53 -04001985 self.assertTrue(repr(sig).startswith('<Signature'))
Yury Selivanov0cd2bf42015-05-15 12:55:20 -04001986 self.assertTrue('(po, pk' in repr(sig))
Yury Selivanov374375d2014-03-27 12:41:53 -04001987
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001988 def test_signature_object_pickle(self):
1989 def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
1990 foo_partial = functools.partial(foo, a=1)
1991
1992 sig = inspect.signature(foo_partial)
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001993
1994 for ver in range(pickle.HIGHEST_PROTOCOL + 1):
1995 with self.subTest(pickle_ver=ver, subclass=False):
1996 sig_pickled = pickle.loads(pickle.dumps(sig, ver))
1997 self.assertEqual(sig, sig_pickled)
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001998
1999 # Test that basic sub-classing works
2000 sig = inspect.signature(foo)
2001 myparam = MyParameter(name='z', kind=inspect.Parameter.POSITIONAL_ONLY)
2002 myparams = collections.OrderedDict(sig.parameters, a=myparam)
2003 mysig = MySignature().replace(parameters=myparams.values(),
2004 return_annotation=sig.return_annotation)
2005 self.assertTrue(isinstance(mysig, MySignature))
2006 self.assertTrue(isinstance(mysig.parameters['z'], MyParameter))
2007
2008 for ver in range(pickle.HIGHEST_PROTOCOL + 1):
2009 with self.subTest(pickle_ver=ver, subclass=True):
2010 sig_pickled = pickle.loads(pickle.dumps(mysig, ver))
2011 self.assertEqual(mysig, sig_pickled)
2012 self.assertTrue(isinstance(sig_pickled, MySignature))
2013 self.assertTrue(isinstance(sig_pickled.parameters['z'],
2014 MyParameter))
2015
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002016 def test_signature_immutability(self):
2017 def test(a):
2018 pass
2019 sig = inspect.signature(test)
2020
2021 with self.assertRaises(AttributeError):
2022 sig.foo = 'bar'
2023
2024 with self.assertRaises(TypeError):
2025 sig.parameters['a'] = None
2026
2027 def test_signature_on_noarg(self):
2028 def test():
2029 pass
2030 self.assertEqual(self.signature(test), ((), ...))
2031
2032 def test_signature_on_wargs(self):
2033 def test(a, b:'foo') -> 123:
2034 pass
2035 self.assertEqual(self.signature(test),
2036 ((('a', ..., ..., "positional_or_keyword"),
2037 ('b', ..., 'foo', "positional_or_keyword")),
2038 123))
2039
2040 def test_signature_on_wkwonly(self):
2041 def test(*, a:float, b:str) -> int:
2042 pass
2043 self.assertEqual(self.signature(test),
2044 ((('a', ..., float, "keyword_only"),
2045 ('b', ..., str, "keyword_only")),
2046 int))
2047
2048 def test_signature_on_complex_args(self):
2049 def test(a, b:'foo'=10, *args:'bar', spam:'baz', ham=123, **kwargs:int):
2050 pass
2051 self.assertEqual(self.signature(test),
2052 ((('a', ..., ..., "positional_or_keyword"),
2053 ('b', 10, 'foo', "positional_or_keyword"),
2054 ('args', ..., 'bar', "var_positional"),
2055 ('spam', ..., 'baz', "keyword_only"),
2056 ('ham', 123, ..., "keyword_only"),
2057 ('kwargs', ..., int, "var_keyword")),
2058 ...))
2059
Dong-hee Na378d7062017-05-18 04:00:51 +09002060 def test_signature_without_self(self):
2061 def test_args_only(*args): # NOQA
2062 pass
2063
2064 def test_args_kwargs_only(*args, **kwargs): # NOQA
2065 pass
2066
2067 class A:
2068 @classmethod
2069 def test_classmethod(*args): # NOQA
2070 pass
2071
2072 @staticmethod
2073 def test_staticmethod(*args): # NOQA
2074 pass
2075
2076 f1 = functools.partialmethod((test_classmethod), 1)
2077 f2 = functools.partialmethod((test_args_only), 1)
2078 f3 = functools.partialmethod((test_staticmethod), 1)
2079 f4 = functools.partialmethod((test_args_kwargs_only),1)
2080
2081 self.assertEqual(self.signature(test_args_only),
2082 ((('args', ..., ..., 'var_positional'),), ...))
2083 self.assertEqual(self.signature(test_args_kwargs_only),
2084 ((('args', ..., ..., 'var_positional'),
2085 ('kwargs', ..., ..., 'var_keyword')), ...))
2086 self.assertEqual(self.signature(A.f1),
2087 ((('args', ..., ..., 'var_positional'),), ...))
2088 self.assertEqual(self.signature(A.f2),
2089 ((('args', ..., ..., 'var_positional'),), ...))
2090 self.assertEqual(self.signature(A.f3),
2091 ((('args', ..., ..., 'var_positional'),), ...))
Serhiy Storchaka13ad3b72017-09-14 09:38:36 +03002092 self.assertEqual(self.signature(A.f4),
Dong-hee Na378d7062017-05-18 04:00:51 +09002093 ((('args', ..., ..., 'var_positional'),
2094 ('kwargs', ..., ..., 'var_keyword')), ...))
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002095 @cpython_only
Larry Hastingsfcafe432013-11-23 17:35:48 -08002096 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2097 "Signature information for builtins requires docstrings")
2098 def test_signature_on_builtins(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002099 import _testcapi
Larry Hastings16c51912014-01-07 11:53:01 -08002100
Larry Hastings5c661892014-01-24 06:17:25 -08002101 def test_unbound_method(o):
2102 """Use this to test unbound methods (things that should have a self)"""
2103 signature = inspect.signature(o)
2104 self.assertTrue(isinstance(signature, inspect.Signature))
2105 self.assertEqual(list(signature.parameters.values())[0].name, 'self')
2106 return signature
2107
2108 def test_callable(o):
2109 """Use this to test bound methods or normal callables (things that don't expect self)"""
2110 signature = inspect.signature(o)
2111 self.assertTrue(isinstance(signature, inspect.Signature))
2112 if signature.parameters:
2113 self.assertNotEqual(list(signature.parameters.values())[0].name, 'self')
2114 return signature
2115
2116 signature = test_callable(_testcapi.docstring_with_signature_with_defaults)
Larry Hastings16c51912014-01-07 11:53:01 -08002117 def p(name): return signature.parameters[name].default
2118 self.assertEqual(p('s'), 'avocado')
Larry Hastings2a727912014-01-16 11:32:01 -08002119 self.assertEqual(p('b'), b'bytes')
Larry Hastings16c51912014-01-07 11:53:01 -08002120 self.assertEqual(p('d'), 3.14)
2121 self.assertEqual(p('i'), 35)
Larry Hastings16c51912014-01-07 11:53:01 -08002122 self.assertEqual(p('n'), None)
2123 self.assertEqual(p('t'), True)
2124 self.assertEqual(p('f'), False)
Larry Hastings2a727912014-01-16 11:32:01 -08002125 self.assertEqual(p('local'), 3)
2126 self.assertEqual(p('sys'), sys.maxsize)
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +02002127 self.assertNotIn('exp', signature.parameters)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002128
Larry Hastings5c661892014-01-24 06:17:25 -08002129 test_callable(object)
2130
2131 # normal method
2132 # (PyMethodDescr_Type, "method_descriptor")
2133 test_unbound_method(_pickle.Pickler.dump)
2134 d = _pickle.Pickler(io.StringIO())
2135 test_callable(d.dump)
2136
2137 # static method
2138 test_callable(str.maketrans)
2139 test_callable('abc'.maketrans)
2140
2141 # class method
2142 test_callable(dict.fromkeys)
2143 test_callable({}.fromkeys)
2144
2145 # wrapper around slot (PyWrapperDescr_Type, "wrapper_descriptor")
2146 test_unbound_method(type.__call__)
2147 test_unbound_method(int.__add__)
2148 test_callable((3).__add__)
2149
2150 # _PyMethodWrapper_Type
2151 # support for 'method-wrapper'
2152 test_callable(min.__call__)
2153
Larry Hastings2623c8c2014-02-08 22:15:29 -08002154 # This doesn't work now.
2155 # (We don't have a valid signature for "type" in 3.4)
2156 with self.assertRaisesRegex(ValueError, "no signature found"):
2157 class ThisWorksNow:
2158 __call__ = type
2159 test_callable(ThisWorksNow())
Larry Hastings5c661892014-01-24 06:17:25 -08002160
Yury Selivanov056e2652014-03-02 12:25:27 -05002161 # Regression test for issue #20786
2162 test_unbound_method(dict.__delitem__)
2163 test_unbound_method(property.__delete__)
2164
Zachary Ware8ef887c2015-04-13 18:22:35 -05002165 # Regression test for issue #20586
2166 test_callable(_testcapi.docstring_with_signature_but_no_doc)
2167
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002168 @cpython_only
Yury Selivanov76c6c592014-01-29 10:52:57 -05002169 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2170 "Signature information for builtins requires docstrings")
2171 def test_signature_on_decorated_builtins(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002172 import _testcapi
Yury Selivanov76c6c592014-01-29 10:52:57 -05002173 func = _testcapi.docstring_with_signature_with_defaults
2174
2175 def decorator(func):
2176 @functools.wraps(func)
2177 def wrapper(*args, **kwargs) -> int:
2178 return func(*args, **kwargs)
2179 return wrapper
2180
2181 decorated_func = decorator(func)
2182
2183 self.assertEqual(inspect.signature(func),
2184 inspect.signature(decorated_func))
Larry Hastings5c661892014-01-24 06:17:25 -08002185
Yury Selivanovbcd4fc12015-05-20 14:30:08 -04002186 def wrapper_like(*args, **kwargs) -> int: pass
2187 self.assertEqual(inspect.signature(decorated_func,
2188 follow_wrapped=False),
2189 inspect.signature(wrapper_like))
2190
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002191 @cpython_only
Larry Hastings5c661892014-01-24 06:17:25 -08002192 def test_signature_on_builtins_no_signature(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002193 import _testcapi
Yury Selivanovbf304fc2015-05-30 17:08:36 -04002194 with self.assertRaisesRegex(ValueError,
2195 'no signature found for builtin'):
Larry Hastings5c661892014-01-24 06:17:25 -08002196 inspect.signature(_testcapi.docstring_no_signature)
2197
Yury Selivanovbf304fc2015-05-30 17:08:36 -04002198 with self.assertRaisesRegex(ValueError,
2199 'no signature found for builtin'):
2200 inspect.signature(str)
2201
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002202 def test_signature_on_non_function(self):
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002203 with self.assertRaisesRegex(TypeError, 'is not a callable object'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002204 inspect.signature(42)
2205
Yury Selivanov63da7c72014-01-31 14:48:37 -05002206 def test_signature_from_functionlike_object(self):
2207 def func(a,b, *args, kwonly=True, kwonlyreq, **kwargs):
2208 pass
2209
2210 class funclike:
2211 # Has to be callable, and have correct
2212 # __code__, __annotations__, __defaults__, __name__,
2213 # and __kwdefaults__ attributes
2214
2215 def __init__(self, func):
2216 self.__name__ = func.__name__
2217 self.__code__ = func.__code__
2218 self.__annotations__ = func.__annotations__
2219 self.__defaults__ = func.__defaults__
2220 self.__kwdefaults__ = func.__kwdefaults__
2221 self.func = func
2222
2223 def __call__(self, *args, **kwargs):
2224 return self.func(*args, **kwargs)
2225
Yury Selivanov57c74fc2015-05-20 23:07:02 -04002226 sig_func = inspect.Signature.from_callable(func)
Yury Selivanov63da7c72014-01-31 14:48:37 -05002227
Yury Selivanov57c74fc2015-05-20 23:07:02 -04002228 sig_funclike = inspect.Signature.from_callable(funclike(func))
Yury Selivanov63da7c72014-01-31 14:48:37 -05002229 self.assertEqual(sig_funclike, sig_func)
2230
2231 sig_funclike = inspect.signature(funclike(func))
2232 self.assertEqual(sig_funclike, sig_func)
2233
2234 # If object is not a duck type of function, then
2235 # signature will try to get a signature for its '__call__'
2236 # method
2237 fl = funclike(func)
2238 del fl.__defaults__
2239 self.assertEqual(self.signature(fl),
2240 ((('args', ..., ..., "var_positional"),
2241 ('kwargs', ..., ..., "var_keyword")),
2242 ...))
2243
Yury Selivanova773de02014-02-21 18:30:53 -05002244 # Test with cython-like builtins:
2245 _orig_isdesc = inspect.ismethoddescriptor
2246 def _isdesc(obj):
2247 if hasattr(obj, '_builtinmock'):
2248 return True
2249 return _orig_isdesc(obj)
2250
2251 with unittest.mock.patch('inspect.ismethoddescriptor', _isdesc):
2252 builtin_func = funclike(func)
2253 # Make sure that our mock setup is working
2254 self.assertFalse(inspect.ismethoddescriptor(builtin_func))
2255 builtin_func._builtinmock = True
2256 self.assertTrue(inspect.ismethoddescriptor(builtin_func))
2257 self.assertEqual(inspect.signature(builtin_func), sig_func)
2258
Yury Selivanov63da7c72014-01-31 14:48:37 -05002259 def test_signature_functionlike_class(self):
2260 # We only want to duck type function-like objects,
2261 # not classes.
2262
2263 def func(a,b, *args, kwonly=True, kwonlyreq, **kwargs):
2264 pass
2265
2266 class funclike:
2267 def __init__(self, marker):
2268 pass
2269
2270 __name__ = func.__name__
2271 __code__ = func.__code__
2272 __annotations__ = func.__annotations__
2273 __defaults__ = func.__defaults__
2274 __kwdefaults__ = func.__kwdefaults__
2275
Yury Selivanov63da7c72014-01-31 14:48:37 -05002276 self.assertEqual(str(inspect.signature(funclike)), '(marker)')
2277
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002278 def test_signature_on_method(self):
2279 class Test:
Yury Selivanov62560fb2014-01-28 12:26:24 -05002280 def __init__(*args):
2281 pass
2282 def m1(self, arg1, arg2=1) -> int:
2283 pass
2284 def m2(*args):
2285 pass
2286 def __call__(*, a):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002287 pass
2288
Yury Selivanov62560fb2014-01-28 12:26:24 -05002289 self.assertEqual(self.signature(Test().m1),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002290 ((('arg1', ..., ..., "positional_or_keyword"),
2291 ('arg2', 1, ..., "positional_or_keyword")),
2292 int))
2293
Yury Selivanov62560fb2014-01-28 12:26:24 -05002294 self.assertEqual(self.signature(Test().m2),
2295 ((('args', ..., ..., "var_positional"),),
2296 ...))
2297
2298 self.assertEqual(self.signature(Test),
2299 ((('args', ..., ..., "var_positional"),),
2300 ...))
2301
2302 with self.assertRaisesRegex(ValueError, 'invalid method signature'):
2303 self.signature(Test())
2304
Yury Selivanov46c759d2015-05-27 21:56:53 -04002305 def test_signature_wrapped_bound_method(self):
2306 # Issue 24298
2307 class Test:
2308 def m1(self, arg1, arg2=1) -> int:
2309 pass
2310 @functools.wraps(Test().m1)
2311 def m1d(*args, **kwargs):
2312 pass
2313 self.assertEqual(self.signature(m1d),
2314 ((('arg1', ..., ..., "positional_or_keyword"),
2315 ('arg2', 1, ..., "positional_or_keyword")),
2316 int))
2317
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002318 def test_signature_on_classmethod(self):
2319 class Test:
2320 @classmethod
2321 def foo(cls, arg1, *, arg2=1):
2322 pass
2323
2324 meth = Test().foo
2325 self.assertEqual(self.signature(meth),
2326 ((('arg1', ..., ..., "positional_or_keyword"),
2327 ('arg2', 1, ..., "keyword_only")),
2328 ...))
2329
2330 meth = Test.foo
2331 self.assertEqual(self.signature(meth),
2332 ((('arg1', ..., ..., "positional_or_keyword"),
2333 ('arg2', 1, ..., "keyword_only")),
2334 ...))
2335
2336 def test_signature_on_staticmethod(self):
2337 class Test:
2338 @staticmethod
2339 def foo(cls, *, arg):
2340 pass
2341
2342 meth = Test().foo
2343 self.assertEqual(self.signature(meth),
2344 ((('cls', ..., ..., "positional_or_keyword"),
2345 ('arg', ..., ..., "keyword_only")),
2346 ...))
2347
2348 meth = Test.foo
2349 self.assertEqual(self.signature(meth),
2350 ((('cls', ..., ..., "positional_or_keyword"),
2351 ('arg', ..., ..., "keyword_only")),
2352 ...))
2353
2354 def test_signature_on_partial(self):
2355 from functools import partial
2356
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002357 Parameter = inspect.Parameter
2358
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002359 def test():
2360 pass
2361
2362 self.assertEqual(self.signature(partial(test)), ((), ...))
2363
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002364 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002365 inspect.signature(partial(test, 1))
2366
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002367 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002368 inspect.signature(partial(test, a=1))
2369
2370 def test(a, b, *, c, d):
2371 pass
2372
2373 self.assertEqual(self.signature(partial(test)),
2374 ((('a', ..., ..., "positional_or_keyword"),
2375 ('b', ..., ..., "positional_or_keyword"),
2376 ('c', ..., ..., "keyword_only"),
2377 ('d', ..., ..., "keyword_only")),
2378 ...))
2379
2380 self.assertEqual(self.signature(partial(test, 1)),
2381 ((('b', ..., ..., "positional_or_keyword"),
2382 ('c', ..., ..., "keyword_only"),
2383 ('d', ..., ..., "keyword_only")),
2384 ...))
2385
2386 self.assertEqual(self.signature(partial(test, 1, c=2)),
2387 ((('b', ..., ..., "positional_or_keyword"),
2388 ('c', 2, ..., "keyword_only"),
2389 ('d', ..., ..., "keyword_only")),
2390 ...))
2391
2392 self.assertEqual(self.signature(partial(test, b=1, c=2)),
2393 ((('a', ..., ..., "positional_or_keyword"),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002394 ('b', 1, ..., "keyword_only"),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002395 ('c', 2, ..., "keyword_only"),
2396 ('d', ..., ..., "keyword_only")),
2397 ...))
2398
2399 self.assertEqual(self.signature(partial(test, 0, b=1, c=2)),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002400 ((('b', 1, ..., "keyword_only"),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002401 ('c', 2, ..., "keyword_only"),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002402 ('d', ..., ..., "keyword_only")),
2403 ...))
2404
2405 self.assertEqual(self.signature(partial(test, a=1)),
2406 ((('a', 1, ..., "keyword_only"),
2407 ('b', ..., ..., "keyword_only"),
2408 ('c', ..., ..., "keyword_only"),
2409 ('d', ..., ..., "keyword_only")),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002410 ...))
2411
2412 def test(a, *args, b, **kwargs):
2413 pass
2414
2415 self.assertEqual(self.signature(partial(test, 1)),
2416 ((('args', ..., ..., "var_positional"),
2417 ('b', ..., ..., "keyword_only"),
2418 ('kwargs', ..., ..., "var_keyword")),
2419 ...))
2420
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002421 self.assertEqual(self.signature(partial(test, a=1)),
2422 ((('a', 1, ..., "keyword_only"),
2423 ('b', ..., ..., "keyword_only"),
2424 ('kwargs', ..., ..., "var_keyword")),
2425 ...))
2426
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002427 self.assertEqual(self.signature(partial(test, 1, 2, 3)),
2428 ((('args', ..., ..., "var_positional"),
2429 ('b', ..., ..., "keyword_only"),
2430 ('kwargs', ..., ..., "var_keyword")),
2431 ...))
2432
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002433 self.assertEqual(self.signature(partial(test, 1, 2, 3, test=True)),
2434 ((('args', ..., ..., "var_positional"),
2435 ('b', ..., ..., "keyword_only"),
2436 ('kwargs', ..., ..., "var_keyword")),
2437 ...))
2438
2439 self.assertEqual(self.signature(partial(test, 1, 2, 3, test=1, b=0)),
2440 ((('args', ..., ..., "var_positional"),
2441 ('b', 0, ..., "keyword_only"),
2442 ('kwargs', ..., ..., "var_keyword")),
2443 ...))
2444
2445 self.assertEqual(self.signature(partial(test, b=0)),
2446 ((('a', ..., ..., "positional_or_keyword"),
2447 ('args', ..., ..., "var_positional"),
2448 ('b', 0, ..., "keyword_only"),
2449 ('kwargs', ..., ..., "var_keyword")),
2450 ...))
2451
2452 self.assertEqual(self.signature(partial(test, b=0, test=1)),
2453 ((('a', ..., ..., "positional_or_keyword"),
2454 ('args', ..., ..., "var_positional"),
2455 ('b', 0, ..., "keyword_only"),
2456 ('kwargs', ..., ..., "var_keyword")),
2457 ...))
2458
2459 def test(a, b, c:int) -> 42:
2460 pass
2461
2462 sig = test.__signature__ = inspect.signature(test)
2463
2464 self.assertEqual(self.signature(partial(partial(test, 1))),
2465 ((('b', ..., ..., "positional_or_keyword"),
2466 ('c', ..., int, "positional_or_keyword")),
2467 42))
2468
2469 self.assertEqual(self.signature(partial(partial(test, 1), 2)),
2470 ((('c', ..., int, "positional_or_keyword"),),
2471 42))
2472
2473 psig = inspect.signature(partial(partial(test, 1), 2))
2474
2475 def foo(a):
2476 return a
2477 _foo = partial(partial(foo, a=10), a=20)
2478 self.assertEqual(self.signature(_foo),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002479 ((('a', 20, ..., "keyword_only"),),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002480 ...))
2481 # check that we don't have any side-effects in signature(),
2482 # and the partial object is still functioning
2483 self.assertEqual(_foo(), 20)
2484
2485 def foo(a, b, c):
2486 return a, b, c
2487 _foo = partial(partial(foo, 1, b=20), b=30)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002488
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002489 self.assertEqual(self.signature(_foo),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002490 ((('b', 30, ..., "keyword_only"),
2491 ('c', ..., ..., "keyword_only")),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002492 ...))
2493 self.assertEqual(_foo(c=10), (1, 30, 10))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002494
2495 def foo(a, b, c, *, d):
2496 return a, b, c, d
2497 _foo = partial(partial(foo, d=20, c=20), b=10, d=30)
2498 self.assertEqual(self.signature(_foo),
2499 ((('a', ..., ..., "positional_or_keyword"),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002500 ('b', 10, ..., "keyword_only"),
2501 ('c', 20, ..., "keyword_only"),
2502 ('d', 30, ..., "keyword_only"),
2503 ),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002504 ...))
2505 ba = inspect.signature(_foo).bind(a=200, b=11)
2506 self.assertEqual(_foo(*ba.args, **ba.kwargs), (200, 11, 20, 30))
2507
2508 def foo(a=1, b=2, c=3):
2509 return a, b, c
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002510 _foo = partial(foo, c=13) # (a=1, b=2, *, c=13)
2511
2512 ba = inspect.signature(_foo).bind(a=11)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002513 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 2, 13))
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002514
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002515 ba = inspect.signature(_foo).bind(11, 12)
2516 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002517
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002518 ba = inspect.signature(_foo).bind(11, b=12)
2519 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002520
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002521 ba = inspect.signature(_foo).bind(b=12)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002522 self.assertEqual(_foo(*ba.args, **ba.kwargs), (1, 12, 13))
2523
2524 _foo = partial(_foo, b=10, c=20)
2525 ba = inspect.signature(_foo).bind(12)
2526 self.assertEqual(_foo(*ba.args, **ba.kwargs), (12, 10, 20))
2527
2528
2529 def foo(a, b, c, d, **kwargs):
2530 pass
2531 sig = inspect.signature(foo)
2532 params = sig.parameters.copy()
2533 params['a'] = params['a'].replace(kind=Parameter.POSITIONAL_ONLY)
2534 params['b'] = params['b'].replace(kind=Parameter.POSITIONAL_ONLY)
2535 foo.__signature__ = inspect.Signature(params.values())
2536 sig = inspect.signature(foo)
2537 self.assertEqual(str(sig), '(a, b, /, c, d, **kwargs)')
2538
2539 self.assertEqual(self.signature(partial(foo, 1)),
2540 ((('b', ..., ..., 'positional_only'),
2541 ('c', ..., ..., 'positional_or_keyword'),
2542 ('d', ..., ..., 'positional_or_keyword'),
2543 ('kwargs', ..., ..., 'var_keyword')),
2544 ...))
2545
2546 self.assertEqual(self.signature(partial(foo, 1, 2)),
2547 ((('c', ..., ..., 'positional_or_keyword'),
2548 ('d', ..., ..., 'positional_or_keyword'),
2549 ('kwargs', ..., ..., 'var_keyword')),
2550 ...))
2551
2552 self.assertEqual(self.signature(partial(foo, 1, 2, 3)),
2553 ((('d', ..., ..., 'positional_or_keyword'),
2554 ('kwargs', ..., ..., 'var_keyword')),
2555 ...))
2556
2557 self.assertEqual(self.signature(partial(foo, 1, 2, c=3)),
2558 ((('c', 3, ..., 'keyword_only'),
2559 ('d', ..., ..., 'keyword_only'),
2560 ('kwargs', ..., ..., 'var_keyword')),
2561 ...))
2562
2563 self.assertEqual(self.signature(partial(foo, 1, c=3)),
2564 ((('b', ..., ..., 'positional_only'),
2565 ('c', 3, ..., 'keyword_only'),
2566 ('d', ..., ..., 'keyword_only'),
2567 ('kwargs', ..., ..., 'var_keyword')),
2568 ...))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002569
Yury Selivanovda5fe4f2014-01-27 17:28:37 -05002570 def test_signature_on_partialmethod(self):
2571 from functools import partialmethod
2572
2573 class Spam:
2574 def test():
2575 pass
2576 ham = partialmethod(test)
2577
2578 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
2579 inspect.signature(Spam.ham)
2580
2581 class Spam:
2582 def test(it, a, *, c) -> 'spam':
2583 pass
2584 ham = partialmethod(test, c=1)
2585
2586 self.assertEqual(self.signature(Spam.ham),
2587 ((('it', ..., ..., 'positional_or_keyword'),
2588 ('a', ..., ..., 'positional_or_keyword'),
2589 ('c', 1, ..., 'keyword_only')),
2590 'spam'))
2591
2592 self.assertEqual(self.signature(Spam().ham),
2593 ((('a', ..., ..., 'positional_or_keyword'),
2594 ('c', 1, ..., 'keyword_only')),
2595 'spam'))
2596
Miss Islington (bot)112f7992018-03-06 10:23:48 -08002597 class Spam:
2598 def test(self: 'anno', x):
2599 pass
2600
2601 g = partialmethod(test, 1)
2602
2603 self.assertEqual(self.signature(Spam.g),
2604 ((('self', ..., 'anno', 'positional_or_keyword'),),
2605 ...))
2606
Yury Selivanov0486f812014-01-29 12:18:59 -05002607 def test_signature_on_fake_partialmethod(self):
2608 def foo(a): pass
2609 foo._partialmethod = 'spam'
2610 self.assertEqual(str(inspect.signature(foo)), '(a)')
2611
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002612 def test_signature_on_decorated(self):
2613 import functools
2614
2615 def decorator(func):
2616 @functools.wraps(func)
2617 def wrapper(*args, **kwargs) -> int:
2618 return func(*args, **kwargs)
2619 return wrapper
2620
2621 class Foo:
2622 @decorator
2623 def bar(self, a, b):
2624 pass
2625
2626 self.assertEqual(self.signature(Foo.bar),
2627 ((('self', ..., ..., "positional_or_keyword"),
2628 ('a', ..., ..., "positional_or_keyword"),
2629 ('b', ..., ..., "positional_or_keyword")),
2630 ...))
2631
2632 self.assertEqual(self.signature(Foo().bar),
2633 ((('a', ..., ..., "positional_or_keyword"),
2634 ('b', ..., ..., "positional_or_keyword")),
2635 ...))
2636
Yury Selivanovbcd4fc12015-05-20 14:30:08 -04002637 self.assertEqual(self.signature(Foo.bar, follow_wrapped=False),
2638 ((('args', ..., ..., "var_positional"),
2639 ('kwargs', ..., ..., "var_keyword")),
2640 ...)) # functools.wraps will copy __annotations__
2641 # from "func" to "wrapper", hence no
2642 # return_annotation
2643
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002644 # Test that we handle method wrappers correctly
2645 def decorator(func):
2646 @functools.wraps(func)
2647 def wrapper(*args, **kwargs) -> int:
2648 return func(42, *args, **kwargs)
2649 sig = inspect.signature(func)
2650 new_params = tuple(sig.parameters.values())[1:]
2651 wrapper.__signature__ = sig.replace(parameters=new_params)
2652 return wrapper
2653
2654 class Foo:
2655 @decorator
2656 def __call__(self, a, b):
2657 pass
2658
2659 self.assertEqual(self.signature(Foo.__call__),
2660 ((('a', ..., ..., "positional_or_keyword"),
2661 ('b', ..., ..., "positional_or_keyword")),
2662 ...))
2663
2664 self.assertEqual(self.signature(Foo().__call__),
2665 ((('b', ..., ..., "positional_or_keyword"),),
2666 ...))
2667
Nick Coghlane8c45d62013-07-28 20:00:01 +10002668 # Test we handle __signature__ partway down the wrapper stack
2669 def wrapped_foo_call():
2670 pass
2671 wrapped_foo_call.__wrapped__ = Foo.__call__
2672
2673 self.assertEqual(self.signature(wrapped_foo_call),
2674 ((('a', ..., ..., "positional_or_keyword"),
2675 ('b', ..., ..., "positional_or_keyword")),
2676 ...))
2677
2678
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002679 def test_signature_on_class(self):
2680 class C:
2681 def __init__(self, a):
2682 pass
2683
2684 self.assertEqual(self.signature(C),
2685 ((('a', ..., ..., "positional_or_keyword"),),
2686 ...))
2687
2688 class CM(type):
2689 def __call__(cls, a):
2690 pass
2691 class C(metaclass=CM):
2692 def __init__(self, b):
2693 pass
2694
2695 self.assertEqual(self.signature(C),
2696 ((('a', ..., ..., "positional_or_keyword"),),
2697 ...))
2698
2699 class CM(type):
2700 def __new__(mcls, name, bases, dct, *, foo=1):
2701 return super().__new__(mcls, name, bases, dct)
2702 class C(metaclass=CM):
2703 def __init__(self, b):
2704 pass
2705
2706 self.assertEqual(self.signature(C),
2707 ((('b', ..., ..., "positional_or_keyword"),),
2708 ...))
2709
2710 self.assertEqual(self.signature(CM),
2711 ((('name', ..., ..., "positional_or_keyword"),
2712 ('bases', ..., ..., "positional_or_keyword"),
2713 ('dct', ..., ..., "positional_or_keyword"),
2714 ('foo', 1, ..., "keyword_only")),
2715 ...))
2716
2717 class CMM(type):
2718 def __new__(mcls, name, bases, dct, *, foo=1):
2719 return super().__new__(mcls, name, bases, dct)
2720 def __call__(cls, nm, bs, dt):
2721 return type(nm, bs, dt)
2722 class CM(type, metaclass=CMM):
2723 def __new__(mcls, name, bases, dct, *, bar=2):
2724 return super().__new__(mcls, name, bases, dct)
2725 class C(metaclass=CM):
2726 def __init__(self, b):
2727 pass
2728
2729 self.assertEqual(self.signature(CMM),
2730 ((('name', ..., ..., "positional_or_keyword"),
2731 ('bases', ..., ..., "positional_or_keyword"),
2732 ('dct', ..., ..., "positional_or_keyword"),
2733 ('foo', 1, ..., "keyword_only")),
2734 ...))
2735
2736 self.assertEqual(self.signature(CM),
2737 ((('nm', ..., ..., "positional_or_keyword"),
2738 ('bs', ..., ..., "positional_or_keyword"),
2739 ('dt', ..., ..., "positional_or_keyword")),
2740 ...))
2741
2742 self.assertEqual(self.signature(C),
2743 ((('b', ..., ..., "positional_or_keyword"),),
2744 ...))
2745
2746 class CM(type):
2747 def __init__(cls, name, bases, dct, *, bar=2):
2748 return super().__init__(name, bases, dct)
2749 class C(metaclass=CM):
2750 def __init__(self, b):
2751 pass
2752
2753 self.assertEqual(self.signature(CM),
2754 ((('name', ..., ..., "positional_or_keyword"),
2755 ('bases', ..., ..., "positional_or_keyword"),
2756 ('dct', ..., ..., "positional_or_keyword"),
2757 ('bar', 2, ..., "keyword_only")),
2758 ...))
2759
Yury Selivanov145dff82014-02-01 13:49:29 -05002760 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2761 "Signature information for builtins requires docstrings")
2762 def test_signature_on_class_without_init(self):
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002763 # Test classes without user-defined __init__ or __new__
2764 class C: pass
2765 self.assertEqual(str(inspect.signature(C)), '()')
2766 class D(C): pass
2767 self.assertEqual(str(inspect.signature(D)), '()')
2768
2769 # Test meta-classes without user-defined __init__ or __new__
2770 class C(type): pass
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002771 class D(C): pass
Larry Hastings2623c8c2014-02-08 22:15:29 -08002772 with self.assertRaisesRegex(ValueError, "callable.*is not supported"):
2773 self.assertEqual(inspect.signature(C), None)
2774 with self.assertRaisesRegex(ValueError, "callable.*is not supported"):
2775 self.assertEqual(inspect.signature(D), None)
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002776
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002777 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2778 "Signature information for builtins requires docstrings")
2779 def test_signature_on_builtin_class(self):
2780 self.assertEqual(str(inspect.signature(_pickle.Pickler)),
2781 '(file, protocol=None, fix_imports=True)')
2782
2783 class P(_pickle.Pickler): pass
2784 class EmptyTrait: pass
2785 class P2(EmptyTrait, P): pass
2786 self.assertEqual(str(inspect.signature(P)),
2787 '(file, protocol=None, fix_imports=True)')
2788 self.assertEqual(str(inspect.signature(P2)),
2789 '(file, protocol=None, fix_imports=True)')
2790
2791 class P3(P2):
2792 def __init__(self, spam):
2793 pass
2794 self.assertEqual(str(inspect.signature(P3)), '(spam)')
2795
2796 class MetaP(type):
2797 def __call__(cls, foo, bar):
2798 pass
2799 class P4(P2, metaclass=MetaP):
2800 pass
2801 self.assertEqual(str(inspect.signature(P4)), '(foo, bar)')
2802
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002803 def test_signature_on_callable_objects(self):
2804 class Foo:
2805 def __call__(self, a):
2806 pass
2807
2808 self.assertEqual(self.signature(Foo()),
2809 ((('a', ..., ..., "positional_or_keyword"),),
2810 ...))
2811
2812 class Spam:
2813 pass
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002814 with self.assertRaisesRegex(TypeError, "is not a callable object"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002815 inspect.signature(Spam())
2816
2817 class Bar(Spam, Foo):
2818 pass
2819
2820 self.assertEqual(self.signature(Bar()),
2821 ((('a', ..., ..., "positional_or_keyword"),),
2822 ...))
2823
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002824 class Wrapped:
2825 pass
2826 Wrapped.__wrapped__ = lambda a: None
2827 self.assertEqual(self.signature(Wrapped),
2828 ((('a', ..., ..., "positional_or_keyword"),),
2829 ...))
Nick Coghlane8c45d62013-07-28 20:00:01 +10002830 # wrapper loop:
2831 Wrapped.__wrapped__ = Wrapped
2832 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
2833 self.signature(Wrapped)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002834
2835 def test_signature_on_lambdas(self):
2836 self.assertEqual(self.signature((lambda a=10: a)),
2837 ((('a', 10, ..., "positional_or_keyword"),),
2838 ...))
2839
2840 def test_signature_equality(self):
2841 def foo(a, *, b:int) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002842 self.assertFalse(inspect.signature(foo) == 42)
2843 self.assertTrue(inspect.signature(foo) != 42)
2844 self.assertTrue(inspect.signature(foo) == EqualsToAll())
2845 self.assertFalse(inspect.signature(foo) != EqualsToAll())
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002846
2847 def bar(a, *, b:int) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002848 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
2849 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002850 self.assertEqual(
2851 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002852
2853 def bar(a, *, b:int) -> int: 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
2859 def bar(a, *, b:int): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002860 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
2861 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002862 self.assertNotEqual(
2863 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002864
2865 def bar(a, *, b:int=42) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002866 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
2867 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002868 self.assertNotEqual(
2869 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002870
2871 def bar(a, *, c) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002872 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
2873 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002874 self.assertNotEqual(
2875 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002876
2877 def bar(a, b:int) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002878 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
2879 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002880 self.assertNotEqual(
2881 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002882 def spam(b:int, a) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002883 self.assertFalse(inspect.signature(spam) == inspect.signature(bar))
2884 self.assertTrue(inspect.signature(spam) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002885 self.assertNotEqual(
2886 hash(inspect.signature(spam)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002887
2888 def foo(*, a, b, c): pass
2889 def bar(*, c, b, a): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002890 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
2891 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002892 self.assertEqual(
2893 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002894
2895 def foo(*, a=1, b, c): pass
2896 def bar(*, c, b, a=1): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002897 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
2898 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002899 self.assertEqual(
2900 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002901
2902 def foo(pos, *, a=1, b, c): pass
2903 def bar(pos, *, c, b, a=1): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002904 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
2905 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002906 self.assertEqual(
2907 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002908
2909 def foo(pos, *, a, b, c): pass
2910 def bar(pos, *, c, b, a=1): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002911 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
2912 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002913 self.assertNotEqual(
2914 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002915
2916 def foo(pos, *args, a=42, b, c, **kwargs:int): pass
2917 def bar(pos, *args, c, b, a=42, **kwargs:int): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002918 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
2919 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002920 self.assertEqual(
2921 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002922
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002923 def test_signature_hashable(self):
2924 S = inspect.Signature
2925 P = inspect.Parameter
2926
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002927 def foo(a): pass
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002928 foo_sig = inspect.signature(foo)
2929
2930 manual_sig = S(parameters=[P('a', P.POSITIONAL_OR_KEYWORD)])
2931
2932 self.assertEqual(hash(foo_sig), hash(manual_sig))
2933 self.assertNotEqual(hash(foo_sig),
2934 hash(manual_sig.replace(return_annotation='spam')))
2935
2936 def bar(a) -> 1: pass
2937 self.assertNotEqual(hash(foo_sig), hash(inspect.signature(bar)))
2938
2939 def foo(a={}): pass
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002940 with self.assertRaisesRegex(TypeError, 'unhashable type'):
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002941 hash(inspect.signature(foo))
2942
2943 def foo(a) -> {}: pass
2944 with self.assertRaisesRegex(TypeError, 'unhashable type'):
2945 hash(inspect.signature(foo))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002946
2947 def test_signature_str(self):
2948 def foo(a:int=1, *, b, c=None, **kwargs) -> 42:
2949 pass
2950 self.assertEqual(str(inspect.signature(foo)),
Dong-hee Na762b9572017-11-16 03:30:59 +09002951 '(a: int = 1, *, b, c=None, **kwargs) -> 42')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002952
2953 def foo(a:int=1, *args, b, c=None, **kwargs) -> 42:
2954 pass
2955 self.assertEqual(str(inspect.signature(foo)),
Dong-hee Na762b9572017-11-16 03:30:59 +09002956 '(a: int = 1, *args, b, c=None, **kwargs) -> 42')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002957
2958 def foo():
2959 pass
2960 self.assertEqual(str(inspect.signature(foo)), '()')
2961
2962 def test_signature_str_positional_only(self):
2963 P = inspect.Parameter
Yury Selivanov2393dca2014-01-27 15:07:58 -05002964 S = inspect.Signature
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002965
2966 def test(a_po, *, b, **kwargs):
2967 return a_po, kwargs
2968
2969 sig = inspect.signature(test)
2970 new_params = list(sig.parameters.values())
2971 new_params[0] = new_params[0].replace(kind=P.POSITIONAL_ONLY)
2972 test.__signature__ = sig.replace(parameters=new_params)
2973
2974 self.assertEqual(str(inspect.signature(test)),
Yury Selivanov2393dca2014-01-27 15:07:58 -05002975 '(a_po, /, *, b, **kwargs)')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002976
Yury Selivanov2393dca2014-01-27 15:07:58 -05002977 self.assertEqual(str(S(parameters=[P('foo', P.POSITIONAL_ONLY)])),
2978 '(foo, /)')
2979
2980 self.assertEqual(str(S(parameters=[
2981 P('foo', P.POSITIONAL_ONLY),
2982 P('bar', P.VAR_KEYWORD)])),
2983 '(foo, /, **bar)')
2984
2985 self.assertEqual(str(S(parameters=[
2986 P('foo', P.POSITIONAL_ONLY),
2987 P('bar', P.VAR_POSITIONAL)])),
2988 '(foo, /, *bar)')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002989
2990 def test_signature_replace_anno(self):
2991 def test() -> 42:
2992 pass
2993
2994 sig = inspect.signature(test)
2995 sig = sig.replace(return_annotation=None)
2996 self.assertIs(sig.return_annotation, None)
2997 sig = sig.replace(return_annotation=sig.empty)
2998 self.assertIs(sig.return_annotation, sig.empty)
2999 sig = sig.replace(return_annotation=42)
3000 self.assertEqual(sig.return_annotation, 42)
3001 self.assertEqual(sig, inspect.signature(test))
3002
Yury Selivanov34ce99f2014-02-18 12:49:41 -05003003 def test_signature_on_mangled_parameters(self):
3004 class Spam:
3005 def foo(self, __p1:1=2, *, __p2:2=3):
3006 pass
3007 class Ham(Spam):
3008 pass
3009
3010 self.assertEqual(self.signature(Spam.foo),
3011 ((('self', ..., ..., "positional_or_keyword"),
3012 ('_Spam__p1', 2, 1, "positional_or_keyword"),
3013 ('_Spam__p2', 3, 2, "keyword_only")),
3014 ...))
3015
3016 self.assertEqual(self.signature(Spam.foo),
3017 self.signature(Ham.foo))
3018
Yury Selivanovda396452014-03-27 12:09:24 -04003019 def test_signature_from_callable_python_obj(self):
3020 class MySignature(inspect.Signature): pass
3021 def foo(a, *, b:1): pass
3022 foo_sig = MySignature.from_callable(foo)
3023 self.assertTrue(isinstance(foo_sig, MySignature))
3024
3025 @unittest.skipIf(MISSING_C_DOCSTRINGS,
3026 "Signature information for builtins requires docstrings")
3027 def test_signature_from_callable_builtin_obj(self):
3028 class MySignature(inspect.Signature): pass
3029 sig = MySignature.from_callable(_pickle.Pickler)
3030 self.assertTrue(isinstance(sig, MySignature))
3031
larryhastingsf36ba122018-01-28 11:13:09 -08003032 def test_signature_definition_order_preserved_on_kwonly(self):
3033 for fn in signatures_with_lexicographic_keyword_only_parameters():
3034 signature = inspect.signature(fn)
3035 l = list(signature.parameters)
3036 sorted_l = sorted(l)
3037 self.assertTrue(l)
3038 self.assertEqual(l, sorted_l)
3039 signature = inspect.signature(unsorted_keyword_only_parameters_fn)
3040 l = list(signature.parameters)
3041 self.assertEqual(l, unsorted_keyword_only_parameters)
3042
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003043
3044class TestParameterObject(unittest.TestCase):
3045 def test_signature_parameter_kinds(self):
3046 P = inspect.Parameter
3047 self.assertTrue(P.POSITIONAL_ONLY < P.POSITIONAL_OR_KEYWORD < \
3048 P.VAR_POSITIONAL < P.KEYWORD_ONLY < P.VAR_KEYWORD)
3049
3050 self.assertEqual(str(P.POSITIONAL_ONLY), 'POSITIONAL_ONLY')
3051 self.assertTrue('POSITIONAL_ONLY' in repr(P.POSITIONAL_ONLY))
3052
3053 def test_signature_parameter_object(self):
3054 p = inspect.Parameter('foo', default=10,
3055 kind=inspect.Parameter.POSITIONAL_ONLY)
3056 self.assertEqual(p.name, 'foo')
3057 self.assertEqual(p.default, 10)
3058 self.assertIs(p.annotation, p.empty)
3059 self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY)
3060
Miss Islington (bot)cb055bc2018-05-29 08:43:54 -07003061 with self.assertRaisesRegex(ValueError, "value '123' is "
3062 "not a valid Parameter.kind"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003063 inspect.Parameter('foo', default=10, kind='123')
3064
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003065 with self.assertRaisesRegex(ValueError, 'not a valid parameter name'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003066 inspect.Parameter('1', kind=inspect.Parameter.VAR_KEYWORD)
3067
Yury Selivanov2393dca2014-01-27 15:07:58 -05003068 with self.assertRaisesRegex(TypeError, 'name must be a str'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003069 inspect.Parameter(None, kind=inspect.Parameter.VAR_KEYWORD)
3070
Yury Selivanov2393dca2014-01-27 15:07:58 -05003071 with self.assertRaisesRegex(ValueError,
3072 'is not a valid parameter name'):
3073 inspect.Parameter('$', kind=inspect.Parameter.VAR_KEYWORD)
3074
Nick Coghlanb4b966e2016-06-04 14:40:03 -07003075 with self.assertRaisesRegex(ValueError,
3076 'is not a valid parameter name'):
3077 inspect.Parameter('.a', kind=inspect.Parameter.VAR_KEYWORD)
3078
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003079 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003080 inspect.Parameter('a', default=42,
3081 kind=inspect.Parameter.VAR_KEYWORD)
3082
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003083 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003084 inspect.Parameter('a', default=42,
3085 kind=inspect.Parameter.VAR_POSITIONAL)
3086
3087 p = inspect.Parameter('a', default=42,
3088 kind=inspect.Parameter.POSITIONAL_OR_KEYWORD)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003089 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003090 p.replace(kind=inspect.Parameter.VAR_POSITIONAL)
3091
3092 self.assertTrue(repr(p).startswith('<Parameter'))
Yury Selivanov374375d2014-03-27 12:41:53 -04003093 self.assertTrue('"a=42"' in repr(p))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003094
Yury Selivanov67ae50e2014-04-08 11:46:50 -04003095 def test_signature_parameter_hashable(self):
3096 P = inspect.Parameter
3097 foo = P('foo', kind=P.POSITIONAL_ONLY)
3098 self.assertEqual(hash(foo), hash(P('foo', kind=P.POSITIONAL_ONLY)))
3099 self.assertNotEqual(hash(foo), hash(P('foo', kind=P.POSITIONAL_ONLY,
3100 default=42)))
3101 self.assertNotEqual(hash(foo),
3102 hash(foo.replace(kind=P.VAR_POSITIONAL)))
3103
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003104 def test_signature_parameter_equality(self):
3105 P = inspect.Parameter
3106 p = P('foo', default=42, kind=inspect.Parameter.KEYWORD_ONLY)
3107
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003108 self.assertTrue(p == p)
3109 self.assertFalse(p != p)
3110 self.assertFalse(p == 42)
3111 self.assertTrue(p != 42)
3112 self.assertTrue(p == EqualsToAll())
3113 self.assertFalse(p != EqualsToAll())
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003114
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003115 self.assertTrue(p == P('foo', default=42,
3116 kind=inspect.Parameter.KEYWORD_ONLY))
3117 self.assertFalse(p != P('foo', default=42,
3118 kind=inspect.Parameter.KEYWORD_ONLY))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003119
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003120 def test_signature_parameter_replace(self):
3121 p = inspect.Parameter('foo', default=42,
3122 kind=inspect.Parameter.KEYWORD_ONLY)
3123
3124 self.assertIsNot(p, p.replace())
3125 self.assertEqual(p, p.replace())
3126
3127 p2 = p.replace(annotation=1)
3128 self.assertEqual(p2.annotation, 1)
3129 p2 = p2.replace(annotation=p2.empty)
3130 self.assertEqual(p, p2)
3131
3132 p2 = p2.replace(name='bar')
3133 self.assertEqual(p2.name, 'bar')
3134 self.assertNotEqual(p2, p)
3135
Yury Selivanov2393dca2014-01-27 15:07:58 -05003136 with self.assertRaisesRegex(ValueError,
3137 'name is a required attribute'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003138 p2 = p2.replace(name=p2.empty)
3139
3140 p2 = p2.replace(name='foo', default=None)
3141 self.assertIs(p2.default, None)
3142 self.assertNotEqual(p2, p)
3143
3144 p2 = p2.replace(name='foo', default=p2.empty)
3145 self.assertIs(p2.default, p2.empty)
3146
3147
3148 p2 = p2.replace(default=42, kind=p2.POSITIONAL_OR_KEYWORD)
3149 self.assertEqual(p2.kind, p2.POSITIONAL_OR_KEYWORD)
3150 self.assertNotEqual(p2, p)
3151
Miss Islington (bot)cb055bc2018-05-29 08:43:54 -07003152 with self.assertRaisesRegex(ValueError,
3153 "value <class 'inspect._empty'> "
3154 "is not a valid Parameter.kind"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003155 p2 = p2.replace(kind=p2.empty)
3156
3157 p2 = p2.replace(kind=p2.KEYWORD_ONLY)
3158 self.assertEqual(p2, p)
3159
3160 def test_signature_parameter_positional_only(self):
Yury Selivanov2393dca2014-01-27 15:07:58 -05003161 with self.assertRaisesRegex(TypeError, 'name must be a str'):
3162 inspect.Parameter(None, kind=inspect.Parameter.POSITIONAL_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003163
Nick Coghlanb4b966e2016-06-04 14:40:03 -07003164 @cpython_only
3165 def test_signature_parameter_implicit(self):
3166 with self.assertRaisesRegex(ValueError,
Miss Islington (bot)cb055bc2018-05-29 08:43:54 -07003167 'implicit arguments must be passed as '
3168 'positional or keyword arguments, '
3169 'not positional-only'):
Nick Coghlanb4b966e2016-06-04 14:40:03 -07003170 inspect.Parameter('.0', kind=inspect.Parameter.POSITIONAL_ONLY)
3171
3172 param = inspect.Parameter(
3173 '.0', kind=inspect.Parameter.POSITIONAL_OR_KEYWORD)
3174 self.assertEqual(param.kind, inspect.Parameter.POSITIONAL_ONLY)
3175 self.assertEqual(param.name, 'implicit0')
3176
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003177 def test_signature_parameter_immutability(self):
Yury Selivanov2393dca2014-01-27 15:07:58 -05003178 p = inspect.Parameter('spam', kind=inspect.Parameter.KEYWORD_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003179
3180 with self.assertRaises(AttributeError):
3181 p.foo = 'bar'
3182
3183 with self.assertRaises(AttributeError):
3184 p.kind = 123
3185
3186
3187class TestSignatureBind(unittest.TestCase):
3188 @staticmethod
3189 def call(func, *args, **kwargs):
3190 sig = inspect.signature(func)
3191 ba = sig.bind(*args, **kwargs)
3192 return func(*ba.args, **ba.kwargs)
3193
3194 def test_signature_bind_empty(self):
3195 def test():
3196 return 42
3197
3198 self.assertEqual(self.call(test), 42)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003199 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003200 self.call(test, 1)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003201 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003202 self.call(test, 1, spam=10)
Yury Selivanov86872752015-05-19 00:27:49 -04003203 with self.assertRaisesRegex(
3204 TypeError, "got an unexpected keyword argument 'spam'"):
3205
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003206 self.call(test, spam=1)
3207
3208 def test_signature_bind_var(self):
3209 def test(*args, **kwargs):
3210 return args, kwargs
3211
3212 self.assertEqual(self.call(test), ((), {}))
3213 self.assertEqual(self.call(test, 1), ((1,), {}))
3214 self.assertEqual(self.call(test, 1, 2), ((1, 2), {}))
3215 self.assertEqual(self.call(test, foo='bar'), ((), {'foo': 'bar'}))
3216 self.assertEqual(self.call(test, 1, foo='bar'), ((1,), {'foo': 'bar'}))
3217 self.assertEqual(self.call(test, args=10), ((), {'args': 10}))
3218 self.assertEqual(self.call(test, 1, 2, foo='bar'),
3219 ((1, 2), {'foo': 'bar'}))
3220
3221 def test_signature_bind_just_args(self):
3222 def test(a, b, c):
3223 return a, b, c
3224
3225 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
3226
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003227 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003228 self.call(test, 1, 2, 3, 4)
3229
Yury Selivanov86872752015-05-19 00:27:49 -04003230 with self.assertRaisesRegex(TypeError,
3231 "missing a required argument: 'b'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003232 self.call(test, 1)
3233
Yury Selivanov86872752015-05-19 00:27:49 -04003234 with self.assertRaisesRegex(TypeError,
3235 "missing a required argument: 'a'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003236 self.call(test)
3237
3238 def test(a, b, c=10):
3239 return a, b, c
3240 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
3241 self.assertEqual(self.call(test, 1, 2), (1, 2, 10))
3242
3243 def test(a=1, b=2, c=3):
3244 return a, b, c
3245 self.assertEqual(self.call(test, a=10, c=13), (10, 2, 13))
3246 self.assertEqual(self.call(test, a=10), (10, 2, 3))
3247 self.assertEqual(self.call(test, b=10), (1, 10, 3))
3248
3249 def test_signature_bind_varargs_order(self):
3250 def test(*args):
3251 return args
3252
3253 self.assertEqual(self.call(test), ())
3254 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
3255
3256 def test_signature_bind_args_and_varargs(self):
3257 def test(a, b, c=3, *args):
3258 return a, b, c, args
3259
3260 self.assertEqual(self.call(test, 1, 2, 3, 4, 5), (1, 2, 3, (4, 5)))
3261 self.assertEqual(self.call(test, 1, 2), (1, 2, 3, ()))
3262 self.assertEqual(self.call(test, b=1, a=2), (2, 1, 3, ()))
3263 self.assertEqual(self.call(test, 1, b=2), (1, 2, 3, ()))
3264
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003265 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003266 "multiple values for argument 'c'"):
3267 self.call(test, 1, 2, 3, c=4)
3268
3269 def test_signature_bind_just_kwargs(self):
3270 def test(**kwargs):
3271 return kwargs
3272
3273 self.assertEqual(self.call(test), {})
3274 self.assertEqual(self.call(test, foo='bar', spam='ham'),
3275 {'foo': 'bar', 'spam': 'ham'})
3276
3277 def test_signature_bind_args_and_kwargs(self):
3278 def test(a, b, c=3, **kwargs):
3279 return a, b, c, kwargs
3280
3281 self.assertEqual(self.call(test, 1, 2), (1, 2, 3, {}))
3282 self.assertEqual(self.call(test, 1, 2, foo='bar', spam='ham'),
3283 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3284 self.assertEqual(self.call(test, b=2, a=1, foo='bar', spam='ham'),
3285 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3286 self.assertEqual(self.call(test, a=1, b=2, foo='bar', spam='ham'),
3287 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3288 self.assertEqual(self.call(test, 1, b=2, foo='bar', spam='ham'),
3289 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3290 self.assertEqual(self.call(test, 1, b=2, c=4, foo='bar', spam='ham'),
3291 (1, 2, 4, {'foo': 'bar', 'spam': 'ham'}))
3292 self.assertEqual(self.call(test, 1, 2, 4, foo='bar'),
3293 (1, 2, 4, {'foo': 'bar'}))
3294 self.assertEqual(self.call(test, c=5, a=4, b=3),
3295 (4, 3, 5, {}))
3296
3297 def test_signature_bind_kwonly(self):
3298 def test(*, foo):
3299 return foo
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003300 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003301 'too many positional arguments'):
3302 self.call(test, 1)
3303 self.assertEqual(self.call(test, foo=1), 1)
3304
3305 def test(a, *, foo=1, bar):
3306 return foo
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003307 with self.assertRaisesRegex(TypeError,
Yury Selivanov86872752015-05-19 00:27:49 -04003308 "missing a required argument: 'bar'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003309 self.call(test, 1)
3310
3311 def test(foo, *, bar):
3312 return foo, bar
3313 self.assertEqual(self.call(test, 1, bar=2), (1, 2))
3314 self.assertEqual(self.call(test, bar=2, foo=1), (1, 2))
3315
Yury Selivanov86872752015-05-19 00:27:49 -04003316 with self.assertRaisesRegex(
3317 TypeError, "got an unexpected keyword argument 'spam'"):
3318
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003319 self.call(test, bar=2, foo=1, spam=10)
3320
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003321 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003322 'too many positional arguments'):
3323 self.call(test, 1, 2)
3324
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003325 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003326 'too many positional arguments'):
3327 self.call(test, 1, 2, bar=2)
3328
Yury Selivanov86872752015-05-19 00:27:49 -04003329 with self.assertRaisesRegex(
3330 TypeError, "got an unexpected keyword argument 'spam'"):
3331
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003332 self.call(test, 1, bar=2, spam='ham')
3333
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003334 with self.assertRaisesRegex(TypeError,
Yury Selivanov86872752015-05-19 00:27:49 -04003335 "missing a required argument: 'bar'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003336 self.call(test, 1)
3337
3338 def test(foo, *, bar, **bin):
3339 return foo, bar, bin
3340 self.assertEqual(self.call(test, 1, bar=2), (1, 2, {}))
3341 self.assertEqual(self.call(test, foo=1, bar=2), (1, 2, {}))
3342 self.assertEqual(self.call(test, 1, bar=2, spam='ham'),
3343 (1, 2, {'spam': 'ham'}))
3344 self.assertEqual(self.call(test, spam='ham', foo=1, bar=2),
3345 (1, 2, {'spam': 'ham'}))
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003346 with self.assertRaisesRegex(TypeError,
Yury Selivanov86872752015-05-19 00:27:49 -04003347 "missing a required argument: 'foo'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003348 self.call(test, spam='ham', bar=2)
3349 self.assertEqual(self.call(test, 1, bar=2, bin=1, spam=10),
3350 (1, 2, {'bin': 1, 'spam': 10}))
3351
3352 def test_signature_bind_arguments(self):
3353 def test(a, *args, b, z=100, **kwargs):
3354 pass
3355 sig = inspect.signature(test)
3356 ba = sig.bind(10, 20, b=30, c=40, args=50, kwargs=60)
3357 # we won't have 'z' argument in the bound arguments object, as we didn't
3358 # pass it to the 'bind'
3359 self.assertEqual(tuple(ba.arguments.items()),
3360 (('a', 10), ('args', (20,)), ('b', 30),
3361 ('kwargs', {'c': 40, 'args': 50, 'kwargs': 60})))
3362 self.assertEqual(ba.kwargs,
3363 {'b': 30, 'c': 40, 'args': 50, 'kwargs': 60})
3364 self.assertEqual(ba.args, (10, 20))
3365
3366 def test_signature_bind_positional_only(self):
3367 P = inspect.Parameter
3368
3369 def test(a_po, b_po, c_po=3, foo=42, *, bar=50, **kwargs):
3370 return a_po, b_po, c_po, foo, bar, kwargs
3371
3372 sig = inspect.signature(test)
3373 new_params = collections.OrderedDict(tuple(sig.parameters.items()))
3374 for name in ('a_po', 'b_po', 'c_po'):
3375 new_params[name] = new_params[name].replace(kind=P.POSITIONAL_ONLY)
3376 new_sig = sig.replace(parameters=new_params.values())
3377 test.__signature__ = new_sig
3378
3379 self.assertEqual(self.call(test, 1, 2, 4, 5, bar=6),
3380 (1, 2, 4, 5, 6, {}))
3381
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05003382 self.assertEqual(self.call(test, 1, 2),
3383 (1, 2, 3, 42, 50, {}))
3384
3385 self.assertEqual(self.call(test, 1, 2, foo=4, bar=5),
3386 (1, 2, 3, 4, 5, {}))
3387
3388 with self.assertRaisesRegex(TypeError, "but was passed as a keyword"):
3389 self.call(test, 1, 2, foo=4, bar=5, c_po=10)
3390
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003391 with self.assertRaisesRegex(TypeError, "parameter is positional only"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003392 self.call(test, 1, 2, c_po=4)
3393
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003394 with self.assertRaisesRegex(TypeError, "parameter is positional only"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003395 self.call(test, a_po=1, b_po=2)
3396
Antoine Pitroubd41d1b2013-01-29 21:20:57 +01003397 def test_signature_bind_with_self_arg(self):
3398 # Issue #17071: one of the parameters is named "self
3399 def test(a, self, b):
3400 pass
3401 sig = inspect.signature(test)
3402 ba = sig.bind(1, 2, 3)
3403 self.assertEqual(ba.args, (1, 2, 3))
3404 ba = sig.bind(1, self=2, b=3)
3405 self.assertEqual(ba.args, (1, 2, 3))
3406
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05003407 def test_signature_bind_vararg_name(self):
3408 def test(a, *args):
3409 return a, args
3410 sig = inspect.signature(test)
3411
Yury Selivanov86872752015-05-19 00:27:49 -04003412 with self.assertRaisesRegex(
3413 TypeError, "got an unexpected keyword argument 'args'"):
3414
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05003415 sig.bind(a=0, args=1)
3416
3417 def test(*args, **kwargs):
3418 return args, kwargs
3419 self.assertEqual(self.call(test, args=1), ((), {'args': 1}))
3420
3421 sig = inspect.signature(test)
3422 ba = sig.bind(args=1)
3423 self.assertEqual(ba.arguments, {'kwargs': {'args': 1}})
3424
Nick Coghlanb4b966e2016-06-04 14:40:03 -07003425 @cpython_only
3426 def test_signature_bind_implicit_arg(self):
3427 # Issue #19611: getcallargs should work with set comprehensions
3428 def make_set():
3429 return {z * z for z in range(5)}
3430 setcomp_code = make_set.__code__.co_consts[1]
3431 setcomp_func = types.FunctionType(setcomp_code, {})
3432
3433 iterator = iter(range(5))
3434 self.assertEqual(self.call(setcomp_func, iterator), {0, 1, 4, 9, 16})
3435
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003436
3437class TestBoundArguments(unittest.TestCase):
3438 def test_signature_bound_arguments_unhashable(self):
3439 def foo(a): pass
3440 ba = inspect.signature(foo).bind(1)
3441
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003442 with self.assertRaisesRegex(TypeError, 'unhashable type'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003443 hash(ba)
3444
3445 def test_signature_bound_arguments_equality(self):
3446 def foo(a): pass
3447 ba = inspect.signature(foo).bind(1)
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003448 self.assertTrue(ba == ba)
3449 self.assertFalse(ba != ba)
3450 self.assertTrue(ba == EqualsToAll())
3451 self.assertFalse(ba != EqualsToAll())
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003452
3453 ba2 = inspect.signature(foo).bind(1)
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003454 self.assertTrue(ba == ba2)
3455 self.assertFalse(ba != ba2)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003456
3457 ba3 = inspect.signature(foo).bind(2)
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003458 self.assertFalse(ba == ba3)
3459 self.assertTrue(ba != ba3)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003460 ba3.arguments['a'] = 1
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003461 self.assertTrue(ba == ba3)
3462 self.assertFalse(ba != ba3)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003463
3464 def bar(b): pass
3465 ba4 = inspect.signature(bar).bind(1)
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003466 self.assertFalse(ba == ba4)
3467 self.assertTrue(ba != ba4)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003468
Yury Selivanov4cfd4ea2015-05-14 18:30:27 -04003469 def foo(*, a, b): pass
3470 sig = inspect.signature(foo)
3471 ba1 = sig.bind(a=1, b=2)
3472 ba2 = sig.bind(b=2, a=1)
Serhiy Storchaka2489bd52015-07-18 23:20:50 +03003473 self.assertTrue(ba1 == ba2)
3474 self.assertFalse(ba1 != ba2)
Yury Selivanov4cfd4ea2015-05-14 18:30:27 -04003475
Yury Selivanova5d63dd2014-03-27 11:31:43 -04003476 def test_signature_bound_arguments_pickle(self):
3477 def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
3478 sig = inspect.signature(foo)
3479 ba = sig.bind(20, 30, z={})
3480
3481 for ver in range(pickle.HIGHEST_PROTOCOL + 1):
3482 with self.subTest(pickle_ver=ver):
3483 ba_pickled = pickle.loads(pickle.dumps(ba, ver))
3484 self.assertEqual(ba, ba_pickled)
3485
Yury Selivanov3f6538f2015-05-14 18:47:17 -04003486 def test_signature_bound_arguments_repr(self):
3487 def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
3488 sig = inspect.signature(foo)
3489 ba = sig.bind(20, 30, z={})
Yury Selivanovf229bc52015-05-15 12:53:56 -04003490 self.assertRegex(repr(ba), r'<BoundArguments \(a=20,.*\}\}\)>')
Yury Selivanov3f6538f2015-05-14 18:47:17 -04003491
Yury Selivanovb907a512015-05-16 13:45:09 -04003492 def test_signature_bound_arguments_apply_defaults(self):
3493 def foo(a, b=1, *args, c:1={}, **kw): pass
3494 sig = inspect.signature(foo)
3495
3496 ba = sig.bind(20)
3497 ba.apply_defaults()
3498 self.assertEqual(
3499 list(ba.arguments.items()),
3500 [('a', 20), ('b', 1), ('args', ()), ('c', {}), ('kw', {})])
3501
3502 # Make sure that we preserve the order:
3503 # i.e. 'c' should be *before* 'kw'.
3504 ba = sig.bind(10, 20, 30, d=1)
3505 ba.apply_defaults()
3506 self.assertEqual(
3507 list(ba.arguments.items()),
3508 [('a', 10), ('b', 20), ('args', (30,)), ('c', {}), ('kw', {'d':1})])
3509
3510 # Make sure that BoundArguments produced by bind_partial()
3511 # are supported.
3512 def foo(a, b): pass
3513 sig = inspect.signature(foo)
3514 ba = sig.bind_partial(20)
3515 ba.apply_defaults()
3516 self.assertEqual(
3517 list(ba.arguments.items()),
3518 [('a', 20)])
3519
3520 # Test no args
3521 def foo(): pass
3522 sig = inspect.signature(foo)
3523 ba = sig.bind()
3524 ba.apply_defaults()
3525 self.assertEqual(list(ba.arguments.items()), [])
3526
Yury Selivanovf9e1f2b2016-03-02 11:07:47 -05003527 # Make sure a no-args binding still acquires proper defaults.
3528 def foo(a='spam'): pass
3529 sig = inspect.signature(foo)
3530 ba = sig.bind()
3531 ba.apply_defaults()
3532 self.assertEqual(list(ba.arguments.items()), [('a', 'spam')])
3533
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003534
Yury Selivanovd82eddc2014-01-29 11:24:39 -05003535class TestSignaturePrivateHelpers(unittest.TestCase):
3536 def test_signature_get_bound_param(self):
3537 getter = inspect._signature_get_bound_param
3538
3539 self.assertEqual(getter('($self)'), 'self')
3540 self.assertEqual(getter('($self, obj)'), 'self')
3541 self.assertEqual(getter('($cls, /, obj)'), 'cls')
3542
Larry Hastings2623c8c2014-02-08 22:15:29 -08003543 def _strip_non_python_syntax(self, input,
3544 clean_signature, self_parameter, last_positional_only):
3545 computed_clean_signature, \
3546 computed_self_parameter, \
3547 computed_last_positional_only = \
3548 inspect._signature_strip_non_python_syntax(input)
3549 self.assertEqual(computed_clean_signature, clean_signature)
3550 self.assertEqual(computed_self_parameter, self_parameter)
3551 self.assertEqual(computed_last_positional_only, last_positional_only)
3552
3553 def test_signature_strip_non_python_syntax(self):
3554 self._strip_non_python_syntax(
3555 "($module, /, path, mode, *, dir_fd=None, " +
3556 "effective_ids=False,\n follow_symlinks=True)",
3557 "(module, path, mode, *, dir_fd=None, " +
3558 "effective_ids=False, follow_symlinks=True)",
3559 0,
3560 0)
3561
3562 self._strip_non_python_syntax(
3563 "($module, word, salt, /)",
3564 "(module, word, salt)",
3565 0,
3566 2)
3567
3568 self._strip_non_python_syntax(
3569 "(x, y=None, z=None, /)",
3570 "(x, y=None, z=None)",
3571 None,
3572 2)
3573
3574 self._strip_non_python_syntax(
3575 "(x, y=None, z=None)",
3576 "(x, y=None, z=None)",
3577 None,
3578 None)
3579
3580 self._strip_non_python_syntax(
3581 "(x,\n y=None,\n z = None )",
3582 "(x, y=None, z=None)",
3583 None,
3584 None)
3585
3586 self._strip_non_python_syntax(
3587 "",
3588 "",
3589 None,
3590 None)
3591
3592 self._strip_non_python_syntax(
3593 None,
3594 None,
3595 None,
3596 None)
3597
Nick Coghlan9c680b02015-04-13 12:54:54 -04003598class TestSignatureDefinitions(unittest.TestCase):
3599 # This test case provides a home for checking that particular APIs
3600 # have signatures available for introspection
3601
3602 @cpython_only
3603 @unittest.skipIf(MISSING_C_DOCSTRINGS,
3604 "Signature information for builtins requires docstrings")
3605 def test_builtins_have_signatures(self):
3606 # This checks all builtin callables in CPython have signatures
3607 # A few have signatures Signature can't yet handle, so we skip those
3608 # since they will have to wait until PEP 457 adds the required
3609 # introspection support to the inspect module
3610 # Some others also haven't been converted yet for various other
3611 # reasons, so we also skip those for the time being, but design
3612 # the test to fail in order to indicate when it needs to be
3613 # updated.
3614 no_signature = set()
3615 # These need PEP 457 groups
3616 needs_groups = {"range", "slice", "dir", "getattr",
3617 "next", "iter", "vars"}
3618 no_signature |= needs_groups
3619 # These need PEP 457 groups or a signature change to accept None
3620 needs_semantic_update = {"round"}
3621 no_signature |= needs_semantic_update
3622 # These need *args support in Argument Clinic
Barry Warsaw36c1d1f2017-10-05 12:11:18 -04003623 needs_varargs = {"breakpoint", "min", "max", "print",
3624 "__build_class__"}
Nick Coghlan9c680b02015-04-13 12:54:54 -04003625 no_signature |= needs_varargs
3626 # These simply weren't covered in the initial AC conversion
3627 # for builtin callables
3628 not_converted_yet = {"open", "__import__"}
3629 no_signature |= not_converted_yet
3630 # These builtin types are expected to provide introspection info
3631 types_with_signatures = set()
3632 # Check the signatures we expect to be there
3633 ns = vars(builtins)
3634 for name, obj in sorted(ns.items()):
3635 if not callable(obj):
3636 continue
3637 # The builtin types haven't been converted to AC yet
3638 if isinstance(obj, type) and (name not in types_with_signatures):
3639 # Note that this also skips all the exception types
3640 no_signature.add(name)
3641 if (name in no_signature):
3642 # Not yet converted
3643 continue
3644 with self.subTest(builtin=name):
3645 self.assertIsNotNone(inspect.signature(obj))
3646 # Check callables that haven't been converted don't claim a signature
3647 # This ensures this test will start failing as more signatures are
3648 # added, so the affected items can be moved into the scope of the
3649 # regression test above
3650 for name in no_signature:
3651 with self.subTest(builtin=name):
3652 self.assertIsNone(obj.__text_signature__)
3653
Yury Selivanovd82eddc2014-01-29 11:24:39 -05003654
Thomas Kluyverf9169ce2017-05-23 04:27:52 +01003655class NTimesUnwrappable:
3656 def __init__(self, n):
3657 self.n = n
3658 self._next = None
3659
3660 @property
3661 def __wrapped__(self):
3662 if self.n <= 0:
3663 raise Exception("Unwrapped too many times")
3664 if self._next is None:
3665 self._next = NTimesUnwrappable(self.n - 1)
3666 return self._next
3667
Nick Coghlane8c45d62013-07-28 20:00:01 +10003668class TestUnwrap(unittest.TestCase):
3669
3670 def test_unwrap_one(self):
3671 def func(a, b):
3672 return a + b
3673 wrapper = functools.lru_cache(maxsize=20)(func)
3674 self.assertIs(inspect.unwrap(wrapper), func)
3675
3676 def test_unwrap_several(self):
3677 def func(a, b):
3678 return a + b
3679 wrapper = func
3680 for __ in range(10):
3681 @functools.wraps(wrapper)
3682 def wrapper():
3683 pass
3684 self.assertIsNot(wrapper.__wrapped__, func)
3685 self.assertIs(inspect.unwrap(wrapper), func)
3686
3687 def test_stop(self):
3688 def func1(a, b):
3689 return a + b
3690 @functools.wraps(func1)
3691 def func2():
3692 pass
3693 @functools.wraps(func2)
3694 def wrapper():
3695 pass
3696 func2.stop_here = 1
3697 unwrapped = inspect.unwrap(wrapper,
3698 stop=(lambda f: hasattr(f, "stop_here")))
3699 self.assertIs(unwrapped, func2)
3700
3701 def test_cycle(self):
3702 def func1(): pass
3703 func1.__wrapped__ = func1
3704 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3705 inspect.unwrap(func1)
3706
3707 def func2(): pass
3708 func2.__wrapped__ = func1
3709 func1.__wrapped__ = func2
3710 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3711 inspect.unwrap(func1)
3712 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3713 inspect.unwrap(func2)
3714
3715 def test_unhashable(self):
3716 def func(): pass
3717 func.__wrapped__ = None
3718 class C:
3719 __hash__ = None
3720 __wrapped__ = func
3721 self.assertIsNone(inspect.unwrap(C()))
3722
Thomas Kluyverf9169ce2017-05-23 04:27:52 +01003723 def test_recursion_limit(self):
3724 obj = NTimesUnwrappable(sys.getrecursionlimit() + 1)
3725 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3726 inspect.unwrap(obj)
3727
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003728class TestMain(unittest.TestCase):
3729 def test_only_source(self):
3730 module = importlib.import_module('unittest')
3731 rc, out, err = assert_python_ok('-m', 'inspect',
3732 'unittest')
3733 lines = out.decode().splitlines()
3734 # ignore the final newline
3735 self.assertEqual(lines[:-1], inspect.getsource(module).splitlines())
3736 self.assertEqual(err, b'')
3737
Yury Selivanov42407ab2014-06-23 10:23:50 -07003738 def test_custom_getattr(self):
3739 def foo():
3740 pass
3741 foo.__signature__ = 42
3742 with self.assertRaises(TypeError):
3743 inspect.signature(foo)
3744
Brett Cannon634a8fc2013-10-02 10:25:42 -04003745 @unittest.skipIf(ThreadPoolExecutor is None,
Brett Cannon0de3f012013-10-02 10:58:58 -04003746 'threads required to test __qualname__ for source files')
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003747 def test_qualname_source(self):
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003748 rc, out, err = assert_python_ok('-m', 'inspect',
3749 'concurrent.futures:ThreadPoolExecutor')
3750 lines = out.decode().splitlines()
3751 # ignore the final newline
3752 self.assertEqual(lines[:-1],
Brett Cannon634a8fc2013-10-02 10:25:42 -04003753 inspect.getsource(ThreadPoolExecutor).splitlines())
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003754 self.assertEqual(err, b'')
3755
3756 def test_builtins(self):
3757 module = importlib.import_module('unittest')
3758 _, out, err = assert_python_failure('-m', 'inspect',
3759 'sys')
3760 lines = err.decode().splitlines()
3761 self.assertEqual(lines, ["Can't get info for builtin modules."])
3762
3763 def test_details(self):
3764 module = importlib.import_module('unittest')
Victor Stinner9def2842016-01-18 12:15:08 +01003765 args = support.optim_args_from_interpreter_flags()
3766 rc, out, err = assert_python_ok(*args, '-m', 'inspect',
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003767 'unittest', '--details')
3768 output = out.decode()
3769 # Just a quick sanity check on the output
3770 self.assertIn(module.__name__, output)
3771 self.assertIn(module.__file__, output)
Victor Stinner9def2842016-01-18 12:15:08 +01003772 self.assertIn(module.__cached__, output)
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003773 self.assertEqual(err, b'')
3774
3775
Yury Selivanovef1e7502014-12-08 16:05:34 -05003776class TestReload(unittest.TestCase):
3777
3778 src_before = textwrap.dedent("""\
3779def foo():
3780 print("Bla")
3781 """)
3782
3783 src_after = textwrap.dedent("""\
3784def foo():
3785 print("Oh no!")
3786 """)
3787
3788 def assertInspectEqual(self, path, source):
3789 inspected_src = inspect.getsource(source)
3790 with open(path) as src:
3791 self.assertEqual(
3792 src.read().splitlines(True),
3793 inspected_src.splitlines(True)
3794 )
3795
3796 def test_getsource_reload(self):
3797 # see issue 1218234
3798 with _ready_to_import('reload_bug', self.src_before) as (name, path):
3799 module = importlib.import_module(name)
3800 self.assertInspectEqual(path, module)
3801 with open(path, 'w') as src:
3802 src.write(self.src_after)
3803 self.assertInspectEqual(path, module)
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003804
Nick Coghlane8c45d62013-07-28 20:00:01 +10003805
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00003806def test_main():
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00003807 run_unittest(
3808 TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBuggyCases,
3809 TestInterpreterStack, TestClassesAndFunctions, TestPredicates,
3810 TestGetcallargsFunctions, TestGetcallargsMethods,
Alexander Belopolskyf546e702010-12-02 00:10:11 +00003811 TestGetcallargsUnboundMethods, TestGetattrStatic, TestGetGeneratorState,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003812 TestNoEOL, TestSignatureObject, TestSignatureBind, TestParameterObject,
Nick Coghlan9c680b02015-04-13 12:54:54 -04003813 TestBoundArguments, TestSignaturePrivateHelpers,
3814 TestSignatureDefinitions,
Yury Selivanov5376ba92015-06-22 12:19:30 -04003815 TestGetClosureVars, TestUnwrap, TestMain, TestReload,
3816 TestGetCoroutineState
Michael Foord95fc51d2010-11-20 15:07:30 +00003817 )
Martin v. Löwis893ffa42003-10-31 15:35:53 +00003818
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00003819if __name__ == "__main__":
3820 test_main()