blob: 1da88c4ddb461e86279f1bb67be027207210f424 [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
17import unicodedata
18import unittest
Yury Selivanova773de02014-02-21 18:30:53 -050019import unittest.mock
Larry Hastings5c661892014-01-24 06:17:25 -080020
Brett Cannon634a8fc2013-10-02 10:25:42 -040021try:
22 from concurrent.futures import ThreadPoolExecutor
23except ImportError:
24 ThreadPoolExecutor = None
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000025
Serhiy Storchakaf28ba362014-02-07 10:10:55 +020026from test.support import run_unittest, TESTFN, DirsOnSysPath, cpython_only
Nick Coghlanf9e227e2014-08-17 14:01:19 +100027from test.support import MISSING_C_DOCSTRINGS, cpython_only
Nick Coghlanf94a16b2013-09-22 22:46:49 +100028from test.script_helper import assert_python_ok, assert_python_failure
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000029from test import inspect_fodder as mod
30from test import inspect_fodder2 as mod2
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000031
R. David Murray74b89242009-05-13 17:33:03 +000032
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000033# Functions tested in this suite:
34# ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode,
Christian Heimes7131fd92008-02-19 14:21:46 +000035# isbuiltin, isroutine, isgenerator, isgeneratorfunction, getmembers,
36# getdoc, getfile, getmodule, getsourcefile, getcomments, getsource,
37# getclasstree, getargspec, getargvalues, formatargspec, formatargvalues,
38# currentframe, stack, trace, isdatadescriptor
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000039
Nick Coghlanf088e5e2008-12-14 11:50:48 +000040# NOTE: There are some additional tests relating to interaction with
41# zipimport in the test_zipimport_support test module.
42
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000043modfile = mod.__file__
Thomas Wouters0e3f5912006-08-11 14:57:12 +000044if modfile.endswith(('c', 'o')):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000045 modfile = modfile[:-1]
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000046
Christian Heimesa3538eb2007-11-06 11:44:48 +000047# Normalize file names: on Windows, the case of file names of compiled
48# modules depends on the path used to start the python executable.
49modfile = normcase(modfile)
50
51def revise(filename, *args):
52 return (normcase(filename),) + args
53
Georg Brandl1a3284e2007-12-02 09:40:06 +000054import builtins
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000055
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000056git = mod.StupidGit()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000057
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000058class IsTestBase(unittest.TestCase):
59 predicates = set([inspect.isbuiltin, inspect.isclass, inspect.iscode,
60 inspect.isframe, inspect.isfunction, inspect.ismethod,
Christian Heimes7131fd92008-02-19 14:21:46 +000061 inspect.ismodule, inspect.istraceback,
62 inspect.isgenerator, inspect.isgeneratorfunction])
Tim Peters5a9fb3c2005-01-07 16:01:32 +000063
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000064 def istest(self, predicate, exp):
65 obj = eval(exp)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000066 self.assertTrue(predicate(obj), '%s(%s)' % (predicate.__name__, exp))
Tim Peters5a9fb3c2005-01-07 16:01:32 +000067
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000068 for other in self.predicates - set([predicate]):
Christian Heimes7131fd92008-02-19 14:21:46 +000069 if predicate == inspect.isgeneratorfunction and\
70 other == inspect.isfunction:
71 continue
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000072 self.assertFalse(other(obj), 'not %s(%s)' % (other.__name__, exp))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000073
Christian Heimes7131fd92008-02-19 14:21:46 +000074def generator_function_example(self):
75 for i in range(2):
76 yield i
77
Yury Selivanova5d63dd2014-03-27 11:31:43 -040078
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000079class TestPredicates(IsTestBase):
Christian Heimes227c8002008-03-03 20:34:40 +000080 def test_sixteen(self):
Guido van Rossumc1f779c2007-07-03 08:25:58 +000081 count = len([x for x in dir(inspect) if x.startswith('is')])
Christian Heimes7131fd92008-02-19 14:21:46 +000082 # This test is here for remember you to update Doc/library/inspect.rst
Christian Heimes78644762008-03-04 23:39:23 +000083 # which claims there are 16 such functions
Christian Heimes227c8002008-03-03 20:34:40 +000084 expected = 16
Thomas Wouters0e3f5912006-08-11 14:57:12 +000085 err_msg = "There are %d (not %d) is* functions" % (count, expected)
86 self.assertEqual(count, expected, err_msg)
Tim Peters5a9fb3c2005-01-07 16:01:32 +000087
Christian Heimes7131fd92008-02-19 14:21:46 +000088
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000089 def test_excluding_predicates(self):
Antoine Pitroud5a1a212012-06-17 23:18:07 +020090 global tb
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000091 self.istest(inspect.isbuiltin, 'sys.exit')
92 self.istest(inspect.isbuiltin, '[].append')
Neal Norwitz221085d2007-02-25 20:55:47 +000093 self.istest(inspect.iscode, 'mod.spam.__code__')
Antoine Pitroud5a1a212012-06-17 23:18:07 +020094 try:
95 1/0
96 except:
97 tb = sys.exc_info()[2]
98 self.istest(inspect.isframe, 'tb.tb_frame')
99 self.istest(inspect.istraceback, 'tb')
100 if hasattr(types, 'GetSetDescriptorType'):
101 self.istest(inspect.isgetsetdescriptor,
102 'type(tb.tb_frame).f_locals')
103 else:
104 self.assertFalse(inspect.isgetsetdescriptor(type(tb.tb_frame).f_locals))
105 finally:
106 # Clear traceback and all the frames and local variables hanging to it.
107 tb = None
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000108 self.istest(inspect.isfunction, 'mod.spam')
Christian Heimes4a22b5d2007-11-25 09:39:14 +0000109 self.istest(inspect.isfunction, 'mod.StupidGit.abuse')
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000110 self.istest(inspect.ismethod, 'git.argue')
111 self.istest(inspect.ismodule, 'mod')
Guido van Rossum813b0e52007-05-21 18:11:34 +0000112 self.istest(inspect.isdatadescriptor, 'collections.defaultdict.default_factory')
Christian Heimes7131fd92008-02-19 14:21:46 +0000113 self.istest(inspect.isgenerator, '(x for x in range(2))')
114 self.istest(inspect.isgeneratorfunction, 'generator_function_example')
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000115 if hasattr(types, 'MemberDescriptorType'):
116 self.istest(inspect.ismemberdescriptor, 'datetime.timedelta.days')
117 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000118 self.assertFalse(inspect.ismemberdescriptor(datetime.timedelta.days))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000119
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000120 def test_isroutine(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000121 self.assertTrue(inspect.isroutine(mod.spam))
122 self.assertTrue(inspect.isroutine([].count))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000123
Benjamin Petersonc4656002009-01-17 22:41:18 +0000124 def test_isclass(self):
125 self.istest(inspect.isclass, 'mod.StupidGit')
126 self.assertTrue(inspect.isclass(list))
127
128 class CustomGetattr(object):
129 def __getattr__(self, attr):
130 return None
131 self.assertFalse(inspect.isclass(CustomGetattr()))
132
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000133 def test_get_slot_members(self):
134 class C(object):
135 __slots__ = ("a", "b")
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000136 x = C()
137 x.a = 42
138 members = dict(inspect.getmembers(x))
Benjamin Peterson577473f2010-01-19 00:09:57 +0000139 self.assertIn('a', members)
140 self.assertNotIn('b', members)
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000141
Benjamin Petersona0dfa822009-11-13 02:25:08 +0000142 def test_isabstract(self):
143 from abc import ABCMeta, abstractmethod
144
145 class AbstractClassExample(metaclass=ABCMeta):
146
147 @abstractmethod
148 def foo(self):
149 pass
150
151 class ClassExample(AbstractClassExample):
152 def foo(self):
153 pass
154
155 a = ClassExample()
156
157 # Test general behaviour.
158 self.assertTrue(inspect.isabstract(AbstractClassExample))
159 self.assertFalse(inspect.isabstract(ClassExample))
160 self.assertFalse(inspect.isabstract(a))
161 self.assertFalse(inspect.isabstract(int))
162 self.assertFalse(inspect.isabstract(5))
163
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000164
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000165class TestInterpreterStack(IsTestBase):
166 def __init__(self, *args, **kwargs):
167 unittest.TestCase.__init__(self, *args, **kwargs)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000168
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000169 git.abuse(7, 8, 9)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000170
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000171 def test_abuse_done(self):
172 self.istest(inspect.istraceback, 'git.ex[2]')
173 self.istest(inspect.isframe, 'mod.fr')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000174
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000175 def test_stack(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000176 self.assertTrue(len(mod.st) >= 5)
Christian Heimesa3538eb2007-11-06 11:44:48 +0000177 self.assertEqual(revise(*mod.st[0][1:]),
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000178 (modfile, 16, 'eggs', [' st = inspect.stack()\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000179 self.assertEqual(revise(*mod.st[1][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000180 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000181 self.assertEqual(revise(*mod.st[2][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000182 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000183 self.assertEqual(revise(*mod.st[3][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000184 (modfile, 39, 'abuse', [' self.argue(a, b, c)\n'], 0))
Antoine Pitroucdcafb72014-08-24 10:50:28 -0400185 # Test named tuple fields
186 record = mod.st[0]
187 self.assertIs(record.frame, mod.fr)
188 self.assertEqual(record.lineno, 16)
189 self.assertEqual(record.filename, mod.__file__)
190 self.assertEqual(record.function, 'eggs')
191 self.assertIn('inspect.stack()', record.code_context[0])
192 self.assertEqual(record.index, 0)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000193
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000194 def test_trace(self):
195 self.assertEqual(len(git.tr), 3)
Florent Xiclunac8575922010-03-24 17:37:49 +0000196 self.assertEqual(revise(*git.tr[0][1:]),
197 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
198 self.assertEqual(revise(*git.tr[1][1:]),
199 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
200 self.assertEqual(revise(*git.tr[2][1:]),
201 (modfile, 18, 'eggs', [' q = y / 0\n'], 0))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000202
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000203 def test_frame(self):
204 args, varargs, varkw, locals = inspect.getargvalues(mod.fr)
205 self.assertEqual(args, ['x', 'y'])
206 self.assertEqual(varargs, None)
207 self.assertEqual(varkw, None)
208 self.assertEqual(locals, {'x': 11, 'p': 11, 'y': 14})
209 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
210 '(x=11, y=14)')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000211
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000212 def test_previous_frame(self):
213 args, varargs, varkw, locals = inspect.getargvalues(mod.fr.f_back)
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000214 self.assertEqual(args, ['a', 'b', 'c', 'd', 'e', 'f'])
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000215 self.assertEqual(varargs, 'g')
216 self.assertEqual(varkw, 'h')
217 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000218 '(a=7, b=8, c=9, d=3, e=4, f=5, *g=(), **h={})')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000219
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000220class GetSourceBase(unittest.TestCase):
221 # Subclasses must override.
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000222 fodderModule = None
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000223
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000224 def __init__(self, *args, **kwargs):
225 unittest.TestCase.__init__(self, *args, **kwargs)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000226
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000227 with open(inspect.getsourcefile(self.fodderModule)) as fp:
Philip Jenveya27c5bd2009-05-28 06:09:08 +0000228 self.source = fp.read()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000229
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000230 def sourcerange(self, top, bottom):
231 lines = self.source.split("\n")
232 return "\n".join(lines[top-1:bottom]) + "\n"
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000233
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000234 def assertSourceEqual(self, obj, top, bottom):
235 self.assertEqual(inspect.getsource(obj),
236 self.sourcerange(top, bottom))
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000237
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000238class TestRetrievingSourceCode(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000239 fodderModule = mod
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000240
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000241 def test_getclasses(self):
242 classes = inspect.getmembers(mod, inspect.isclass)
243 self.assertEqual(classes,
244 [('FesteringGob', mod.FesteringGob),
245 ('MalodorousPervert', mod.MalodorousPervert),
246 ('ParrotDroppings', mod.ParrotDroppings),
Serhiy Storchaka362c1b52013-09-05 17:14:32 +0300247 ('StupidGit', mod.StupidGit),
248 ('Tit', mod.MalodorousPervert),
249 ])
250 tree = inspect.getclasstree([cls[1] for cls in classes])
251 self.assertEqual(tree,
252 [(object, ()),
253 [(mod.ParrotDroppings, (object,)),
254 [(mod.FesteringGob, (mod.MalodorousPervert,
255 mod.ParrotDroppings))
256 ],
257 (mod.StupidGit, (object,)),
258 [(mod.MalodorousPervert, (mod.StupidGit,)),
259 [(mod.FesteringGob, (mod.MalodorousPervert,
260 mod.ParrotDroppings))
261 ]
262 ]
263 ]
264 ])
265 tree = inspect.getclasstree([cls[1] for cls in classes], True)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000266 self.assertEqual(tree,
Thomas Wouters725af872006-04-15 09:13:19 +0000267 [(object, ()),
268 [(mod.ParrotDroppings, (object,)),
269 (mod.StupidGit, (object,)),
270 [(mod.MalodorousPervert, (mod.StupidGit,)),
271 [(mod.FesteringGob, (mod.MalodorousPervert,
272 mod.ParrotDroppings))
273 ]
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000274 ]
275 ]
276 ])
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000277
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000278 def test_getfunctions(self):
279 functions = inspect.getmembers(mod, inspect.isfunction)
280 self.assertEqual(functions, [('eggs', mod.eggs),
281 ('spam', mod.spam)])
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000282
R. David Murray378c0cf2010-02-24 01:46:21 +0000283 @unittest.skipIf(sys.flags.optimize >= 2,
284 "Docstrings are omitted with -O2 and above")
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000285 def test_getdoc(self):
286 self.assertEqual(inspect.getdoc(mod), 'A module docstring.')
287 self.assertEqual(inspect.getdoc(mod.StupidGit),
288 'A longer,\n\nindented\n\ndocstring.')
289 self.assertEqual(inspect.getdoc(git.abuse),
290 'Another\n\ndocstring\n\ncontaining\n\ntabs')
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000291
Georg Brandl0c77a822008-06-10 16:37:50 +0000292 def test_cleandoc(self):
293 self.assertEqual(inspect.cleandoc('An\n indented\n docstring.'),
294 'An\nindented\ndocstring.')
295
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000296 def test_getcomments(self):
297 self.assertEqual(inspect.getcomments(mod), '# line 1\n')
298 self.assertEqual(inspect.getcomments(mod.StupidGit), '# line 20\n')
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000299
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000300 def test_getmodule(self):
Thomas Wouters89f507f2006-12-13 04:49:30 +0000301 # Check actual module
302 self.assertEqual(inspect.getmodule(mod), mod)
303 # Check class (uses __module__ attribute)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000304 self.assertEqual(inspect.getmodule(mod.StupidGit), mod)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000305 # Check a method (no __module__ attribute, falls back to filename)
306 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
307 # Do it again (check the caching isn't broken)
308 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
309 # Check a builtin
Georg Brandl1a3284e2007-12-02 09:40:06 +0000310 self.assertEqual(inspect.getmodule(str), sys.modules["builtins"])
Thomas Wouters89f507f2006-12-13 04:49:30 +0000311 # Check filename override
312 self.assertEqual(inspect.getmodule(None, modfile), mod)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000313
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000314 def test_getsource(self):
315 self.assertSourceEqual(git.abuse, 29, 39)
316 self.assertSourceEqual(mod.StupidGit, 21, 46)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000317
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000318 def test_getsourcefile(self):
Christian Heimesa3538eb2007-11-06 11:44:48 +0000319 self.assertEqual(normcase(inspect.getsourcefile(mod.spam)), modfile)
320 self.assertEqual(normcase(inspect.getsourcefile(git.abuse)), modfile)
R. David Murraya1b37402010-06-17 02:04:29 +0000321 fn = "_non_existing_filename_used_for_sourcefile_test.py"
322 co = compile("None", fn, "exec")
R. David Murray4155f972010-06-17 13:23:18 +0000323 self.assertEqual(inspect.getsourcefile(co), None)
R. David Murraya1b37402010-06-17 02:04:29 +0000324 linecache.cache[co.co_filename] = (1, None, "None", co.co_filename)
Antoine Pitrou5d62a612012-07-08 13:48:46 +0200325 try:
326 self.assertEqual(normcase(inspect.getsourcefile(co)), fn)
327 finally:
328 del linecache.cache[co.co_filename]
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000329
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000330 def test_getfile(self):
331 self.assertEqual(inspect.getfile(mod.StupidGit), mod.__file__)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000332
Yury Selivanov2eed8b72014-01-27 13:24:56 -0500333 def test_getfile_class_without_module(self):
334 class CM(type):
335 @property
336 def __module__(cls):
337 raise AttributeError
338 class C(metaclass=CM):
339 pass
340 with self.assertRaises(TypeError):
341 inspect.getfile(C)
342
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000343 def test_getmodule_recursion(self):
Christian Heimes45f9af32007-11-27 21:50:00 +0000344 from types import ModuleType
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000345 name = '__inspect_dummy'
Christian Heimes45f9af32007-11-27 21:50:00 +0000346 m = sys.modules[name] = ModuleType(name)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000347 m.__file__ = "<string>" # hopefully not a real filename...
348 m.__loader__ = "dummy" # pretend the filename is understood by a loader
Georg Brandl7cae87c2006-09-06 06:51:57 +0000349 exec("def x(): pass", m.__dict__)
Neal Norwitz221085d2007-02-25 20:55:47 +0000350 self.assertEqual(inspect.getsourcefile(m.x.__code__), '<string>')
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000351 del sys.modules[name]
352 inspect.getmodule(compile('a=10','','single'))
353
Benjamin Peterson9620cc02011-06-11 15:53:11 -0500354 def test_proceed_with_fake_filename(self):
355 '''doctest monkeypatches linecache to enable inspection'''
356 fn, source = '<test>', 'def x(): pass\n'
357 getlines = linecache.getlines
358 def monkey(filename, module_globals=None):
359 if filename == fn:
Ezio Melottid8b509b2011-09-28 17:37:55 +0300360 return source.splitlines(keepends=True)
Benjamin Peterson9620cc02011-06-11 15:53:11 -0500361 else:
362 return getlines(filename, module_globals)
363 linecache.getlines = monkey
364 try:
365 ns = {}
366 exec(compile(source, fn, 'single'), ns)
367 inspect.getsource(ns["x"])
368 finally:
369 linecache.getlines = getlines
370
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000371class TestDecorators(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000372 fodderModule = mod2
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000373
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000374 def test_wrapped_decorator(self):
Christian Heimes09aaa882008-02-23 15:01:06 +0000375 self.assertSourceEqual(mod2.wrapped, 14, 17)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000376
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000377 def test_replacing_decorator(self):
378 self.assertSourceEqual(mod2.gone, 9, 10)
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000379
Yury Selivanov081bbf62014-09-26 17:34:54 -0400380 def test_getsource_unwrap(self):
381 self.assertSourceEqual(mod2.real, 122, 124)
382
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000383class TestOneliners(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000384 fodderModule = mod2
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000385 def test_oneline_lambda(self):
386 # Test inspect.getsource with a one-line lambda function.
387 self.assertSourceEqual(mod2.oll, 25, 25)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000388
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000389 def test_threeline_lambda(self):
390 # Test inspect.getsource with a three-line lambda function,
391 # where the second and third lines are _not_ indented.
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000392 self.assertSourceEqual(mod2.tll, 28, 30)
393
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000394 def test_twoline_indented_lambda(self):
395 # Test inspect.getsource with a two-line lambda function,
396 # where the second line _is_ indented.
397 self.assertSourceEqual(mod2.tlli, 33, 34)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000398
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000399 def test_onelinefunc(self):
400 # Test inspect.getsource with a regular one-line function.
401 self.assertSourceEqual(mod2.onelinefunc, 37, 37)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000402
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000403 def test_manyargs(self):
404 # Test inspect.getsource with a regular function where
405 # the arguments are on two lines and _not_ indented and
406 # the body on the second line with the last arguments.
407 self.assertSourceEqual(mod2.manyargs, 40, 41)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000408
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000409 def test_twolinefunc(self):
410 # Test inspect.getsource with a regular function where
411 # the body is on two lines, following the argument list and
412 # continued on the next line by a \\.
413 self.assertSourceEqual(mod2.twolinefunc, 44, 45)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000414
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000415 def test_lambda_in_list(self):
416 # Test inspect.getsource with a one-line lambda function
417 # defined in a list, indented.
418 self.assertSourceEqual(mod2.a[1], 49, 49)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000419
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000420 def test_anonymous(self):
421 # Test inspect.getsource with a lambda function defined
422 # as argument to another function.
423 self.assertSourceEqual(mod2.anonymous, 55, 55)
424
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000425class TestBuggyCases(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000426 fodderModule = mod2
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000427
428 def test_with_comment(self):
429 self.assertSourceEqual(mod2.with_comment, 58, 59)
430
431 def test_multiline_sig(self):
432 self.assertSourceEqual(mod2.multiline_sig[0], 63, 64)
433
Armin Rigodd5c0232005-09-25 11:45:45 +0000434 def test_nested_class(self):
435 self.assertSourceEqual(mod2.func69().func71, 71, 72)
436
437 def test_one_liner_followed_by_non_name(self):
438 self.assertSourceEqual(mod2.func77, 77, 77)
439
440 def test_one_liner_dedent_non_name(self):
441 self.assertSourceEqual(mod2.cls82.func83, 83, 83)
442
443 def test_with_comment_instead_of_docstring(self):
444 self.assertSourceEqual(mod2.func88, 88, 90)
445
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000446 def test_method_in_dynamic_class(self):
447 self.assertSourceEqual(mod2.method_in_dynamic_class, 95, 97)
448
R. David Murrayb5655772009-05-14 16:17:50 +0000449 @unittest.skipIf(
450 not hasattr(unicodedata, '__file__') or
451 unicodedata.__file__[-4:] in (".pyc", ".pyo"),
452 "unicodedata is not an external binary module")
R. David Murray74b89242009-05-13 17:33:03 +0000453 def test_findsource_binary(self):
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200454 self.assertRaises(OSError, inspect.getsource, unicodedata)
455 self.assertRaises(OSError, inspect.findsource, unicodedata)
R. David Murray74b89242009-05-13 17:33:03 +0000456
R. David Murraya1b37402010-06-17 02:04:29 +0000457 def test_findsource_code_in_linecache(self):
458 lines = ["x=1"]
459 co = compile(lines[0], "_dynamically_created_file", "exec")
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200460 self.assertRaises(OSError, inspect.findsource, co)
461 self.assertRaises(OSError, inspect.getsource, co)
R. David Murraya1b37402010-06-17 02:04:29 +0000462 linecache.cache[co.co_filename] = (1, None, lines, co.co_filename)
Antoine Pitrou5d62a612012-07-08 13:48:46 +0200463 try:
464 self.assertEqual(inspect.findsource(co), (lines,0))
465 self.assertEqual(inspect.getsource(co), lines[0])
466 finally:
467 del linecache.cache[co.co_filename]
R. David Murraya1b37402010-06-17 02:04:29 +0000468
Ezio Melotti1b145922013-03-30 05:17:24 +0200469 def test_findsource_without_filename(self):
470 for fname in ['', '<string>']:
471 co = compile('x=1', fname, "exec")
472 self.assertRaises(IOError, inspect.findsource, co)
473 self.assertRaises(IOError, inspect.getsource, co)
474
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000475class TestNoEOL(GetSourceBase):
476 def __init__(self, *args, **kwargs):
477 self.tempdir = TESTFN + '_dir'
478 os.mkdir(self.tempdir)
479 with open(os.path.join(self.tempdir,
480 'inspect_fodder3%spy' % os.extsep), 'w') as f:
481 f.write("class X:\n pass # No EOL")
482 with DirsOnSysPath(self.tempdir):
483 import inspect_fodder3 as mod3
484 self.fodderModule = mod3
485 GetSourceBase.__init__(self, *args, **kwargs)
486
487 def tearDown(self):
488 shutil.rmtree(self.tempdir)
489
490 def test_class(self):
491 self.assertSourceEqual(self.fodderModule.X, 1, 2)
492
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100493
494class _BrokenDataDescriptor(object):
495 """
496 A broken data descriptor. See bug #1785.
497 """
498 def __get__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700499 raise AttributeError("broken data descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100500
501 def __set__(*args):
502 raise RuntimeError
503
504 def __getattr__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700505 raise AttributeError("broken data descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100506
507
508class _BrokenMethodDescriptor(object):
509 """
510 A broken method descriptor. See bug #1785.
511 """
512 def __get__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700513 raise AttributeError("broken method descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100514
515 def __getattr__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700516 raise AttributeError("broken method descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100517
518
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000519# Helper for testing classify_class_attrs.
Tim Peters13b49d32001-09-23 02:00:29 +0000520def attrs_wo_objs(cls):
521 return [t[:3] for t in inspect.classify_class_attrs(cls)]
522
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100523
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000524class TestClassesAndFunctions(unittest.TestCase):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000525 def test_newstyle_mro(self):
526 # The same w/ new-class MRO.
527 class A(object): pass
528 class B(A): pass
529 class C(A): pass
530 class D(B, C): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000531
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000532 expected = (D, B, C, A, object)
533 got = inspect.getmro(D)
534 self.assertEqual(expected, got)
Tim Peters13b49d32001-09-23 02:00:29 +0000535
Christian Heimes3795b532007-11-08 13:48:53 +0000536 def assertArgSpecEquals(self, routine, args_e, varargs_e=None,
537 varkw_e=None, defaults_e=None, formatted=None):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000538 args, varargs, varkw, defaults = inspect.getargspec(routine)
539 self.assertEqual(args, args_e)
540 self.assertEqual(varargs, varargs_e)
541 self.assertEqual(varkw, varkw_e)
542 self.assertEqual(defaults, defaults_e)
543 if formatted is not None:
544 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults),
545 formatted)
Tim Peters13b49d32001-09-23 02:00:29 +0000546
Christian Heimes3795b532007-11-08 13:48:53 +0000547 def assertFullArgSpecEquals(self, routine, args_e, varargs_e=None,
548 varkw_e=None, defaults_e=None,
549 kwonlyargs_e=[], kwonlydefaults_e=None,
550 ann_e={}, formatted=None):
551 args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \
552 inspect.getfullargspec(routine)
553 self.assertEqual(args, args_e)
554 self.assertEqual(varargs, varargs_e)
555 self.assertEqual(varkw, varkw_e)
556 self.assertEqual(defaults, defaults_e)
557 self.assertEqual(kwonlyargs, kwonlyargs_e)
558 self.assertEqual(kwonlydefaults, kwonlydefaults_e)
559 self.assertEqual(ann, ann_e)
560 if formatted is not None:
561 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults,
562 kwonlyargs, kwonlydefaults, ann),
563 formatted)
564
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000565 def test_getargspec(self):
Christian Heimes3795b532007-11-08 13:48:53 +0000566 self.assertArgSpecEquals(mod.eggs, ['x', 'y'], formatted='(x, y)')
Tim Peters13b49d32001-09-23 02:00:29 +0000567
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000568 self.assertArgSpecEquals(mod.spam,
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000569 ['a', 'b', 'c', 'd', 'e', 'f'],
570 'g', 'h', (3, 4, 5),
571 '(a, b, c, d=3, e=4, f=5, *g, **h)')
Tim Peters13b49d32001-09-23 02:00:29 +0000572
Christian Heimes3795b532007-11-08 13:48:53 +0000573 self.assertRaises(ValueError, self.assertArgSpecEquals,
574 mod2.keyworded, [])
575
576 self.assertRaises(ValueError, self.assertArgSpecEquals,
577 mod2.annotated, [])
Benjamin Peterson9953a8d2009-01-17 04:15:01 +0000578 self.assertRaises(ValueError, self.assertArgSpecEquals,
579 mod2.keyword_only_arg, [])
580
Christian Heimes3795b532007-11-08 13:48:53 +0000581
582 def test_getfullargspec(self):
583 self.assertFullArgSpecEquals(mod2.keyworded, [], varargs_e='arg1',
584 kwonlyargs_e=['arg2'],
585 kwonlydefaults_e={'arg2':1},
586 formatted='(*arg1, arg2=1)')
587
588 self.assertFullArgSpecEquals(mod2.annotated, ['arg1'],
Christian Heimesc9543e42007-11-28 08:28:28 +0000589 ann_e={'arg1' : list},
Christian Heimes3795b532007-11-08 13:48:53 +0000590 formatted='(arg1: list)')
Benjamin Peterson9953a8d2009-01-17 04:15:01 +0000591 self.assertFullArgSpecEquals(mod2.keyword_only_arg, [],
592 kwonlyargs_e=['arg'],
593 formatted='(*, arg)')
594
Yury Selivanov57d240e2014-02-19 16:27:23 -0500595 def test_argspec_api_ignores_wrapped(self):
596 # Issue 20684: low level introspection API must ignore __wrapped__
597 @functools.wraps(mod.spam)
598 def ham(x, y):
599 pass
600 # Basic check
601 self.assertArgSpecEquals(ham, ['x', 'y'], formatted='(x, y)')
602 self.assertFullArgSpecEquals(ham, ['x', 'y'], formatted='(x, y)')
603 self.assertFullArgSpecEquals(functools.partial(ham),
604 ['x', 'y'], formatted='(x, y)')
605 # Other variants
606 def check_method(f):
607 self.assertArgSpecEquals(f, ['self', 'x', 'y'],
608 formatted='(self, x, y)')
609 class C:
610 @functools.wraps(mod.spam)
611 def ham(self, x, y):
612 pass
613 pham = functools.partialmethod(ham)
614 @functools.wraps(mod.spam)
615 def __call__(self, x, y):
616 pass
617 check_method(C())
618 check_method(C.ham)
619 check_method(C().ham)
620 check_method(C.pham)
621 check_method(C().pham)
622
623 class C_new:
624 @functools.wraps(mod.spam)
625 def __new__(self, x, y):
626 pass
627 check_method(C_new)
628
629 class C_init:
630 @functools.wraps(mod.spam)
631 def __init__(self, x, y):
632 pass
633 check_method(C_init)
634
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500635 def test_getfullargspec_signature_attr(self):
636 def test():
637 pass
638 spam_param = inspect.Parameter('spam', inspect.Parameter.POSITIONAL_ONLY)
639 test.__signature__ = inspect.Signature(parameters=(spam_param,))
640
641 self.assertFullArgSpecEquals(test, args_e=['spam'], formatted='(spam)')
642
Yury Selivanov4cb93912014-01-29 11:54:12 -0500643 def test_getfullargspec_signature_annos(self):
644 def test(a:'spam') -> 'ham': pass
645 spec = inspect.getfullargspec(test)
646 self.assertEqual(test.__annotations__, spec.annotations)
647
648 def test(): pass
649 spec = inspect.getfullargspec(test)
650 self.assertEqual(test.__annotations__, spec.annotations)
651
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500652 @unittest.skipIf(MISSING_C_DOCSTRINGS,
653 "Signature information for builtins requires docstrings")
654 def test_getfullargspec_builtin_methods(self):
655 self.assertFullArgSpecEquals(_pickle.Pickler.dump,
656 args_e=['self', 'obj'], formatted='(self, obj)')
657
658 self.assertFullArgSpecEquals(_pickle.Pickler(io.BytesIO()).dump,
659 args_e=['self', 'obj'], formatted='(self, obj)')
660
Yury Selivanov8c185ee2014-02-21 01:32:42 -0500661 self.assertFullArgSpecEquals(
662 os.stat,
663 args_e=['path'],
664 kwonlyargs_e=['dir_fd', 'follow_symlinks'],
665 kwonlydefaults_e={'dir_fd': None, 'follow_symlinks': True},
666 formatted='(path, *, dir_fd=None, follow_symlinks=True)')
667
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200668 @cpython_only
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500669 @unittest.skipIf(MISSING_C_DOCSTRINGS,
670 "Signature information for builtins requires docstrings")
671 def test_getfullagrspec_builtin_func(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200672 import _testcapi
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500673 builtin = _testcapi.docstring_with_signature_with_defaults
674 spec = inspect.getfullargspec(builtin)
675 self.assertEqual(spec.defaults[0], 'avocado')
676
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200677 @cpython_only
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500678 @unittest.skipIf(MISSING_C_DOCSTRINGS,
679 "Signature information for builtins requires docstrings")
680 def test_getfullagrspec_builtin_func_no_signature(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200681 import _testcapi
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500682 builtin = _testcapi.docstring_no_signature
683 with self.assertRaises(TypeError):
684 inspect.getfullargspec(builtin)
Christian Heimes3795b532007-11-08 13:48:53 +0000685
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000686 def test_getargspec_method(self):
687 class A(object):
688 def m(self):
689 pass
690 self.assertArgSpecEquals(A.m, ['self'])
Tim Peters13b49d32001-09-23 02:00:29 +0000691
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000692 def test_classify_newstyle(self):
693 class A(object):
Tim Peters13b49d32001-09-23 02:00:29 +0000694
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000695 def s(): pass
696 s = staticmethod(s)
Tim Peters13b49d32001-09-23 02:00:29 +0000697
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000698 def c(cls): pass
699 c = classmethod(c)
Tim Peters13b49d32001-09-23 02:00:29 +0000700
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000701 def getp(self): pass
702 p = property(getp)
Tim Peters13b49d32001-09-23 02:00:29 +0000703
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000704 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000705
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000706 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000707
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000708 datablob = '1'
Tim Peters13b49d32001-09-23 02:00:29 +0000709
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100710 dd = _BrokenDataDescriptor()
711 md = _BrokenMethodDescriptor()
712
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000713 attrs = attrs_wo_objs(A)
Yury Selivanov0860a0b2014-01-31 14:28:44 -0500714
715 self.assertIn(('__new__', 'method', object), attrs, 'missing __new__')
716 self.assertIn(('__init__', 'method', object), attrs, 'missing __init__')
717
Benjamin Peterson577473f2010-01-19 00:09:57 +0000718 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
719 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
720 self.assertIn(('p', 'property', A), attrs, 'missing property')
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000721 self.assertIn(('m', 'method', A), attrs,
722 'missing plain method: %r' % attrs)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000723 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
724 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100725 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
726 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000727
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000728 class B(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000729
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000730 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000731
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000732 attrs = attrs_wo_objs(B)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000733 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
734 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
735 self.assertIn(('p', 'property', A), attrs, 'missing property')
736 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
737 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
738 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100739 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
740 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000741
742
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000743 class C(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000744
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000745 def m(self): pass
746 def c(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000747
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000748 attrs = attrs_wo_objs(C)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000749 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
750 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
751 self.assertIn(('p', 'property', A), attrs, 'missing property')
752 self.assertIn(('m', 'method', C), attrs, 'missing plain method')
753 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
754 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100755 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
756 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000757
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000758 class D(B, C):
Tim Peters13b49d32001-09-23 02:00:29 +0000759
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000760 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000761
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000762 attrs = attrs_wo_objs(D)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000763 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
764 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
765 self.assertIn(('p', 'property', A), attrs, 'missing property')
766 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
767 self.assertIn(('m1', 'method', D), attrs, 'missing plain method')
768 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100769 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
770 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
771
772 def test_classify_builtin_types(self):
773 # Simple sanity check that all built-in types can have their
774 # attributes classified.
775 for name in dir(__builtins__):
776 builtin = getattr(__builtins__, name)
777 if isinstance(builtin, type):
778 inspect.classify_class_attrs(builtin)
779
Ethan Furman63c141c2013-10-18 00:27:39 -0700780 def test_classify_DynamicClassAttribute(self):
781 class Meta(type):
782 def __getattr__(self, name):
783 if name == 'ham':
784 return 'spam'
785 return super().__getattr__(name)
786 class VA(metaclass=Meta):
Ethan Furmane03ea372013-09-25 07:14:41 -0700787 @types.DynamicClassAttribute
788 def ham(self):
789 return 'eggs'
Ethan Furman63c141c2013-10-18 00:27:39 -0700790 should_find_dca = inspect.Attribute('ham', 'data', VA, VA.__dict__['ham'])
791 self.assertIn(should_find_dca, inspect.classify_class_attrs(VA))
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700792 should_find_ga = inspect.Attribute('ham', 'data', Meta, 'spam')
Ethan Furman63c141c2013-10-18 00:27:39 -0700793 self.assertIn(should_find_ga, inspect.classify_class_attrs(VA))
794
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700795 def test_classify_metaclass_class_attribute(self):
796 class Meta(type):
797 fish = 'slap'
798 def __dir__(self):
799 return ['__class__', '__modules__', '__name__', 'fish']
800 class Class(metaclass=Meta):
801 pass
802 should_find = inspect.Attribute('fish', 'data', Meta, 'slap')
803 self.assertIn(should_find, inspect.classify_class_attrs(Class))
804
Ethan Furman63c141c2013-10-18 00:27:39 -0700805 def test_classify_VirtualAttribute(self):
806 class Meta(type):
807 def __dir__(cls):
808 return ['__class__', '__module__', '__name__', 'BOOM']
809 def __getattr__(self, name):
810 if name =='BOOM':
811 return 42
812 return super().__getattr(name)
813 class Class(metaclass=Meta):
814 pass
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700815 should_find = inspect.Attribute('BOOM', 'data', Meta, 42)
Ethan Furman63c141c2013-10-18 00:27:39 -0700816 self.assertIn(should_find, inspect.classify_class_attrs(Class))
817
818 def test_classify_VirtualAttribute_multi_classes(self):
819 class Meta1(type):
820 def __dir__(cls):
821 return ['__class__', '__module__', '__name__', 'one']
822 def __getattr__(self, name):
823 if name =='one':
824 return 1
825 return super().__getattr__(name)
826 class Meta2(type):
827 def __dir__(cls):
828 return ['__class__', '__module__', '__name__', 'two']
829 def __getattr__(self, name):
830 if name =='two':
831 return 2
832 return super().__getattr__(name)
833 class Meta3(Meta1, Meta2):
834 def __dir__(cls):
835 return list(sorted(set(['__class__', '__module__', '__name__', 'three'] +
836 Meta1.__dir__(cls) + Meta2.__dir__(cls))))
837 def __getattr__(self, name):
838 if name =='three':
839 return 3
840 return super().__getattr__(name)
841 class Class1(metaclass=Meta1):
842 pass
843 class Class2(Class1, metaclass=Meta3):
844 pass
845
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700846 should_find1 = inspect.Attribute('one', 'data', Meta1, 1)
847 should_find2 = inspect.Attribute('two', 'data', Meta2, 2)
848 should_find3 = inspect.Attribute('three', 'data', Meta3, 3)
Ethan Furman63c141c2013-10-18 00:27:39 -0700849 cca = inspect.classify_class_attrs(Class2)
850 for sf in (should_find1, should_find2, should_find3):
851 self.assertIn(sf, cca)
852
853 def test_classify_class_attrs_with_buggy_dir(self):
854 class M(type):
855 def __dir__(cls):
856 return ['__class__', '__name__', 'missing']
857 class C(metaclass=M):
858 pass
859 attrs = [a[0] for a in inspect.classify_class_attrs(C)]
860 self.assertNotIn('missing', attrs)
Ethan Furmane03ea372013-09-25 07:14:41 -0700861
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100862 def test_getmembers_descriptors(self):
863 class A(object):
864 dd = _BrokenDataDescriptor()
865 md = _BrokenMethodDescriptor()
866
867 def pred_wrapper(pred):
868 # A quick'n'dirty way to discard standard attributes of new-style
869 # classes.
870 class Empty(object):
871 pass
872 def wrapped(x):
873 if '__name__' in dir(x) and hasattr(Empty, x.__name__):
874 return False
875 return pred(x)
876 return wrapped
877
878 ismethoddescriptor = pred_wrapper(inspect.ismethoddescriptor)
879 isdatadescriptor = pred_wrapper(inspect.isdatadescriptor)
880
881 self.assertEqual(inspect.getmembers(A, ismethoddescriptor),
882 [('md', A.__dict__['md'])])
883 self.assertEqual(inspect.getmembers(A, isdatadescriptor),
884 [('dd', A.__dict__['dd'])])
885
886 class B(A):
887 pass
888
889 self.assertEqual(inspect.getmembers(B, ismethoddescriptor),
890 [('md', A.__dict__['md'])])
891 self.assertEqual(inspect.getmembers(B, isdatadescriptor),
892 [('dd', A.__dict__['dd'])])
893
Antoine Pitrou0c603812012-01-18 17:40:18 +0100894 def test_getmembers_method(self):
895 class B:
896 def f(self):
897 pass
898
899 self.assertIn(('f', B.f), inspect.getmembers(B))
900 self.assertNotIn(('f', B.f), inspect.getmembers(B, inspect.ismethod))
901 b = B()
902 self.assertIn(('f', b.f), inspect.getmembers(b))
903 self.assertIn(('f', b.f), inspect.getmembers(b, inspect.ismethod))
904
Ethan Furmane03ea372013-09-25 07:14:41 -0700905 def test_getmembers_VirtualAttribute(self):
Ethan Furman63c141c2013-10-18 00:27:39 -0700906 class M(type):
907 def __getattr__(cls, name):
908 if name == 'eggs':
909 return 'scrambled'
910 return super().__getattr__(name)
911 class A(metaclass=M):
Ethan Furmane03ea372013-09-25 07:14:41 -0700912 @types.DynamicClassAttribute
913 def eggs(self):
914 return 'spam'
Ethan Furman63c141c2013-10-18 00:27:39 -0700915 self.assertIn(('eggs', 'scrambled'), inspect.getmembers(A))
916 self.assertIn(('eggs', 'spam'), inspect.getmembers(A()))
917
918 def test_getmembers_with_buggy_dir(self):
919 class M(type):
920 def __dir__(cls):
921 return ['__class__', '__name__', 'missing']
922 class C(metaclass=M):
923 pass
924 attrs = [a[0] for a in inspect.getmembers(C)]
925 self.assertNotIn('missing', attrs)
Ethan Furmane03ea372013-09-25 07:14:41 -0700926
Jeremy Hyltonc4bf5ed2003-06-27 18:43:12 +0000927
Nick Coghlan2f92e542012-06-23 19:39:55 +1000928_global_ref = object()
929class TestGetClosureVars(unittest.TestCase):
930
931 def test_name_resolution(self):
932 # Basic test of the 4 different resolution mechanisms
933 def f(nonlocal_ref):
934 def g(local_ref):
935 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
936 return g
937 _arg = object()
938 nonlocal_vars = {"nonlocal_ref": _arg}
939 global_vars = {"_global_ref": _global_ref}
940 builtin_vars = {"print": print}
941 unbound_names = {"unbound_ref"}
942 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
943 builtin_vars, unbound_names)
944 self.assertEqual(inspect.getclosurevars(f(_arg)), expected)
945
946 def test_generator_closure(self):
947 def f(nonlocal_ref):
948 def g(local_ref):
949 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
950 yield
951 return g
952 _arg = object()
953 nonlocal_vars = {"nonlocal_ref": _arg}
954 global_vars = {"_global_ref": _global_ref}
955 builtin_vars = {"print": print}
956 unbound_names = {"unbound_ref"}
957 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
958 builtin_vars, unbound_names)
959 self.assertEqual(inspect.getclosurevars(f(_arg)), expected)
960
961 def test_method_closure(self):
962 class C:
963 def f(self, nonlocal_ref):
964 def g(local_ref):
965 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
966 return g
967 _arg = object()
968 nonlocal_vars = {"nonlocal_ref": _arg}
969 global_vars = {"_global_ref": _global_ref}
970 builtin_vars = {"print": print}
971 unbound_names = {"unbound_ref"}
972 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
973 builtin_vars, unbound_names)
974 self.assertEqual(inspect.getclosurevars(C().f(_arg)), expected)
975
976 def test_nonlocal_vars(self):
977 # More complex tests of nonlocal resolution
978 def _nonlocal_vars(f):
979 return inspect.getclosurevars(f).nonlocals
980
981 def make_adder(x):
982 def add(y):
983 return x + y
984 return add
985
986 def curry(func, arg1):
987 return lambda arg2: func(arg1, arg2)
988
989 def less_than(a, b):
990 return a < b
991
992 # The infamous Y combinator.
993 def Y(le):
994 def g(f):
995 return le(lambda x: f(f)(x))
996 Y.g_ref = g
997 return g(g)
998
999 def check_y_combinator(func):
1000 self.assertEqual(_nonlocal_vars(func), {'f': Y.g_ref})
1001
1002 inc = make_adder(1)
1003 add_two = make_adder(2)
1004 greater_than_five = curry(less_than, 5)
1005
1006 self.assertEqual(_nonlocal_vars(inc), {'x': 1})
1007 self.assertEqual(_nonlocal_vars(add_two), {'x': 2})
1008 self.assertEqual(_nonlocal_vars(greater_than_five),
1009 {'arg1': 5, 'func': less_than})
1010 self.assertEqual(_nonlocal_vars((lambda x: lambda y: x + y)(3)),
1011 {'x': 3})
1012 Y(check_y_combinator)
1013
1014 def test_getclosurevars_empty(self):
1015 def foo(): pass
1016 _empty = inspect.ClosureVars({}, {}, {}, set())
1017 self.assertEqual(inspect.getclosurevars(lambda: True), _empty)
1018 self.assertEqual(inspect.getclosurevars(foo), _empty)
1019
1020 def test_getclosurevars_error(self):
1021 class T: pass
1022 self.assertRaises(TypeError, inspect.getclosurevars, 1)
1023 self.assertRaises(TypeError, inspect.getclosurevars, list)
1024 self.assertRaises(TypeError, inspect.getclosurevars, {})
1025
Nick Coghlan6c6e2542012-06-23 20:07:39 +10001026 def _private_globals(self):
1027 code = """def f(): print(path)"""
1028 ns = {}
1029 exec(code, ns)
1030 return ns["f"], ns
1031
1032 def test_builtins_fallback(self):
1033 f, ns = self._private_globals()
1034 ns.pop("__builtins__", None)
1035 expected = inspect.ClosureVars({}, {}, {"print":print}, {"path"})
1036 self.assertEqual(inspect.getclosurevars(f), expected)
1037
1038 def test_builtins_as_dict(self):
1039 f, ns = self._private_globals()
1040 ns["__builtins__"] = {"path":1}
1041 expected = inspect.ClosureVars({}, {}, {"path":1}, {"print"})
1042 self.assertEqual(inspect.getclosurevars(f), expected)
1043
1044 def test_builtins_as_module(self):
1045 f, ns = self._private_globals()
1046 ns["__builtins__"] = os
1047 expected = inspect.ClosureVars({}, {}, {"path":os.path}, {"print"})
1048 self.assertEqual(inspect.getclosurevars(f), expected)
1049
Nick Coghlan2f92e542012-06-23 19:39:55 +10001050
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001051class TestGetcallargsFunctions(unittest.TestCase):
1052
1053 def assertEqualCallArgs(self, func, call_params_string, locs=None):
1054 locs = dict(locs or {}, func=func)
1055 r1 = eval('func(%s)' % call_params_string, None, locs)
1056 r2 = eval('inspect.getcallargs(func, %s)' % call_params_string, None,
1057 locs)
1058 self.assertEqual(r1, r2)
1059
1060 def assertEqualException(self, func, call_param_string, locs=None):
1061 locs = dict(locs or {}, func=func)
1062 try:
1063 eval('func(%s)' % call_param_string, None, locs)
1064 except Exception as e:
1065 ex1 = e
1066 else:
1067 self.fail('Exception not raised')
1068 try:
1069 eval('inspect.getcallargs(func, %s)' % call_param_string, None,
1070 locs)
1071 except Exception as e:
1072 ex2 = e
1073 else:
1074 self.fail('Exception not raised')
1075 self.assertIs(type(ex1), type(ex2))
1076 self.assertEqual(str(ex1), str(ex2))
1077 del ex1, ex2
1078
1079 def makeCallable(self, signature):
1080 """Create a function that returns its locals()"""
1081 code = "lambda %s: locals()"
1082 return eval(code % signature)
1083
1084 def test_plain(self):
1085 f = self.makeCallable('a, b=1')
1086 self.assertEqualCallArgs(f, '2')
1087 self.assertEqualCallArgs(f, '2, 3')
1088 self.assertEqualCallArgs(f, 'a=2')
1089 self.assertEqualCallArgs(f, 'b=3, a=2')
1090 self.assertEqualCallArgs(f, '2, b=3')
1091 # expand *iterable / **mapping
1092 self.assertEqualCallArgs(f, '*(2,)')
1093 self.assertEqualCallArgs(f, '*[2]')
1094 self.assertEqualCallArgs(f, '*(2, 3)')
1095 self.assertEqualCallArgs(f, '*[2, 3]')
1096 self.assertEqualCallArgs(f, '**{"a":2}')
1097 self.assertEqualCallArgs(f, 'b=3, **{"a":2}')
1098 self.assertEqualCallArgs(f, '2, **{"b":3}')
1099 self.assertEqualCallArgs(f, '**{"b":3, "a":2}')
1100 # expand UserList / UserDict
1101 self.assertEqualCallArgs(f, '*collections.UserList([2])')
1102 self.assertEqualCallArgs(f, '*collections.UserList([2, 3])')
1103 self.assertEqualCallArgs(f, '**collections.UserDict(a=2)')
1104 self.assertEqualCallArgs(f, '2, **collections.UserDict(b=3)')
1105 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3)')
1106
1107 def test_varargs(self):
1108 f = self.makeCallable('a, b=1, *c')
1109 self.assertEqualCallArgs(f, '2')
1110 self.assertEqualCallArgs(f, '2, 3')
1111 self.assertEqualCallArgs(f, '2, 3, 4')
1112 self.assertEqualCallArgs(f, '*(2,3,4)')
1113 self.assertEqualCallArgs(f, '2, *[3,4]')
1114 self.assertEqualCallArgs(f, '2, 3, *collections.UserList([4])')
1115
1116 def test_varkw(self):
1117 f = self.makeCallable('a, b=1, **c')
1118 self.assertEqualCallArgs(f, 'a=2')
1119 self.assertEqualCallArgs(f, '2, b=3, c=4')
1120 self.assertEqualCallArgs(f, 'b=3, a=2, c=4')
1121 self.assertEqualCallArgs(f, 'c=4, **{"a":2, "b":3}')
1122 self.assertEqualCallArgs(f, '2, c=4, **{"b":3}')
1123 self.assertEqualCallArgs(f, 'b=2, **{"a":3, "c":4}')
1124 self.assertEqualCallArgs(f, '**collections.UserDict(a=2, b=3, c=4)')
1125 self.assertEqualCallArgs(f, '2, c=4, **collections.UserDict(b=3)')
1126 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3, c=4)')
1127
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001128 def test_varkw_only(self):
1129 # issue11256:
1130 f = self.makeCallable('**c')
1131 self.assertEqualCallArgs(f, '')
1132 self.assertEqualCallArgs(f, 'a=1')
1133 self.assertEqualCallArgs(f, 'a=1, b=2')
1134 self.assertEqualCallArgs(f, 'c=3, **{"a": 1, "b": 2}')
1135 self.assertEqualCallArgs(f, '**collections.UserDict(a=1, b=2)')
1136 self.assertEqualCallArgs(f, 'c=3, **collections.UserDict(a=1, b=2)')
1137
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001138 def test_keyword_only(self):
1139 f = self.makeCallable('a=3, *, c, d=2')
1140 self.assertEqualCallArgs(f, 'c=3')
1141 self.assertEqualCallArgs(f, 'c=3, a=3')
1142 self.assertEqualCallArgs(f, 'a=2, c=4')
1143 self.assertEqualCallArgs(f, '4, c=4')
1144 self.assertEqualException(f, '')
1145 self.assertEqualException(f, '3')
1146 self.assertEqualException(f, 'a=3')
1147 self.assertEqualException(f, 'd=4')
1148
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001149 f = self.makeCallable('*, c, d=2')
1150 self.assertEqualCallArgs(f, 'c=3')
1151 self.assertEqualCallArgs(f, 'c=3, d=4')
1152 self.assertEqualCallArgs(f, 'd=4, c=3')
1153
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001154 def test_multiple_features(self):
1155 f = self.makeCallable('a, b=2, *f, **g')
1156 self.assertEqualCallArgs(f, '2, 3, 7')
1157 self.assertEqualCallArgs(f, '2, 3, x=8')
1158 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
1159 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9')
1160 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9')
1161 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
1162 '[2, 3, (4,[5,6])]), **{"y":9, "z":10}')
1163 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
1164 '(4,[5,6])]), **collections.UserDict('
1165 'y=9, z=10)')
1166
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001167 f = self.makeCallable('a, b=2, *f, x, y=99, **g')
1168 self.assertEqualCallArgs(f, '2, 3, x=8')
1169 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
1170 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9, z=10')
1171 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9, z=10')
1172 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
1173 '[2, 3, (4,[5,6])]), q=0, **{"y":9, "z":10}')
1174 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
1175 '(4,[5,6])]), q=0, **collections.UserDict('
1176 'y=9, z=10)')
1177
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001178 def test_errors(self):
1179 f0 = self.makeCallable('')
1180 f1 = self.makeCallable('a, b')
1181 f2 = self.makeCallable('a, b=1')
1182 # f0 takes no arguments
1183 self.assertEqualException(f0, '1')
1184 self.assertEqualException(f0, 'x=1')
1185 self.assertEqualException(f0, '1,x=1')
1186 # f1 takes exactly 2 arguments
1187 self.assertEqualException(f1, '')
1188 self.assertEqualException(f1, '1')
1189 self.assertEqualException(f1, 'a=2')
1190 self.assertEqualException(f1, 'b=3')
1191 # f2 takes at least 1 argument
1192 self.assertEqualException(f2, '')
1193 self.assertEqualException(f2, 'b=3')
1194 for f in f1, f2:
1195 # f1/f2 takes exactly/at most 2 arguments
1196 self.assertEqualException(f, '2, 3, 4')
1197 self.assertEqualException(f, '1, 2, 3, a=1')
1198 self.assertEqualException(f, '2, 3, 4, c=5')
Georg Brandl178e5ea2012-02-21 00:32:36 +01001199 # XXX: success of this one depends on dict order
1200 ## self.assertEqualException(f, '2, 3, 4, a=1, c=5')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001201 # f got an unexpected keyword argument
1202 self.assertEqualException(f, 'c=2')
1203 self.assertEqualException(f, '2, c=3')
1204 self.assertEqualException(f, '2, 3, c=4')
1205 self.assertEqualException(f, '2, c=4, b=3')
1206 self.assertEqualException(f, '**{u"\u03c0\u03b9": 4}')
1207 # f got multiple values for keyword argument
1208 self.assertEqualException(f, '1, a=2')
1209 self.assertEqualException(f, '1, **{"a":2}')
1210 self.assertEqualException(f, '1, 2, b=3')
1211 # XXX: Python inconsistency
1212 # - for functions and bound methods: unexpected keyword 'c'
1213 # - for unbound methods: multiple values for keyword 'a'
1214 #self.assertEqualException(f, '1, c=3, a=2')
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001215 # issue11256:
1216 f3 = self.makeCallable('**c')
1217 self.assertEqualException(f3, '1, 2')
1218 self.assertEqualException(f3, '1, 2, a=1, b=2')
1219 f4 = self.makeCallable('*, a, b=0')
1220 self.assertEqualException(f3, '1, 2')
1221 self.assertEqualException(f3, '1, 2, a=1, b=2')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001222
Yury Selivanov875df202014-03-27 18:23:03 -04001223 # issue #20816: getcallargs() fails to iterate over non-existent
1224 # kwonlydefaults and raises a wrong TypeError
1225 def f5(*, a): pass
1226 with self.assertRaisesRegex(TypeError,
1227 'missing 1 required keyword-only'):
1228 inspect.getcallargs(f5)
1229
1230
Yury Selivanovdccfa132014-03-27 18:42:52 -04001231 # issue20817:
1232 def f6(a, b, c):
1233 pass
1234 with self.assertRaisesRegex(TypeError, "'a', 'b' and 'c'"):
1235 inspect.getcallargs(f6)
1236
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001237class TestGetcallargsMethods(TestGetcallargsFunctions):
1238
1239 def setUp(self):
1240 class Foo(object):
1241 pass
1242 self.cls = Foo
1243 self.inst = Foo()
1244
1245 def makeCallable(self, signature):
1246 assert 'self' not in signature
1247 mk = super(TestGetcallargsMethods, self).makeCallable
1248 self.cls.method = mk('self, ' + signature)
1249 return self.inst.method
1250
1251class TestGetcallargsUnboundMethods(TestGetcallargsMethods):
1252
1253 def makeCallable(self, signature):
1254 super(TestGetcallargsUnboundMethods, self).makeCallable(signature)
1255 return self.cls.method
1256
1257 def assertEqualCallArgs(self, func, call_params_string, locs=None):
1258 return super(TestGetcallargsUnboundMethods, self).assertEqualCallArgs(
1259 *self._getAssertEqualParams(func, call_params_string, locs))
1260
1261 def assertEqualException(self, func, call_params_string, locs=None):
1262 return super(TestGetcallargsUnboundMethods, self).assertEqualException(
1263 *self._getAssertEqualParams(func, call_params_string, locs))
1264
1265 def _getAssertEqualParams(self, func, call_params_string, locs=None):
1266 assert 'inst' not in call_params_string
1267 locs = dict(locs or {}, inst=self.inst)
1268 return (func, 'inst,' + call_params_string, locs)
1269
Michael Foord95fc51d2010-11-20 15:07:30 +00001270
1271class TestGetattrStatic(unittest.TestCase):
1272
1273 def test_basic(self):
1274 class Thing(object):
1275 x = object()
1276
1277 thing = Thing()
1278 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1279 self.assertEqual(inspect.getattr_static(thing, 'x', None), Thing.x)
1280 with self.assertRaises(AttributeError):
1281 inspect.getattr_static(thing, 'y')
1282
1283 self.assertEqual(inspect.getattr_static(thing, 'y', 3), 3)
1284
1285 def test_inherited(self):
1286 class Thing(object):
1287 x = object()
1288 class OtherThing(Thing):
1289 pass
1290
1291 something = OtherThing()
1292 self.assertEqual(inspect.getattr_static(something, 'x'), Thing.x)
1293
1294 def test_instance_attr(self):
1295 class Thing(object):
1296 x = 2
1297 def __init__(self, x):
1298 self.x = x
1299 thing = Thing(3)
1300 self.assertEqual(inspect.getattr_static(thing, 'x'), 3)
1301 del thing.x
1302 self.assertEqual(inspect.getattr_static(thing, 'x'), 2)
1303
1304 def test_property(self):
1305 class Thing(object):
1306 @property
1307 def x(self):
1308 raise AttributeError("I'm pretending not to exist")
1309 thing = Thing()
1310 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1311
Ezio Melotti75cbd732011-04-28 00:59:29 +03001312 def test_descriptor_raises_AttributeError(self):
Michael Foord95fc51d2010-11-20 15:07:30 +00001313 class descriptor(object):
1314 def __get__(*_):
1315 raise AttributeError("I'm pretending not to exist")
1316 desc = descriptor()
1317 class Thing(object):
1318 x = desc
1319 thing = Thing()
1320 self.assertEqual(inspect.getattr_static(thing, 'x'), desc)
1321
1322 def test_classAttribute(self):
1323 class Thing(object):
1324 x = object()
1325
1326 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.x)
1327
Ethan Furmane03ea372013-09-25 07:14:41 -07001328 def test_classVirtualAttribute(self):
1329 class Thing(object):
1330 @types.DynamicClassAttribute
1331 def x(self):
1332 return self._x
1333 _x = object()
1334
1335 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.__dict__['x'])
1336
Michael Foord95fc51d2010-11-20 15:07:30 +00001337 def test_inherited_classattribute(self):
1338 class Thing(object):
1339 x = object()
1340 class OtherThing(Thing):
1341 pass
1342
1343 self.assertEqual(inspect.getattr_static(OtherThing, 'x'), Thing.x)
1344
1345 def test_slots(self):
1346 class Thing(object):
1347 y = 'bar'
1348 __slots__ = ['x']
1349 def __init__(self):
1350 self.x = 'foo'
1351 thing = Thing()
1352 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1353 self.assertEqual(inspect.getattr_static(thing, 'y'), 'bar')
1354
1355 del thing.x
1356 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1357
1358 def test_metaclass(self):
1359 class meta(type):
1360 attr = 'foo'
1361 class Thing(object, metaclass=meta):
1362 pass
1363 self.assertEqual(inspect.getattr_static(Thing, 'attr'), 'foo')
1364
1365 class sub(meta):
1366 pass
1367 class OtherThing(object, metaclass=sub):
1368 x = 3
1369 self.assertEqual(inspect.getattr_static(OtherThing, 'attr'), 'foo')
1370
1371 class OtherOtherThing(OtherThing):
1372 pass
1373 # this test is odd, but it was added as it exposed a bug
1374 self.assertEqual(inspect.getattr_static(OtherOtherThing, 'x'), 3)
1375
1376 def test_no_dict_no_slots(self):
1377 self.assertEqual(inspect.getattr_static(1, 'foo', None), None)
1378 self.assertNotEqual(inspect.getattr_static('foo', 'lower'), None)
1379
1380 def test_no_dict_no_slots_instance_member(self):
1381 # returns descriptor
1382 with open(__file__) as handle:
1383 self.assertEqual(inspect.getattr_static(handle, 'name'), type(handle).name)
1384
1385 def test_inherited_slots(self):
1386 # returns descriptor
1387 class Thing(object):
1388 __slots__ = ['x']
1389 def __init__(self):
1390 self.x = 'foo'
1391
1392 class OtherThing(Thing):
1393 pass
1394 # it would be nice if this worked...
1395 # we get the descriptor instead of the instance attribute
1396 self.assertEqual(inspect.getattr_static(OtherThing(), 'x'), Thing.x)
1397
1398 def test_descriptor(self):
1399 class descriptor(object):
1400 def __get__(self, instance, owner):
1401 return 3
1402 class Foo(object):
1403 d = descriptor()
1404
1405 foo = Foo()
1406
1407 # for a non data descriptor we return the instance attribute
1408 foo.__dict__['d'] = 1
1409 self.assertEqual(inspect.getattr_static(foo, 'd'), 1)
1410
1411 # if the descriptor is a data-desciptor we should return the
1412 # descriptor
1413 descriptor.__set__ = lambda s, i, v: None
1414 self.assertEqual(inspect.getattr_static(foo, 'd'), Foo.__dict__['d'])
1415
1416
1417 def test_metaclass_with_descriptor(self):
1418 class descriptor(object):
1419 def __get__(self, instance, owner):
1420 return 3
1421 class meta(type):
1422 d = descriptor()
1423 class Thing(object, metaclass=meta):
1424 pass
1425 self.assertEqual(inspect.getattr_static(Thing, 'd'), meta.__dict__['d'])
1426
1427
Michael Foordcc7ebb82010-11-20 16:20:16 +00001428 def test_class_as_property(self):
1429 class Base(object):
1430 foo = 3
1431
1432 class Something(Base):
Michael Foord35184ed2010-11-20 16:58:30 +00001433 executed = False
Michael Foordcc7ebb82010-11-20 16:20:16 +00001434 @property
1435 def __class__(self):
Michael Foord35184ed2010-11-20 16:58:30 +00001436 self.executed = True
Michael Foordcc7ebb82010-11-20 16:20:16 +00001437 return object
1438
Michael Foord35184ed2010-11-20 16:58:30 +00001439 instance = Something()
1440 self.assertEqual(inspect.getattr_static(instance, 'foo'), 3)
1441 self.assertFalse(instance.executed)
Michael Foordcc7ebb82010-11-20 16:20:16 +00001442 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1443
Michael Foorde5162652010-11-20 16:40:44 +00001444 def test_mro_as_property(self):
1445 class Meta(type):
1446 @property
1447 def __mro__(self):
1448 return (object,)
1449
1450 class Base(object):
1451 foo = 3
1452
1453 class Something(Base, metaclass=Meta):
1454 pass
1455
1456 self.assertEqual(inspect.getattr_static(Something(), 'foo'), 3)
1457 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1458
Michael Foorddcebe0f2011-03-15 19:20:44 -04001459 def test_dict_as_property(self):
1460 test = self
1461 test.called = False
1462
1463 class Foo(dict):
1464 a = 3
1465 @property
1466 def __dict__(self):
1467 test.called = True
1468 return {}
1469
1470 foo = Foo()
1471 foo.a = 4
1472 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1473 self.assertFalse(test.called)
1474
1475 def test_custom_object_dict(self):
1476 test = self
1477 test.called = False
1478
1479 class Custom(dict):
1480 def get(self, key, default=None):
1481 test.called = True
1482 super().get(key, default)
1483
1484 class Foo(object):
1485 a = 3
1486 foo = Foo()
1487 foo.__dict__ = Custom()
1488 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1489 self.assertFalse(test.called)
1490
1491 def test_metaclass_dict_as_property(self):
1492 class Meta(type):
1493 @property
1494 def __dict__(self):
1495 self.executed = True
1496
1497 class Thing(metaclass=Meta):
1498 executed = False
1499
1500 def __init__(self):
1501 self.spam = 42
1502
1503 instance = Thing()
1504 self.assertEqual(inspect.getattr_static(instance, "spam"), 42)
1505 self.assertFalse(Thing.executed)
Michael Foorde5162652010-11-20 16:40:44 +00001506
Michael Foorda51623b2011-12-18 22:01:40 +00001507 def test_module(self):
1508 sentinel = object()
1509 self.assertIsNot(inspect.getattr_static(sys, "version", sentinel),
1510 sentinel)
1511
Michael Foord3ba95f82011-12-22 01:13:37 +00001512 def test_metaclass_with_metaclass_with_dict_as_property(self):
1513 class MetaMeta(type):
1514 @property
1515 def __dict__(self):
1516 self.executed = True
1517 return dict(spam=42)
1518
1519 class Meta(type, metaclass=MetaMeta):
1520 executed = False
1521
1522 class Thing(metaclass=Meta):
1523 pass
1524
1525 with self.assertRaises(AttributeError):
1526 inspect.getattr_static(Thing, "spam")
1527 self.assertFalse(Thing.executed)
1528
Nick Coghlane0f04652010-11-21 03:44:04 +00001529class TestGetGeneratorState(unittest.TestCase):
1530
1531 def setUp(self):
1532 def number_generator():
1533 for number in range(5):
1534 yield number
1535 self.generator = number_generator()
1536
1537 def _generatorstate(self):
1538 return inspect.getgeneratorstate(self.generator)
1539
1540 def test_created(self):
1541 self.assertEqual(self._generatorstate(), inspect.GEN_CREATED)
1542
1543 def test_suspended(self):
1544 next(self.generator)
1545 self.assertEqual(self._generatorstate(), inspect.GEN_SUSPENDED)
1546
1547 def test_closed_after_exhaustion(self):
1548 for i in self.generator:
1549 pass
1550 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1551
1552 def test_closed_after_immediate_exception(self):
1553 with self.assertRaises(RuntimeError):
1554 self.generator.throw(RuntimeError)
1555 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1556
1557 def test_running(self):
1558 # As mentioned on issue #10220, checking for the RUNNING state only
1559 # makes sense inside the generator itself.
1560 # The following generator checks for this by using the closure's
1561 # reference to self and the generator state checking helper method
1562 def running_check_generator():
1563 for number in range(5):
1564 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1565 yield number
1566 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1567 self.generator = running_check_generator()
1568 # Running up to the first yield
1569 next(self.generator)
1570 # Running after the first yield
1571 next(self.generator)
1572
Nick Coghlan7921b9f2010-11-30 06:36:04 +00001573 def test_easy_debugging(self):
1574 # repr() and str() of a generator state should contain the state name
1575 names = 'GEN_CREATED GEN_RUNNING GEN_SUSPENDED GEN_CLOSED'.split()
1576 for name in names:
1577 state = getattr(inspect, name)
1578 self.assertIn(name, repr(state))
1579 self.assertIn(name, str(state))
1580
Nick Coghlan04e2e3f2012-06-23 19:52:05 +10001581 def test_getgeneratorlocals(self):
1582 def each(lst, a=None):
1583 b=(1, 2, 3)
1584 for v in lst:
1585 if v == 3:
1586 c = 12
1587 yield v
1588
1589 numbers = each([1, 2, 3])
1590 self.assertEqual(inspect.getgeneratorlocals(numbers),
1591 {'a': None, 'lst': [1, 2, 3]})
1592 next(numbers)
1593 self.assertEqual(inspect.getgeneratorlocals(numbers),
1594 {'a': None, 'lst': [1, 2, 3], 'v': 1,
1595 'b': (1, 2, 3)})
1596 next(numbers)
1597 self.assertEqual(inspect.getgeneratorlocals(numbers),
1598 {'a': None, 'lst': [1, 2, 3], 'v': 2,
1599 'b': (1, 2, 3)})
1600 next(numbers)
1601 self.assertEqual(inspect.getgeneratorlocals(numbers),
1602 {'a': None, 'lst': [1, 2, 3], 'v': 3,
1603 'b': (1, 2, 3), 'c': 12})
1604 try:
1605 next(numbers)
1606 except StopIteration:
1607 pass
1608 self.assertEqual(inspect.getgeneratorlocals(numbers), {})
1609
1610 def test_getgeneratorlocals_empty(self):
1611 def yield_one():
1612 yield 1
1613 one = yield_one()
1614 self.assertEqual(inspect.getgeneratorlocals(one), {})
1615 try:
1616 next(one)
1617 except StopIteration:
1618 pass
1619 self.assertEqual(inspect.getgeneratorlocals(one), {})
1620
1621 def test_getgeneratorlocals_error(self):
1622 self.assertRaises(TypeError, inspect.getgeneratorlocals, 1)
1623 self.assertRaises(TypeError, inspect.getgeneratorlocals, lambda x: True)
1624 self.assertRaises(TypeError, inspect.getgeneratorlocals, set)
1625 self.assertRaises(TypeError, inspect.getgeneratorlocals, (2,3))
1626
Nick Coghlane0f04652010-11-21 03:44:04 +00001627
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001628class MySignature(inspect.Signature):
1629 # Top-level to make it picklable;
1630 # used in test_signature_object_pickle
1631 pass
1632
1633class MyParameter(inspect.Parameter):
1634 # Top-level to make it picklable;
1635 # used in test_signature_object_pickle
1636 pass
1637
Nick Coghlanf9e227e2014-08-17 14:01:19 +10001638 @cpython_only
1639 @unittest.skipIf(MISSING_C_DOCSTRINGS,
1640 "Signature information for builtins requires docstrings")
1641 def test_builtins_have_signatures(self):
1642 # This checks all builtin callables in CPython have signatures
1643 # A few have signatures Signature can't yet handle, so we skip those
1644 # since they will have to wait until PEP 457 adds the required
1645 # introspection support to the inspect module
1646 # Some others also haven't been converted yet for various other
1647 # reasons, so we also skip those for the time being, but design
1648 # the test to fail in order to indicate when it needs to be
1649 # updated.
1650 no_signature = set()
1651 # These need PEP 457 groups
1652 needs_groups = ["range", "slice", "dir", "getattr",
1653 "next", "iter", "vars"]
1654 no_signature |= needs_groups
1655 # These need PEP 457 groups or a signature change to accept None
1656 needs_semantic_update = ["round"]
1657 no_signature |= needs_semantic_update
1658 # These need *args support in Argument Clinic
1659 needs_varargs = ["min", "max", "print", "__build_class__"]
1660 no_signature |= needs_varargs
1661 # These simply weren't covered in the initial AC conversion
1662 # for builtin callables
1663 not_converted_yet = ["open", "__import__"]
1664 no_signature |= not_converted_yet
1665 # These builtin types are expected to provide introspection info
1666 types_with_signatures = set()
1667 # Check the signatures we expect to be there
1668 ns = vars(builtins)
1669 for name, obj in sorted(ns.items()):
1670 if not callable(obj):
1671 continue
1672 # The builtin types haven't been converted to AC yet
1673 if isinstance(obj, type) and (name not in types_with_signatures):
1674 # Note that this also skips all the exception types
1675 no_signature.append(name)
1676 if (name in no_signature):
1677 # Not yet converted
1678 continue
1679 with self.subTest(builtin=name):
1680 self.assertIsNotNone(inspect.signature(obj))
1681 # Check callables that haven't been converted don't claim a signature
1682 # This ensures this test will start failing as more signatures are
1683 # added, so the affected items can be moved into the scope of the
1684 # regression test above
1685 for name in no_signature:
1686 with self.subTest(builtin=name):
1687 self.assertIsNone(ns[name].__text_signature__)
1688
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001689
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001690class TestSignatureObject(unittest.TestCase):
1691 @staticmethod
1692 def signature(func):
1693 sig = inspect.signature(func)
1694 return (tuple((param.name,
1695 (... if param.default is param.empty else param.default),
1696 (... if param.annotation is param.empty
1697 else param.annotation),
1698 str(param.kind).lower())
1699 for param in sig.parameters.values()),
1700 (... if sig.return_annotation is sig.empty
1701 else sig.return_annotation))
1702
1703 def test_signature_object(self):
1704 S = inspect.Signature
1705 P = inspect.Parameter
1706
1707 self.assertEqual(str(S()), '()')
1708
Yury Selivanov07a9e452014-01-29 10:58:16 -05001709 def test(po, pk, pod=42, pkd=100, *args, ko, **kwargs):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001710 pass
1711 sig = inspect.signature(test)
1712 po = sig.parameters['po'].replace(kind=P.POSITIONAL_ONLY)
Yury Selivanov07a9e452014-01-29 10:58:16 -05001713 pod = sig.parameters['pod'].replace(kind=P.POSITIONAL_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001714 pk = sig.parameters['pk']
Yury Selivanov07a9e452014-01-29 10:58:16 -05001715 pkd = sig.parameters['pkd']
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001716 args = sig.parameters['args']
1717 ko = sig.parameters['ko']
1718 kwargs = sig.parameters['kwargs']
1719
1720 S((po, pk, args, ko, kwargs))
1721
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001722 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001723 S((pk, po, args, ko, kwargs))
1724
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001725 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001726 S((po, args, pk, ko, kwargs))
1727
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001728 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001729 S((args, po, pk, ko, kwargs))
1730
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001731 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001732 S((po, pk, args, kwargs, ko))
1733
1734 kwargs2 = kwargs.replace(name='args')
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001735 with self.assertRaisesRegex(ValueError, 'duplicate parameter name'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001736 S((po, pk, args, kwargs2, ko))
1737
Yury Selivanov07a9e452014-01-29 10:58:16 -05001738 with self.assertRaisesRegex(ValueError, 'follows default argument'):
1739 S((pod, po))
1740
1741 with self.assertRaisesRegex(ValueError, 'follows default argument'):
1742 S((po, pkd, pk))
1743
1744 with self.assertRaisesRegex(ValueError, 'follows default argument'):
1745 S((pkd, pk))
1746
Yury Selivanov374375d2014-03-27 12:41:53 -04001747 self.assertTrue(repr(sig).startswith('<Signature'))
1748 self.assertTrue('"(po, pk' in repr(sig))
1749
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001750 def test_signature_object_pickle(self):
1751 def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
1752 foo_partial = functools.partial(foo, a=1)
1753
1754 sig = inspect.signature(foo_partial)
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001755
1756 for ver in range(pickle.HIGHEST_PROTOCOL + 1):
1757 with self.subTest(pickle_ver=ver, subclass=False):
1758 sig_pickled = pickle.loads(pickle.dumps(sig, ver))
1759 self.assertEqual(sig, sig_pickled)
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001760
1761 # Test that basic sub-classing works
1762 sig = inspect.signature(foo)
1763 myparam = MyParameter(name='z', kind=inspect.Parameter.POSITIONAL_ONLY)
1764 myparams = collections.OrderedDict(sig.parameters, a=myparam)
1765 mysig = MySignature().replace(parameters=myparams.values(),
1766 return_annotation=sig.return_annotation)
1767 self.assertTrue(isinstance(mysig, MySignature))
1768 self.assertTrue(isinstance(mysig.parameters['z'], MyParameter))
1769
1770 for ver in range(pickle.HIGHEST_PROTOCOL + 1):
1771 with self.subTest(pickle_ver=ver, subclass=True):
1772 sig_pickled = pickle.loads(pickle.dumps(mysig, ver))
1773 self.assertEqual(mysig, sig_pickled)
1774 self.assertTrue(isinstance(sig_pickled, MySignature))
1775 self.assertTrue(isinstance(sig_pickled.parameters['z'],
1776 MyParameter))
1777
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001778 def test_signature_immutability(self):
1779 def test(a):
1780 pass
1781 sig = inspect.signature(test)
1782
1783 with self.assertRaises(AttributeError):
1784 sig.foo = 'bar'
1785
1786 with self.assertRaises(TypeError):
1787 sig.parameters['a'] = None
1788
1789 def test_signature_on_noarg(self):
1790 def test():
1791 pass
1792 self.assertEqual(self.signature(test), ((), ...))
1793
1794 def test_signature_on_wargs(self):
1795 def test(a, b:'foo') -> 123:
1796 pass
1797 self.assertEqual(self.signature(test),
1798 ((('a', ..., ..., "positional_or_keyword"),
1799 ('b', ..., 'foo', "positional_or_keyword")),
1800 123))
1801
1802 def test_signature_on_wkwonly(self):
1803 def test(*, a:float, b:str) -> int:
1804 pass
1805 self.assertEqual(self.signature(test),
1806 ((('a', ..., float, "keyword_only"),
1807 ('b', ..., str, "keyword_only")),
1808 int))
1809
1810 def test_signature_on_complex_args(self):
1811 def test(a, b:'foo'=10, *args:'bar', spam:'baz', ham=123, **kwargs:int):
1812 pass
1813 self.assertEqual(self.signature(test),
1814 ((('a', ..., ..., "positional_or_keyword"),
1815 ('b', 10, 'foo', "positional_or_keyword"),
1816 ('args', ..., 'bar', "var_positional"),
1817 ('spam', ..., 'baz', "keyword_only"),
1818 ('ham', 123, ..., "keyword_only"),
1819 ('kwargs', ..., int, "var_keyword")),
1820 ...))
1821
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02001822 @cpython_only
Larry Hastingsfcafe432013-11-23 17:35:48 -08001823 @unittest.skipIf(MISSING_C_DOCSTRINGS,
1824 "Signature information for builtins requires docstrings")
1825 def test_signature_on_builtins(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02001826 import _testcapi
Larry Hastings16c51912014-01-07 11:53:01 -08001827
Larry Hastings5c661892014-01-24 06:17:25 -08001828 def test_unbound_method(o):
1829 """Use this to test unbound methods (things that should have a self)"""
1830 signature = inspect.signature(o)
1831 self.assertTrue(isinstance(signature, inspect.Signature))
1832 self.assertEqual(list(signature.parameters.values())[0].name, 'self')
1833 return signature
1834
1835 def test_callable(o):
1836 """Use this to test bound methods or normal callables (things that don't expect self)"""
1837 signature = inspect.signature(o)
1838 self.assertTrue(isinstance(signature, inspect.Signature))
1839 if signature.parameters:
1840 self.assertNotEqual(list(signature.parameters.values())[0].name, 'self')
1841 return signature
1842
1843 signature = test_callable(_testcapi.docstring_with_signature_with_defaults)
Larry Hastings16c51912014-01-07 11:53:01 -08001844 def p(name): return signature.parameters[name].default
1845 self.assertEqual(p('s'), 'avocado')
Larry Hastings2a727912014-01-16 11:32:01 -08001846 self.assertEqual(p('b'), b'bytes')
Larry Hastings16c51912014-01-07 11:53:01 -08001847 self.assertEqual(p('d'), 3.14)
1848 self.assertEqual(p('i'), 35)
Larry Hastings16c51912014-01-07 11:53:01 -08001849 self.assertEqual(p('n'), None)
1850 self.assertEqual(p('t'), True)
1851 self.assertEqual(p('f'), False)
Larry Hastings2a727912014-01-16 11:32:01 -08001852 self.assertEqual(p('local'), 3)
1853 self.assertEqual(p('sys'), sys.maxsize)
1854 self.assertEqual(p('exp'), sys.maxsize - 1)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001855
Larry Hastings5c661892014-01-24 06:17:25 -08001856 test_callable(object)
1857
1858 # normal method
1859 # (PyMethodDescr_Type, "method_descriptor")
1860 test_unbound_method(_pickle.Pickler.dump)
1861 d = _pickle.Pickler(io.StringIO())
1862 test_callable(d.dump)
1863
1864 # static method
1865 test_callable(str.maketrans)
1866 test_callable('abc'.maketrans)
1867
1868 # class method
1869 test_callable(dict.fromkeys)
1870 test_callable({}.fromkeys)
1871
1872 # wrapper around slot (PyWrapperDescr_Type, "wrapper_descriptor")
1873 test_unbound_method(type.__call__)
1874 test_unbound_method(int.__add__)
1875 test_callable((3).__add__)
1876
1877 # _PyMethodWrapper_Type
1878 # support for 'method-wrapper'
1879 test_callable(min.__call__)
1880
Larry Hastings2623c8c2014-02-08 22:15:29 -08001881 # This doesn't work now.
1882 # (We don't have a valid signature for "type" in 3.4)
1883 with self.assertRaisesRegex(ValueError, "no signature found"):
1884 class ThisWorksNow:
1885 __call__ = type
1886 test_callable(ThisWorksNow())
Larry Hastings5c661892014-01-24 06:17:25 -08001887
Yury Selivanov056e2652014-03-02 12:25:27 -05001888 # Regression test for issue #20786
1889 test_unbound_method(dict.__delitem__)
1890 test_unbound_method(property.__delete__)
1891
1892
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02001893 @cpython_only
Yury Selivanov76c6c592014-01-29 10:52:57 -05001894 @unittest.skipIf(MISSING_C_DOCSTRINGS,
1895 "Signature information for builtins requires docstrings")
1896 def test_signature_on_decorated_builtins(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02001897 import _testcapi
Yury Selivanov76c6c592014-01-29 10:52:57 -05001898 func = _testcapi.docstring_with_signature_with_defaults
1899
1900 def decorator(func):
1901 @functools.wraps(func)
1902 def wrapper(*args, **kwargs) -> int:
1903 return func(*args, **kwargs)
1904 return wrapper
1905
1906 decorated_func = decorator(func)
1907
1908 self.assertEqual(inspect.signature(func),
1909 inspect.signature(decorated_func))
Larry Hastings5c661892014-01-24 06:17:25 -08001910
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02001911 @cpython_only
Larry Hastings5c661892014-01-24 06:17:25 -08001912 def test_signature_on_builtins_no_signature(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02001913 import _testcapi
Larry Hastings5c661892014-01-24 06:17:25 -08001914 with self.assertRaisesRegex(ValueError, 'no signature found for builtin'):
1915 inspect.signature(_testcapi.docstring_no_signature)
1916
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001917 def test_signature_on_non_function(self):
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001918 with self.assertRaisesRegex(TypeError, 'is not a callable object'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001919 inspect.signature(42)
1920
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001921 with self.assertRaisesRegex(TypeError, 'is not a Python function'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001922 inspect.Signature.from_function(42)
1923
Yury Selivanovb77511d2014-01-29 10:46:14 -05001924 def test_signature_from_builtin_errors(self):
1925 with self.assertRaisesRegex(TypeError, 'is not a Python builtin'):
1926 inspect.Signature.from_builtin(42)
1927
Yury Selivanov63da7c72014-01-31 14:48:37 -05001928 def test_signature_from_functionlike_object(self):
1929 def func(a,b, *args, kwonly=True, kwonlyreq, **kwargs):
1930 pass
1931
1932 class funclike:
1933 # Has to be callable, and have correct
1934 # __code__, __annotations__, __defaults__, __name__,
1935 # and __kwdefaults__ attributes
1936
1937 def __init__(self, func):
1938 self.__name__ = func.__name__
1939 self.__code__ = func.__code__
1940 self.__annotations__ = func.__annotations__
1941 self.__defaults__ = func.__defaults__
1942 self.__kwdefaults__ = func.__kwdefaults__
1943 self.func = func
1944
1945 def __call__(self, *args, **kwargs):
1946 return self.func(*args, **kwargs)
1947
1948 sig_func = inspect.Signature.from_function(func)
1949
1950 sig_funclike = inspect.Signature.from_function(funclike(func))
1951 self.assertEqual(sig_funclike, sig_func)
1952
1953 sig_funclike = inspect.signature(funclike(func))
1954 self.assertEqual(sig_funclike, sig_func)
1955
1956 # If object is not a duck type of function, then
1957 # signature will try to get a signature for its '__call__'
1958 # method
1959 fl = funclike(func)
1960 del fl.__defaults__
1961 self.assertEqual(self.signature(fl),
1962 ((('args', ..., ..., "var_positional"),
1963 ('kwargs', ..., ..., "var_keyword")),
1964 ...))
1965
Yury Selivanova773de02014-02-21 18:30:53 -05001966 # Test with cython-like builtins:
1967 _orig_isdesc = inspect.ismethoddescriptor
1968 def _isdesc(obj):
1969 if hasattr(obj, '_builtinmock'):
1970 return True
1971 return _orig_isdesc(obj)
1972
1973 with unittest.mock.patch('inspect.ismethoddescriptor', _isdesc):
1974 builtin_func = funclike(func)
1975 # Make sure that our mock setup is working
1976 self.assertFalse(inspect.ismethoddescriptor(builtin_func))
1977 builtin_func._builtinmock = True
1978 self.assertTrue(inspect.ismethoddescriptor(builtin_func))
1979 self.assertEqual(inspect.signature(builtin_func), sig_func)
1980
Yury Selivanov63da7c72014-01-31 14:48:37 -05001981 def test_signature_functionlike_class(self):
1982 # We only want to duck type function-like objects,
1983 # not classes.
1984
1985 def func(a,b, *args, kwonly=True, kwonlyreq, **kwargs):
1986 pass
1987
1988 class funclike:
1989 def __init__(self, marker):
1990 pass
1991
1992 __name__ = func.__name__
1993 __code__ = func.__code__
1994 __annotations__ = func.__annotations__
1995 __defaults__ = func.__defaults__
1996 __kwdefaults__ = func.__kwdefaults__
1997
1998 with self.assertRaisesRegex(TypeError, 'is not a Python function'):
1999 inspect.Signature.from_function(funclike)
2000
2001 self.assertEqual(str(inspect.signature(funclike)), '(marker)')
2002
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002003 def test_signature_on_method(self):
2004 class Test:
Yury Selivanov62560fb2014-01-28 12:26:24 -05002005 def __init__(*args):
2006 pass
2007 def m1(self, arg1, arg2=1) -> int:
2008 pass
2009 def m2(*args):
2010 pass
2011 def __call__(*, a):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002012 pass
2013
Yury Selivanov62560fb2014-01-28 12:26:24 -05002014 self.assertEqual(self.signature(Test().m1),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002015 ((('arg1', ..., ..., "positional_or_keyword"),
2016 ('arg2', 1, ..., "positional_or_keyword")),
2017 int))
2018
Yury Selivanov62560fb2014-01-28 12:26:24 -05002019 self.assertEqual(self.signature(Test().m2),
2020 ((('args', ..., ..., "var_positional"),),
2021 ...))
2022
2023 self.assertEqual(self.signature(Test),
2024 ((('args', ..., ..., "var_positional"),),
2025 ...))
2026
2027 with self.assertRaisesRegex(ValueError, 'invalid method signature'):
2028 self.signature(Test())
2029
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002030 def test_signature_on_classmethod(self):
2031 class Test:
2032 @classmethod
2033 def foo(cls, arg1, *, arg2=1):
2034 pass
2035
2036 meth = Test().foo
2037 self.assertEqual(self.signature(meth),
2038 ((('arg1', ..., ..., "positional_or_keyword"),
2039 ('arg2', 1, ..., "keyword_only")),
2040 ...))
2041
2042 meth = Test.foo
2043 self.assertEqual(self.signature(meth),
2044 ((('arg1', ..., ..., "positional_or_keyword"),
2045 ('arg2', 1, ..., "keyword_only")),
2046 ...))
2047
2048 def test_signature_on_staticmethod(self):
2049 class Test:
2050 @staticmethod
2051 def foo(cls, *, arg):
2052 pass
2053
2054 meth = Test().foo
2055 self.assertEqual(self.signature(meth),
2056 ((('cls', ..., ..., "positional_or_keyword"),
2057 ('arg', ..., ..., "keyword_only")),
2058 ...))
2059
2060 meth = Test.foo
2061 self.assertEqual(self.signature(meth),
2062 ((('cls', ..., ..., "positional_or_keyword"),
2063 ('arg', ..., ..., "keyword_only")),
2064 ...))
2065
2066 def test_signature_on_partial(self):
2067 from functools import partial
2068
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002069 Parameter = inspect.Parameter
2070
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002071 def test():
2072 pass
2073
2074 self.assertEqual(self.signature(partial(test)), ((), ...))
2075
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002076 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002077 inspect.signature(partial(test, 1))
2078
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002079 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002080 inspect.signature(partial(test, a=1))
2081
2082 def test(a, b, *, c, d):
2083 pass
2084
2085 self.assertEqual(self.signature(partial(test)),
2086 ((('a', ..., ..., "positional_or_keyword"),
2087 ('b', ..., ..., "positional_or_keyword"),
2088 ('c', ..., ..., "keyword_only"),
2089 ('d', ..., ..., "keyword_only")),
2090 ...))
2091
2092 self.assertEqual(self.signature(partial(test, 1)),
2093 ((('b', ..., ..., "positional_or_keyword"),
2094 ('c', ..., ..., "keyword_only"),
2095 ('d', ..., ..., "keyword_only")),
2096 ...))
2097
2098 self.assertEqual(self.signature(partial(test, 1, c=2)),
2099 ((('b', ..., ..., "positional_or_keyword"),
2100 ('c', 2, ..., "keyword_only"),
2101 ('d', ..., ..., "keyword_only")),
2102 ...))
2103
2104 self.assertEqual(self.signature(partial(test, b=1, c=2)),
2105 ((('a', ..., ..., "positional_or_keyword"),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002106 ('b', 1, ..., "keyword_only"),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002107 ('c', 2, ..., "keyword_only"),
2108 ('d', ..., ..., "keyword_only")),
2109 ...))
2110
2111 self.assertEqual(self.signature(partial(test, 0, b=1, c=2)),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002112 ((('b', 1, ..., "keyword_only"),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002113 ('c', 2, ..., "keyword_only"),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002114 ('d', ..., ..., "keyword_only")),
2115 ...))
2116
2117 self.assertEqual(self.signature(partial(test, a=1)),
2118 ((('a', 1, ..., "keyword_only"),
2119 ('b', ..., ..., "keyword_only"),
2120 ('c', ..., ..., "keyword_only"),
2121 ('d', ..., ..., "keyword_only")),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002122 ...))
2123
2124 def test(a, *args, b, **kwargs):
2125 pass
2126
2127 self.assertEqual(self.signature(partial(test, 1)),
2128 ((('args', ..., ..., "var_positional"),
2129 ('b', ..., ..., "keyword_only"),
2130 ('kwargs', ..., ..., "var_keyword")),
2131 ...))
2132
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002133 self.assertEqual(self.signature(partial(test, a=1)),
2134 ((('a', 1, ..., "keyword_only"),
2135 ('b', ..., ..., "keyword_only"),
2136 ('kwargs', ..., ..., "var_keyword")),
2137 ...))
2138
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002139 self.assertEqual(self.signature(partial(test, 1, 2, 3)),
2140 ((('args', ..., ..., "var_positional"),
2141 ('b', ..., ..., "keyword_only"),
2142 ('kwargs', ..., ..., "var_keyword")),
2143 ...))
2144
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002145 self.assertEqual(self.signature(partial(test, 1, 2, 3, test=True)),
2146 ((('args', ..., ..., "var_positional"),
2147 ('b', ..., ..., "keyword_only"),
2148 ('kwargs', ..., ..., "var_keyword")),
2149 ...))
2150
2151 self.assertEqual(self.signature(partial(test, 1, 2, 3, test=1, b=0)),
2152 ((('args', ..., ..., "var_positional"),
2153 ('b', 0, ..., "keyword_only"),
2154 ('kwargs', ..., ..., "var_keyword")),
2155 ...))
2156
2157 self.assertEqual(self.signature(partial(test, b=0)),
2158 ((('a', ..., ..., "positional_or_keyword"),
2159 ('args', ..., ..., "var_positional"),
2160 ('b', 0, ..., "keyword_only"),
2161 ('kwargs', ..., ..., "var_keyword")),
2162 ...))
2163
2164 self.assertEqual(self.signature(partial(test, b=0, test=1)),
2165 ((('a', ..., ..., "positional_or_keyword"),
2166 ('args', ..., ..., "var_positional"),
2167 ('b', 0, ..., "keyword_only"),
2168 ('kwargs', ..., ..., "var_keyword")),
2169 ...))
2170
2171 def test(a, b, c:int) -> 42:
2172 pass
2173
2174 sig = test.__signature__ = inspect.signature(test)
2175
2176 self.assertEqual(self.signature(partial(partial(test, 1))),
2177 ((('b', ..., ..., "positional_or_keyword"),
2178 ('c', ..., int, "positional_or_keyword")),
2179 42))
2180
2181 self.assertEqual(self.signature(partial(partial(test, 1), 2)),
2182 ((('c', ..., int, "positional_or_keyword"),),
2183 42))
2184
2185 psig = inspect.signature(partial(partial(test, 1), 2))
2186
2187 def foo(a):
2188 return a
2189 _foo = partial(partial(foo, a=10), a=20)
2190 self.assertEqual(self.signature(_foo),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002191 ((('a', 20, ..., "keyword_only"),),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002192 ...))
2193 # check that we don't have any side-effects in signature(),
2194 # and the partial object is still functioning
2195 self.assertEqual(_foo(), 20)
2196
2197 def foo(a, b, c):
2198 return a, b, c
2199 _foo = partial(partial(foo, 1, b=20), b=30)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002200
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002201 self.assertEqual(self.signature(_foo),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002202 ((('b', 30, ..., "keyword_only"),
2203 ('c', ..., ..., "keyword_only")),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002204 ...))
2205 self.assertEqual(_foo(c=10), (1, 30, 10))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002206
2207 def foo(a, b, c, *, d):
2208 return a, b, c, d
2209 _foo = partial(partial(foo, d=20, c=20), b=10, d=30)
2210 self.assertEqual(self.signature(_foo),
2211 ((('a', ..., ..., "positional_or_keyword"),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002212 ('b', 10, ..., "keyword_only"),
2213 ('c', 20, ..., "keyword_only"),
2214 ('d', 30, ..., "keyword_only"),
2215 ),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002216 ...))
2217 ba = inspect.signature(_foo).bind(a=200, b=11)
2218 self.assertEqual(_foo(*ba.args, **ba.kwargs), (200, 11, 20, 30))
2219
2220 def foo(a=1, b=2, c=3):
2221 return a, b, c
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002222 _foo = partial(foo, c=13) # (a=1, b=2, *, c=13)
2223
2224 ba = inspect.signature(_foo).bind(a=11)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002225 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 2, 13))
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002226
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002227 ba = inspect.signature(_foo).bind(11, 12)
2228 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002229
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002230 ba = inspect.signature(_foo).bind(11, b=12)
2231 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002232
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002233 ba = inspect.signature(_foo).bind(b=12)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002234 self.assertEqual(_foo(*ba.args, **ba.kwargs), (1, 12, 13))
2235
2236 _foo = partial(_foo, b=10, c=20)
2237 ba = inspect.signature(_foo).bind(12)
2238 self.assertEqual(_foo(*ba.args, **ba.kwargs), (12, 10, 20))
2239
2240
2241 def foo(a, b, c, d, **kwargs):
2242 pass
2243 sig = inspect.signature(foo)
2244 params = sig.parameters.copy()
2245 params['a'] = params['a'].replace(kind=Parameter.POSITIONAL_ONLY)
2246 params['b'] = params['b'].replace(kind=Parameter.POSITIONAL_ONLY)
2247 foo.__signature__ = inspect.Signature(params.values())
2248 sig = inspect.signature(foo)
2249 self.assertEqual(str(sig), '(a, b, /, c, d, **kwargs)')
2250
2251 self.assertEqual(self.signature(partial(foo, 1)),
2252 ((('b', ..., ..., 'positional_only'),
2253 ('c', ..., ..., 'positional_or_keyword'),
2254 ('d', ..., ..., 'positional_or_keyword'),
2255 ('kwargs', ..., ..., 'var_keyword')),
2256 ...))
2257
2258 self.assertEqual(self.signature(partial(foo, 1, 2)),
2259 ((('c', ..., ..., 'positional_or_keyword'),
2260 ('d', ..., ..., 'positional_or_keyword'),
2261 ('kwargs', ..., ..., 'var_keyword')),
2262 ...))
2263
2264 self.assertEqual(self.signature(partial(foo, 1, 2, 3)),
2265 ((('d', ..., ..., 'positional_or_keyword'),
2266 ('kwargs', ..., ..., 'var_keyword')),
2267 ...))
2268
2269 self.assertEqual(self.signature(partial(foo, 1, 2, c=3)),
2270 ((('c', 3, ..., 'keyword_only'),
2271 ('d', ..., ..., 'keyword_only'),
2272 ('kwargs', ..., ..., 'var_keyword')),
2273 ...))
2274
2275 self.assertEqual(self.signature(partial(foo, 1, c=3)),
2276 ((('b', ..., ..., 'positional_only'),
2277 ('c', 3, ..., 'keyword_only'),
2278 ('d', ..., ..., 'keyword_only'),
2279 ('kwargs', ..., ..., 'var_keyword')),
2280 ...))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002281
Yury Selivanovda5fe4f2014-01-27 17:28:37 -05002282 def test_signature_on_partialmethod(self):
2283 from functools import partialmethod
2284
2285 class Spam:
2286 def test():
2287 pass
2288 ham = partialmethod(test)
2289
2290 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
2291 inspect.signature(Spam.ham)
2292
2293 class Spam:
2294 def test(it, a, *, c) -> 'spam':
2295 pass
2296 ham = partialmethod(test, c=1)
2297
2298 self.assertEqual(self.signature(Spam.ham),
2299 ((('it', ..., ..., 'positional_or_keyword'),
2300 ('a', ..., ..., 'positional_or_keyword'),
2301 ('c', 1, ..., 'keyword_only')),
2302 'spam'))
2303
2304 self.assertEqual(self.signature(Spam().ham),
2305 ((('a', ..., ..., 'positional_or_keyword'),
2306 ('c', 1, ..., 'keyword_only')),
2307 'spam'))
2308
Yury Selivanov0486f812014-01-29 12:18:59 -05002309 def test_signature_on_fake_partialmethod(self):
2310 def foo(a): pass
2311 foo._partialmethod = 'spam'
2312 self.assertEqual(str(inspect.signature(foo)), '(a)')
2313
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002314 def test_signature_on_decorated(self):
2315 import functools
2316
2317 def decorator(func):
2318 @functools.wraps(func)
2319 def wrapper(*args, **kwargs) -> int:
2320 return func(*args, **kwargs)
2321 return wrapper
2322
2323 class Foo:
2324 @decorator
2325 def bar(self, a, b):
2326 pass
2327
2328 self.assertEqual(self.signature(Foo.bar),
2329 ((('self', ..., ..., "positional_or_keyword"),
2330 ('a', ..., ..., "positional_or_keyword"),
2331 ('b', ..., ..., "positional_or_keyword")),
2332 ...))
2333
2334 self.assertEqual(self.signature(Foo().bar),
2335 ((('a', ..., ..., "positional_or_keyword"),
2336 ('b', ..., ..., "positional_or_keyword")),
2337 ...))
2338
2339 # Test that we handle method wrappers correctly
2340 def decorator(func):
2341 @functools.wraps(func)
2342 def wrapper(*args, **kwargs) -> int:
2343 return func(42, *args, **kwargs)
2344 sig = inspect.signature(func)
2345 new_params = tuple(sig.parameters.values())[1:]
2346 wrapper.__signature__ = sig.replace(parameters=new_params)
2347 return wrapper
2348
2349 class Foo:
2350 @decorator
2351 def __call__(self, a, b):
2352 pass
2353
2354 self.assertEqual(self.signature(Foo.__call__),
2355 ((('a', ..., ..., "positional_or_keyword"),
2356 ('b', ..., ..., "positional_or_keyword")),
2357 ...))
2358
2359 self.assertEqual(self.signature(Foo().__call__),
2360 ((('b', ..., ..., "positional_or_keyword"),),
2361 ...))
2362
Nick Coghlane8c45d62013-07-28 20:00:01 +10002363 # Test we handle __signature__ partway down the wrapper stack
2364 def wrapped_foo_call():
2365 pass
2366 wrapped_foo_call.__wrapped__ = Foo.__call__
2367
2368 self.assertEqual(self.signature(wrapped_foo_call),
2369 ((('a', ..., ..., "positional_or_keyword"),
2370 ('b', ..., ..., "positional_or_keyword")),
2371 ...))
2372
2373
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002374 def test_signature_on_class(self):
2375 class C:
2376 def __init__(self, a):
2377 pass
2378
2379 self.assertEqual(self.signature(C),
2380 ((('a', ..., ..., "positional_or_keyword"),),
2381 ...))
2382
2383 class CM(type):
2384 def __call__(cls, a):
2385 pass
2386 class C(metaclass=CM):
2387 def __init__(self, b):
2388 pass
2389
2390 self.assertEqual(self.signature(C),
2391 ((('a', ..., ..., "positional_or_keyword"),),
2392 ...))
2393
2394 class CM(type):
2395 def __new__(mcls, name, bases, dct, *, foo=1):
2396 return super().__new__(mcls, name, bases, dct)
2397 class C(metaclass=CM):
2398 def __init__(self, b):
2399 pass
2400
2401 self.assertEqual(self.signature(C),
2402 ((('b', ..., ..., "positional_or_keyword"),),
2403 ...))
2404
2405 self.assertEqual(self.signature(CM),
2406 ((('name', ..., ..., "positional_or_keyword"),
2407 ('bases', ..., ..., "positional_or_keyword"),
2408 ('dct', ..., ..., "positional_or_keyword"),
2409 ('foo', 1, ..., "keyword_only")),
2410 ...))
2411
2412 class CMM(type):
2413 def __new__(mcls, name, bases, dct, *, foo=1):
2414 return super().__new__(mcls, name, bases, dct)
2415 def __call__(cls, nm, bs, dt):
2416 return type(nm, bs, dt)
2417 class CM(type, metaclass=CMM):
2418 def __new__(mcls, name, bases, dct, *, bar=2):
2419 return super().__new__(mcls, name, bases, dct)
2420 class C(metaclass=CM):
2421 def __init__(self, b):
2422 pass
2423
2424 self.assertEqual(self.signature(CMM),
2425 ((('name', ..., ..., "positional_or_keyword"),
2426 ('bases', ..., ..., "positional_or_keyword"),
2427 ('dct', ..., ..., "positional_or_keyword"),
2428 ('foo', 1, ..., "keyword_only")),
2429 ...))
2430
2431 self.assertEqual(self.signature(CM),
2432 ((('nm', ..., ..., "positional_or_keyword"),
2433 ('bs', ..., ..., "positional_or_keyword"),
2434 ('dt', ..., ..., "positional_or_keyword")),
2435 ...))
2436
2437 self.assertEqual(self.signature(C),
2438 ((('b', ..., ..., "positional_or_keyword"),),
2439 ...))
2440
2441 class CM(type):
2442 def __init__(cls, name, bases, dct, *, bar=2):
2443 return super().__init__(name, bases, dct)
2444 class C(metaclass=CM):
2445 def __init__(self, b):
2446 pass
2447
2448 self.assertEqual(self.signature(CM),
2449 ((('name', ..., ..., "positional_or_keyword"),
2450 ('bases', ..., ..., "positional_or_keyword"),
2451 ('dct', ..., ..., "positional_or_keyword"),
2452 ('bar', 2, ..., "keyword_only")),
2453 ...))
2454
Yury Selivanov145dff82014-02-01 13:49:29 -05002455 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2456 "Signature information for builtins requires docstrings")
2457 def test_signature_on_class_without_init(self):
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002458 # Test classes without user-defined __init__ or __new__
2459 class C: pass
2460 self.assertEqual(str(inspect.signature(C)), '()')
2461 class D(C): pass
2462 self.assertEqual(str(inspect.signature(D)), '()')
2463
2464 # Test meta-classes without user-defined __init__ or __new__
2465 class C(type): pass
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002466 class D(C): pass
Larry Hastings2623c8c2014-02-08 22:15:29 -08002467 with self.assertRaisesRegex(ValueError, "callable.*is not supported"):
2468 self.assertEqual(inspect.signature(C), None)
2469 with self.assertRaisesRegex(ValueError, "callable.*is not supported"):
2470 self.assertEqual(inspect.signature(D), None)
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002471
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002472 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2473 "Signature information for builtins requires docstrings")
2474 def test_signature_on_builtin_class(self):
2475 self.assertEqual(str(inspect.signature(_pickle.Pickler)),
2476 '(file, protocol=None, fix_imports=True)')
2477
2478 class P(_pickle.Pickler): pass
2479 class EmptyTrait: pass
2480 class P2(EmptyTrait, P): pass
2481 self.assertEqual(str(inspect.signature(P)),
2482 '(file, protocol=None, fix_imports=True)')
2483 self.assertEqual(str(inspect.signature(P2)),
2484 '(file, protocol=None, fix_imports=True)')
2485
2486 class P3(P2):
2487 def __init__(self, spam):
2488 pass
2489 self.assertEqual(str(inspect.signature(P3)), '(spam)')
2490
2491 class MetaP(type):
2492 def __call__(cls, foo, bar):
2493 pass
2494 class P4(P2, metaclass=MetaP):
2495 pass
2496 self.assertEqual(str(inspect.signature(P4)), '(foo, bar)')
2497
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002498 def test_signature_on_callable_objects(self):
2499 class Foo:
2500 def __call__(self, a):
2501 pass
2502
2503 self.assertEqual(self.signature(Foo()),
2504 ((('a', ..., ..., "positional_or_keyword"),),
2505 ...))
2506
2507 class Spam:
2508 pass
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002509 with self.assertRaisesRegex(TypeError, "is not a callable object"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002510 inspect.signature(Spam())
2511
2512 class Bar(Spam, Foo):
2513 pass
2514
2515 self.assertEqual(self.signature(Bar()),
2516 ((('a', ..., ..., "positional_or_keyword"),),
2517 ...))
2518
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002519 class Wrapped:
2520 pass
2521 Wrapped.__wrapped__ = lambda a: None
2522 self.assertEqual(self.signature(Wrapped),
2523 ((('a', ..., ..., "positional_or_keyword"),),
2524 ...))
Nick Coghlane8c45d62013-07-28 20:00:01 +10002525 # wrapper loop:
2526 Wrapped.__wrapped__ = Wrapped
2527 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
2528 self.signature(Wrapped)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002529
2530 def test_signature_on_lambdas(self):
2531 self.assertEqual(self.signature((lambda a=10: a)),
2532 ((('a', 10, ..., "positional_or_keyword"),),
2533 ...))
2534
2535 def test_signature_equality(self):
2536 def foo(a, *, b:int) -> float: pass
2537 self.assertNotEqual(inspect.signature(foo), 42)
2538
2539 def bar(a, *, b:int) -> float: pass
2540 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002541 self.assertEqual(
2542 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002543
2544 def bar(a, *, b:int) -> int: pass
2545 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002546 self.assertNotEqual(
2547 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002548
2549 def bar(a, *, b:int): pass
2550 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002551 self.assertNotEqual(
2552 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002553
2554 def bar(a, *, b:int=42) -> float: pass
2555 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002556 self.assertNotEqual(
2557 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002558
2559 def bar(a, *, c) -> float: pass
2560 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002561 self.assertNotEqual(
2562 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002563
2564 def bar(a, b:int) -> float: pass
2565 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002566 self.assertNotEqual(
2567 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002568 def spam(b:int, a) -> float: pass
2569 self.assertNotEqual(inspect.signature(spam), inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002570 self.assertNotEqual(
2571 hash(inspect.signature(spam)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002572
2573 def foo(*, a, b, c): pass
2574 def bar(*, c, b, a): pass
2575 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002576 self.assertEqual(
2577 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002578
2579 def foo(*, a=1, b, c): pass
2580 def bar(*, c, b, a=1): pass
2581 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002582 self.assertEqual(
2583 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002584
2585 def foo(pos, *, a=1, b, c): pass
2586 def bar(pos, *, c, b, a=1): pass
2587 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002588 self.assertEqual(
2589 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002590
2591 def foo(pos, *, a, b, c): pass
2592 def bar(pos, *, c, b, a=1): pass
2593 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002594 self.assertNotEqual(
2595 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002596
2597 def foo(pos, *args, a=42, b, c, **kwargs:int): pass
2598 def bar(pos, *args, c, b, a=42, **kwargs:int): pass
2599 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002600 self.assertEqual(
2601 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002602
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002603 def test_signature_hashable(self):
2604 S = inspect.Signature
2605 P = inspect.Parameter
2606
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002607 def foo(a): pass
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002608 foo_sig = inspect.signature(foo)
2609
2610 manual_sig = S(parameters=[P('a', P.POSITIONAL_OR_KEYWORD)])
2611
2612 self.assertEqual(hash(foo_sig), hash(manual_sig))
2613 self.assertNotEqual(hash(foo_sig),
2614 hash(manual_sig.replace(return_annotation='spam')))
2615
2616 def bar(a) -> 1: pass
2617 self.assertNotEqual(hash(foo_sig), hash(inspect.signature(bar)))
2618
2619 def foo(a={}): pass
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002620 with self.assertRaisesRegex(TypeError, 'unhashable type'):
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002621 hash(inspect.signature(foo))
2622
2623 def foo(a) -> {}: pass
2624 with self.assertRaisesRegex(TypeError, 'unhashable type'):
2625 hash(inspect.signature(foo))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002626
2627 def test_signature_str(self):
2628 def foo(a:int=1, *, b, c=None, **kwargs) -> 42:
2629 pass
2630 self.assertEqual(str(inspect.signature(foo)),
2631 '(a:int=1, *, b, c=None, **kwargs) -> 42')
2632
2633 def foo(a:int=1, *args, b, c=None, **kwargs) -> 42:
2634 pass
2635 self.assertEqual(str(inspect.signature(foo)),
2636 '(a:int=1, *args, b, c=None, **kwargs) -> 42')
2637
2638 def foo():
2639 pass
2640 self.assertEqual(str(inspect.signature(foo)), '()')
2641
2642 def test_signature_str_positional_only(self):
2643 P = inspect.Parameter
Yury Selivanov2393dca2014-01-27 15:07:58 -05002644 S = inspect.Signature
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002645
2646 def test(a_po, *, b, **kwargs):
2647 return a_po, kwargs
2648
2649 sig = inspect.signature(test)
2650 new_params = list(sig.parameters.values())
2651 new_params[0] = new_params[0].replace(kind=P.POSITIONAL_ONLY)
2652 test.__signature__ = sig.replace(parameters=new_params)
2653
2654 self.assertEqual(str(inspect.signature(test)),
Yury Selivanov2393dca2014-01-27 15:07:58 -05002655 '(a_po, /, *, b, **kwargs)')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002656
Yury Selivanov2393dca2014-01-27 15:07:58 -05002657 self.assertEqual(str(S(parameters=[P('foo', P.POSITIONAL_ONLY)])),
2658 '(foo, /)')
2659
2660 self.assertEqual(str(S(parameters=[
2661 P('foo', P.POSITIONAL_ONLY),
2662 P('bar', P.VAR_KEYWORD)])),
2663 '(foo, /, **bar)')
2664
2665 self.assertEqual(str(S(parameters=[
2666 P('foo', P.POSITIONAL_ONLY),
2667 P('bar', P.VAR_POSITIONAL)])),
2668 '(foo, /, *bar)')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002669
2670 def test_signature_replace_anno(self):
2671 def test() -> 42:
2672 pass
2673
2674 sig = inspect.signature(test)
2675 sig = sig.replace(return_annotation=None)
2676 self.assertIs(sig.return_annotation, None)
2677 sig = sig.replace(return_annotation=sig.empty)
2678 self.assertIs(sig.return_annotation, sig.empty)
2679 sig = sig.replace(return_annotation=42)
2680 self.assertEqual(sig.return_annotation, 42)
2681 self.assertEqual(sig, inspect.signature(test))
2682
Yury Selivanov34ce99f2014-02-18 12:49:41 -05002683 def test_signature_on_mangled_parameters(self):
2684 class Spam:
2685 def foo(self, __p1:1=2, *, __p2:2=3):
2686 pass
2687 class Ham(Spam):
2688 pass
2689
2690 self.assertEqual(self.signature(Spam.foo),
2691 ((('self', ..., ..., "positional_or_keyword"),
2692 ('_Spam__p1', 2, 1, "positional_or_keyword"),
2693 ('_Spam__p2', 3, 2, "keyword_only")),
2694 ...))
2695
2696 self.assertEqual(self.signature(Spam.foo),
2697 self.signature(Ham.foo))
2698
Yury Selivanovda396452014-03-27 12:09:24 -04002699 def test_signature_from_callable_python_obj(self):
2700 class MySignature(inspect.Signature): pass
2701 def foo(a, *, b:1): pass
2702 foo_sig = MySignature.from_callable(foo)
2703 self.assertTrue(isinstance(foo_sig, MySignature))
2704
2705 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2706 "Signature information for builtins requires docstrings")
2707 def test_signature_from_callable_builtin_obj(self):
2708 class MySignature(inspect.Signature): pass
2709 sig = MySignature.from_callable(_pickle.Pickler)
2710 self.assertTrue(isinstance(sig, MySignature))
2711
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002712
2713class TestParameterObject(unittest.TestCase):
2714 def test_signature_parameter_kinds(self):
2715 P = inspect.Parameter
2716 self.assertTrue(P.POSITIONAL_ONLY < P.POSITIONAL_OR_KEYWORD < \
2717 P.VAR_POSITIONAL < P.KEYWORD_ONLY < P.VAR_KEYWORD)
2718
2719 self.assertEqual(str(P.POSITIONAL_ONLY), 'POSITIONAL_ONLY')
2720 self.assertTrue('POSITIONAL_ONLY' in repr(P.POSITIONAL_ONLY))
2721
2722 def test_signature_parameter_object(self):
2723 p = inspect.Parameter('foo', default=10,
2724 kind=inspect.Parameter.POSITIONAL_ONLY)
2725 self.assertEqual(p.name, 'foo')
2726 self.assertEqual(p.default, 10)
2727 self.assertIs(p.annotation, p.empty)
2728 self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY)
2729
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002730 with self.assertRaisesRegex(ValueError, 'invalid value'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002731 inspect.Parameter('foo', default=10, kind='123')
2732
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002733 with self.assertRaisesRegex(ValueError, 'not a valid parameter name'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002734 inspect.Parameter('1', kind=inspect.Parameter.VAR_KEYWORD)
2735
Yury Selivanov2393dca2014-01-27 15:07:58 -05002736 with self.assertRaisesRegex(TypeError, 'name must be a str'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002737 inspect.Parameter(None, kind=inspect.Parameter.VAR_KEYWORD)
2738
Yury Selivanov2393dca2014-01-27 15:07:58 -05002739 with self.assertRaisesRegex(ValueError,
2740 'is not a valid parameter name'):
2741 inspect.Parameter('$', kind=inspect.Parameter.VAR_KEYWORD)
2742
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002743 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002744 inspect.Parameter('a', default=42,
2745 kind=inspect.Parameter.VAR_KEYWORD)
2746
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002747 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002748 inspect.Parameter('a', default=42,
2749 kind=inspect.Parameter.VAR_POSITIONAL)
2750
2751 p = inspect.Parameter('a', default=42,
2752 kind=inspect.Parameter.POSITIONAL_OR_KEYWORD)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002753 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002754 p.replace(kind=inspect.Parameter.VAR_POSITIONAL)
2755
2756 self.assertTrue(repr(p).startswith('<Parameter'))
Yury Selivanov374375d2014-03-27 12:41:53 -04002757 self.assertTrue('"a=42"' in repr(p))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002758
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002759 def test_signature_parameter_hashable(self):
2760 P = inspect.Parameter
2761 foo = P('foo', kind=P.POSITIONAL_ONLY)
2762 self.assertEqual(hash(foo), hash(P('foo', kind=P.POSITIONAL_ONLY)))
2763 self.assertNotEqual(hash(foo), hash(P('foo', kind=P.POSITIONAL_ONLY,
2764 default=42)))
2765 self.assertNotEqual(hash(foo),
2766 hash(foo.replace(kind=P.VAR_POSITIONAL)))
2767
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002768 def test_signature_parameter_equality(self):
2769 P = inspect.Parameter
2770 p = P('foo', default=42, kind=inspect.Parameter.KEYWORD_ONLY)
2771
2772 self.assertEqual(p, p)
2773 self.assertNotEqual(p, 42)
2774
2775 self.assertEqual(p, P('foo', default=42,
2776 kind=inspect.Parameter.KEYWORD_ONLY))
2777
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002778 def test_signature_parameter_replace(self):
2779 p = inspect.Parameter('foo', default=42,
2780 kind=inspect.Parameter.KEYWORD_ONLY)
2781
2782 self.assertIsNot(p, p.replace())
2783 self.assertEqual(p, p.replace())
2784
2785 p2 = p.replace(annotation=1)
2786 self.assertEqual(p2.annotation, 1)
2787 p2 = p2.replace(annotation=p2.empty)
2788 self.assertEqual(p, p2)
2789
2790 p2 = p2.replace(name='bar')
2791 self.assertEqual(p2.name, 'bar')
2792 self.assertNotEqual(p2, p)
2793
Yury Selivanov2393dca2014-01-27 15:07:58 -05002794 with self.assertRaisesRegex(ValueError,
2795 'name is a required attribute'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002796 p2 = p2.replace(name=p2.empty)
2797
2798 p2 = p2.replace(name='foo', default=None)
2799 self.assertIs(p2.default, None)
2800 self.assertNotEqual(p2, p)
2801
2802 p2 = p2.replace(name='foo', default=p2.empty)
2803 self.assertIs(p2.default, p2.empty)
2804
2805
2806 p2 = p2.replace(default=42, kind=p2.POSITIONAL_OR_KEYWORD)
2807 self.assertEqual(p2.kind, p2.POSITIONAL_OR_KEYWORD)
2808 self.assertNotEqual(p2, p)
2809
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002810 with self.assertRaisesRegex(ValueError, 'invalid value for'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002811 p2 = p2.replace(kind=p2.empty)
2812
2813 p2 = p2.replace(kind=p2.KEYWORD_ONLY)
2814 self.assertEqual(p2, p)
2815
2816 def test_signature_parameter_positional_only(self):
Yury Selivanov2393dca2014-01-27 15:07:58 -05002817 with self.assertRaisesRegex(TypeError, 'name must be a str'):
2818 inspect.Parameter(None, kind=inspect.Parameter.POSITIONAL_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002819
2820 def test_signature_parameter_immutability(self):
Yury Selivanov2393dca2014-01-27 15:07:58 -05002821 p = inspect.Parameter('spam', kind=inspect.Parameter.KEYWORD_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002822
2823 with self.assertRaises(AttributeError):
2824 p.foo = 'bar'
2825
2826 with self.assertRaises(AttributeError):
2827 p.kind = 123
2828
2829
2830class TestSignatureBind(unittest.TestCase):
2831 @staticmethod
2832 def call(func, *args, **kwargs):
2833 sig = inspect.signature(func)
2834 ba = sig.bind(*args, **kwargs)
2835 return func(*ba.args, **ba.kwargs)
2836
2837 def test_signature_bind_empty(self):
2838 def test():
2839 return 42
2840
2841 self.assertEqual(self.call(test), 42)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002842 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002843 self.call(test, 1)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002844 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002845 self.call(test, 1, spam=10)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002846 with self.assertRaisesRegex(TypeError, 'too many keyword arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002847 self.call(test, spam=1)
2848
2849 def test_signature_bind_var(self):
2850 def test(*args, **kwargs):
2851 return args, kwargs
2852
2853 self.assertEqual(self.call(test), ((), {}))
2854 self.assertEqual(self.call(test, 1), ((1,), {}))
2855 self.assertEqual(self.call(test, 1, 2), ((1, 2), {}))
2856 self.assertEqual(self.call(test, foo='bar'), ((), {'foo': 'bar'}))
2857 self.assertEqual(self.call(test, 1, foo='bar'), ((1,), {'foo': 'bar'}))
2858 self.assertEqual(self.call(test, args=10), ((), {'args': 10}))
2859 self.assertEqual(self.call(test, 1, 2, foo='bar'),
2860 ((1, 2), {'foo': 'bar'}))
2861
2862 def test_signature_bind_just_args(self):
2863 def test(a, b, c):
2864 return a, b, c
2865
2866 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
2867
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002868 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002869 self.call(test, 1, 2, 3, 4)
2870
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002871 with self.assertRaisesRegex(TypeError, "'b' parameter lacking default"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002872 self.call(test, 1)
2873
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002874 with self.assertRaisesRegex(TypeError, "'a' parameter lacking default"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002875 self.call(test)
2876
2877 def test(a, b, c=10):
2878 return a, b, c
2879 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
2880 self.assertEqual(self.call(test, 1, 2), (1, 2, 10))
2881
2882 def test(a=1, b=2, c=3):
2883 return a, b, c
2884 self.assertEqual(self.call(test, a=10, c=13), (10, 2, 13))
2885 self.assertEqual(self.call(test, a=10), (10, 2, 3))
2886 self.assertEqual(self.call(test, b=10), (1, 10, 3))
2887
2888 def test_signature_bind_varargs_order(self):
2889 def test(*args):
2890 return args
2891
2892 self.assertEqual(self.call(test), ())
2893 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
2894
2895 def test_signature_bind_args_and_varargs(self):
2896 def test(a, b, c=3, *args):
2897 return a, b, c, args
2898
2899 self.assertEqual(self.call(test, 1, 2, 3, 4, 5), (1, 2, 3, (4, 5)))
2900 self.assertEqual(self.call(test, 1, 2), (1, 2, 3, ()))
2901 self.assertEqual(self.call(test, b=1, a=2), (2, 1, 3, ()))
2902 self.assertEqual(self.call(test, 1, b=2), (1, 2, 3, ()))
2903
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002904 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002905 "multiple values for argument 'c'"):
2906 self.call(test, 1, 2, 3, c=4)
2907
2908 def test_signature_bind_just_kwargs(self):
2909 def test(**kwargs):
2910 return kwargs
2911
2912 self.assertEqual(self.call(test), {})
2913 self.assertEqual(self.call(test, foo='bar', spam='ham'),
2914 {'foo': 'bar', 'spam': 'ham'})
2915
2916 def test_signature_bind_args_and_kwargs(self):
2917 def test(a, b, c=3, **kwargs):
2918 return a, b, c, kwargs
2919
2920 self.assertEqual(self.call(test, 1, 2), (1, 2, 3, {}))
2921 self.assertEqual(self.call(test, 1, 2, foo='bar', spam='ham'),
2922 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
2923 self.assertEqual(self.call(test, b=2, a=1, foo='bar', spam='ham'),
2924 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
2925 self.assertEqual(self.call(test, a=1, b=2, foo='bar', spam='ham'),
2926 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
2927 self.assertEqual(self.call(test, 1, b=2, foo='bar', spam='ham'),
2928 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
2929 self.assertEqual(self.call(test, 1, b=2, c=4, foo='bar', spam='ham'),
2930 (1, 2, 4, {'foo': 'bar', 'spam': 'ham'}))
2931 self.assertEqual(self.call(test, 1, 2, 4, foo='bar'),
2932 (1, 2, 4, {'foo': 'bar'}))
2933 self.assertEqual(self.call(test, c=5, a=4, b=3),
2934 (4, 3, 5, {}))
2935
2936 def test_signature_bind_kwonly(self):
2937 def test(*, foo):
2938 return foo
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002939 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002940 'too many positional arguments'):
2941 self.call(test, 1)
2942 self.assertEqual(self.call(test, foo=1), 1)
2943
2944 def test(a, *, foo=1, bar):
2945 return foo
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002946 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002947 "'bar' parameter lacking default value"):
2948 self.call(test, 1)
2949
2950 def test(foo, *, bar):
2951 return foo, bar
2952 self.assertEqual(self.call(test, 1, bar=2), (1, 2))
2953 self.assertEqual(self.call(test, bar=2, foo=1), (1, 2))
2954
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002955 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002956 'too many keyword arguments'):
2957 self.call(test, bar=2, foo=1, spam=10)
2958
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002959 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002960 'too many positional arguments'):
2961 self.call(test, 1, 2)
2962
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002963 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002964 'too many positional arguments'):
2965 self.call(test, 1, 2, bar=2)
2966
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002967 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002968 'too many keyword arguments'):
2969 self.call(test, 1, bar=2, spam='ham')
2970
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002971 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002972 "'bar' parameter lacking default value"):
2973 self.call(test, 1)
2974
2975 def test(foo, *, bar, **bin):
2976 return foo, bar, bin
2977 self.assertEqual(self.call(test, 1, bar=2), (1, 2, {}))
2978 self.assertEqual(self.call(test, foo=1, bar=2), (1, 2, {}))
2979 self.assertEqual(self.call(test, 1, bar=2, spam='ham'),
2980 (1, 2, {'spam': 'ham'}))
2981 self.assertEqual(self.call(test, spam='ham', foo=1, bar=2),
2982 (1, 2, {'spam': 'ham'}))
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002983 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002984 "'foo' parameter lacking default value"):
2985 self.call(test, spam='ham', bar=2)
2986 self.assertEqual(self.call(test, 1, bar=2, bin=1, spam=10),
2987 (1, 2, {'bin': 1, 'spam': 10}))
2988
2989 def test_signature_bind_arguments(self):
2990 def test(a, *args, b, z=100, **kwargs):
2991 pass
2992 sig = inspect.signature(test)
2993 ba = sig.bind(10, 20, b=30, c=40, args=50, kwargs=60)
2994 # we won't have 'z' argument in the bound arguments object, as we didn't
2995 # pass it to the 'bind'
2996 self.assertEqual(tuple(ba.arguments.items()),
2997 (('a', 10), ('args', (20,)), ('b', 30),
2998 ('kwargs', {'c': 40, 'args': 50, 'kwargs': 60})))
2999 self.assertEqual(ba.kwargs,
3000 {'b': 30, 'c': 40, 'args': 50, 'kwargs': 60})
3001 self.assertEqual(ba.args, (10, 20))
3002
3003 def test_signature_bind_positional_only(self):
3004 P = inspect.Parameter
3005
3006 def test(a_po, b_po, c_po=3, foo=42, *, bar=50, **kwargs):
3007 return a_po, b_po, c_po, foo, bar, kwargs
3008
3009 sig = inspect.signature(test)
3010 new_params = collections.OrderedDict(tuple(sig.parameters.items()))
3011 for name in ('a_po', 'b_po', 'c_po'):
3012 new_params[name] = new_params[name].replace(kind=P.POSITIONAL_ONLY)
3013 new_sig = sig.replace(parameters=new_params.values())
3014 test.__signature__ = new_sig
3015
3016 self.assertEqual(self.call(test, 1, 2, 4, 5, bar=6),
3017 (1, 2, 4, 5, 6, {}))
3018
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05003019 self.assertEqual(self.call(test, 1, 2),
3020 (1, 2, 3, 42, 50, {}))
3021
3022 self.assertEqual(self.call(test, 1, 2, foo=4, bar=5),
3023 (1, 2, 3, 4, 5, {}))
3024
3025 with self.assertRaisesRegex(TypeError, "but was passed as a keyword"):
3026 self.call(test, 1, 2, foo=4, bar=5, c_po=10)
3027
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003028 with self.assertRaisesRegex(TypeError, "parameter is positional only"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003029 self.call(test, 1, 2, c_po=4)
3030
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003031 with self.assertRaisesRegex(TypeError, "parameter is positional only"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003032 self.call(test, a_po=1, b_po=2)
3033
Antoine Pitroubd41d1b2013-01-29 21:20:57 +01003034 def test_signature_bind_with_self_arg(self):
3035 # Issue #17071: one of the parameters is named "self
3036 def test(a, self, b):
3037 pass
3038 sig = inspect.signature(test)
3039 ba = sig.bind(1, 2, 3)
3040 self.assertEqual(ba.args, (1, 2, 3))
3041 ba = sig.bind(1, self=2, b=3)
3042 self.assertEqual(ba.args, (1, 2, 3))
3043
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05003044 def test_signature_bind_vararg_name(self):
3045 def test(a, *args):
3046 return a, args
3047 sig = inspect.signature(test)
3048
3049 with self.assertRaisesRegex(TypeError, "too many keyword arguments"):
3050 sig.bind(a=0, args=1)
3051
3052 def test(*args, **kwargs):
3053 return args, kwargs
3054 self.assertEqual(self.call(test, args=1), ((), {'args': 1}))
3055
3056 sig = inspect.signature(test)
3057 ba = sig.bind(args=1)
3058 self.assertEqual(ba.arguments, {'kwargs': {'args': 1}})
3059
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003060
3061class TestBoundArguments(unittest.TestCase):
3062 def test_signature_bound_arguments_unhashable(self):
3063 def foo(a): pass
3064 ba = inspect.signature(foo).bind(1)
3065
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003066 with self.assertRaisesRegex(TypeError, 'unhashable type'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003067 hash(ba)
3068
3069 def test_signature_bound_arguments_equality(self):
3070 def foo(a): pass
3071 ba = inspect.signature(foo).bind(1)
3072 self.assertEqual(ba, ba)
3073
3074 ba2 = inspect.signature(foo).bind(1)
3075 self.assertEqual(ba, ba2)
3076
3077 ba3 = inspect.signature(foo).bind(2)
3078 self.assertNotEqual(ba, ba3)
3079 ba3.arguments['a'] = 1
3080 self.assertEqual(ba, ba3)
3081
3082 def bar(b): pass
3083 ba4 = inspect.signature(bar).bind(1)
3084 self.assertNotEqual(ba, ba4)
3085
Yury Selivanova5d63dd2014-03-27 11:31:43 -04003086 def test_signature_bound_arguments_pickle(self):
3087 def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
3088 sig = inspect.signature(foo)
3089 ba = sig.bind(20, 30, z={})
3090
3091 for ver in range(pickle.HIGHEST_PROTOCOL + 1):
3092 with self.subTest(pickle_ver=ver):
3093 ba_pickled = pickle.loads(pickle.dumps(ba, ver))
3094 self.assertEqual(ba, ba_pickled)
3095
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003096
Yury Selivanovd82eddc2014-01-29 11:24:39 -05003097class TestSignaturePrivateHelpers(unittest.TestCase):
3098 def test_signature_get_bound_param(self):
3099 getter = inspect._signature_get_bound_param
3100
3101 self.assertEqual(getter('($self)'), 'self')
3102 self.assertEqual(getter('($self, obj)'), 'self')
3103 self.assertEqual(getter('($cls, /, obj)'), 'cls')
3104
Larry Hastings2623c8c2014-02-08 22:15:29 -08003105 def _strip_non_python_syntax(self, input,
3106 clean_signature, self_parameter, last_positional_only):
3107 computed_clean_signature, \
3108 computed_self_parameter, \
3109 computed_last_positional_only = \
3110 inspect._signature_strip_non_python_syntax(input)
3111 self.assertEqual(computed_clean_signature, clean_signature)
3112 self.assertEqual(computed_self_parameter, self_parameter)
3113 self.assertEqual(computed_last_positional_only, last_positional_only)
3114
3115 def test_signature_strip_non_python_syntax(self):
3116 self._strip_non_python_syntax(
3117 "($module, /, path, mode, *, dir_fd=None, " +
3118 "effective_ids=False,\n follow_symlinks=True)",
3119 "(module, path, mode, *, dir_fd=None, " +
3120 "effective_ids=False, follow_symlinks=True)",
3121 0,
3122 0)
3123
3124 self._strip_non_python_syntax(
3125 "($module, word, salt, /)",
3126 "(module, word, salt)",
3127 0,
3128 2)
3129
3130 self._strip_non_python_syntax(
3131 "(x, y=None, z=None, /)",
3132 "(x, y=None, z=None)",
3133 None,
3134 2)
3135
3136 self._strip_non_python_syntax(
3137 "(x, y=None, z=None)",
3138 "(x, y=None, z=None)",
3139 None,
3140 None)
3141
3142 self._strip_non_python_syntax(
3143 "(x,\n y=None,\n z = None )",
3144 "(x, y=None, z=None)",
3145 None,
3146 None)
3147
3148 self._strip_non_python_syntax(
3149 "",
3150 "",
3151 None,
3152 None)
3153
3154 self._strip_non_python_syntax(
3155 None,
3156 None,
3157 None,
3158 None)
3159
Yury Selivanovd82eddc2014-01-29 11:24:39 -05003160
Nick Coghlane8c45d62013-07-28 20:00:01 +10003161class TestUnwrap(unittest.TestCase):
3162
3163 def test_unwrap_one(self):
3164 def func(a, b):
3165 return a + b
3166 wrapper = functools.lru_cache(maxsize=20)(func)
3167 self.assertIs(inspect.unwrap(wrapper), func)
3168
3169 def test_unwrap_several(self):
3170 def func(a, b):
3171 return a + b
3172 wrapper = func
3173 for __ in range(10):
3174 @functools.wraps(wrapper)
3175 def wrapper():
3176 pass
3177 self.assertIsNot(wrapper.__wrapped__, func)
3178 self.assertIs(inspect.unwrap(wrapper), func)
3179
3180 def test_stop(self):
3181 def func1(a, b):
3182 return a + b
3183 @functools.wraps(func1)
3184 def func2():
3185 pass
3186 @functools.wraps(func2)
3187 def wrapper():
3188 pass
3189 func2.stop_here = 1
3190 unwrapped = inspect.unwrap(wrapper,
3191 stop=(lambda f: hasattr(f, "stop_here")))
3192 self.assertIs(unwrapped, func2)
3193
3194 def test_cycle(self):
3195 def func1(): pass
3196 func1.__wrapped__ = func1
3197 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3198 inspect.unwrap(func1)
3199
3200 def func2(): pass
3201 func2.__wrapped__ = func1
3202 func1.__wrapped__ = func2
3203 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3204 inspect.unwrap(func1)
3205 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3206 inspect.unwrap(func2)
3207
3208 def test_unhashable(self):
3209 def func(): pass
3210 func.__wrapped__ = None
3211 class C:
3212 __hash__ = None
3213 __wrapped__ = func
3214 self.assertIsNone(inspect.unwrap(C()))
3215
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003216class TestMain(unittest.TestCase):
3217 def test_only_source(self):
3218 module = importlib.import_module('unittest')
3219 rc, out, err = assert_python_ok('-m', 'inspect',
3220 'unittest')
3221 lines = out.decode().splitlines()
3222 # ignore the final newline
3223 self.assertEqual(lines[:-1], inspect.getsource(module).splitlines())
3224 self.assertEqual(err, b'')
3225
Yury Selivanov42407ab2014-06-23 10:23:50 -07003226 def test_custom_getattr(self):
3227 def foo():
3228 pass
3229 foo.__signature__ = 42
3230 with self.assertRaises(TypeError):
3231 inspect.signature(foo)
3232
Brett Cannon634a8fc2013-10-02 10:25:42 -04003233 @unittest.skipIf(ThreadPoolExecutor is None,
Brett Cannon0de3f012013-10-02 10:58:58 -04003234 'threads required to test __qualname__ for source files')
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003235 def test_qualname_source(self):
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003236 rc, out, err = assert_python_ok('-m', 'inspect',
3237 'concurrent.futures:ThreadPoolExecutor')
3238 lines = out.decode().splitlines()
3239 # ignore the final newline
3240 self.assertEqual(lines[:-1],
Brett Cannon634a8fc2013-10-02 10:25:42 -04003241 inspect.getsource(ThreadPoolExecutor).splitlines())
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003242 self.assertEqual(err, b'')
3243
3244 def test_builtins(self):
3245 module = importlib.import_module('unittest')
3246 _, out, err = assert_python_failure('-m', 'inspect',
3247 'sys')
3248 lines = err.decode().splitlines()
3249 self.assertEqual(lines, ["Can't get info for builtin modules."])
3250
3251 def test_details(self):
3252 module = importlib.import_module('unittest')
3253 rc, out, err = assert_python_ok('-m', 'inspect',
3254 'unittest', '--details')
3255 output = out.decode()
3256 # Just a quick sanity check on the output
3257 self.assertIn(module.__name__, output)
3258 self.assertIn(module.__file__, output)
Serhiy Storchakab12cb6a2013-12-08 18:16:18 +02003259 if not sys.flags.optimize:
3260 self.assertIn(module.__cached__, output)
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003261 self.assertEqual(err, b'')
3262
3263
3264
Nick Coghlane8c45d62013-07-28 20:00:01 +10003265
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00003266def test_main():
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00003267 run_unittest(
3268 TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBuggyCases,
3269 TestInterpreterStack, TestClassesAndFunctions, TestPredicates,
3270 TestGetcallargsFunctions, TestGetcallargsMethods,
Alexander Belopolskyf546e702010-12-02 00:10:11 +00003271 TestGetcallargsUnboundMethods, TestGetattrStatic, TestGetGeneratorState,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003272 TestNoEOL, TestSignatureObject, TestSignatureBind, TestParameterObject,
Yury Selivanovd82eddc2014-01-29 11:24:39 -05003273 TestBoundArguments, TestSignaturePrivateHelpers, TestGetClosureVars,
3274 TestUnwrap, TestMain
Michael Foord95fc51d2010-11-20 15:07:30 +00003275 )
Martin v. Löwis893ffa42003-10-31 15:35:53 +00003276
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00003277if __name__ == "__main__":
3278 test_main()