blob: a88e7fdbd8cb7c0c1457455dd91683fb66988513 [file] [log] [blame]
Nick Coghlanf9e227e2014-08-17 14:01:19 +10001import builtins
Guido van Rossum813b0e52007-05-21 18:11:34 +00002import collections
Larry Hastings5c661892014-01-24 06:17:25 -08003import datetime
Nick Coghlane8c45d62013-07-28 20:00:01 +10004import functools
Nick Coghlanf94a16b2013-09-22 22:46:49 +10005import importlib
Larry Hastings5c661892014-01-24 06:17:25 -08006import inspect
7import io
8import linecache
9import os
Christian Heimesa3538eb2007-11-06 11:44:48 +000010from os.path import normcase
Larry Hastings5c661892014-01-24 06:17:25 -080011import _pickle
Yury Selivanova5d63dd2014-03-27 11:31:43 -040012import pickle
Larry Hastings5c661892014-01-24 06:17:25 -080013import re
14import shutil
15import sys
16import types
Yury Selivanovef1e7502014-12-08 16:05:34 -050017import textwrap
Larry Hastings5c661892014-01-24 06:17:25 -080018import unicodedata
19import unittest
Yury Selivanova773de02014-02-21 18:30:53 -050020import unittest.mock
Yury Selivanov75445082015-05-11 22:57:16 -040021import warnings
Larry Hastings5c661892014-01-24 06:17:25 -080022
Brett Cannon634a8fc2013-10-02 10:25:42 -040023try:
24 from concurrent.futures import ThreadPoolExecutor
25except ImportError:
26 ThreadPoolExecutor = None
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000027
Serhiy Storchakaf28ba362014-02-07 10:10:55 +020028from test.support import run_unittest, TESTFN, DirsOnSysPath, cpython_only
Nick Coghlanf9e227e2014-08-17 14:01:19 +100029from test.support import MISSING_C_DOCSTRINGS, cpython_only
Berker Peksagce643912015-05-06 06:33:17 +030030from test.support.script_helper import assert_python_ok, assert_python_failure
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000031from test import inspect_fodder as mod
32from test import inspect_fodder2 as mod2
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
Georg Brandl1a3284e2007-12-02 09:40:06 +000058import builtins
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000059
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000060git = mod.StupidGit()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000061
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000062class IsTestBase(unittest.TestCase):
63 predicates = set([inspect.isbuiltin, inspect.isclass, inspect.iscode,
64 inspect.isframe, inspect.isfunction, inspect.ismethod,
Christian Heimes7131fd92008-02-19 14:21:46 +000065 inspect.ismodule, inspect.istraceback,
Yury Selivanov75445082015-05-11 22:57:16 -040066 inspect.isgenerator, inspect.isgeneratorfunction,
67 inspect.iscoroutine, inspect.iscoroutinefunction])
Tim Peters5a9fb3c2005-01-07 16:01:32 +000068
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000069 def istest(self, predicate, exp):
70 obj = eval(exp)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000071 self.assertTrue(predicate(obj), '%s(%s)' % (predicate.__name__, exp))
Tim Peters5a9fb3c2005-01-07 16:01:32 +000072
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000073 for other in self.predicates - set([predicate]):
Yury Selivanov75445082015-05-11 22:57:16 -040074 if (predicate == inspect.isgeneratorfunction or \
75 predicate == inspect.iscoroutinefunction) and \
Christian Heimes7131fd92008-02-19 14:21:46 +000076 other == inspect.isfunction:
77 continue
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000078 self.assertFalse(other(obj), 'not %s(%s)' % (other.__name__, exp))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000079
Christian Heimes7131fd92008-02-19 14:21:46 +000080def generator_function_example(self):
81 for i in range(2):
82 yield i
83
Yury Selivanov75445082015-05-11 22:57:16 -040084async def coroutine_function_example(self):
85 return 'spam'
86
87@types.coroutine
88def gen_coroutine_function_example(self):
89 yield
90 return 'spam'
91
Serhiy Storchaka3018cc42015-07-18 23:19:05 +030092class EqualsToAll:
93 def __eq__(self, other):
94 return True
Yury Selivanova5d63dd2014-03-27 11:31:43 -040095
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000096class TestPredicates(IsTestBase):
Christian Heimes7131fd92008-02-19 14:21:46 +000097
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000098 def test_excluding_predicates(self):
Antoine Pitroud5a1a212012-06-17 23:18:07 +020099 global tb
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000100 self.istest(inspect.isbuiltin, 'sys.exit')
101 self.istest(inspect.isbuiltin, '[].append')
Neal Norwitz221085d2007-02-25 20:55:47 +0000102 self.istest(inspect.iscode, 'mod.spam.__code__')
Antoine Pitroud5a1a212012-06-17 23:18:07 +0200103 try:
104 1/0
105 except:
106 tb = sys.exc_info()[2]
107 self.istest(inspect.isframe, 'tb.tb_frame')
108 self.istest(inspect.istraceback, 'tb')
109 if hasattr(types, 'GetSetDescriptorType'):
110 self.istest(inspect.isgetsetdescriptor,
111 'type(tb.tb_frame).f_locals')
112 else:
113 self.assertFalse(inspect.isgetsetdescriptor(type(tb.tb_frame).f_locals))
114 finally:
115 # Clear traceback and all the frames and local variables hanging to it.
116 tb = None
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000117 self.istest(inspect.isfunction, 'mod.spam')
Christian Heimes4a22b5d2007-11-25 09:39:14 +0000118 self.istest(inspect.isfunction, 'mod.StupidGit.abuse')
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000119 self.istest(inspect.ismethod, 'git.argue')
120 self.istest(inspect.ismodule, 'mod')
Guido van Rossum813b0e52007-05-21 18:11:34 +0000121 self.istest(inspect.isdatadescriptor, 'collections.defaultdict.default_factory')
Christian Heimes7131fd92008-02-19 14:21:46 +0000122 self.istest(inspect.isgenerator, '(x for x in range(2))')
123 self.istest(inspect.isgeneratorfunction, 'generator_function_example')
Yury Selivanov75445082015-05-11 22:57:16 -0400124
125 with warnings.catch_warnings():
126 warnings.simplefilter("ignore")
127 self.istest(inspect.iscoroutine, 'coroutine_function_example(1)')
128 self.istest(inspect.iscoroutinefunction, 'coroutine_function_example')
129
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000130 if hasattr(types, 'MemberDescriptorType'):
131 self.istest(inspect.ismemberdescriptor, 'datetime.timedelta.days')
132 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000133 self.assertFalse(inspect.ismemberdescriptor(datetime.timedelta.days))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000134
Yury Selivanov75445082015-05-11 22:57:16 -0400135 def test_iscoroutine(self):
136 gen_coro = gen_coroutine_function_example(1)
137 coro = coroutine_function_example(1)
138
Yury Selivanov5376ba92015-06-22 12:19:30 -0400139 self.assertFalse(
Yury Selivanov75445082015-05-11 22:57:16 -0400140 inspect.iscoroutinefunction(gen_coroutine_function_example))
Yury Selivanov5376ba92015-06-22 12:19:30 -0400141 self.assertFalse(inspect.iscoroutine(gen_coro))
Yury Selivanov75445082015-05-11 22:57:16 -0400142
143 self.assertTrue(
144 inspect.isgeneratorfunction(gen_coroutine_function_example))
145 self.assertTrue(inspect.isgenerator(gen_coro))
146
147 self.assertTrue(
148 inspect.iscoroutinefunction(coroutine_function_example))
149 self.assertTrue(inspect.iscoroutine(coro))
150
151 self.assertFalse(
152 inspect.isgeneratorfunction(coroutine_function_example))
153 self.assertFalse(inspect.isgenerator(coro))
154
155 coro.close(); gen_coro.close() # silence warnings
156
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -0400157 def test_isawaitable(self):
158 def gen(): yield
159 self.assertFalse(inspect.isawaitable(gen()))
160
161 coro = coroutine_function_example(1)
162 gen_coro = gen_coroutine_function_example(1)
163
164 self.assertTrue(inspect.isawaitable(coro))
165 self.assertTrue(inspect.isawaitable(gen_coro))
166
167 class Future:
168 def __await__():
169 pass
170 self.assertTrue(inspect.isawaitable(Future()))
171 self.assertFalse(inspect.isawaitable(Future))
172
173 class NotFuture: pass
174 not_fut = NotFuture()
175 not_fut.__await__ = lambda: None
176 self.assertFalse(inspect.isawaitable(not_fut))
177
178 coro.close(); gen_coro.close() # silence warnings
179
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000180 def test_isroutine(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000181 self.assertTrue(inspect.isroutine(mod.spam))
182 self.assertTrue(inspect.isroutine([].count))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000183
Benjamin Petersonc4656002009-01-17 22:41:18 +0000184 def test_isclass(self):
185 self.istest(inspect.isclass, 'mod.StupidGit')
186 self.assertTrue(inspect.isclass(list))
187
188 class CustomGetattr(object):
189 def __getattr__(self, attr):
190 return None
191 self.assertFalse(inspect.isclass(CustomGetattr()))
192
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000193 def test_get_slot_members(self):
194 class C(object):
195 __slots__ = ("a", "b")
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000196 x = C()
197 x.a = 42
198 members = dict(inspect.getmembers(x))
Benjamin Peterson577473f2010-01-19 00:09:57 +0000199 self.assertIn('a', members)
200 self.assertNotIn('b', members)
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000201
Benjamin Petersona0dfa822009-11-13 02:25:08 +0000202 def test_isabstract(self):
203 from abc import ABCMeta, abstractmethod
204
205 class AbstractClassExample(metaclass=ABCMeta):
206
207 @abstractmethod
208 def foo(self):
209 pass
210
211 class ClassExample(AbstractClassExample):
212 def foo(self):
213 pass
214
215 a = ClassExample()
216
217 # Test general behaviour.
218 self.assertTrue(inspect.isabstract(AbstractClassExample))
219 self.assertFalse(inspect.isabstract(ClassExample))
220 self.assertFalse(inspect.isabstract(a))
221 self.assertFalse(inspect.isabstract(int))
222 self.assertFalse(inspect.isabstract(5))
223
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000224
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000225class TestInterpreterStack(IsTestBase):
226 def __init__(self, *args, **kwargs):
227 unittest.TestCase.__init__(self, *args, **kwargs)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000228
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000229 git.abuse(7, 8, 9)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000230
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000231 def test_abuse_done(self):
232 self.istest(inspect.istraceback, 'git.ex[2]')
233 self.istest(inspect.isframe, 'mod.fr')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000234
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000235 def test_stack(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000236 self.assertTrue(len(mod.st) >= 5)
Christian Heimesa3538eb2007-11-06 11:44:48 +0000237 self.assertEqual(revise(*mod.st[0][1:]),
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000238 (modfile, 16, 'eggs', [' st = inspect.stack()\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000239 self.assertEqual(revise(*mod.st[1][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000240 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000241 self.assertEqual(revise(*mod.st[2][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000242 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000243 self.assertEqual(revise(*mod.st[3][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000244 (modfile, 39, 'abuse', [' self.argue(a, b, c)\n'], 0))
Antoine Pitroucdcafb72014-08-24 10:50:28 -0400245 # Test named tuple fields
246 record = mod.st[0]
247 self.assertIs(record.frame, mod.fr)
248 self.assertEqual(record.lineno, 16)
249 self.assertEqual(record.filename, mod.__file__)
250 self.assertEqual(record.function, 'eggs')
251 self.assertIn('inspect.stack()', record.code_context[0])
252 self.assertEqual(record.index, 0)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000253
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000254 def test_trace(self):
255 self.assertEqual(len(git.tr), 3)
Florent Xiclunac8575922010-03-24 17:37:49 +0000256 self.assertEqual(revise(*git.tr[0][1:]),
257 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
258 self.assertEqual(revise(*git.tr[1][1:]),
259 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
260 self.assertEqual(revise(*git.tr[2][1:]),
261 (modfile, 18, 'eggs', [' q = y / 0\n'], 0))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000262
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000263 def test_frame(self):
264 args, varargs, varkw, locals = inspect.getargvalues(mod.fr)
265 self.assertEqual(args, ['x', 'y'])
266 self.assertEqual(varargs, None)
267 self.assertEqual(varkw, None)
268 self.assertEqual(locals, {'x': 11, 'p': 11, 'y': 14})
269 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
270 '(x=11, y=14)')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000271
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000272 def test_previous_frame(self):
273 args, varargs, varkw, locals = inspect.getargvalues(mod.fr.f_back)
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000274 self.assertEqual(args, ['a', 'b', 'c', 'd', 'e', 'f'])
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000275 self.assertEqual(varargs, 'g')
276 self.assertEqual(varkw, 'h')
277 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000278 '(a=7, b=8, c=9, d=3, e=4, f=5, *g=(), **h={})')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000279
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000280class GetSourceBase(unittest.TestCase):
281 # Subclasses must override.
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000282 fodderModule = None
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000283
Yury Selivanov6738b112015-05-16 10:10:21 -0400284 def setUp(self):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000285 with open(inspect.getsourcefile(self.fodderModule)) as fp:
Philip Jenveya27c5bd2009-05-28 06:09:08 +0000286 self.source = fp.read()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000287
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000288 def sourcerange(self, top, bottom):
289 lines = self.source.split("\n")
290 return "\n".join(lines[top-1:bottom]) + "\n"
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000291
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000292 def assertSourceEqual(self, obj, top, bottom):
293 self.assertEqual(inspect.getsource(obj),
294 self.sourcerange(top, bottom))
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000295
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000296class TestRetrievingSourceCode(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000297 fodderModule = mod
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000298
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000299 def test_getclasses(self):
300 classes = inspect.getmembers(mod, inspect.isclass)
301 self.assertEqual(classes,
302 [('FesteringGob', mod.FesteringGob),
303 ('MalodorousPervert', mod.MalodorousPervert),
304 ('ParrotDroppings', mod.ParrotDroppings),
Serhiy Storchaka362c1b52013-09-05 17:14:32 +0300305 ('StupidGit', mod.StupidGit),
306 ('Tit', mod.MalodorousPervert),
307 ])
308 tree = inspect.getclasstree([cls[1] for cls in classes])
309 self.assertEqual(tree,
310 [(object, ()),
311 [(mod.ParrotDroppings, (object,)),
312 [(mod.FesteringGob, (mod.MalodorousPervert,
313 mod.ParrotDroppings))
314 ],
315 (mod.StupidGit, (object,)),
316 [(mod.MalodorousPervert, (mod.StupidGit,)),
317 [(mod.FesteringGob, (mod.MalodorousPervert,
318 mod.ParrotDroppings))
319 ]
320 ]
321 ]
322 ])
323 tree = inspect.getclasstree([cls[1] for cls in classes], True)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000324 self.assertEqual(tree,
Thomas Wouters725af872006-04-15 09:13:19 +0000325 [(object, ()),
326 [(mod.ParrotDroppings, (object,)),
327 (mod.StupidGit, (object,)),
328 [(mod.MalodorousPervert, (mod.StupidGit,)),
329 [(mod.FesteringGob, (mod.MalodorousPervert,
330 mod.ParrotDroppings))
331 ]
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000332 ]
333 ]
334 ])
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000335
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000336 def test_getfunctions(self):
337 functions = inspect.getmembers(mod, inspect.isfunction)
338 self.assertEqual(functions, [('eggs', mod.eggs),
Yury Selivanove4e811d2015-07-21 19:01:52 +0300339 ('lobbest', mod.lobbest),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000340 ('spam', mod.spam)])
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000341
R. David Murray378c0cf2010-02-24 01:46:21 +0000342 @unittest.skipIf(sys.flags.optimize >= 2,
343 "Docstrings are omitted with -O2 and above")
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000344 def test_getdoc(self):
345 self.assertEqual(inspect.getdoc(mod), 'A module docstring.')
346 self.assertEqual(inspect.getdoc(mod.StupidGit),
347 'A longer,\n\nindented\n\ndocstring.')
348 self.assertEqual(inspect.getdoc(git.abuse),
349 'Another\n\ndocstring\n\ncontaining\n\ntabs')
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000350
Serhiy Storchaka5cf2b7252015-04-03 22:38:53 +0300351 @unittest.skipIf(sys.flags.optimize >= 2,
352 "Docstrings are omitted with -O2 and above")
353 def test_getdoc_inherited(self):
354 self.assertEqual(inspect.getdoc(mod.FesteringGob),
355 'A longer,\n\nindented\n\ndocstring.')
356 self.assertEqual(inspect.getdoc(mod.FesteringGob.abuse),
357 'Another\n\ndocstring\n\ncontaining\n\ntabs')
358 self.assertEqual(inspect.getdoc(mod.FesteringGob().abuse),
359 'Another\n\ndocstring\n\ncontaining\n\ntabs')
360 self.assertEqual(inspect.getdoc(mod.FesteringGob.contradiction),
361 'The automatic gainsaying.')
362
363 @unittest.skipIf(MISSING_C_DOCSTRINGS, "test requires docstrings")
364 def test_finddoc(self):
365 finddoc = inspect._finddoc
366 self.assertEqual(finddoc(int), int.__doc__)
367 self.assertEqual(finddoc(int.to_bytes), int.to_bytes.__doc__)
368 self.assertEqual(finddoc(int().to_bytes), int.to_bytes.__doc__)
369 self.assertEqual(finddoc(int.from_bytes), int.from_bytes.__doc__)
370 self.assertEqual(finddoc(int.real), int.real.__doc__)
371
Georg Brandl0c77a822008-06-10 16:37:50 +0000372 def test_cleandoc(self):
373 self.assertEqual(inspect.cleandoc('An\n indented\n docstring.'),
374 'An\nindented\ndocstring.')
375
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000376 def test_getcomments(self):
377 self.assertEqual(inspect.getcomments(mod), '# line 1\n')
378 self.assertEqual(inspect.getcomments(mod.StupidGit), '# line 20\n')
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000379
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000380 def test_getmodule(self):
Thomas Wouters89f507f2006-12-13 04:49:30 +0000381 # Check actual module
382 self.assertEqual(inspect.getmodule(mod), mod)
383 # Check class (uses __module__ attribute)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000384 self.assertEqual(inspect.getmodule(mod.StupidGit), mod)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000385 # Check a method (no __module__ attribute, falls back to filename)
386 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
387 # Do it again (check the caching isn't broken)
388 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
389 # Check a builtin
Georg Brandl1a3284e2007-12-02 09:40:06 +0000390 self.assertEqual(inspect.getmodule(str), sys.modules["builtins"])
Thomas Wouters89f507f2006-12-13 04:49:30 +0000391 # Check filename override
392 self.assertEqual(inspect.getmodule(None, modfile), mod)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000393
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000394 def test_getsource(self):
395 self.assertSourceEqual(git.abuse, 29, 39)
Serhiy Storchakaac4bdcc2015-10-29 08:15:50 +0200396 self.assertSourceEqual(mod.StupidGit, 21, 51)
397 self.assertSourceEqual(mod.lobbest, 75, 76)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000398
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000399 def test_getsourcefile(self):
Christian Heimesa3538eb2007-11-06 11:44:48 +0000400 self.assertEqual(normcase(inspect.getsourcefile(mod.spam)), modfile)
401 self.assertEqual(normcase(inspect.getsourcefile(git.abuse)), modfile)
R. David Murraya1b37402010-06-17 02:04:29 +0000402 fn = "_non_existing_filename_used_for_sourcefile_test.py"
403 co = compile("None", fn, "exec")
R. David Murray4155f972010-06-17 13:23:18 +0000404 self.assertEqual(inspect.getsourcefile(co), None)
R. David Murraya1b37402010-06-17 02:04:29 +0000405 linecache.cache[co.co_filename] = (1, None, "None", co.co_filename)
Antoine Pitrou5d62a612012-07-08 13:48:46 +0200406 try:
407 self.assertEqual(normcase(inspect.getsourcefile(co)), fn)
408 finally:
409 del linecache.cache[co.co_filename]
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000410
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000411 def test_getfile(self):
412 self.assertEqual(inspect.getfile(mod.StupidGit), mod.__file__)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000413
Yury Selivanov2eed8b72014-01-27 13:24:56 -0500414 def test_getfile_class_without_module(self):
415 class CM(type):
416 @property
417 def __module__(cls):
418 raise AttributeError
419 class C(metaclass=CM):
420 pass
421 with self.assertRaises(TypeError):
422 inspect.getfile(C)
423
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000424 def test_getmodule_recursion(self):
Christian Heimes45f9af32007-11-27 21:50:00 +0000425 from types import ModuleType
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000426 name = '__inspect_dummy'
Christian Heimes45f9af32007-11-27 21:50:00 +0000427 m = sys.modules[name] = ModuleType(name)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000428 m.__file__ = "<string>" # hopefully not a real filename...
429 m.__loader__ = "dummy" # pretend the filename is understood by a loader
Georg Brandl7cae87c2006-09-06 06:51:57 +0000430 exec("def x(): pass", m.__dict__)
Neal Norwitz221085d2007-02-25 20:55:47 +0000431 self.assertEqual(inspect.getsourcefile(m.x.__code__), '<string>')
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000432 del sys.modules[name]
433 inspect.getmodule(compile('a=10','','single'))
434
Benjamin Peterson9620cc02011-06-11 15:53:11 -0500435 def test_proceed_with_fake_filename(self):
436 '''doctest monkeypatches linecache to enable inspection'''
437 fn, source = '<test>', 'def x(): pass\n'
438 getlines = linecache.getlines
439 def monkey(filename, module_globals=None):
440 if filename == fn:
Ezio Melottid8b509b2011-09-28 17:37:55 +0300441 return source.splitlines(keepends=True)
Benjamin Peterson9620cc02011-06-11 15:53:11 -0500442 else:
443 return getlines(filename, module_globals)
444 linecache.getlines = monkey
445 try:
446 ns = {}
447 exec(compile(source, fn, 'single'), ns)
448 inspect.getsource(ns["x"])
449 finally:
450 linecache.getlines = getlines
451
Antoine Pitroua8723a02015-04-15 00:41:29 +0200452 def test_getsource_on_code_object(self):
453 self.assertSourceEqual(mod.eggs.__code__, 12, 18)
454
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000455class TestDecorators(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000456 fodderModule = mod2
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000457
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000458 def test_wrapped_decorator(self):
Christian Heimes09aaa882008-02-23 15:01:06 +0000459 self.assertSourceEqual(mod2.wrapped, 14, 17)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000460
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000461 def test_replacing_decorator(self):
462 self.assertSourceEqual(mod2.gone, 9, 10)
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000463
Yury Selivanov081bbf62014-09-26 17:34:54 -0400464 def test_getsource_unwrap(self):
Antoine Pitroua8723a02015-04-15 00:41:29 +0200465 self.assertSourceEqual(mod2.real, 130, 132)
466
467 def test_decorator_with_lambda(self):
468 self.assertSourceEqual(mod2.func114, 113, 115)
Yury Selivanov081bbf62014-09-26 17:34:54 -0400469
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000470class TestOneliners(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000471 fodderModule = mod2
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000472 def test_oneline_lambda(self):
473 # Test inspect.getsource with a one-line lambda function.
474 self.assertSourceEqual(mod2.oll, 25, 25)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000475
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000476 def test_threeline_lambda(self):
477 # Test inspect.getsource with a three-line lambda function,
478 # where the second and third lines are _not_ indented.
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000479 self.assertSourceEqual(mod2.tll, 28, 30)
480
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000481 def test_twoline_indented_lambda(self):
482 # Test inspect.getsource with a two-line lambda function,
483 # where the second line _is_ indented.
484 self.assertSourceEqual(mod2.tlli, 33, 34)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000485
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000486 def test_onelinefunc(self):
487 # Test inspect.getsource with a regular one-line function.
488 self.assertSourceEqual(mod2.onelinefunc, 37, 37)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000489
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000490 def test_manyargs(self):
491 # Test inspect.getsource with a regular function where
492 # the arguments are on two lines and _not_ indented and
493 # the body on the second line with the last arguments.
494 self.assertSourceEqual(mod2.manyargs, 40, 41)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000495
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000496 def test_twolinefunc(self):
497 # Test inspect.getsource with a regular function where
498 # the body is on two lines, following the argument list and
499 # continued on the next line by a \\.
500 self.assertSourceEqual(mod2.twolinefunc, 44, 45)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000501
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000502 def test_lambda_in_list(self):
503 # Test inspect.getsource with a one-line lambda function
504 # defined in a list, indented.
505 self.assertSourceEqual(mod2.a[1], 49, 49)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000506
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000507 def test_anonymous(self):
508 # Test inspect.getsource with a lambda function defined
509 # as argument to another function.
510 self.assertSourceEqual(mod2.anonymous, 55, 55)
511
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000512class TestBuggyCases(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000513 fodderModule = mod2
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000514
515 def test_with_comment(self):
516 self.assertSourceEqual(mod2.with_comment, 58, 59)
517
518 def test_multiline_sig(self):
519 self.assertSourceEqual(mod2.multiline_sig[0], 63, 64)
520
Armin Rigodd5c0232005-09-25 11:45:45 +0000521 def test_nested_class(self):
522 self.assertSourceEqual(mod2.func69().func71, 71, 72)
523
524 def test_one_liner_followed_by_non_name(self):
525 self.assertSourceEqual(mod2.func77, 77, 77)
526
527 def test_one_liner_dedent_non_name(self):
528 self.assertSourceEqual(mod2.cls82.func83, 83, 83)
529
530 def test_with_comment_instead_of_docstring(self):
531 self.assertSourceEqual(mod2.func88, 88, 90)
532
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000533 def test_method_in_dynamic_class(self):
534 self.assertSourceEqual(mod2.method_in_dynamic_class, 95, 97)
535
R David Murray32562d72014-10-03 11:15:38 -0400536 # This should not skip for CPython, but might on a repackaged python where
537 # unicodedata is not an external module, or on pypy.
538 @unittest.skipIf(not hasattr(unicodedata, '__file__') or
539 unicodedata.__file__.endswith('.py'),
540 "unicodedata is not an external binary module")
R. David Murray74b89242009-05-13 17:33:03 +0000541 def test_findsource_binary(self):
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200542 self.assertRaises(OSError, inspect.getsource, unicodedata)
543 self.assertRaises(OSError, inspect.findsource, unicodedata)
R. David Murray74b89242009-05-13 17:33:03 +0000544
R. David Murraya1b37402010-06-17 02:04:29 +0000545 def test_findsource_code_in_linecache(self):
546 lines = ["x=1"]
547 co = compile(lines[0], "_dynamically_created_file", "exec")
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200548 self.assertRaises(OSError, inspect.findsource, co)
549 self.assertRaises(OSError, inspect.getsource, co)
R. David Murraya1b37402010-06-17 02:04:29 +0000550 linecache.cache[co.co_filename] = (1, None, lines, co.co_filename)
Antoine Pitrou5d62a612012-07-08 13:48:46 +0200551 try:
552 self.assertEqual(inspect.findsource(co), (lines,0))
553 self.assertEqual(inspect.getsource(co), lines[0])
554 finally:
555 del linecache.cache[co.co_filename]
R. David Murraya1b37402010-06-17 02:04:29 +0000556
Ezio Melotti1b145922013-03-30 05:17:24 +0200557 def test_findsource_without_filename(self):
558 for fname in ['', '<string>']:
559 co = compile('x=1', fname, "exec")
560 self.assertRaises(IOError, inspect.findsource, co)
561 self.assertRaises(IOError, inspect.getsource, co)
562
Antoine Pitroua8723a02015-04-15 00:41:29 +0200563 def test_getsource_on_method(self):
564 self.assertSourceEqual(mod2.ClassWithMethod.method, 118, 119)
565
Yury Selivanov4f4913b2015-07-23 17:10:00 +0300566 def test_nested_func(self):
567 self.assertSourceEqual(mod2.cls135.func136, 136, 139)
568
569
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000570class TestNoEOL(GetSourceBase):
Yury Selivanov6738b112015-05-16 10:10:21 -0400571 def setUp(self):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000572 self.tempdir = TESTFN + '_dir'
573 os.mkdir(self.tempdir)
574 with open(os.path.join(self.tempdir,
575 'inspect_fodder3%spy' % os.extsep), 'w') as f:
576 f.write("class X:\n pass # No EOL")
577 with DirsOnSysPath(self.tempdir):
578 import inspect_fodder3 as mod3
579 self.fodderModule = mod3
Yury Selivanov6738b112015-05-16 10:10:21 -0400580 super().setUp()
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000581
582 def tearDown(self):
583 shutil.rmtree(self.tempdir)
584
585 def test_class(self):
586 self.assertSourceEqual(self.fodderModule.X, 1, 2)
587
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100588
589class _BrokenDataDescriptor(object):
590 """
591 A broken data descriptor. See bug #1785.
592 """
593 def __get__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700594 raise AttributeError("broken data descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100595
596 def __set__(*args):
597 raise RuntimeError
598
599 def __getattr__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700600 raise AttributeError("broken data descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100601
602
603class _BrokenMethodDescriptor(object):
604 """
605 A broken method descriptor. See bug #1785.
606 """
607 def __get__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700608 raise AttributeError("broken method descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100609
610 def __getattr__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700611 raise AttributeError("broken method descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100612
613
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000614# Helper for testing classify_class_attrs.
Tim Peters13b49d32001-09-23 02:00:29 +0000615def attrs_wo_objs(cls):
616 return [t[:3] for t in inspect.classify_class_attrs(cls)]
617
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100618
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000619class TestClassesAndFunctions(unittest.TestCase):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000620 def test_newstyle_mro(self):
621 # The same w/ new-class MRO.
622 class A(object): pass
623 class B(A): pass
624 class C(A): pass
625 class D(B, C): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000626
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000627 expected = (D, B, C, A, object)
628 got = inspect.getmro(D)
629 self.assertEqual(expected, got)
Tim Peters13b49d32001-09-23 02:00:29 +0000630
Christian Heimes3795b532007-11-08 13:48:53 +0000631 def assertFullArgSpecEquals(self, routine, args_e, varargs_e=None,
632 varkw_e=None, defaults_e=None,
633 kwonlyargs_e=[], kwonlydefaults_e=None,
634 ann_e={}, formatted=None):
635 args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \
636 inspect.getfullargspec(routine)
637 self.assertEqual(args, args_e)
638 self.assertEqual(varargs, varargs_e)
639 self.assertEqual(varkw, varkw_e)
640 self.assertEqual(defaults, defaults_e)
641 self.assertEqual(kwonlyargs, kwonlyargs_e)
642 self.assertEqual(kwonlydefaults, kwonlydefaults_e)
643 self.assertEqual(ann, ann_e)
644 if formatted is not None:
645 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults,
646 kwonlyargs, kwonlydefaults, ann),
647 formatted)
648
Christian Heimes3795b532007-11-08 13:48:53 +0000649 def test_getfullargspec(self):
650 self.assertFullArgSpecEquals(mod2.keyworded, [], varargs_e='arg1',
651 kwonlyargs_e=['arg2'],
652 kwonlydefaults_e={'arg2':1},
653 formatted='(*arg1, arg2=1)')
654
655 self.assertFullArgSpecEquals(mod2.annotated, ['arg1'],
Christian Heimesc9543e42007-11-28 08:28:28 +0000656 ann_e={'arg1' : list},
Christian Heimes3795b532007-11-08 13:48:53 +0000657 formatted='(arg1: list)')
Benjamin Peterson9953a8d2009-01-17 04:15:01 +0000658 self.assertFullArgSpecEquals(mod2.keyword_only_arg, [],
659 kwonlyargs_e=['arg'],
660 formatted='(*, arg)')
661
Yury Selivanovf1b5ccb2015-07-23 17:36:02 +0300662 def test_fullargspec_api_ignores_wrapped(self):
Yury Selivanov57d240e2014-02-19 16:27:23 -0500663 # Issue 20684: low level introspection API must ignore __wrapped__
664 @functools.wraps(mod.spam)
665 def ham(x, y):
666 pass
667 # Basic check
Yury Selivanov57d240e2014-02-19 16:27:23 -0500668 self.assertFullArgSpecEquals(ham, ['x', 'y'], formatted='(x, y)')
669 self.assertFullArgSpecEquals(functools.partial(ham),
670 ['x', 'y'], formatted='(x, y)')
671 # Other variants
672 def check_method(f):
Yury Selivanovf1b5ccb2015-07-23 17:36:02 +0300673 self.assertFullArgSpecEquals(f, ['self', 'x', 'y'],
674 formatted='(self, x, y)')
Yury Selivanov57d240e2014-02-19 16:27:23 -0500675 class C:
676 @functools.wraps(mod.spam)
677 def ham(self, x, y):
678 pass
679 pham = functools.partialmethod(ham)
680 @functools.wraps(mod.spam)
681 def __call__(self, x, y):
682 pass
683 check_method(C())
684 check_method(C.ham)
685 check_method(C().ham)
686 check_method(C.pham)
687 check_method(C().pham)
688
689 class C_new:
690 @functools.wraps(mod.spam)
691 def __new__(self, x, y):
692 pass
693 check_method(C_new)
694
695 class C_init:
696 @functools.wraps(mod.spam)
697 def __init__(self, x, y):
698 pass
699 check_method(C_init)
700
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500701 def test_getfullargspec_signature_attr(self):
702 def test():
703 pass
704 spam_param = inspect.Parameter('spam', inspect.Parameter.POSITIONAL_ONLY)
705 test.__signature__ = inspect.Signature(parameters=(spam_param,))
706
707 self.assertFullArgSpecEquals(test, args_e=['spam'], formatted='(spam)')
708
Yury Selivanov4cb93912014-01-29 11:54:12 -0500709 def test_getfullargspec_signature_annos(self):
710 def test(a:'spam') -> 'ham': pass
711 spec = inspect.getfullargspec(test)
712 self.assertEqual(test.__annotations__, spec.annotations)
713
714 def test(): pass
715 spec = inspect.getfullargspec(test)
716 self.assertEqual(test.__annotations__, spec.annotations)
717
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500718 @unittest.skipIf(MISSING_C_DOCSTRINGS,
719 "Signature information for builtins requires docstrings")
720 def test_getfullargspec_builtin_methods(self):
721 self.assertFullArgSpecEquals(_pickle.Pickler.dump,
722 args_e=['self', 'obj'], formatted='(self, obj)')
723
724 self.assertFullArgSpecEquals(_pickle.Pickler(io.BytesIO()).dump,
725 args_e=['self', 'obj'], formatted='(self, obj)')
726
Yury Selivanov8c185ee2014-02-21 01:32:42 -0500727 self.assertFullArgSpecEquals(
728 os.stat,
729 args_e=['path'],
730 kwonlyargs_e=['dir_fd', 'follow_symlinks'],
731 kwonlydefaults_e={'dir_fd': None, 'follow_symlinks': True},
732 formatted='(path, *, dir_fd=None, follow_symlinks=True)')
733
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200734 @cpython_only
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500735 @unittest.skipIf(MISSING_C_DOCSTRINGS,
736 "Signature information for builtins requires docstrings")
737 def test_getfullagrspec_builtin_func(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200738 import _testcapi
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500739 builtin = _testcapi.docstring_with_signature_with_defaults
740 spec = inspect.getfullargspec(builtin)
741 self.assertEqual(spec.defaults[0], 'avocado')
742
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200743 @cpython_only
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500744 @unittest.skipIf(MISSING_C_DOCSTRINGS,
745 "Signature information for builtins requires docstrings")
746 def test_getfullagrspec_builtin_func_no_signature(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200747 import _testcapi
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500748 builtin = _testcapi.docstring_no_signature
749 with self.assertRaises(TypeError):
750 inspect.getfullargspec(builtin)
Christian Heimes3795b532007-11-08 13:48:53 +0000751
Yury Selivanovf1b5ccb2015-07-23 17:36:02 +0300752 def test_getfullargspec_method(self):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000753 class A(object):
754 def m(self):
755 pass
Yury Selivanovf1b5ccb2015-07-23 17:36:02 +0300756 self.assertFullArgSpecEquals(A.m, ['self'])
Tim Peters13b49d32001-09-23 02:00:29 +0000757
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000758 def test_classify_newstyle(self):
759 class A(object):
Tim Peters13b49d32001-09-23 02:00:29 +0000760
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000761 def s(): pass
762 s = staticmethod(s)
Tim Peters13b49d32001-09-23 02:00:29 +0000763
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000764 def c(cls): pass
765 c = classmethod(c)
Tim Peters13b49d32001-09-23 02:00:29 +0000766
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000767 def getp(self): pass
768 p = property(getp)
Tim Peters13b49d32001-09-23 02:00:29 +0000769
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000770 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000771
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000772 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000773
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000774 datablob = '1'
Tim Peters13b49d32001-09-23 02:00:29 +0000775
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100776 dd = _BrokenDataDescriptor()
777 md = _BrokenMethodDescriptor()
778
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000779 attrs = attrs_wo_objs(A)
Yury Selivanov0860a0b2014-01-31 14:28:44 -0500780
781 self.assertIn(('__new__', 'method', object), attrs, 'missing __new__')
782 self.assertIn(('__init__', 'method', object), attrs, 'missing __init__')
783
Benjamin Peterson577473f2010-01-19 00:09:57 +0000784 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
785 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
786 self.assertIn(('p', 'property', A), attrs, 'missing property')
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000787 self.assertIn(('m', 'method', A), attrs,
788 'missing plain method: %r' % attrs)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000789 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
790 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100791 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
792 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000793
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000794 class B(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000795
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000796 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000797
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000798 attrs = attrs_wo_objs(B)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000799 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
800 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
801 self.assertIn(('p', 'property', A), attrs, 'missing property')
802 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
803 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
804 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100805 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
806 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000807
808
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000809 class C(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000810
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000811 def m(self): pass
812 def c(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000813
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000814 attrs = attrs_wo_objs(C)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000815 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
816 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
817 self.assertIn(('p', 'property', A), attrs, 'missing property')
818 self.assertIn(('m', 'method', C), attrs, 'missing plain method')
819 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
820 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100821 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
822 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000823
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000824 class D(B, C):
Tim Peters13b49d32001-09-23 02:00:29 +0000825
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000826 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000827
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000828 attrs = attrs_wo_objs(D)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000829 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
830 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
831 self.assertIn(('p', 'property', A), attrs, 'missing property')
832 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
833 self.assertIn(('m1', 'method', D), attrs, 'missing plain method')
834 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100835 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
836 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
837
838 def test_classify_builtin_types(self):
839 # Simple sanity check that all built-in types can have their
840 # attributes classified.
841 for name in dir(__builtins__):
842 builtin = getattr(__builtins__, name)
843 if isinstance(builtin, type):
844 inspect.classify_class_attrs(builtin)
845
Ethan Furman63c141c2013-10-18 00:27:39 -0700846 def test_classify_DynamicClassAttribute(self):
847 class Meta(type):
848 def __getattr__(self, name):
849 if name == 'ham':
850 return 'spam'
851 return super().__getattr__(name)
852 class VA(metaclass=Meta):
Ethan Furmane03ea372013-09-25 07:14:41 -0700853 @types.DynamicClassAttribute
854 def ham(self):
855 return 'eggs'
Ethan Furman63c141c2013-10-18 00:27:39 -0700856 should_find_dca = inspect.Attribute('ham', 'data', VA, VA.__dict__['ham'])
857 self.assertIn(should_find_dca, inspect.classify_class_attrs(VA))
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700858 should_find_ga = inspect.Attribute('ham', 'data', Meta, 'spam')
Ethan Furman63c141c2013-10-18 00:27:39 -0700859 self.assertIn(should_find_ga, inspect.classify_class_attrs(VA))
860
Yury Selivanovbf341fb2015-05-21 15:41:57 -0400861 def test_classify_overrides_bool(self):
862 class NoBool(object):
863 def __eq__(self, other):
864 return NoBool()
865
866 def __bool__(self):
867 raise NotImplementedError(
868 "This object does not specify a boolean value")
869
870 class HasNB(object):
871 dd = NoBool()
872
873 should_find_attr = inspect.Attribute('dd', 'data', HasNB, HasNB.dd)
874 self.assertIn(should_find_attr, inspect.classify_class_attrs(HasNB))
875
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700876 def test_classify_metaclass_class_attribute(self):
877 class Meta(type):
878 fish = 'slap'
879 def __dir__(self):
Serhiy Storchakaa60c2fe2015-03-12 21:56:08 +0200880 return ['__class__', '__module__', '__name__', 'fish']
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700881 class Class(metaclass=Meta):
882 pass
883 should_find = inspect.Attribute('fish', 'data', Meta, 'slap')
884 self.assertIn(should_find, inspect.classify_class_attrs(Class))
885
Ethan Furman63c141c2013-10-18 00:27:39 -0700886 def test_classify_VirtualAttribute(self):
887 class Meta(type):
888 def __dir__(cls):
889 return ['__class__', '__module__', '__name__', 'BOOM']
890 def __getattr__(self, name):
891 if name =='BOOM':
892 return 42
893 return super().__getattr(name)
894 class Class(metaclass=Meta):
895 pass
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700896 should_find = inspect.Attribute('BOOM', 'data', Meta, 42)
Ethan Furman63c141c2013-10-18 00:27:39 -0700897 self.assertIn(should_find, inspect.classify_class_attrs(Class))
898
899 def test_classify_VirtualAttribute_multi_classes(self):
900 class Meta1(type):
901 def __dir__(cls):
902 return ['__class__', '__module__', '__name__', 'one']
903 def __getattr__(self, name):
904 if name =='one':
905 return 1
906 return super().__getattr__(name)
907 class Meta2(type):
908 def __dir__(cls):
909 return ['__class__', '__module__', '__name__', 'two']
910 def __getattr__(self, name):
911 if name =='two':
912 return 2
913 return super().__getattr__(name)
914 class Meta3(Meta1, Meta2):
915 def __dir__(cls):
916 return list(sorted(set(['__class__', '__module__', '__name__', 'three'] +
917 Meta1.__dir__(cls) + Meta2.__dir__(cls))))
918 def __getattr__(self, name):
919 if name =='three':
920 return 3
921 return super().__getattr__(name)
922 class Class1(metaclass=Meta1):
923 pass
924 class Class2(Class1, metaclass=Meta3):
925 pass
926
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700927 should_find1 = inspect.Attribute('one', 'data', Meta1, 1)
928 should_find2 = inspect.Attribute('two', 'data', Meta2, 2)
929 should_find3 = inspect.Attribute('three', 'data', Meta3, 3)
Ethan Furman63c141c2013-10-18 00:27:39 -0700930 cca = inspect.classify_class_attrs(Class2)
931 for sf in (should_find1, should_find2, should_find3):
932 self.assertIn(sf, cca)
933
934 def test_classify_class_attrs_with_buggy_dir(self):
935 class M(type):
936 def __dir__(cls):
937 return ['__class__', '__name__', 'missing']
938 class C(metaclass=M):
939 pass
940 attrs = [a[0] for a in inspect.classify_class_attrs(C)]
941 self.assertNotIn('missing', attrs)
Ethan Furmane03ea372013-09-25 07:14:41 -0700942
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100943 def test_getmembers_descriptors(self):
944 class A(object):
945 dd = _BrokenDataDescriptor()
946 md = _BrokenMethodDescriptor()
947
948 def pred_wrapper(pred):
949 # A quick'n'dirty way to discard standard attributes of new-style
950 # classes.
951 class Empty(object):
952 pass
953 def wrapped(x):
954 if '__name__' in dir(x) and hasattr(Empty, x.__name__):
955 return False
956 return pred(x)
957 return wrapped
958
959 ismethoddescriptor = pred_wrapper(inspect.ismethoddescriptor)
960 isdatadescriptor = pred_wrapper(inspect.isdatadescriptor)
961
962 self.assertEqual(inspect.getmembers(A, ismethoddescriptor),
963 [('md', A.__dict__['md'])])
964 self.assertEqual(inspect.getmembers(A, isdatadescriptor),
965 [('dd', A.__dict__['dd'])])
966
967 class B(A):
968 pass
969
970 self.assertEqual(inspect.getmembers(B, ismethoddescriptor),
971 [('md', A.__dict__['md'])])
972 self.assertEqual(inspect.getmembers(B, isdatadescriptor),
973 [('dd', A.__dict__['dd'])])
974
Antoine Pitrou0c603812012-01-18 17:40:18 +0100975 def test_getmembers_method(self):
976 class B:
977 def f(self):
978 pass
979
980 self.assertIn(('f', B.f), inspect.getmembers(B))
981 self.assertNotIn(('f', B.f), inspect.getmembers(B, inspect.ismethod))
982 b = B()
983 self.assertIn(('f', b.f), inspect.getmembers(b))
984 self.assertIn(('f', b.f), inspect.getmembers(b, inspect.ismethod))
985
Ethan Furmane03ea372013-09-25 07:14:41 -0700986 def test_getmembers_VirtualAttribute(self):
Ethan Furman63c141c2013-10-18 00:27:39 -0700987 class M(type):
988 def __getattr__(cls, name):
989 if name == 'eggs':
990 return 'scrambled'
991 return super().__getattr__(name)
992 class A(metaclass=M):
Ethan Furmane03ea372013-09-25 07:14:41 -0700993 @types.DynamicClassAttribute
994 def eggs(self):
995 return 'spam'
Ethan Furman63c141c2013-10-18 00:27:39 -0700996 self.assertIn(('eggs', 'scrambled'), inspect.getmembers(A))
997 self.assertIn(('eggs', 'spam'), inspect.getmembers(A()))
998
999 def test_getmembers_with_buggy_dir(self):
1000 class M(type):
1001 def __dir__(cls):
1002 return ['__class__', '__name__', 'missing']
1003 class C(metaclass=M):
1004 pass
1005 attrs = [a[0] for a in inspect.getmembers(C)]
1006 self.assertNotIn('missing', attrs)
Ethan Furmane03ea372013-09-25 07:14:41 -07001007
Jeremy Hyltonc4bf5ed2003-06-27 18:43:12 +00001008
Nick Coghlan2f92e542012-06-23 19:39:55 +10001009_global_ref = object()
1010class TestGetClosureVars(unittest.TestCase):
1011
1012 def test_name_resolution(self):
1013 # Basic test of the 4 different resolution mechanisms
1014 def f(nonlocal_ref):
1015 def g(local_ref):
1016 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
1017 return g
1018 _arg = object()
1019 nonlocal_vars = {"nonlocal_ref": _arg}
1020 global_vars = {"_global_ref": _global_ref}
1021 builtin_vars = {"print": print}
1022 unbound_names = {"unbound_ref"}
1023 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
1024 builtin_vars, unbound_names)
1025 self.assertEqual(inspect.getclosurevars(f(_arg)), expected)
1026
1027 def test_generator_closure(self):
1028 def f(nonlocal_ref):
1029 def g(local_ref):
1030 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
1031 yield
1032 return g
1033 _arg = object()
1034 nonlocal_vars = {"nonlocal_ref": _arg}
1035 global_vars = {"_global_ref": _global_ref}
1036 builtin_vars = {"print": print}
1037 unbound_names = {"unbound_ref"}
1038 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
1039 builtin_vars, unbound_names)
1040 self.assertEqual(inspect.getclosurevars(f(_arg)), expected)
1041
1042 def test_method_closure(self):
1043 class C:
1044 def f(self, nonlocal_ref):
1045 def g(local_ref):
1046 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
1047 return g
1048 _arg = object()
1049 nonlocal_vars = {"nonlocal_ref": _arg}
1050 global_vars = {"_global_ref": _global_ref}
1051 builtin_vars = {"print": print}
1052 unbound_names = {"unbound_ref"}
1053 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
1054 builtin_vars, unbound_names)
1055 self.assertEqual(inspect.getclosurevars(C().f(_arg)), expected)
1056
1057 def test_nonlocal_vars(self):
1058 # More complex tests of nonlocal resolution
1059 def _nonlocal_vars(f):
1060 return inspect.getclosurevars(f).nonlocals
1061
1062 def make_adder(x):
1063 def add(y):
1064 return x + y
1065 return add
1066
1067 def curry(func, arg1):
1068 return lambda arg2: func(arg1, arg2)
1069
1070 def less_than(a, b):
1071 return a < b
1072
1073 # The infamous Y combinator.
1074 def Y(le):
1075 def g(f):
1076 return le(lambda x: f(f)(x))
1077 Y.g_ref = g
1078 return g(g)
1079
1080 def check_y_combinator(func):
1081 self.assertEqual(_nonlocal_vars(func), {'f': Y.g_ref})
1082
1083 inc = make_adder(1)
1084 add_two = make_adder(2)
1085 greater_than_five = curry(less_than, 5)
1086
1087 self.assertEqual(_nonlocal_vars(inc), {'x': 1})
1088 self.assertEqual(_nonlocal_vars(add_two), {'x': 2})
1089 self.assertEqual(_nonlocal_vars(greater_than_five),
1090 {'arg1': 5, 'func': less_than})
1091 self.assertEqual(_nonlocal_vars((lambda x: lambda y: x + y)(3)),
1092 {'x': 3})
1093 Y(check_y_combinator)
1094
1095 def test_getclosurevars_empty(self):
1096 def foo(): pass
1097 _empty = inspect.ClosureVars({}, {}, {}, set())
1098 self.assertEqual(inspect.getclosurevars(lambda: True), _empty)
1099 self.assertEqual(inspect.getclosurevars(foo), _empty)
1100
1101 def test_getclosurevars_error(self):
1102 class T: pass
1103 self.assertRaises(TypeError, inspect.getclosurevars, 1)
1104 self.assertRaises(TypeError, inspect.getclosurevars, list)
1105 self.assertRaises(TypeError, inspect.getclosurevars, {})
1106
Nick Coghlan6c6e2542012-06-23 20:07:39 +10001107 def _private_globals(self):
1108 code = """def f(): print(path)"""
1109 ns = {}
1110 exec(code, ns)
1111 return ns["f"], ns
1112
1113 def test_builtins_fallback(self):
1114 f, ns = self._private_globals()
1115 ns.pop("__builtins__", None)
1116 expected = inspect.ClosureVars({}, {}, {"print":print}, {"path"})
1117 self.assertEqual(inspect.getclosurevars(f), expected)
1118
1119 def test_builtins_as_dict(self):
1120 f, ns = self._private_globals()
1121 ns["__builtins__"] = {"path":1}
1122 expected = inspect.ClosureVars({}, {}, {"path":1}, {"print"})
1123 self.assertEqual(inspect.getclosurevars(f), expected)
1124
1125 def test_builtins_as_module(self):
1126 f, ns = self._private_globals()
1127 ns["__builtins__"] = os
1128 expected = inspect.ClosureVars({}, {}, {"path":os.path}, {"print"})
1129 self.assertEqual(inspect.getclosurevars(f), expected)
1130
Nick Coghlan2f92e542012-06-23 19:39:55 +10001131
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001132class TestGetcallargsFunctions(unittest.TestCase):
1133
1134 def assertEqualCallArgs(self, func, call_params_string, locs=None):
1135 locs = dict(locs or {}, func=func)
1136 r1 = eval('func(%s)' % call_params_string, None, locs)
1137 r2 = eval('inspect.getcallargs(func, %s)' % call_params_string, None,
1138 locs)
1139 self.assertEqual(r1, r2)
1140
1141 def assertEqualException(self, func, call_param_string, locs=None):
1142 locs = dict(locs or {}, func=func)
1143 try:
1144 eval('func(%s)' % call_param_string, None, locs)
1145 except Exception as e:
1146 ex1 = e
1147 else:
1148 self.fail('Exception not raised')
1149 try:
1150 eval('inspect.getcallargs(func, %s)' % call_param_string, None,
1151 locs)
1152 except Exception as e:
1153 ex2 = e
1154 else:
1155 self.fail('Exception not raised')
1156 self.assertIs(type(ex1), type(ex2))
1157 self.assertEqual(str(ex1), str(ex2))
1158 del ex1, ex2
1159
1160 def makeCallable(self, signature):
1161 """Create a function that returns its locals()"""
1162 code = "lambda %s: locals()"
1163 return eval(code % signature)
1164
1165 def test_plain(self):
1166 f = self.makeCallable('a, b=1')
1167 self.assertEqualCallArgs(f, '2')
1168 self.assertEqualCallArgs(f, '2, 3')
1169 self.assertEqualCallArgs(f, 'a=2')
1170 self.assertEqualCallArgs(f, 'b=3, a=2')
1171 self.assertEqualCallArgs(f, '2, b=3')
1172 # expand *iterable / **mapping
1173 self.assertEqualCallArgs(f, '*(2,)')
1174 self.assertEqualCallArgs(f, '*[2]')
1175 self.assertEqualCallArgs(f, '*(2, 3)')
1176 self.assertEqualCallArgs(f, '*[2, 3]')
1177 self.assertEqualCallArgs(f, '**{"a":2}')
1178 self.assertEqualCallArgs(f, 'b=3, **{"a":2}')
1179 self.assertEqualCallArgs(f, '2, **{"b":3}')
1180 self.assertEqualCallArgs(f, '**{"b":3, "a":2}')
1181 # expand UserList / UserDict
1182 self.assertEqualCallArgs(f, '*collections.UserList([2])')
1183 self.assertEqualCallArgs(f, '*collections.UserList([2, 3])')
1184 self.assertEqualCallArgs(f, '**collections.UserDict(a=2)')
1185 self.assertEqualCallArgs(f, '2, **collections.UserDict(b=3)')
1186 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3)')
1187
1188 def test_varargs(self):
1189 f = self.makeCallable('a, b=1, *c')
1190 self.assertEqualCallArgs(f, '2')
1191 self.assertEqualCallArgs(f, '2, 3')
1192 self.assertEqualCallArgs(f, '2, 3, 4')
1193 self.assertEqualCallArgs(f, '*(2,3,4)')
1194 self.assertEqualCallArgs(f, '2, *[3,4]')
1195 self.assertEqualCallArgs(f, '2, 3, *collections.UserList([4])')
1196
1197 def test_varkw(self):
1198 f = self.makeCallable('a, b=1, **c')
1199 self.assertEqualCallArgs(f, 'a=2')
1200 self.assertEqualCallArgs(f, '2, b=3, c=4')
1201 self.assertEqualCallArgs(f, 'b=3, a=2, c=4')
1202 self.assertEqualCallArgs(f, 'c=4, **{"a":2, "b":3}')
1203 self.assertEqualCallArgs(f, '2, c=4, **{"b":3}')
1204 self.assertEqualCallArgs(f, 'b=2, **{"a":3, "c":4}')
1205 self.assertEqualCallArgs(f, '**collections.UserDict(a=2, b=3, c=4)')
1206 self.assertEqualCallArgs(f, '2, c=4, **collections.UserDict(b=3)')
1207 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3, c=4)')
1208
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001209 def test_varkw_only(self):
1210 # issue11256:
1211 f = self.makeCallable('**c')
1212 self.assertEqualCallArgs(f, '')
1213 self.assertEqualCallArgs(f, 'a=1')
1214 self.assertEqualCallArgs(f, 'a=1, b=2')
1215 self.assertEqualCallArgs(f, 'c=3, **{"a": 1, "b": 2}')
1216 self.assertEqualCallArgs(f, '**collections.UserDict(a=1, b=2)')
1217 self.assertEqualCallArgs(f, 'c=3, **collections.UserDict(a=1, b=2)')
1218
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001219 def test_keyword_only(self):
1220 f = self.makeCallable('a=3, *, c, d=2')
1221 self.assertEqualCallArgs(f, 'c=3')
1222 self.assertEqualCallArgs(f, 'c=3, a=3')
1223 self.assertEqualCallArgs(f, 'a=2, c=4')
1224 self.assertEqualCallArgs(f, '4, c=4')
1225 self.assertEqualException(f, '')
1226 self.assertEqualException(f, '3')
1227 self.assertEqualException(f, 'a=3')
1228 self.assertEqualException(f, 'd=4')
1229
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001230 f = self.makeCallable('*, c, d=2')
1231 self.assertEqualCallArgs(f, 'c=3')
1232 self.assertEqualCallArgs(f, 'c=3, d=4')
1233 self.assertEqualCallArgs(f, 'd=4, c=3')
1234
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001235 def test_multiple_features(self):
1236 f = self.makeCallable('a, b=2, *f, **g')
1237 self.assertEqualCallArgs(f, '2, 3, 7')
1238 self.assertEqualCallArgs(f, '2, 3, x=8')
1239 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
1240 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9')
1241 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9')
1242 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
1243 '[2, 3, (4,[5,6])]), **{"y":9, "z":10}')
1244 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
1245 '(4,[5,6])]), **collections.UserDict('
1246 'y=9, z=10)')
1247
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001248 f = self.makeCallable('a, b=2, *f, x, y=99, **g')
1249 self.assertEqualCallArgs(f, '2, 3, x=8')
1250 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
1251 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9, z=10')
1252 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9, z=10')
1253 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
1254 '[2, 3, (4,[5,6])]), q=0, **{"y":9, "z":10}')
1255 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
1256 '(4,[5,6])]), q=0, **collections.UserDict('
1257 'y=9, z=10)')
1258
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001259 def test_errors(self):
1260 f0 = self.makeCallable('')
1261 f1 = self.makeCallable('a, b')
1262 f2 = self.makeCallable('a, b=1')
1263 # f0 takes no arguments
1264 self.assertEqualException(f0, '1')
1265 self.assertEqualException(f0, 'x=1')
1266 self.assertEqualException(f0, '1,x=1')
1267 # f1 takes exactly 2 arguments
1268 self.assertEqualException(f1, '')
1269 self.assertEqualException(f1, '1')
1270 self.assertEqualException(f1, 'a=2')
1271 self.assertEqualException(f1, 'b=3')
1272 # f2 takes at least 1 argument
1273 self.assertEqualException(f2, '')
1274 self.assertEqualException(f2, 'b=3')
1275 for f in f1, f2:
1276 # f1/f2 takes exactly/at most 2 arguments
1277 self.assertEqualException(f, '2, 3, 4')
1278 self.assertEqualException(f, '1, 2, 3, a=1')
1279 self.assertEqualException(f, '2, 3, 4, c=5')
Georg Brandl178e5ea2012-02-21 00:32:36 +01001280 # XXX: success of this one depends on dict order
1281 ## self.assertEqualException(f, '2, 3, 4, a=1, c=5')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001282 # f got an unexpected keyword argument
1283 self.assertEqualException(f, 'c=2')
1284 self.assertEqualException(f, '2, c=3')
1285 self.assertEqualException(f, '2, 3, c=4')
1286 self.assertEqualException(f, '2, c=4, b=3')
1287 self.assertEqualException(f, '**{u"\u03c0\u03b9": 4}')
1288 # f got multiple values for keyword argument
1289 self.assertEqualException(f, '1, a=2')
1290 self.assertEqualException(f, '1, **{"a":2}')
1291 self.assertEqualException(f, '1, 2, b=3')
1292 # XXX: Python inconsistency
1293 # - for functions and bound methods: unexpected keyword 'c'
1294 # - for unbound methods: multiple values for keyword 'a'
1295 #self.assertEqualException(f, '1, c=3, a=2')
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001296 # issue11256:
1297 f3 = self.makeCallable('**c')
1298 self.assertEqualException(f3, '1, 2')
1299 self.assertEqualException(f3, '1, 2, a=1, b=2')
1300 f4 = self.makeCallable('*, a, b=0')
1301 self.assertEqualException(f3, '1, 2')
1302 self.assertEqualException(f3, '1, 2, a=1, b=2')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001303
Yury Selivanov875df202014-03-27 18:23:03 -04001304 # issue #20816: getcallargs() fails to iterate over non-existent
1305 # kwonlydefaults and raises a wrong TypeError
1306 def f5(*, a): pass
1307 with self.assertRaisesRegex(TypeError,
1308 'missing 1 required keyword-only'):
1309 inspect.getcallargs(f5)
1310
1311
Yury Selivanovdccfa132014-03-27 18:42:52 -04001312 # issue20817:
1313 def f6(a, b, c):
1314 pass
1315 with self.assertRaisesRegex(TypeError, "'a', 'b' and 'c'"):
1316 inspect.getcallargs(f6)
1317
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001318class TestGetcallargsMethods(TestGetcallargsFunctions):
1319
1320 def setUp(self):
1321 class Foo(object):
1322 pass
1323 self.cls = Foo
1324 self.inst = Foo()
1325
1326 def makeCallable(self, signature):
1327 assert 'self' not in signature
1328 mk = super(TestGetcallargsMethods, self).makeCallable
1329 self.cls.method = mk('self, ' + signature)
1330 return self.inst.method
1331
1332class TestGetcallargsUnboundMethods(TestGetcallargsMethods):
1333
1334 def makeCallable(self, signature):
1335 super(TestGetcallargsUnboundMethods, self).makeCallable(signature)
1336 return self.cls.method
1337
1338 def assertEqualCallArgs(self, func, call_params_string, locs=None):
1339 return super(TestGetcallargsUnboundMethods, self).assertEqualCallArgs(
1340 *self._getAssertEqualParams(func, call_params_string, locs))
1341
1342 def assertEqualException(self, func, call_params_string, locs=None):
1343 return super(TestGetcallargsUnboundMethods, self).assertEqualException(
1344 *self._getAssertEqualParams(func, call_params_string, locs))
1345
1346 def _getAssertEqualParams(self, func, call_params_string, locs=None):
1347 assert 'inst' not in call_params_string
1348 locs = dict(locs or {}, inst=self.inst)
1349 return (func, 'inst,' + call_params_string, locs)
1350
Michael Foord95fc51d2010-11-20 15:07:30 +00001351
1352class TestGetattrStatic(unittest.TestCase):
1353
1354 def test_basic(self):
1355 class Thing(object):
1356 x = object()
1357
1358 thing = Thing()
1359 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1360 self.assertEqual(inspect.getattr_static(thing, 'x', None), Thing.x)
1361 with self.assertRaises(AttributeError):
1362 inspect.getattr_static(thing, 'y')
1363
1364 self.assertEqual(inspect.getattr_static(thing, 'y', 3), 3)
1365
1366 def test_inherited(self):
1367 class Thing(object):
1368 x = object()
1369 class OtherThing(Thing):
1370 pass
1371
1372 something = OtherThing()
1373 self.assertEqual(inspect.getattr_static(something, 'x'), Thing.x)
1374
1375 def test_instance_attr(self):
1376 class Thing(object):
1377 x = 2
1378 def __init__(self, x):
1379 self.x = x
1380 thing = Thing(3)
1381 self.assertEqual(inspect.getattr_static(thing, 'x'), 3)
1382 del thing.x
1383 self.assertEqual(inspect.getattr_static(thing, 'x'), 2)
1384
1385 def test_property(self):
1386 class Thing(object):
1387 @property
1388 def x(self):
1389 raise AttributeError("I'm pretending not to exist")
1390 thing = Thing()
1391 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1392
Ezio Melotti75cbd732011-04-28 00:59:29 +03001393 def test_descriptor_raises_AttributeError(self):
Michael Foord95fc51d2010-11-20 15:07:30 +00001394 class descriptor(object):
1395 def __get__(*_):
1396 raise AttributeError("I'm pretending not to exist")
1397 desc = descriptor()
1398 class Thing(object):
1399 x = desc
1400 thing = Thing()
1401 self.assertEqual(inspect.getattr_static(thing, 'x'), desc)
1402
1403 def test_classAttribute(self):
1404 class Thing(object):
1405 x = object()
1406
1407 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.x)
1408
Ethan Furmane03ea372013-09-25 07:14:41 -07001409 def test_classVirtualAttribute(self):
1410 class Thing(object):
1411 @types.DynamicClassAttribute
1412 def x(self):
1413 return self._x
1414 _x = object()
1415
1416 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.__dict__['x'])
1417
Michael Foord95fc51d2010-11-20 15:07:30 +00001418 def test_inherited_classattribute(self):
1419 class Thing(object):
1420 x = object()
1421 class OtherThing(Thing):
1422 pass
1423
1424 self.assertEqual(inspect.getattr_static(OtherThing, 'x'), Thing.x)
1425
1426 def test_slots(self):
1427 class Thing(object):
1428 y = 'bar'
1429 __slots__ = ['x']
1430 def __init__(self):
1431 self.x = 'foo'
1432 thing = Thing()
1433 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1434 self.assertEqual(inspect.getattr_static(thing, 'y'), 'bar')
1435
1436 del thing.x
1437 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1438
1439 def test_metaclass(self):
1440 class meta(type):
1441 attr = 'foo'
1442 class Thing(object, metaclass=meta):
1443 pass
1444 self.assertEqual(inspect.getattr_static(Thing, 'attr'), 'foo')
1445
1446 class sub(meta):
1447 pass
1448 class OtherThing(object, metaclass=sub):
1449 x = 3
1450 self.assertEqual(inspect.getattr_static(OtherThing, 'attr'), 'foo')
1451
1452 class OtherOtherThing(OtherThing):
1453 pass
1454 # this test is odd, but it was added as it exposed a bug
1455 self.assertEqual(inspect.getattr_static(OtherOtherThing, 'x'), 3)
1456
1457 def test_no_dict_no_slots(self):
1458 self.assertEqual(inspect.getattr_static(1, 'foo', None), None)
1459 self.assertNotEqual(inspect.getattr_static('foo', 'lower'), None)
1460
1461 def test_no_dict_no_slots_instance_member(self):
1462 # returns descriptor
1463 with open(__file__) as handle:
1464 self.assertEqual(inspect.getattr_static(handle, 'name'), type(handle).name)
1465
1466 def test_inherited_slots(self):
1467 # returns descriptor
1468 class Thing(object):
1469 __slots__ = ['x']
1470 def __init__(self):
1471 self.x = 'foo'
1472
1473 class OtherThing(Thing):
1474 pass
1475 # it would be nice if this worked...
1476 # we get the descriptor instead of the instance attribute
1477 self.assertEqual(inspect.getattr_static(OtherThing(), 'x'), Thing.x)
1478
1479 def test_descriptor(self):
1480 class descriptor(object):
1481 def __get__(self, instance, owner):
1482 return 3
1483 class Foo(object):
1484 d = descriptor()
1485
1486 foo = Foo()
1487
1488 # for a non data descriptor we return the instance attribute
1489 foo.__dict__['d'] = 1
1490 self.assertEqual(inspect.getattr_static(foo, 'd'), 1)
1491
1492 # if the descriptor is a data-desciptor we should return the
1493 # descriptor
1494 descriptor.__set__ = lambda s, i, v: None
1495 self.assertEqual(inspect.getattr_static(foo, 'd'), Foo.__dict__['d'])
1496
1497
1498 def test_metaclass_with_descriptor(self):
1499 class descriptor(object):
1500 def __get__(self, instance, owner):
1501 return 3
1502 class meta(type):
1503 d = descriptor()
1504 class Thing(object, metaclass=meta):
1505 pass
1506 self.assertEqual(inspect.getattr_static(Thing, 'd'), meta.__dict__['d'])
1507
1508
Michael Foordcc7ebb82010-11-20 16:20:16 +00001509 def test_class_as_property(self):
1510 class Base(object):
1511 foo = 3
1512
1513 class Something(Base):
Michael Foord35184ed2010-11-20 16:58:30 +00001514 executed = False
Michael Foordcc7ebb82010-11-20 16:20:16 +00001515 @property
1516 def __class__(self):
Michael Foord35184ed2010-11-20 16:58:30 +00001517 self.executed = True
Michael Foordcc7ebb82010-11-20 16:20:16 +00001518 return object
1519
Michael Foord35184ed2010-11-20 16:58:30 +00001520 instance = Something()
1521 self.assertEqual(inspect.getattr_static(instance, 'foo'), 3)
1522 self.assertFalse(instance.executed)
Michael Foordcc7ebb82010-11-20 16:20:16 +00001523 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1524
Michael Foorde5162652010-11-20 16:40:44 +00001525 def test_mro_as_property(self):
1526 class Meta(type):
1527 @property
1528 def __mro__(self):
1529 return (object,)
1530
1531 class Base(object):
1532 foo = 3
1533
1534 class Something(Base, metaclass=Meta):
1535 pass
1536
1537 self.assertEqual(inspect.getattr_static(Something(), 'foo'), 3)
1538 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1539
Michael Foorddcebe0f2011-03-15 19:20:44 -04001540 def test_dict_as_property(self):
1541 test = self
1542 test.called = False
1543
1544 class Foo(dict):
1545 a = 3
1546 @property
1547 def __dict__(self):
1548 test.called = True
1549 return {}
1550
1551 foo = Foo()
1552 foo.a = 4
1553 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1554 self.assertFalse(test.called)
1555
1556 def test_custom_object_dict(self):
1557 test = self
1558 test.called = False
1559
1560 class Custom(dict):
1561 def get(self, key, default=None):
1562 test.called = True
1563 super().get(key, default)
1564
1565 class Foo(object):
1566 a = 3
1567 foo = Foo()
1568 foo.__dict__ = Custom()
1569 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1570 self.assertFalse(test.called)
1571
1572 def test_metaclass_dict_as_property(self):
1573 class Meta(type):
1574 @property
1575 def __dict__(self):
1576 self.executed = True
1577
1578 class Thing(metaclass=Meta):
1579 executed = False
1580
1581 def __init__(self):
1582 self.spam = 42
1583
1584 instance = Thing()
1585 self.assertEqual(inspect.getattr_static(instance, "spam"), 42)
1586 self.assertFalse(Thing.executed)
Michael Foorde5162652010-11-20 16:40:44 +00001587
Michael Foorda51623b2011-12-18 22:01:40 +00001588 def test_module(self):
1589 sentinel = object()
1590 self.assertIsNot(inspect.getattr_static(sys, "version", sentinel),
1591 sentinel)
1592
Michael Foord3ba95f82011-12-22 01:13:37 +00001593 def test_metaclass_with_metaclass_with_dict_as_property(self):
1594 class MetaMeta(type):
1595 @property
1596 def __dict__(self):
1597 self.executed = True
1598 return dict(spam=42)
1599
1600 class Meta(type, metaclass=MetaMeta):
1601 executed = False
1602
1603 class Thing(metaclass=Meta):
1604 pass
1605
1606 with self.assertRaises(AttributeError):
1607 inspect.getattr_static(Thing, "spam")
1608 self.assertFalse(Thing.executed)
1609
Nick Coghlane0f04652010-11-21 03:44:04 +00001610class TestGetGeneratorState(unittest.TestCase):
1611
1612 def setUp(self):
1613 def number_generator():
1614 for number in range(5):
1615 yield number
1616 self.generator = number_generator()
1617
1618 def _generatorstate(self):
1619 return inspect.getgeneratorstate(self.generator)
1620
1621 def test_created(self):
1622 self.assertEqual(self._generatorstate(), inspect.GEN_CREATED)
1623
1624 def test_suspended(self):
1625 next(self.generator)
1626 self.assertEqual(self._generatorstate(), inspect.GEN_SUSPENDED)
1627
1628 def test_closed_after_exhaustion(self):
1629 for i in self.generator:
1630 pass
1631 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1632
1633 def test_closed_after_immediate_exception(self):
1634 with self.assertRaises(RuntimeError):
1635 self.generator.throw(RuntimeError)
1636 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1637
1638 def test_running(self):
1639 # As mentioned on issue #10220, checking for the RUNNING state only
1640 # makes sense inside the generator itself.
1641 # The following generator checks for this by using the closure's
1642 # reference to self and the generator state checking helper method
1643 def running_check_generator():
1644 for number in range(5):
1645 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1646 yield number
1647 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1648 self.generator = running_check_generator()
1649 # Running up to the first yield
1650 next(self.generator)
1651 # Running after the first yield
1652 next(self.generator)
1653
Nick Coghlan7921b9f2010-11-30 06:36:04 +00001654 def test_easy_debugging(self):
1655 # repr() and str() of a generator state should contain the state name
1656 names = 'GEN_CREATED GEN_RUNNING GEN_SUSPENDED GEN_CLOSED'.split()
1657 for name in names:
1658 state = getattr(inspect, name)
1659 self.assertIn(name, repr(state))
1660 self.assertIn(name, str(state))
1661
Nick Coghlan04e2e3f2012-06-23 19:52:05 +10001662 def test_getgeneratorlocals(self):
1663 def each(lst, a=None):
1664 b=(1, 2, 3)
1665 for v in lst:
1666 if v == 3:
1667 c = 12
1668 yield v
1669
1670 numbers = each([1, 2, 3])
1671 self.assertEqual(inspect.getgeneratorlocals(numbers),
1672 {'a': None, 'lst': [1, 2, 3]})
1673 next(numbers)
1674 self.assertEqual(inspect.getgeneratorlocals(numbers),
1675 {'a': None, 'lst': [1, 2, 3], 'v': 1,
1676 'b': (1, 2, 3)})
1677 next(numbers)
1678 self.assertEqual(inspect.getgeneratorlocals(numbers),
1679 {'a': None, 'lst': [1, 2, 3], 'v': 2,
1680 'b': (1, 2, 3)})
1681 next(numbers)
1682 self.assertEqual(inspect.getgeneratorlocals(numbers),
1683 {'a': None, 'lst': [1, 2, 3], 'v': 3,
1684 'b': (1, 2, 3), 'c': 12})
1685 try:
1686 next(numbers)
1687 except StopIteration:
1688 pass
1689 self.assertEqual(inspect.getgeneratorlocals(numbers), {})
1690
1691 def test_getgeneratorlocals_empty(self):
1692 def yield_one():
1693 yield 1
1694 one = yield_one()
1695 self.assertEqual(inspect.getgeneratorlocals(one), {})
1696 try:
1697 next(one)
1698 except StopIteration:
1699 pass
1700 self.assertEqual(inspect.getgeneratorlocals(one), {})
1701
1702 def test_getgeneratorlocals_error(self):
1703 self.assertRaises(TypeError, inspect.getgeneratorlocals, 1)
1704 self.assertRaises(TypeError, inspect.getgeneratorlocals, lambda x: True)
1705 self.assertRaises(TypeError, inspect.getgeneratorlocals, set)
1706 self.assertRaises(TypeError, inspect.getgeneratorlocals, (2,3))
1707
Nick Coghlane0f04652010-11-21 03:44:04 +00001708
Yury Selivanov5376ba92015-06-22 12:19:30 -04001709class TestGetCoroutineState(unittest.TestCase):
1710
1711 def setUp(self):
1712 @types.coroutine
1713 def number_coroutine():
1714 for number in range(5):
1715 yield number
1716 async def coroutine():
1717 await number_coroutine()
1718 self.coroutine = coroutine()
1719
1720 def tearDown(self):
1721 self.coroutine.close()
1722
1723 def _coroutinestate(self):
1724 return inspect.getcoroutinestate(self.coroutine)
1725
1726 def test_created(self):
1727 self.assertEqual(self._coroutinestate(), inspect.CORO_CREATED)
1728
1729 def test_suspended(self):
1730 self.coroutine.send(None)
1731 self.assertEqual(self._coroutinestate(), inspect.CORO_SUSPENDED)
1732
1733 def test_closed_after_exhaustion(self):
1734 while True:
1735 try:
1736 self.coroutine.send(None)
1737 except StopIteration:
1738 break
1739
1740 self.assertEqual(self._coroutinestate(), inspect.CORO_CLOSED)
1741
1742 def test_closed_after_immediate_exception(self):
1743 with self.assertRaises(RuntimeError):
1744 self.coroutine.throw(RuntimeError)
1745 self.assertEqual(self._coroutinestate(), inspect.CORO_CLOSED)
1746
1747 def test_easy_debugging(self):
1748 # repr() and str() of a coroutine state should contain the state name
1749 names = 'CORO_CREATED CORO_RUNNING CORO_SUSPENDED CORO_CLOSED'.split()
1750 for name in names:
1751 state = getattr(inspect, name)
1752 self.assertIn(name, repr(state))
1753 self.assertIn(name, str(state))
1754
1755 def test_getcoroutinelocals(self):
1756 @types.coroutine
1757 def gencoro():
1758 yield
1759
1760 gencoro = gencoro()
1761 async def func(a=None):
1762 b = 'spam'
1763 await gencoro
1764
1765 coro = func()
1766 self.assertEqual(inspect.getcoroutinelocals(coro),
1767 {'a': None, 'gencoro': gencoro})
1768 coro.send(None)
1769 self.assertEqual(inspect.getcoroutinelocals(coro),
1770 {'a': None, 'gencoro': gencoro, 'b': 'spam'})
1771
1772
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001773class MySignature(inspect.Signature):
1774 # Top-level to make it picklable;
1775 # used in test_signature_object_pickle
1776 pass
1777
1778class MyParameter(inspect.Parameter):
1779 # Top-level to make it picklable;
1780 # used in test_signature_object_pickle
1781 pass
1782
Nick Coghlanf9e227e2014-08-17 14:01:19 +10001783
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001784
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001785class TestSignatureObject(unittest.TestCase):
1786 @staticmethod
Yury Selivanovbcd4fc12015-05-20 14:30:08 -04001787 def signature(func, **kw):
1788 sig = inspect.signature(func, **kw)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001789 return (tuple((param.name,
1790 (... if param.default is param.empty else param.default),
1791 (... if param.annotation is param.empty
1792 else param.annotation),
1793 str(param.kind).lower())
1794 for param in sig.parameters.values()),
1795 (... if sig.return_annotation is sig.empty
1796 else sig.return_annotation))
1797
1798 def test_signature_object(self):
1799 S = inspect.Signature
1800 P = inspect.Parameter
1801
1802 self.assertEqual(str(S()), '()')
1803
Yury Selivanov07a9e452014-01-29 10:58:16 -05001804 def test(po, pk, pod=42, pkd=100, *args, ko, **kwargs):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001805 pass
1806 sig = inspect.signature(test)
1807 po = sig.parameters['po'].replace(kind=P.POSITIONAL_ONLY)
Yury Selivanov07a9e452014-01-29 10:58:16 -05001808 pod = sig.parameters['pod'].replace(kind=P.POSITIONAL_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001809 pk = sig.parameters['pk']
Yury Selivanov07a9e452014-01-29 10:58:16 -05001810 pkd = sig.parameters['pkd']
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001811 args = sig.parameters['args']
1812 ko = sig.parameters['ko']
1813 kwargs = sig.parameters['kwargs']
1814
1815 S((po, pk, args, ko, kwargs))
1816
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001817 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001818 S((pk, po, args, ko, kwargs))
1819
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001820 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001821 S((po, args, pk, ko, kwargs))
1822
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001823 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001824 S((args, po, pk, ko, kwargs))
1825
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001826 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001827 S((po, pk, args, kwargs, ko))
1828
1829 kwargs2 = kwargs.replace(name='args')
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001830 with self.assertRaisesRegex(ValueError, 'duplicate parameter name'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001831 S((po, pk, args, kwargs2, ko))
1832
Yury Selivanov07a9e452014-01-29 10:58:16 -05001833 with self.assertRaisesRegex(ValueError, 'follows default argument'):
1834 S((pod, po))
1835
1836 with self.assertRaisesRegex(ValueError, 'follows default argument'):
1837 S((po, pkd, pk))
1838
1839 with self.assertRaisesRegex(ValueError, 'follows default argument'):
1840 S((pkd, pk))
1841
Yury Selivanov374375d2014-03-27 12:41:53 -04001842 self.assertTrue(repr(sig).startswith('<Signature'))
Yury Selivanov0cd2bf42015-05-15 12:55:20 -04001843 self.assertTrue('(po, pk' in repr(sig))
Yury Selivanov374375d2014-03-27 12:41:53 -04001844
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001845 def test_signature_object_pickle(self):
1846 def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
1847 foo_partial = functools.partial(foo, a=1)
1848
1849 sig = inspect.signature(foo_partial)
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001850
1851 for ver in range(pickle.HIGHEST_PROTOCOL + 1):
1852 with self.subTest(pickle_ver=ver, subclass=False):
1853 sig_pickled = pickle.loads(pickle.dumps(sig, ver))
1854 self.assertEqual(sig, sig_pickled)
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001855
1856 # Test that basic sub-classing works
1857 sig = inspect.signature(foo)
1858 myparam = MyParameter(name='z', kind=inspect.Parameter.POSITIONAL_ONLY)
1859 myparams = collections.OrderedDict(sig.parameters, a=myparam)
1860 mysig = MySignature().replace(parameters=myparams.values(),
1861 return_annotation=sig.return_annotation)
1862 self.assertTrue(isinstance(mysig, MySignature))
1863 self.assertTrue(isinstance(mysig.parameters['z'], MyParameter))
1864
1865 for ver in range(pickle.HIGHEST_PROTOCOL + 1):
1866 with self.subTest(pickle_ver=ver, subclass=True):
1867 sig_pickled = pickle.loads(pickle.dumps(mysig, ver))
1868 self.assertEqual(mysig, sig_pickled)
1869 self.assertTrue(isinstance(sig_pickled, MySignature))
1870 self.assertTrue(isinstance(sig_pickled.parameters['z'],
1871 MyParameter))
1872
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001873 def test_signature_immutability(self):
1874 def test(a):
1875 pass
1876 sig = inspect.signature(test)
1877
1878 with self.assertRaises(AttributeError):
1879 sig.foo = 'bar'
1880
1881 with self.assertRaises(TypeError):
1882 sig.parameters['a'] = None
1883
1884 def test_signature_on_noarg(self):
1885 def test():
1886 pass
1887 self.assertEqual(self.signature(test), ((), ...))
1888
1889 def test_signature_on_wargs(self):
1890 def test(a, b:'foo') -> 123:
1891 pass
1892 self.assertEqual(self.signature(test),
1893 ((('a', ..., ..., "positional_or_keyword"),
1894 ('b', ..., 'foo', "positional_or_keyword")),
1895 123))
1896
1897 def test_signature_on_wkwonly(self):
1898 def test(*, a:float, b:str) -> int:
1899 pass
1900 self.assertEqual(self.signature(test),
1901 ((('a', ..., float, "keyword_only"),
1902 ('b', ..., str, "keyword_only")),
1903 int))
1904
1905 def test_signature_on_complex_args(self):
1906 def test(a, b:'foo'=10, *args:'bar', spam:'baz', ham=123, **kwargs:int):
1907 pass
1908 self.assertEqual(self.signature(test),
1909 ((('a', ..., ..., "positional_or_keyword"),
1910 ('b', 10, 'foo', "positional_or_keyword"),
1911 ('args', ..., 'bar', "var_positional"),
1912 ('spam', ..., 'baz', "keyword_only"),
1913 ('ham', 123, ..., "keyword_only"),
1914 ('kwargs', ..., int, "var_keyword")),
1915 ...))
1916
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02001917 @cpython_only
Larry Hastingsfcafe432013-11-23 17:35:48 -08001918 @unittest.skipIf(MISSING_C_DOCSTRINGS,
1919 "Signature information for builtins requires docstrings")
1920 def test_signature_on_builtins(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02001921 import _testcapi
Larry Hastings16c51912014-01-07 11:53:01 -08001922
Larry Hastings5c661892014-01-24 06:17:25 -08001923 def test_unbound_method(o):
1924 """Use this to test unbound methods (things that should have a self)"""
1925 signature = inspect.signature(o)
1926 self.assertTrue(isinstance(signature, inspect.Signature))
1927 self.assertEqual(list(signature.parameters.values())[0].name, 'self')
1928 return signature
1929
1930 def test_callable(o):
1931 """Use this to test bound methods or normal callables (things that don't expect self)"""
1932 signature = inspect.signature(o)
1933 self.assertTrue(isinstance(signature, inspect.Signature))
1934 if signature.parameters:
1935 self.assertNotEqual(list(signature.parameters.values())[0].name, 'self')
1936 return signature
1937
1938 signature = test_callable(_testcapi.docstring_with_signature_with_defaults)
Larry Hastings16c51912014-01-07 11:53:01 -08001939 def p(name): return signature.parameters[name].default
1940 self.assertEqual(p('s'), 'avocado')
Larry Hastings2a727912014-01-16 11:32:01 -08001941 self.assertEqual(p('b'), b'bytes')
Larry Hastings16c51912014-01-07 11:53:01 -08001942 self.assertEqual(p('d'), 3.14)
1943 self.assertEqual(p('i'), 35)
Larry Hastings16c51912014-01-07 11:53:01 -08001944 self.assertEqual(p('n'), None)
1945 self.assertEqual(p('t'), True)
1946 self.assertEqual(p('f'), False)
Larry Hastings2a727912014-01-16 11:32:01 -08001947 self.assertEqual(p('local'), 3)
1948 self.assertEqual(p('sys'), sys.maxsize)
1949 self.assertEqual(p('exp'), sys.maxsize - 1)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001950
Larry Hastings5c661892014-01-24 06:17:25 -08001951 test_callable(object)
1952
1953 # normal method
1954 # (PyMethodDescr_Type, "method_descriptor")
1955 test_unbound_method(_pickle.Pickler.dump)
1956 d = _pickle.Pickler(io.StringIO())
1957 test_callable(d.dump)
1958
1959 # static method
1960 test_callable(str.maketrans)
1961 test_callable('abc'.maketrans)
1962
1963 # class method
1964 test_callable(dict.fromkeys)
1965 test_callable({}.fromkeys)
1966
1967 # wrapper around slot (PyWrapperDescr_Type, "wrapper_descriptor")
1968 test_unbound_method(type.__call__)
1969 test_unbound_method(int.__add__)
1970 test_callable((3).__add__)
1971
1972 # _PyMethodWrapper_Type
1973 # support for 'method-wrapper'
1974 test_callable(min.__call__)
1975
Larry Hastings2623c8c2014-02-08 22:15:29 -08001976 # This doesn't work now.
1977 # (We don't have a valid signature for "type" in 3.4)
1978 with self.assertRaisesRegex(ValueError, "no signature found"):
1979 class ThisWorksNow:
1980 __call__ = type
1981 test_callable(ThisWorksNow())
Larry Hastings5c661892014-01-24 06:17:25 -08001982
Yury Selivanov056e2652014-03-02 12:25:27 -05001983 # Regression test for issue #20786
1984 test_unbound_method(dict.__delitem__)
1985 test_unbound_method(property.__delete__)
1986
Zachary Ware8ef887c2015-04-13 18:22:35 -05001987 # Regression test for issue #20586
1988 test_callable(_testcapi.docstring_with_signature_but_no_doc)
1989
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02001990 @cpython_only
Yury Selivanov76c6c592014-01-29 10:52:57 -05001991 @unittest.skipIf(MISSING_C_DOCSTRINGS,
1992 "Signature information for builtins requires docstrings")
1993 def test_signature_on_decorated_builtins(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02001994 import _testcapi
Yury Selivanov76c6c592014-01-29 10:52:57 -05001995 func = _testcapi.docstring_with_signature_with_defaults
1996
1997 def decorator(func):
1998 @functools.wraps(func)
1999 def wrapper(*args, **kwargs) -> int:
2000 return func(*args, **kwargs)
2001 return wrapper
2002
2003 decorated_func = decorator(func)
2004
2005 self.assertEqual(inspect.signature(func),
2006 inspect.signature(decorated_func))
Larry Hastings5c661892014-01-24 06:17:25 -08002007
Yury Selivanovbcd4fc12015-05-20 14:30:08 -04002008 def wrapper_like(*args, **kwargs) -> int: pass
2009 self.assertEqual(inspect.signature(decorated_func,
2010 follow_wrapped=False),
2011 inspect.signature(wrapper_like))
2012
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002013 @cpython_only
Larry Hastings5c661892014-01-24 06:17:25 -08002014 def test_signature_on_builtins_no_signature(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02002015 import _testcapi
Yury Selivanovbf304fc2015-05-30 17:08:36 -04002016 with self.assertRaisesRegex(ValueError,
2017 'no signature found for builtin'):
Larry Hastings5c661892014-01-24 06:17:25 -08002018 inspect.signature(_testcapi.docstring_no_signature)
2019
Yury Selivanovbf304fc2015-05-30 17:08:36 -04002020 with self.assertRaisesRegex(ValueError,
2021 'no signature found for builtin'):
2022 inspect.signature(str)
2023
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002024 def test_signature_on_non_function(self):
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002025 with self.assertRaisesRegex(TypeError, 'is not a callable object'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002026 inspect.signature(42)
2027
Yury Selivanov63da7c72014-01-31 14:48:37 -05002028 def test_signature_from_functionlike_object(self):
2029 def func(a,b, *args, kwonly=True, kwonlyreq, **kwargs):
2030 pass
2031
2032 class funclike:
2033 # Has to be callable, and have correct
2034 # __code__, __annotations__, __defaults__, __name__,
2035 # and __kwdefaults__ attributes
2036
2037 def __init__(self, func):
2038 self.__name__ = func.__name__
2039 self.__code__ = func.__code__
2040 self.__annotations__ = func.__annotations__
2041 self.__defaults__ = func.__defaults__
2042 self.__kwdefaults__ = func.__kwdefaults__
2043 self.func = func
2044
2045 def __call__(self, *args, **kwargs):
2046 return self.func(*args, **kwargs)
2047
Yury Selivanov57c74fc2015-05-20 23:07:02 -04002048 sig_func = inspect.Signature.from_callable(func)
Yury Selivanov63da7c72014-01-31 14:48:37 -05002049
Yury Selivanov57c74fc2015-05-20 23:07:02 -04002050 sig_funclike = inspect.Signature.from_callable(funclike(func))
Yury Selivanov63da7c72014-01-31 14:48:37 -05002051 self.assertEqual(sig_funclike, sig_func)
2052
2053 sig_funclike = inspect.signature(funclike(func))
2054 self.assertEqual(sig_funclike, sig_func)
2055
2056 # If object is not a duck type of function, then
2057 # signature will try to get a signature for its '__call__'
2058 # method
2059 fl = funclike(func)
2060 del fl.__defaults__
2061 self.assertEqual(self.signature(fl),
2062 ((('args', ..., ..., "var_positional"),
2063 ('kwargs', ..., ..., "var_keyword")),
2064 ...))
2065
Yury Selivanova773de02014-02-21 18:30:53 -05002066 # Test with cython-like builtins:
2067 _orig_isdesc = inspect.ismethoddescriptor
2068 def _isdesc(obj):
2069 if hasattr(obj, '_builtinmock'):
2070 return True
2071 return _orig_isdesc(obj)
2072
2073 with unittest.mock.patch('inspect.ismethoddescriptor', _isdesc):
2074 builtin_func = funclike(func)
2075 # Make sure that our mock setup is working
2076 self.assertFalse(inspect.ismethoddescriptor(builtin_func))
2077 builtin_func._builtinmock = True
2078 self.assertTrue(inspect.ismethoddescriptor(builtin_func))
2079 self.assertEqual(inspect.signature(builtin_func), sig_func)
2080
Yury Selivanov63da7c72014-01-31 14:48:37 -05002081 def test_signature_functionlike_class(self):
2082 # We only want to duck type function-like objects,
2083 # not classes.
2084
2085 def func(a,b, *args, kwonly=True, kwonlyreq, **kwargs):
2086 pass
2087
2088 class funclike:
2089 def __init__(self, marker):
2090 pass
2091
2092 __name__ = func.__name__
2093 __code__ = func.__code__
2094 __annotations__ = func.__annotations__
2095 __defaults__ = func.__defaults__
2096 __kwdefaults__ = func.__kwdefaults__
2097
Yury Selivanov63da7c72014-01-31 14:48:37 -05002098 self.assertEqual(str(inspect.signature(funclike)), '(marker)')
2099
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002100 def test_signature_on_method(self):
2101 class Test:
Yury Selivanov62560fb2014-01-28 12:26:24 -05002102 def __init__(*args):
2103 pass
2104 def m1(self, arg1, arg2=1) -> int:
2105 pass
2106 def m2(*args):
2107 pass
2108 def __call__(*, a):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002109 pass
2110
Yury Selivanov62560fb2014-01-28 12:26:24 -05002111 self.assertEqual(self.signature(Test().m1),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002112 ((('arg1', ..., ..., "positional_or_keyword"),
2113 ('arg2', 1, ..., "positional_or_keyword")),
2114 int))
2115
Yury Selivanov62560fb2014-01-28 12:26:24 -05002116 self.assertEqual(self.signature(Test().m2),
2117 ((('args', ..., ..., "var_positional"),),
2118 ...))
2119
2120 self.assertEqual(self.signature(Test),
2121 ((('args', ..., ..., "var_positional"),),
2122 ...))
2123
2124 with self.assertRaisesRegex(ValueError, 'invalid method signature'):
2125 self.signature(Test())
2126
Yury Selivanov46c759d2015-05-27 21:56:53 -04002127 def test_signature_wrapped_bound_method(self):
2128 # Issue 24298
2129 class Test:
2130 def m1(self, arg1, arg2=1) -> int:
2131 pass
2132 @functools.wraps(Test().m1)
2133 def m1d(*args, **kwargs):
2134 pass
2135 self.assertEqual(self.signature(m1d),
2136 ((('arg1', ..., ..., "positional_or_keyword"),
2137 ('arg2', 1, ..., "positional_or_keyword")),
2138 int))
2139
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002140 def test_signature_on_classmethod(self):
2141 class Test:
2142 @classmethod
2143 def foo(cls, arg1, *, arg2=1):
2144 pass
2145
2146 meth = Test().foo
2147 self.assertEqual(self.signature(meth),
2148 ((('arg1', ..., ..., "positional_or_keyword"),
2149 ('arg2', 1, ..., "keyword_only")),
2150 ...))
2151
2152 meth = Test.foo
2153 self.assertEqual(self.signature(meth),
2154 ((('arg1', ..., ..., "positional_or_keyword"),
2155 ('arg2', 1, ..., "keyword_only")),
2156 ...))
2157
2158 def test_signature_on_staticmethod(self):
2159 class Test:
2160 @staticmethod
2161 def foo(cls, *, arg):
2162 pass
2163
2164 meth = Test().foo
2165 self.assertEqual(self.signature(meth),
2166 ((('cls', ..., ..., "positional_or_keyword"),
2167 ('arg', ..., ..., "keyword_only")),
2168 ...))
2169
2170 meth = Test.foo
2171 self.assertEqual(self.signature(meth),
2172 ((('cls', ..., ..., "positional_or_keyword"),
2173 ('arg', ..., ..., "keyword_only")),
2174 ...))
2175
2176 def test_signature_on_partial(self):
2177 from functools import partial
2178
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002179 Parameter = inspect.Parameter
2180
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002181 def test():
2182 pass
2183
2184 self.assertEqual(self.signature(partial(test)), ((), ...))
2185
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002186 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002187 inspect.signature(partial(test, 1))
2188
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002189 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002190 inspect.signature(partial(test, a=1))
2191
2192 def test(a, b, *, c, d):
2193 pass
2194
2195 self.assertEqual(self.signature(partial(test)),
2196 ((('a', ..., ..., "positional_or_keyword"),
2197 ('b', ..., ..., "positional_or_keyword"),
2198 ('c', ..., ..., "keyword_only"),
2199 ('d', ..., ..., "keyword_only")),
2200 ...))
2201
2202 self.assertEqual(self.signature(partial(test, 1)),
2203 ((('b', ..., ..., "positional_or_keyword"),
2204 ('c', ..., ..., "keyword_only"),
2205 ('d', ..., ..., "keyword_only")),
2206 ...))
2207
2208 self.assertEqual(self.signature(partial(test, 1, c=2)),
2209 ((('b', ..., ..., "positional_or_keyword"),
2210 ('c', 2, ..., "keyword_only"),
2211 ('d', ..., ..., "keyword_only")),
2212 ...))
2213
2214 self.assertEqual(self.signature(partial(test, b=1, c=2)),
2215 ((('a', ..., ..., "positional_or_keyword"),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002216 ('b', 1, ..., "keyword_only"),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002217 ('c', 2, ..., "keyword_only"),
2218 ('d', ..., ..., "keyword_only")),
2219 ...))
2220
2221 self.assertEqual(self.signature(partial(test, 0, b=1, c=2)),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002222 ((('b', 1, ..., "keyword_only"),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002223 ('c', 2, ..., "keyword_only"),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002224 ('d', ..., ..., "keyword_only")),
2225 ...))
2226
2227 self.assertEqual(self.signature(partial(test, a=1)),
2228 ((('a', 1, ..., "keyword_only"),
2229 ('b', ..., ..., "keyword_only"),
2230 ('c', ..., ..., "keyword_only"),
2231 ('d', ..., ..., "keyword_only")),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002232 ...))
2233
2234 def test(a, *args, b, **kwargs):
2235 pass
2236
2237 self.assertEqual(self.signature(partial(test, 1)),
2238 ((('args', ..., ..., "var_positional"),
2239 ('b', ..., ..., "keyword_only"),
2240 ('kwargs', ..., ..., "var_keyword")),
2241 ...))
2242
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002243 self.assertEqual(self.signature(partial(test, a=1)),
2244 ((('a', 1, ..., "keyword_only"),
2245 ('b', ..., ..., "keyword_only"),
2246 ('kwargs', ..., ..., "var_keyword")),
2247 ...))
2248
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002249 self.assertEqual(self.signature(partial(test, 1, 2, 3)),
2250 ((('args', ..., ..., "var_positional"),
2251 ('b', ..., ..., "keyword_only"),
2252 ('kwargs', ..., ..., "var_keyword")),
2253 ...))
2254
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002255 self.assertEqual(self.signature(partial(test, 1, 2, 3, test=True)),
2256 ((('args', ..., ..., "var_positional"),
2257 ('b', ..., ..., "keyword_only"),
2258 ('kwargs', ..., ..., "var_keyword")),
2259 ...))
2260
2261 self.assertEqual(self.signature(partial(test, 1, 2, 3, test=1, b=0)),
2262 ((('args', ..., ..., "var_positional"),
2263 ('b', 0, ..., "keyword_only"),
2264 ('kwargs', ..., ..., "var_keyword")),
2265 ...))
2266
2267 self.assertEqual(self.signature(partial(test, b=0)),
2268 ((('a', ..., ..., "positional_or_keyword"),
2269 ('args', ..., ..., "var_positional"),
2270 ('b', 0, ..., "keyword_only"),
2271 ('kwargs', ..., ..., "var_keyword")),
2272 ...))
2273
2274 self.assertEqual(self.signature(partial(test, b=0, test=1)),
2275 ((('a', ..., ..., "positional_or_keyword"),
2276 ('args', ..., ..., "var_positional"),
2277 ('b', 0, ..., "keyword_only"),
2278 ('kwargs', ..., ..., "var_keyword")),
2279 ...))
2280
2281 def test(a, b, c:int) -> 42:
2282 pass
2283
2284 sig = test.__signature__ = inspect.signature(test)
2285
2286 self.assertEqual(self.signature(partial(partial(test, 1))),
2287 ((('b', ..., ..., "positional_or_keyword"),
2288 ('c', ..., int, "positional_or_keyword")),
2289 42))
2290
2291 self.assertEqual(self.signature(partial(partial(test, 1), 2)),
2292 ((('c', ..., int, "positional_or_keyword"),),
2293 42))
2294
2295 psig = inspect.signature(partial(partial(test, 1), 2))
2296
2297 def foo(a):
2298 return a
2299 _foo = partial(partial(foo, a=10), a=20)
2300 self.assertEqual(self.signature(_foo),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002301 ((('a', 20, ..., "keyword_only"),),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002302 ...))
2303 # check that we don't have any side-effects in signature(),
2304 # and the partial object is still functioning
2305 self.assertEqual(_foo(), 20)
2306
2307 def foo(a, b, c):
2308 return a, b, c
2309 _foo = partial(partial(foo, 1, b=20), b=30)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002310
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002311 self.assertEqual(self.signature(_foo),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002312 ((('b', 30, ..., "keyword_only"),
2313 ('c', ..., ..., "keyword_only")),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002314 ...))
2315 self.assertEqual(_foo(c=10), (1, 30, 10))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002316
2317 def foo(a, b, c, *, d):
2318 return a, b, c, d
2319 _foo = partial(partial(foo, d=20, c=20), b=10, d=30)
2320 self.assertEqual(self.signature(_foo),
2321 ((('a', ..., ..., "positional_or_keyword"),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002322 ('b', 10, ..., "keyword_only"),
2323 ('c', 20, ..., "keyword_only"),
2324 ('d', 30, ..., "keyword_only"),
2325 ),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002326 ...))
2327 ba = inspect.signature(_foo).bind(a=200, b=11)
2328 self.assertEqual(_foo(*ba.args, **ba.kwargs), (200, 11, 20, 30))
2329
2330 def foo(a=1, b=2, c=3):
2331 return a, b, c
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002332 _foo = partial(foo, c=13) # (a=1, b=2, *, c=13)
2333
2334 ba = inspect.signature(_foo).bind(a=11)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002335 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 2, 13))
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002336
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002337 ba = inspect.signature(_foo).bind(11, 12)
2338 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002339
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002340 ba = inspect.signature(_foo).bind(11, b=12)
2341 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002342
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002343 ba = inspect.signature(_foo).bind(b=12)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002344 self.assertEqual(_foo(*ba.args, **ba.kwargs), (1, 12, 13))
2345
2346 _foo = partial(_foo, b=10, c=20)
2347 ba = inspect.signature(_foo).bind(12)
2348 self.assertEqual(_foo(*ba.args, **ba.kwargs), (12, 10, 20))
2349
2350
2351 def foo(a, b, c, d, **kwargs):
2352 pass
2353 sig = inspect.signature(foo)
2354 params = sig.parameters.copy()
2355 params['a'] = params['a'].replace(kind=Parameter.POSITIONAL_ONLY)
2356 params['b'] = params['b'].replace(kind=Parameter.POSITIONAL_ONLY)
2357 foo.__signature__ = inspect.Signature(params.values())
2358 sig = inspect.signature(foo)
2359 self.assertEqual(str(sig), '(a, b, /, c, d, **kwargs)')
2360
2361 self.assertEqual(self.signature(partial(foo, 1)),
2362 ((('b', ..., ..., 'positional_only'),
2363 ('c', ..., ..., 'positional_or_keyword'),
2364 ('d', ..., ..., 'positional_or_keyword'),
2365 ('kwargs', ..., ..., 'var_keyword')),
2366 ...))
2367
2368 self.assertEqual(self.signature(partial(foo, 1, 2)),
2369 ((('c', ..., ..., 'positional_or_keyword'),
2370 ('d', ..., ..., 'positional_or_keyword'),
2371 ('kwargs', ..., ..., 'var_keyword')),
2372 ...))
2373
2374 self.assertEqual(self.signature(partial(foo, 1, 2, 3)),
2375 ((('d', ..., ..., 'positional_or_keyword'),
2376 ('kwargs', ..., ..., 'var_keyword')),
2377 ...))
2378
2379 self.assertEqual(self.signature(partial(foo, 1, 2, c=3)),
2380 ((('c', 3, ..., 'keyword_only'),
2381 ('d', ..., ..., 'keyword_only'),
2382 ('kwargs', ..., ..., 'var_keyword')),
2383 ...))
2384
2385 self.assertEqual(self.signature(partial(foo, 1, c=3)),
2386 ((('b', ..., ..., 'positional_only'),
2387 ('c', 3, ..., 'keyword_only'),
2388 ('d', ..., ..., 'keyword_only'),
2389 ('kwargs', ..., ..., 'var_keyword')),
2390 ...))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002391
Yury Selivanovda5fe4f2014-01-27 17:28:37 -05002392 def test_signature_on_partialmethod(self):
2393 from functools import partialmethod
2394
2395 class Spam:
2396 def test():
2397 pass
2398 ham = partialmethod(test)
2399
2400 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
2401 inspect.signature(Spam.ham)
2402
2403 class Spam:
2404 def test(it, a, *, c) -> 'spam':
2405 pass
2406 ham = partialmethod(test, c=1)
2407
2408 self.assertEqual(self.signature(Spam.ham),
2409 ((('it', ..., ..., 'positional_or_keyword'),
2410 ('a', ..., ..., 'positional_or_keyword'),
2411 ('c', 1, ..., 'keyword_only')),
2412 'spam'))
2413
2414 self.assertEqual(self.signature(Spam().ham),
2415 ((('a', ..., ..., 'positional_or_keyword'),
2416 ('c', 1, ..., 'keyword_only')),
2417 'spam'))
2418
Yury Selivanov0486f812014-01-29 12:18:59 -05002419 def test_signature_on_fake_partialmethod(self):
2420 def foo(a): pass
2421 foo._partialmethod = 'spam'
2422 self.assertEqual(str(inspect.signature(foo)), '(a)')
2423
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002424 def test_signature_on_decorated(self):
2425 import functools
2426
2427 def decorator(func):
2428 @functools.wraps(func)
2429 def wrapper(*args, **kwargs) -> int:
2430 return func(*args, **kwargs)
2431 return wrapper
2432
2433 class Foo:
2434 @decorator
2435 def bar(self, a, b):
2436 pass
2437
2438 self.assertEqual(self.signature(Foo.bar),
2439 ((('self', ..., ..., "positional_or_keyword"),
2440 ('a', ..., ..., "positional_or_keyword"),
2441 ('b', ..., ..., "positional_or_keyword")),
2442 ...))
2443
2444 self.assertEqual(self.signature(Foo().bar),
2445 ((('a', ..., ..., "positional_or_keyword"),
2446 ('b', ..., ..., "positional_or_keyword")),
2447 ...))
2448
Yury Selivanovbcd4fc12015-05-20 14:30:08 -04002449 self.assertEqual(self.signature(Foo.bar, follow_wrapped=False),
2450 ((('args', ..., ..., "var_positional"),
2451 ('kwargs', ..., ..., "var_keyword")),
2452 ...)) # functools.wraps will copy __annotations__
2453 # from "func" to "wrapper", hence no
2454 # return_annotation
2455
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002456 # Test that we handle method wrappers correctly
2457 def decorator(func):
2458 @functools.wraps(func)
2459 def wrapper(*args, **kwargs) -> int:
2460 return func(42, *args, **kwargs)
2461 sig = inspect.signature(func)
2462 new_params = tuple(sig.parameters.values())[1:]
2463 wrapper.__signature__ = sig.replace(parameters=new_params)
2464 return wrapper
2465
2466 class Foo:
2467 @decorator
2468 def __call__(self, a, b):
2469 pass
2470
2471 self.assertEqual(self.signature(Foo.__call__),
2472 ((('a', ..., ..., "positional_or_keyword"),
2473 ('b', ..., ..., "positional_or_keyword")),
2474 ...))
2475
2476 self.assertEqual(self.signature(Foo().__call__),
2477 ((('b', ..., ..., "positional_or_keyword"),),
2478 ...))
2479
Nick Coghlane8c45d62013-07-28 20:00:01 +10002480 # Test we handle __signature__ partway down the wrapper stack
2481 def wrapped_foo_call():
2482 pass
2483 wrapped_foo_call.__wrapped__ = Foo.__call__
2484
2485 self.assertEqual(self.signature(wrapped_foo_call),
2486 ((('a', ..., ..., "positional_or_keyword"),
2487 ('b', ..., ..., "positional_or_keyword")),
2488 ...))
2489
2490
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002491 def test_signature_on_class(self):
2492 class C:
2493 def __init__(self, a):
2494 pass
2495
2496 self.assertEqual(self.signature(C),
2497 ((('a', ..., ..., "positional_or_keyword"),),
2498 ...))
2499
2500 class CM(type):
2501 def __call__(cls, a):
2502 pass
2503 class C(metaclass=CM):
2504 def __init__(self, b):
2505 pass
2506
2507 self.assertEqual(self.signature(C),
2508 ((('a', ..., ..., "positional_or_keyword"),),
2509 ...))
2510
2511 class CM(type):
2512 def __new__(mcls, name, bases, dct, *, foo=1):
2513 return super().__new__(mcls, name, bases, dct)
2514 class C(metaclass=CM):
2515 def __init__(self, b):
2516 pass
2517
2518 self.assertEqual(self.signature(C),
2519 ((('b', ..., ..., "positional_or_keyword"),),
2520 ...))
2521
2522 self.assertEqual(self.signature(CM),
2523 ((('name', ..., ..., "positional_or_keyword"),
2524 ('bases', ..., ..., "positional_or_keyword"),
2525 ('dct', ..., ..., "positional_or_keyword"),
2526 ('foo', 1, ..., "keyword_only")),
2527 ...))
2528
2529 class CMM(type):
2530 def __new__(mcls, name, bases, dct, *, foo=1):
2531 return super().__new__(mcls, name, bases, dct)
2532 def __call__(cls, nm, bs, dt):
2533 return type(nm, bs, dt)
2534 class CM(type, metaclass=CMM):
2535 def __new__(mcls, name, bases, dct, *, bar=2):
2536 return super().__new__(mcls, name, bases, dct)
2537 class C(metaclass=CM):
2538 def __init__(self, b):
2539 pass
2540
2541 self.assertEqual(self.signature(CMM),
2542 ((('name', ..., ..., "positional_or_keyword"),
2543 ('bases', ..., ..., "positional_or_keyword"),
2544 ('dct', ..., ..., "positional_or_keyword"),
2545 ('foo', 1, ..., "keyword_only")),
2546 ...))
2547
2548 self.assertEqual(self.signature(CM),
2549 ((('nm', ..., ..., "positional_or_keyword"),
2550 ('bs', ..., ..., "positional_or_keyword"),
2551 ('dt', ..., ..., "positional_or_keyword")),
2552 ...))
2553
2554 self.assertEqual(self.signature(C),
2555 ((('b', ..., ..., "positional_or_keyword"),),
2556 ...))
2557
2558 class CM(type):
2559 def __init__(cls, name, bases, dct, *, bar=2):
2560 return super().__init__(name, bases, dct)
2561 class C(metaclass=CM):
2562 def __init__(self, b):
2563 pass
2564
2565 self.assertEqual(self.signature(CM),
2566 ((('name', ..., ..., "positional_or_keyword"),
2567 ('bases', ..., ..., "positional_or_keyword"),
2568 ('dct', ..., ..., "positional_or_keyword"),
2569 ('bar', 2, ..., "keyword_only")),
2570 ...))
2571
Yury Selivanov145dff82014-02-01 13:49:29 -05002572 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2573 "Signature information for builtins requires docstrings")
2574 def test_signature_on_class_without_init(self):
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002575 # Test classes without user-defined __init__ or __new__
2576 class C: pass
2577 self.assertEqual(str(inspect.signature(C)), '()')
2578 class D(C): pass
2579 self.assertEqual(str(inspect.signature(D)), '()')
2580
2581 # Test meta-classes without user-defined __init__ or __new__
2582 class C(type): pass
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002583 class D(C): pass
Larry Hastings2623c8c2014-02-08 22:15:29 -08002584 with self.assertRaisesRegex(ValueError, "callable.*is not supported"):
2585 self.assertEqual(inspect.signature(C), None)
2586 with self.assertRaisesRegex(ValueError, "callable.*is not supported"):
2587 self.assertEqual(inspect.signature(D), None)
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002588
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002589 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2590 "Signature information for builtins requires docstrings")
2591 def test_signature_on_builtin_class(self):
2592 self.assertEqual(str(inspect.signature(_pickle.Pickler)),
2593 '(file, protocol=None, fix_imports=True)')
2594
2595 class P(_pickle.Pickler): pass
2596 class EmptyTrait: pass
2597 class P2(EmptyTrait, P): pass
2598 self.assertEqual(str(inspect.signature(P)),
2599 '(file, protocol=None, fix_imports=True)')
2600 self.assertEqual(str(inspect.signature(P2)),
2601 '(file, protocol=None, fix_imports=True)')
2602
2603 class P3(P2):
2604 def __init__(self, spam):
2605 pass
2606 self.assertEqual(str(inspect.signature(P3)), '(spam)')
2607
2608 class MetaP(type):
2609 def __call__(cls, foo, bar):
2610 pass
2611 class P4(P2, metaclass=MetaP):
2612 pass
2613 self.assertEqual(str(inspect.signature(P4)), '(foo, bar)')
2614
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002615 def test_signature_on_callable_objects(self):
2616 class Foo:
2617 def __call__(self, a):
2618 pass
2619
2620 self.assertEqual(self.signature(Foo()),
2621 ((('a', ..., ..., "positional_or_keyword"),),
2622 ...))
2623
2624 class Spam:
2625 pass
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002626 with self.assertRaisesRegex(TypeError, "is not a callable object"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002627 inspect.signature(Spam())
2628
2629 class Bar(Spam, Foo):
2630 pass
2631
2632 self.assertEqual(self.signature(Bar()),
2633 ((('a', ..., ..., "positional_or_keyword"),),
2634 ...))
2635
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002636 class Wrapped:
2637 pass
2638 Wrapped.__wrapped__ = lambda a: None
2639 self.assertEqual(self.signature(Wrapped),
2640 ((('a', ..., ..., "positional_or_keyword"),),
2641 ...))
Nick Coghlane8c45d62013-07-28 20:00:01 +10002642 # wrapper loop:
2643 Wrapped.__wrapped__ = Wrapped
2644 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
2645 self.signature(Wrapped)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002646
2647 def test_signature_on_lambdas(self):
2648 self.assertEqual(self.signature((lambda a=10: a)),
2649 ((('a', 10, ..., "positional_or_keyword"),),
2650 ...))
2651
2652 def test_signature_equality(self):
2653 def foo(a, *, b:int) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002654 self.assertFalse(inspect.signature(foo) == 42)
2655 self.assertTrue(inspect.signature(foo) != 42)
2656 self.assertTrue(inspect.signature(foo) == EqualsToAll())
2657 self.assertFalse(inspect.signature(foo) != EqualsToAll())
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002658
2659 def bar(a, *, b:int) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002660 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
2661 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002662 self.assertEqual(
2663 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002664
2665 def bar(a, *, b:int) -> int: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002666 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
2667 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002668 self.assertNotEqual(
2669 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002670
2671 def bar(a, *, b:int): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002672 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
2673 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002674 self.assertNotEqual(
2675 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002676
2677 def bar(a, *, b:int=42) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002678 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
2679 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002680 self.assertNotEqual(
2681 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002682
2683 def bar(a, *, c) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002684 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
2685 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002686 self.assertNotEqual(
2687 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002688
2689 def bar(a, b:int) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002690 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
2691 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002692 self.assertNotEqual(
2693 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002694 def spam(b:int, a) -> float: pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002695 self.assertFalse(inspect.signature(spam) == inspect.signature(bar))
2696 self.assertTrue(inspect.signature(spam) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002697 self.assertNotEqual(
2698 hash(inspect.signature(spam)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002699
2700 def foo(*, a, b, c): pass
2701 def bar(*, c, b, a): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002702 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
2703 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002704 self.assertEqual(
2705 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002706
2707 def foo(*, a=1, b, c): pass
2708 def bar(*, c, b, a=1): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002709 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
2710 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002711 self.assertEqual(
2712 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002713
2714 def foo(pos, *, a=1, b, c): pass
2715 def bar(pos, *, c, b, a=1): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002716 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
2717 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002718 self.assertEqual(
2719 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002720
2721 def foo(pos, *, a, b, c): pass
2722 def bar(pos, *, c, b, a=1): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002723 self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
2724 self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002725 self.assertNotEqual(
2726 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002727
2728 def foo(pos, *args, a=42, b, c, **kwargs:int): pass
2729 def bar(pos, *args, c, b, a=42, **kwargs:int): pass
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002730 self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
2731 self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002732 self.assertEqual(
2733 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002734
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002735 def test_signature_hashable(self):
2736 S = inspect.Signature
2737 P = inspect.Parameter
2738
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002739 def foo(a): pass
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002740 foo_sig = inspect.signature(foo)
2741
2742 manual_sig = S(parameters=[P('a', P.POSITIONAL_OR_KEYWORD)])
2743
2744 self.assertEqual(hash(foo_sig), hash(manual_sig))
2745 self.assertNotEqual(hash(foo_sig),
2746 hash(manual_sig.replace(return_annotation='spam')))
2747
2748 def bar(a) -> 1: pass
2749 self.assertNotEqual(hash(foo_sig), hash(inspect.signature(bar)))
2750
2751 def foo(a={}): pass
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002752 with self.assertRaisesRegex(TypeError, 'unhashable type'):
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002753 hash(inspect.signature(foo))
2754
2755 def foo(a) -> {}: pass
2756 with self.assertRaisesRegex(TypeError, 'unhashable type'):
2757 hash(inspect.signature(foo))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002758
2759 def test_signature_str(self):
2760 def foo(a:int=1, *, b, c=None, **kwargs) -> 42:
2761 pass
2762 self.assertEqual(str(inspect.signature(foo)),
2763 '(a:int=1, *, b, c=None, **kwargs) -> 42')
2764
2765 def foo(a:int=1, *args, b, c=None, **kwargs) -> 42:
2766 pass
2767 self.assertEqual(str(inspect.signature(foo)),
2768 '(a:int=1, *args, b, c=None, **kwargs) -> 42')
2769
2770 def foo():
2771 pass
2772 self.assertEqual(str(inspect.signature(foo)), '()')
2773
2774 def test_signature_str_positional_only(self):
2775 P = inspect.Parameter
Yury Selivanov2393dca2014-01-27 15:07:58 -05002776 S = inspect.Signature
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002777
2778 def test(a_po, *, b, **kwargs):
2779 return a_po, kwargs
2780
2781 sig = inspect.signature(test)
2782 new_params = list(sig.parameters.values())
2783 new_params[0] = new_params[0].replace(kind=P.POSITIONAL_ONLY)
2784 test.__signature__ = sig.replace(parameters=new_params)
2785
2786 self.assertEqual(str(inspect.signature(test)),
Yury Selivanov2393dca2014-01-27 15:07:58 -05002787 '(a_po, /, *, b, **kwargs)')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002788
Yury Selivanov2393dca2014-01-27 15:07:58 -05002789 self.assertEqual(str(S(parameters=[P('foo', P.POSITIONAL_ONLY)])),
2790 '(foo, /)')
2791
2792 self.assertEqual(str(S(parameters=[
2793 P('foo', P.POSITIONAL_ONLY),
2794 P('bar', P.VAR_KEYWORD)])),
2795 '(foo, /, **bar)')
2796
2797 self.assertEqual(str(S(parameters=[
2798 P('foo', P.POSITIONAL_ONLY),
2799 P('bar', P.VAR_POSITIONAL)])),
2800 '(foo, /, *bar)')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002801
2802 def test_signature_replace_anno(self):
2803 def test() -> 42:
2804 pass
2805
2806 sig = inspect.signature(test)
2807 sig = sig.replace(return_annotation=None)
2808 self.assertIs(sig.return_annotation, None)
2809 sig = sig.replace(return_annotation=sig.empty)
2810 self.assertIs(sig.return_annotation, sig.empty)
2811 sig = sig.replace(return_annotation=42)
2812 self.assertEqual(sig.return_annotation, 42)
2813 self.assertEqual(sig, inspect.signature(test))
2814
Yury Selivanov34ce99f2014-02-18 12:49:41 -05002815 def test_signature_on_mangled_parameters(self):
2816 class Spam:
2817 def foo(self, __p1:1=2, *, __p2:2=3):
2818 pass
2819 class Ham(Spam):
2820 pass
2821
2822 self.assertEqual(self.signature(Spam.foo),
2823 ((('self', ..., ..., "positional_or_keyword"),
2824 ('_Spam__p1', 2, 1, "positional_or_keyword"),
2825 ('_Spam__p2', 3, 2, "keyword_only")),
2826 ...))
2827
2828 self.assertEqual(self.signature(Spam.foo),
2829 self.signature(Ham.foo))
2830
Yury Selivanovda396452014-03-27 12:09:24 -04002831 def test_signature_from_callable_python_obj(self):
2832 class MySignature(inspect.Signature): pass
2833 def foo(a, *, b:1): pass
2834 foo_sig = MySignature.from_callable(foo)
2835 self.assertTrue(isinstance(foo_sig, MySignature))
2836
2837 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2838 "Signature information for builtins requires docstrings")
2839 def test_signature_from_callable_builtin_obj(self):
2840 class MySignature(inspect.Signature): pass
2841 sig = MySignature.from_callable(_pickle.Pickler)
2842 self.assertTrue(isinstance(sig, MySignature))
2843
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002844
2845class TestParameterObject(unittest.TestCase):
2846 def test_signature_parameter_kinds(self):
2847 P = inspect.Parameter
2848 self.assertTrue(P.POSITIONAL_ONLY < P.POSITIONAL_OR_KEYWORD < \
2849 P.VAR_POSITIONAL < P.KEYWORD_ONLY < P.VAR_KEYWORD)
2850
2851 self.assertEqual(str(P.POSITIONAL_ONLY), 'POSITIONAL_ONLY')
2852 self.assertTrue('POSITIONAL_ONLY' in repr(P.POSITIONAL_ONLY))
2853
2854 def test_signature_parameter_object(self):
2855 p = inspect.Parameter('foo', default=10,
2856 kind=inspect.Parameter.POSITIONAL_ONLY)
2857 self.assertEqual(p.name, 'foo')
2858 self.assertEqual(p.default, 10)
2859 self.assertIs(p.annotation, p.empty)
2860 self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY)
2861
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002862 with self.assertRaisesRegex(ValueError, 'invalid value'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002863 inspect.Parameter('foo', default=10, kind='123')
2864
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002865 with self.assertRaisesRegex(ValueError, 'not a valid parameter name'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002866 inspect.Parameter('1', kind=inspect.Parameter.VAR_KEYWORD)
2867
Yury Selivanov2393dca2014-01-27 15:07:58 -05002868 with self.assertRaisesRegex(TypeError, 'name must be a str'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002869 inspect.Parameter(None, kind=inspect.Parameter.VAR_KEYWORD)
2870
Yury Selivanov2393dca2014-01-27 15:07:58 -05002871 with self.assertRaisesRegex(ValueError,
2872 'is not a valid parameter name'):
2873 inspect.Parameter('$', kind=inspect.Parameter.VAR_KEYWORD)
2874
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002875 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002876 inspect.Parameter('a', default=42,
2877 kind=inspect.Parameter.VAR_KEYWORD)
2878
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002879 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002880 inspect.Parameter('a', default=42,
2881 kind=inspect.Parameter.VAR_POSITIONAL)
2882
2883 p = inspect.Parameter('a', default=42,
2884 kind=inspect.Parameter.POSITIONAL_OR_KEYWORD)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002885 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002886 p.replace(kind=inspect.Parameter.VAR_POSITIONAL)
2887
2888 self.assertTrue(repr(p).startswith('<Parameter'))
Yury Selivanov374375d2014-03-27 12:41:53 -04002889 self.assertTrue('"a=42"' in repr(p))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002890
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002891 def test_signature_parameter_hashable(self):
2892 P = inspect.Parameter
2893 foo = P('foo', kind=P.POSITIONAL_ONLY)
2894 self.assertEqual(hash(foo), hash(P('foo', kind=P.POSITIONAL_ONLY)))
2895 self.assertNotEqual(hash(foo), hash(P('foo', kind=P.POSITIONAL_ONLY,
2896 default=42)))
2897 self.assertNotEqual(hash(foo),
2898 hash(foo.replace(kind=P.VAR_POSITIONAL)))
2899
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002900 def test_signature_parameter_equality(self):
2901 P = inspect.Parameter
2902 p = P('foo', default=42, kind=inspect.Parameter.KEYWORD_ONLY)
2903
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002904 self.assertTrue(p == p)
2905 self.assertFalse(p != p)
2906 self.assertFalse(p == 42)
2907 self.assertTrue(p != 42)
2908 self.assertTrue(p == EqualsToAll())
2909 self.assertFalse(p != EqualsToAll())
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002910
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002911 self.assertTrue(p == P('foo', default=42,
2912 kind=inspect.Parameter.KEYWORD_ONLY))
2913 self.assertFalse(p != P('foo', default=42,
2914 kind=inspect.Parameter.KEYWORD_ONLY))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002915
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002916 def test_signature_parameter_replace(self):
2917 p = inspect.Parameter('foo', default=42,
2918 kind=inspect.Parameter.KEYWORD_ONLY)
2919
2920 self.assertIsNot(p, p.replace())
2921 self.assertEqual(p, p.replace())
2922
2923 p2 = p.replace(annotation=1)
2924 self.assertEqual(p2.annotation, 1)
2925 p2 = p2.replace(annotation=p2.empty)
2926 self.assertEqual(p, p2)
2927
2928 p2 = p2.replace(name='bar')
2929 self.assertEqual(p2.name, 'bar')
2930 self.assertNotEqual(p2, p)
2931
Yury Selivanov2393dca2014-01-27 15:07:58 -05002932 with self.assertRaisesRegex(ValueError,
2933 'name is a required attribute'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002934 p2 = p2.replace(name=p2.empty)
2935
2936 p2 = p2.replace(name='foo', default=None)
2937 self.assertIs(p2.default, None)
2938 self.assertNotEqual(p2, p)
2939
2940 p2 = p2.replace(name='foo', default=p2.empty)
2941 self.assertIs(p2.default, p2.empty)
2942
2943
2944 p2 = p2.replace(default=42, kind=p2.POSITIONAL_OR_KEYWORD)
2945 self.assertEqual(p2.kind, p2.POSITIONAL_OR_KEYWORD)
2946 self.assertNotEqual(p2, p)
2947
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002948 with self.assertRaisesRegex(ValueError, 'invalid value for'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002949 p2 = p2.replace(kind=p2.empty)
2950
2951 p2 = p2.replace(kind=p2.KEYWORD_ONLY)
2952 self.assertEqual(p2, p)
2953
2954 def test_signature_parameter_positional_only(self):
Yury Selivanov2393dca2014-01-27 15:07:58 -05002955 with self.assertRaisesRegex(TypeError, 'name must be a str'):
2956 inspect.Parameter(None, kind=inspect.Parameter.POSITIONAL_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002957
2958 def test_signature_parameter_immutability(self):
Yury Selivanov2393dca2014-01-27 15:07:58 -05002959 p = inspect.Parameter('spam', kind=inspect.Parameter.KEYWORD_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002960
2961 with self.assertRaises(AttributeError):
2962 p.foo = 'bar'
2963
2964 with self.assertRaises(AttributeError):
2965 p.kind = 123
2966
2967
2968class TestSignatureBind(unittest.TestCase):
2969 @staticmethod
2970 def call(func, *args, **kwargs):
2971 sig = inspect.signature(func)
2972 ba = sig.bind(*args, **kwargs)
2973 return func(*ba.args, **ba.kwargs)
2974
2975 def test_signature_bind_empty(self):
2976 def test():
2977 return 42
2978
2979 self.assertEqual(self.call(test), 42)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002980 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002981 self.call(test, 1)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002982 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002983 self.call(test, 1, spam=10)
Yury Selivanov86872752015-05-19 00:27:49 -04002984 with self.assertRaisesRegex(
2985 TypeError, "got an unexpected keyword argument 'spam'"):
2986
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002987 self.call(test, spam=1)
2988
2989 def test_signature_bind_var(self):
2990 def test(*args, **kwargs):
2991 return args, kwargs
2992
2993 self.assertEqual(self.call(test), ((), {}))
2994 self.assertEqual(self.call(test, 1), ((1,), {}))
2995 self.assertEqual(self.call(test, 1, 2), ((1, 2), {}))
2996 self.assertEqual(self.call(test, foo='bar'), ((), {'foo': 'bar'}))
2997 self.assertEqual(self.call(test, 1, foo='bar'), ((1,), {'foo': 'bar'}))
2998 self.assertEqual(self.call(test, args=10), ((), {'args': 10}))
2999 self.assertEqual(self.call(test, 1, 2, foo='bar'),
3000 ((1, 2), {'foo': 'bar'}))
3001
3002 def test_signature_bind_just_args(self):
3003 def test(a, b, c):
3004 return a, b, c
3005
3006 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
3007
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003008 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003009 self.call(test, 1, 2, 3, 4)
3010
Yury Selivanov86872752015-05-19 00:27:49 -04003011 with self.assertRaisesRegex(TypeError,
3012 "missing a required argument: 'b'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003013 self.call(test, 1)
3014
Yury Selivanov86872752015-05-19 00:27:49 -04003015 with self.assertRaisesRegex(TypeError,
3016 "missing a required argument: 'a'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003017 self.call(test)
3018
3019 def test(a, b, c=10):
3020 return a, b, c
3021 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
3022 self.assertEqual(self.call(test, 1, 2), (1, 2, 10))
3023
3024 def test(a=1, b=2, c=3):
3025 return a, b, c
3026 self.assertEqual(self.call(test, a=10, c=13), (10, 2, 13))
3027 self.assertEqual(self.call(test, a=10), (10, 2, 3))
3028 self.assertEqual(self.call(test, b=10), (1, 10, 3))
3029
3030 def test_signature_bind_varargs_order(self):
3031 def test(*args):
3032 return args
3033
3034 self.assertEqual(self.call(test), ())
3035 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
3036
3037 def test_signature_bind_args_and_varargs(self):
3038 def test(a, b, c=3, *args):
3039 return a, b, c, args
3040
3041 self.assertEqual(self.call(test, 1, 2, 3, 4, 5), (1, 2, 3, (4, 5)))
3042 self.assertEqual(self.call(test, 1, 2), (1, 2, 3, ()))
3043 self.assertEqual(self.call(test, b=1, a=2), (2, 1, 3, ()))
3044 self.assertEqual(self.call(test, 1, b=2), (1, 2, 3, ()))
3045
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003046 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003047 "multiple values for argument 'c'"):
3048 self.call(test, 1, 2, 3, c=4)
3049
3050 def test_signature_bind_just_kwargs(self):
3051 def test(**kwargs):
3052 return kwargs
3053
3054 self.assertEqual(self.call(test), {})
3055 self.assertEqual(self.call(test, foo='bar', spam='ham'),
3056 {'foo': 'bar', 'spam': 'ham'})
3057
3058 def test_signature_bind_args_and_kwargs(self):
3059 def test(a, b, c=3, **kwargs):
3060 return a, b, c, kwargs
3061
3062 self.assertEqual(self.call(test, 1, 2), (1, 2, 3, {}))
3063 self.assertEqual(self.call(test, 1, 2, foo='bar', spam='ham'),
3064 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3065 self.assertEqual(self.call(test, b=2, a=1, foo='bar', spam='ham'),
3066 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3067 self.assertEqual(self.call(test, a=1, b=2, foo='bar', spam='ham'),
3068 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3069 self.assertEqual(self.call(test, 1, b=2, foo='bar', spam='ham'),
3070 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3071 self.assertEqual(self.call(test, 1, b=2, c=4, foo='bar', spam='ham'),
3072 (1, 2, 4, {'foo': 'bar', 'spam': 'ham'}))
3073 self.assertEqual(self.call(test, 1, 2, 4, foo='bar'),
3074 (1, 2, 4, {'foo': 'bar'}))
3075 self.assertEqual(self.call(test, c=5, a=4, b=3),
3076 (4, 3, 5, {}))
3077
3078 def test_signature_bind_kwonly(self):
3079 def test(*, foo):
3080 return foo
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003081 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003082 'too many positional arguments'):
3083 self.call(test, 1)
3084 self.assertEqual(self.call(test, foo=1), 1)
3085
3086 def test(a, *, foo=1, bar):
3087 return foo
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003088 with self.assertRaisesRegex(TypeError,
Yury Selivanov86872752015-05-19 00:27:49 -04003089 "missing a required argument: 'bar'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003090 self.call(test, 1)
3091
3092 def test(foo, *, bar):
3093 return foo, bar
3094 self.assertEqual(self.call(test, 1, bar=2), (1, 2))
3095 self.assertEqual(self.call(test, bar=2, foo=1), (1, 2))
3096
Yury Selivanov86872752015-05-19 00:27:49 -04003097 with self.assertRaisesRegex(
3098 TypeError, "got an unexpected keyword argument 'spam'"):
3099
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003100 self.call(test, bar=2, foo=1, spam=10)
3101
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003102 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003103 'too many positional arguments'):
3104 self.call(test, 1, 2)
3105
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003106 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003107 'too many positional arguments'):
3108 self.call(test, 1, 2, bar=2)
3109
Yury Selivanov86872752015-05-19 00:27:49 -04003110 with self.assertRaisesRegex(
3111 TypeError, "got an unexpected keyword argument 'spam'"):
3112
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003113 self.call(test, 1, bar=2, spam='ham')
3114
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003115 with self.assertRaisesRegex(TypeError,
Yury Selivanov86872752015-05-19 00:27:49 -04003116 "missing a required argument: 'bar'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003117 self.call(test, 1)
3118
3119 def test(foo, *, bar, **bin):
3120 return foo, bar, bin
3121 self.assertEqual(self.call(test, 1, bar=2), (1, 2, {}))
3122 self.assertEqual(self.call(test, foo=1, bar=2), (1, 2, {}))
3123 self.assertEqual(self.call(test, 1, bar=2, spam='ham'),
3124 (1, 2, {'spam': 'ham'}))
3125 self.assertEqual(self.call(test, spam='ham', foo=1, bar=2),
3126 (1, 2, {'spam': 'ham'}))
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003127 with self.assertRaisesRegex(TypeError,
Yury Selivanov86872752015-05-19 00:27:49 -04003128 "missing a required argument: 'foo'"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003129 self.call(test, spam='ham', bar=2)
3130 self.assertEqual(self.call(test, 1, bar=2, bin=1, spam=10),
3131 (1, 2, {'bin': 1, 'spam': 10}))
3132
3133 def test_signature_bind_arguments(self):
3134 def test(a, *args, b, z=100, **kwargs):
3135 pass
3136 sig = inspect.signature(test)
3137 ba = sig.bind(10, 20, b=30, c=40, args=50, kwargs=60)
3138 # we won't have 'z' argument in the bound arguments object, as we didn't
3139 # pass it to the 'bind'
3140 self.assertEqual(tuple(ba.arguments.items()),
3141 (('a', 10), ('args', (20,)), ('b', 30),
3142 ('kwargs', {'c': 40, 'args': 50, 'kwargs': 60})))
3143 self.assertEqual(ba.kwargs,
3144 {'b': 30, 'c': 40, 'args': 50, 'kwargs': 60})
3145 self.assertEqual(ba.args, (10, 20))
3146
3147 def test_signature_bind_positional_only(self):
3148 P = inspect.Parameter
3149
3150 def test(a_po, b_po, c_po=3, foo=42, *, bar=50, **kwargs):
3151 return a_po, b_po, c_po, foo, bar, kwargs
3152
3153 sig = inspect.signature(test)
3154 new_params = collections.OrderedDict(tuple(sig.parameters.items()))
3155 for name in ('a_po', 'b_po', 'c_po'):
3156 new_params[name] = new_params[name].replace(kind=P.POSITIONAL_ONLY)
3157 new_sig = sig.replace(parameters=new_params.values())
3158 test.__signature__ = new_sig
3159
3160 self.assertEqual(self.call(test, 1, 2, 4, 5, bar=6),
3161 (1, 2, 4, 5, 6, {}))
3162
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05003163 self.assertEqual(self.call(test, 1, 2),
3164 (1, 2, 3, 42, 50, {}))
3165
3166 self.assertEqual(self.call(test, 1, 2, foo=4, bar=5),
3167 (1, 2, 3, 4, 5, {}))
3168
3169 with self.assertRaisesRegex(TypeError, "but was passed as a keyword"):
3170 self.call(test, 1, 2, foo=4, bar=5, c_po=10)
3171
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003172 with self.assertRaisesRegex(TypeError, "parameter is positional only"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003173 self.call(test, 1, 2, c_po=4)
3174
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003175 with self.assertRaisesRegex(TypeError, "parameter is positional only"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003176 self.call(test, a_po=1, b_po=2)
3177
Antoine Pitroubd41d1b2013-01-29 21:20:57 +01003178 def test_signature_bind_with_self_arg(self):
3179 # Issue #17071: one of the parameters is named "self
3180 def test(a, self, b):
3181 pass
3182 sig = inspect.signature(test)
3183 ba = sig.bind(1, 2, 3)
3184 self.assertEqual(ba.args, (1, 2, 3))
3185 ba = sig.bind(1, self=2, b=3)
3186 self.assertEqual(ba.args, (1, 2, 3))
3187
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05003188 def test_signature_bind_vararg_name(self):
3189 def test(a, *args):
3190 return a, args
3191 sig = inspect.signature(test)
3192
Yury Selivanov86872752015-05-19 00:27:49 -04003193 with self.assertRaisesRegex(
3194 TypeError, "got an unexpected keyword argument 'args'"):
3195
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05003196 sig.bind(a=0, args=1)
3197
3198 def test(*args, **kwargs):
3199 return args, kwargs
3200 self.assertEqual(self.call(test, args=1), ((), {'args': 1}))
3201
3202 sig = inspect.signature(test)
3203 ba = sig.bind(args=1)
3204 self.assertEqual(ba.arguments, {'kwargs': {'args': 1}})
3205
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003206
3207class TestBoundArguments(unittest.TestCase):
3208 def test_signature_bound_arguments_unhashable(self):
3209 def foo(a): pass
3210 ba = inspect.signature(foo).bind(1)
3211
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003212 with self.assertRaisesRegex(TypeError, 'unhashable type'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003213 hash(ba)
3214
3215 def test_signature_bound_arguments_equality(self):
3216 def foo(a): pass
3217 ba = inspect.signature(foo).bind(1)
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003218 self.assertTrue(ba == ba)
3219 self.assertFalse(ba != ba)
3220 self.assertTrue(ba == EqualsToAll())
3221 self.assertFalse(ba != EqualsToAll())
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003222
3223 ba2 = inspect.signature(foo).bind(1)
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003224 self.assertTrue(ba == ba2)
3225 self.assertFalse(ba != ba2)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003226
3227 ba3 = inspect.signature(foo).bind(2)
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003228 self.assertFalse(ba == ba3)
3229 self.assertTrue(ba != ba3)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003230 ba3.arguments['a'] = 1
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003231 self.assertTrue(ba == ba3)
3232 self.assertFalse(ba != ba3)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003233
3234 def bar(b): pass
3235 ba4 = inspect.signature(bar).bind(1)
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003236 self.assertFalse(ba == ba4)
3237 self.assertTrue(ba != ba4)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003238
Yury Selivanov4cfd4ea2015-05-14 18:30:27 -04003239 def foo(*, a, b): pass
3240 sig = inspect.signature(foo)
3241 ba1 = sig.bind(a=1, b=2)
3242 ba2 = sig.bind(b=2, a=1)
Serhiy Storchaka2489bd52015-07-18 23:20:50 +03003243 self.assertTrue(ba1 == ba2)
3244 self.assertFalse(ba1 != ba2)
Yury Selivanov4cfd4ea2015-05-14 18:30:27 -04003245
Yury Selivanova5d63dd2014-03-27 11:31:43 -04003246 def test_signature_bound_arguments_pickle(self):
3247 def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
3248 sig = inspect.signature(foo)
3249 ba = sig.bind(20, 30, z={})
3250
3251 for ver in range(pickle.HIGHEST_PROTOCOL + 1):
3252 with self.subTest(pickle_ver=ver):
3253 ba_pickled = pickle.loads(pickle.dumps(ba, ver))
3254 self.assertEqual(ba, ba_pickled)
3255
Yury Selivanov3f6538f2015-05-14 18:47:17 -04003256 def test_signature_bound_arguments_repr(self):
3257 def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
3258 sig = inspect.signature(foo)
3259 ba = sig.bind(20, 30, z={})
Yury Selivanovf229bc52015-05-15 12:53:56 -04003260 self.assertRegex(repr(ba), r'<BoundArguments \(a=20,.*\}\}\)>')
Yury Selivanov3f6538f2015-05-14 18:47:17 -04003261
Yury Selivanovb907a512015-05-16 13:45:09 -04003262 def test_signature_bound_arguments_apply_defaults(self):
3263 def foo(a, b=1, *args, c:1={}, **kw): pass
3264 sig = inspect.signature(foo)
3265
3266 ba = sig.bind(20)
3267 ba.apply_defaults()
3268 self.assertEqual(
3269 list(ba.arguments.items()),
3270 [('a', 20), ('b', 1), ('args', ()), ('c', {}), ('kw', {})])
3271
3272 # Make sure that we preserve the order:
3273 # i.e. 'c' should be *before* 'kw'.
3274 ba = sig.bind(10, 20, 30, d=1)
3275 ba.apply_defaults()
3276 self.assertEqual(
3277 list(ba.arguments.items()),
3278 [('a', 10), ('b', 20), ('args', (30,)), ('c', {}), ('kw', {'d':1})])
3279
3280 # Make sure that BoundArguments produced by bind_partial()
3281 # are supported.
3282 def foo(a, b): pass
3283 sig = inspect.signature(foo)
3284 ba = sig.bind_partial(20)
3285 ba.apply_defaults()
3286 self.assertEqual(
3287 list(ba.arguments.items()),
3288 [('a', 20)])
3289
3290 # Test no args
3291 def foo(): pass
3292 sig = inspect.signature(foo)
3293 ba = sig.bind()
3294 ba.apply_defaults()
3295 self.assertEqual(list(ba.arguments.items()), [])
3296
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003297
Yury Selivanovd82eddc2014-01-29 11:24:39 -05003298class TestSignaturePrivateHelpers(unittest.TestCase):
3299 def test_signature_get_bound_param(self):
3300 getter = inspect._signature_get_bound_param
3301
3302 self.assertEqual(getter('($self)'), 'self')
3303 self.assertEqual(getter('($self, obj)'), 'self')
3304 self.assertEqual(getter('($cls, /, obj)'), 'cls')
3305
Larry Hastings2623c8c2014-02-08 22:15:29 -08003306 def _strip_non_python_syntax(self, input,
3307 clean_signature, self_parameter, last_positional_only):
3308 computed_clean_signature, \
3309 computed_self_parameter, \
3310 computed_last_positional_only = \
3311 inspect._signature_strip_non_python_syntax(input)
3312 self.assertEqual(computed_clean_signature, clean_signature)
3313 self.assertEqual(computed_self_parameter, self_parameter)
3314 self.assertEqual(computed_last_positional_only, last_positional_only)
3315
3316 def test_signature_strip_non_python_syntax(self):
3317 self._strip_non_python_syntax(
3318 "($module, /, path, mode, *, dir_fd=None, " +
3319 "effective_ids=False,\n follow_symlinks=True)",
3320 "(module, path, mode, *, dir_fd=None, " +
3321 "effective_ids=False, follow_symlinks=True)",
3322 0,
3323 0)
3324
3325 self._strip_non_python_syntax(
3326 "($module, word, salt, /)",
3327 "(module, word, salt)",
3328 0,
3329 2)
3330
3331 self._strip_non_python_syntax(
3332 "(x, y=None, z=None, /)",
3333 "(x, y=None, z=None)",
3334 None,
3335 2)
3336
3337 self._strip_non_python_syntax(
3338 "(x, y=None, z=None)",
3339 "(x, y=None, z=None)",
3340 None,
3341 None)
3342
3343 self._strip_non_python_syntax(
3344 "(x,\n y=None,\n z = None )",
3345 "(x, y=None, z=None)",
3346 None,
3347 None)
3348
3349 self._strip_non_python_syntax(
3350 "",
3351 "",
3352 None,
3353 None)
3354
3355 self._strip_non_python_syntax(
3356 None,
3357 None,
3358 None,
3359 None)
3360
Nick Coghlan9c680b02015-04-13 12:54:54 -04003361class TestSignatureDefinitions(unittest.TestCase):
3362 # This test case provides a home for checking that particular APIs
3363 # have signatures available for introspection
3364
3365 @cpython_only
3366 @unittest.skipIf(MISSING_C_DOCSTRINGS,
3367 "Signature information for builtins requires docstrings")
3368 def test_builtins_have_signatures(self):
3369 # This checks all builtin callables in CPython have signatures
3370 # A few have signatures Signature can't yet handle, so we skip those
3371 # since they will have to wait until PEP 457 adds the required
3372 # introspection support to the inspect module
3373 # Some others also haven't been converted yet for various other
3374 # reasons, so we also skip those for the time being, but design
3375 # the test to fail in order to indicate when it needs to be
3376 # updated.
3377 no_signature = set()
3378 # These need PEP 457 groups
3379 needs_groups = {"range", "slice", "dir", "getattr",
3380 "next", "iter", "vars"}
3381 no_signature |= needs_groups
3382 # These need PEP 457 groups or a signature change to accept None
3383 needs_semantic_update = {"round"}
3384 no_signature |= needs_semantic_update
3385 # These need *args support in Argument Clinic
3386 needs_varargs = {"min", "max", "print", "__build_class__"}
3387 no_signature |= needs_varargs
3388 # These simply weren't covered in the initial AC conversion
3389 # for builtin callables
3390 not_converted_yet = {"open", "__import__"}
3391 no_signature |= not_converted_yet
3392 # These builtin types are expected to provide introspection info
3393 types_with_signatures = set()
3394 # Check the signatures we expect to be there
3395 ns = vars(builtins)
3396 for name, obj in sorted(ns.items()):
3397 if not callable(obj):
3398 continue
3399 # The builtin types haven't been converted to AC yet
3400 if isinstance(obj, type) and (name not in types_with_signatures):
3401 # Note that this also skips all the exception types
3402 no_signature.add(name)
3403 if (name in no_signature):
3404 # Not yet converted
3405 continue
3406 with self.subTest(builtin=name):
3407 self.assertIsNotNone(inspect.signature(obj))
3408 # Check callables that haven't been converted don't claim a signature
3409 # This ensures this test will start failing as more signatures are
3410 # added, so the affected items can be moved into the scope of the
3411 # regression test above
3412 for name in no_signature:
3413 with self.subTest(builtin=name):
3414 self.assertIsNone(obj.__text_signature__)
3415
Yury Selivanovd82eddc2014-01-29 11:24:39 -05003416
Nick Coghlane8c45d62013-07-28 20:00:01 +10003417class TestUnwrap(unittest.TestCase):
3418
3419 def test_unwrap_one(self):
3420 def func(a, b):
3421 return a + b
3422 wrapper = functools.lru_cache(maxsize=20)(func)
3423 self.assertIs(inspect.unwrap(wrapper), func)
3424
3425 def test_unwrap_several(self):
3426 def func(a, b):
3427 return a + b
3428 wrapper = func
3429 for __ in range(10):
3430 @functools.wraps(wrapper)
3431 def wrapper():
3432 pass
3433 self.assertIsNot(wrapper.__wrapped__, func)
3434 self.assertIs(inspect.unwrap(wrapper), func)
3435
3436 def test_stop(self):
3437 def func1(a, b):
3438 return a + b
3439 @functools.wraps(func1)
3440 def func2():
3441 pass
3442 @functools.wraps(func2)
3443 def wrapper():
3444 pass
3445 func2.stop_here = 1
3446 unwrapped = inspect.unwrap(wrapper,
3447 stop=(lambda f: hasattr(f, "stop_here")))
3448 self.assertIs(unwrapped, func2)
3449
3450 def test_cycle(self):
3451 def func1(): pass
3452 func1.__wrapped__ = func1
3453 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3454 inspect.unwrap(func1)
3455
3456 def func2(): pass
3457 func2.__wrapped__ = func1
3458 func1.__wrapped__ = func2
3459 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3460 inspect.unwrap(func1)
3461 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3462 inspect.unwrap(func2)
3463
3464 def test_unhashable(self):
3465 def func(): pass
3466 func.__wrapped__ = None
3467 class C:
3468 __hash__ = None
3469 __wrapped__ = func
3470 self.assertIsNone(inspect.unwrap(C()))
3471
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003472class TestMain(unittest.TestCase):
3473 def test_only_source(self):
3474 module = importlib.import_module('unittest')
3475 rc, out, err = assert_python_ok('-m', 'inspect',
3476 'unittest')
3477 lines = out.decode().splitlines()
3478 # ignore the final newline
3479 self.assertEqual(lines[:-1], inspect.getsource(module).splitlines())
3480 self.assertEqual(err, b'')
3481
Yury Selivanov42407ab2014-06-23 10:23:50 -07003482 def test_custom_getattr(self):
3483 def foo():
3484 pass
3485 foo.__signature__ = 42
3486 with self.assertRaises(TypeError):
3487 inspect.signature(foo)
3488
Brett Cannon634a8fc2013-10-02 10:25:42 -04003489 @unittest.skipIf(ThreadPoolExecutor is None,
Brett Cannon0de3f012013-10-02 10:58:58 -04003490 'threads required to test __qualname__ for source files')
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003491 def test_qualname_source(self):
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003492 rc, out, err = assert_python_ok('-m', 'inspect',
3493 'concurrent.futures:ThreadPoolExecutor')
3494 lines = out.decode().splitlines()
3495 # ignore the final newline
3496 self.assertEqual(lines[:-1],
Brett Cannon634a8fc2013-10-02 10:25:42 -04003497 inspect.getsource(ThreadPoolExecutor).splitlines())
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003498 self.assertEqual(err, b'')
3499
3500 def test_builtins(self):
3501 module = importlib.import_module('unittest')
3502 _, out, err = assert_python_failure('-m', 'inspect',
3503 'sys')
3504 lines = err.decode().splitlines()
3505 self.assertEqual(lines, ["Can't get info for builtin modules."])
3506
3507 def test_details(self):
3508 module = importlib.import_module('unittest')
3509 rc, out, err = assert_python_ok('-m', 'inspect',
3510 'unittest', '--details')
3511 output = out.decode()
3512 # Just a quick sanity check on the output
3513 self.assertIn(module.__name__, output)
3514 self.assertIn(module.__file__, output)
Serhiy Storchakab12cb6a2013-12-08 18:16:18 +02003515 if not sys.flags.optimize:
3516 self.assertIn(module.__cached__, output)
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003517 self.assertEqual(err, b'')
3518
3519
Yury Selivanovef1e7502014-12-08 16:05:34 -05003520class TestReload(unittest.TestCase):
3521
3522 src_before = textwrap.dedent("""\
3523def foo():
3524 print("Bla")
3525 """)
3526
3527 src_after = textwrap.dedent("""\
3528def foo():
3529 print("Oh no!")
3530 """)
3531
3532 def assertInspectEqual(self, path, source):
3533 inspected_src = inspect.getsource(source)
3534 with open(path) as src:
3535 self.assertEqual(
3536 src.read().splitlines(True),
3537 inspected_src.splitlines(True)
3538 )
3539
3540 def test_getsource_reload(self):
3541 # see issue 1218234
3542 with _ready_to_import('reload_bug', self.src_before) as (name, path):
3543 module = importlib.import_module(name)
3544 self.assertInspectEqual(path, module)
3545 with open(path, 'w') as src:
3546 src.write(self.src_after)
3547 self.assertInspectEqual(path, module)
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003548
Nick Coghlane8c45d62013-07-28 20:00:01 +10003549
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00003550def test_main():
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00003551 run_unittest(
3552 TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBuggyCases,
3553 TestInterpreterStack, TestClassesAndFunctions, TestPredicates,
3554 TestGetcallargsFunctions, TestGetcallargsMethods,
Alexander Belopolskyf546e702010-12-02 00:10:11 +00003555 TestGetcallargsUnboundMethods, TestGetattrStatic, TestGetGeneratorState,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003556 TestNoEOL, TestSignatureObject, TestSignatureBind, TestParameterObject,
Nick Coghlan9c680b02015-04-13 12:54:54 -04003557 TestBoundArguments, TestSignaturePrivateHelpers,
3558 TestSignatureDefinitions,
Yury Selivanov5376ba92015-06-22 12:19:30 -04003559 TestGetClosureVars, TestUnwrap, TestMain, TestReload,
3560 TestGetCoroutineState
Michael Foord95fc51d2010-11-20 15:07:30 +00003561 )
Martin v. Löwis893ffa42003-10-31 15:35:53 +00003562
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00003563if __name__ == "__main__":
3564 test_main()