blob: 9586041dee8d5d16a081a5d370bbe5d1db6e829d [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 Murray32562d72014-10-03 11:15:38 -0400449 # This should not skip for CPython, but might on a repackaged python where
450 # unicodedata is not an external module, or on pypy.
451 @unittest.skipIf(not hasattr(unicodedata, '__file__') or
452 unicodedata.__file__.endswith('.py'),
453 "unicodedata is not an external binary module")
R. David Murray74b89242009-05-13 17:33:03 +0000454 def test_findsource_binary(self):
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200455 self.assertRaises(OSError, inspect.getsource, unicodedata)
456 self.assertRaises(OSError, inspect.findsource, unicodedata)
R. David Murray74b89242009-05-13 17:33:03 +0000457
R. David Murraya1b37402010-06-17 02:04:29 +0000458 def test_findsource_code_in_linecache(self):
459 lines = ["x=1"]
460 co = compile(lines[0], "_dynamically_created_file", "exec")
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200461 self.assertRaises(OSError, inspect.findsource, co)
462 self.assertRaises(OSError, inspect.getsource, co)
R. David Murraya1b37402010-06-17 02:04:29 +0000463 linecache.cache[co.co_filename] = (1, None, lines, co.co_filename)
Antoine Pitrou5d62a612012-07-08 13:48:46 +0200464 try:
465 self.assertEqual(inspect.findsource(co), (lines,0))
466 self.assertEqual(inspect.getsource(co), lines[0])
467 finally:
468 del linecache.cache[co.co_filename]
R. David Murraya1b37402010-06-17 02:04:29 +0000469
Ezio Melotti1b145922013-03-30 05:17:24 +0200470 def test_findsource_without_filename(self):
471 for fname in ['', '<string>']:
472 co = compile('x=1', fname, "exec")
473 self.assertRaises(IOError, inspect.findsource, co)
474 self.assertRaises(IOError, inspect.getsource, co)
475
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000476class TestNoEOL(GetSourceBase):
477 def __init__(self, *args, **kwargs):
478 self.tempdir = TESTFN + '_dir'
479 os.mkdir(self.tempdir)
480 with open(os.path.join(self.tempdir,
481 'inspect_fodder3%spy' % os.extsep), 'w') as f:
482 f.write("class X:\n pass # No EOL")
483 with DirsOnSysPath(self.tempdir):
484 import inspect_fodder3 as mod3
485 self.fodderModule = mod3
486 GetSourceBase.__init__(self, *args, **kwargs)
487
488 def tearDown(self):
489 shutil.rmtree(self.tempdir)
490
491 def test_class(self):
492 self.assertSourceEqual(self.fodderModule.X, 1, 2)
493
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100494
495class _BrokenDataDescriptor(object):
496 """
497 A broken data descriptor. See bug #1785.
498 """
499 def __get__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700500 raise AttributeError("broken data descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100501
502 def __set__(*args):
503 raise RuntimeError
504
505 def __getattr__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700506 raise AttributeError("broken data descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100507
508
509class _BrokenMethodDescriptor(object):
510 """
511 A broken method descriptor. See bug #1785.
512 """
513 def __get__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700514 raise AttributeError("broken method descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100515
516 def __getattr__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700517 raise AttributeError("broken method descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100518
519
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000520# Helper for testing classify_class_attrs.
Tim Peters13b49d32001-09-23 02:00:29 +0000521def attrs_wo_objs(cls):
522 return [t[:3] for t in inspect.classify_class_attrs(cls)]
523
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100524
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000525class TestClassesAndFunctions(unittest.TestCase):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000526 def test_newstyle_mro(self):
527 # The same w/ new-class MRO.
528 class A(object): pass
529 class B(A): pass
530 class C(A): pass
531 class D(B, C): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000532
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000533 expected = (D, B, C, A, object)
534 got = inspect.getmro(D)
535 self.assertEqual(expected, got)
Tim Peters13b49d32001-09-23 02:00:29 +0000536
Christian Heimes3795b532007-11-08 13:48:53 +0000537 def assertArgSpecEquals(self, routine, args_e, varargs_e=None,
538 varkw_e=None, defaults_e=None, formatted=None):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000539 args, varargs, varkw, defaults = inspect.getargspec(routine)
540 self.assertEqual(args, args_e)
541 self.assertEqual(varargs, varargs_e)
542 self.assertEqual(varkw, varkw_e)
543 self.assertEqual(defaults, defaults_e)
544 if formatted is not None:
545 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults),
546 formatted)
Tim Peters13b49d32001-09-23 02:00:29 +0000547
Christian Heimes3795b532007-11-08 13:48:53 +0000548 def assertFullArgSpecEquals(self, routine, args_e, varargs_e=None,
549 varkw_e=None, defaults_e=None,
550 kwonlyargs_e=[], kwonlydefaults_e=None,
551 ann_e={}, formatted=None):
552 args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \
553 inspect.getfullargspec(routine)
554 self.assertEqual(args, args_e)
555 self.assertEqual(varargs, varargs_e)
556 self.assertEqual(varkw, varkw_e)
557 self.assertEqual(defaults, defaults_e)
558 self.assertEqual(kwonlyargs, kwonlyargs_e)
559 self.assertEqual(kwonlydefaults, kwonlydefaults_e)
560 self.assertEqual(ann, ann_e)
561 if formatted is not None:
562 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults,
563 kwonlyargs, kwonlydefaults, ann),
564 formatted)
565
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000566 def test_getargspec(self):
Christian Heimes3795b532007-11-08 13:48:53 +0000567 self.assertArgSpecEquals(mod.eggs, ['x', 'y'], formatted='(x, y)')
Tim Peters13b49d32001-09-23 02:00:29 +0000568
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000569 self.assertArgSpecEquals(mod.spam,
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000570 ['a', 'b', 'c', 'd', 'e', 'f'],
571 'g', 'h', (3, 4, 5),
572 '(a, b, c, d=3, e=4, f=5, *g, **h)')
Tim Peters13b49d32001-09-23 02:00:29 +0000573
Christian Heimes3795b532007-11-08 13:48:53 +0000574 self.assertRaises(ValueError, self.assertArgSpecEquals,
575 mod2.keyworded, [])
576
577 self.assertRaises(ValueError, self.assertArgSpecEquals,
578 mod2.annotated, [])
Benjamin Peterson9953a8d2009-01-17 04:15:01 +0000579 self.assertRaises(ValueError, self.assertArgSpecEquals,
580 mod2.keyword_only_arg, [])
581
Christian Heimes3795b532007-11-08 13:48:53 +0000582
583 def test_getfullargspec(self):
584 self.assertFullArgSpecEquals(mod2.keyworded, [], varargs_e='arg1',
585 kwonlyargs_e=['arg2'],
586 kwonlydefaults_e={'arg2':1},
587 formatted='(*arg1, arg2=1)')
588
589 self.assertFullArgSpecEquals(mod2.annotated, ['arg1'],
Christian Heimesc9543e42007-11-28 08:28:28 +0000590 ann_e={'arg1' : list},
Christian Heimes3795b532007-11-08 13:48:53 +0000591 formatted='(arg1: list)')
Benjamin Peterson9953a8d2009-01-17 04:15:01 +0000592 self.assertFullArgSpecEquals(mod2.keyword_only_arg, [],
593 kwonlyargs_e=['arg'],
594 formatted='(*, arg)')
595
Yury Selivanov57d240e2014-02-19 16:27:23 -0500596 def test_argspec_api_ignores_wrapped(self):
597 # Issue 20684: low level introspection API must ignore __wrapped__
598 @functools.wraps(mod.spam)
599 def ham(x, y):
600 pass
601 # Basic check
602 self.assertArgSpecEquals(ham, ['x', 'y'], formatted='(x, y)')
603 self.assertFullArgSpecEquals(ham, ['x', 'y'], formatted='(x, y)')
604 self.assertFullArgSpecEquals(functools.partial(ham),
605 ['x', 'y'], formatted='(x, y)')
606 # Other variants
607 def check_method(f):
608 self.assertArgSpecEquals(f, ['self', 'x', 'y'],
609 formatted='(self, x, y)')
610 class C:
611 @functools.wraps(mod.spam)
612 def ham(self, x, y):
613 pass
614 pham = functools.partialmethod(ham)
615 @functools.wraps(mod.spam)
616 def __call__(self, x, y):
617 pass
618 check_method(C())
619 check_method(C.ham)
620 check_method(C().ham)
621 check_method(C.pham)
622 check_method(C().pham)
623
624 class C_new:
625 @functools.wraps(mod.spam)
626 def __new__(self, x, y):
627 pass
628 check_method(C_new)
629
630 class C_init:
631 @functools.wraps(mod.spam)
632 def __init__(self, x, y):
633 pass
634 check_method(C_init)
635
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500636 def test_getfullargspec_signature_attr(self):
637 def test():
638 pass
639 spam_param = inspect.Parameter('spam', inspect.Parameter.POSITIONAL_ONLY)
640 test.__signature__ = inspect.Signature(parameters=(spam_param,))
641
642 self.assertFullArgSpecEquals(test, args_e=['spam'], formatted='(spam)')
643
Yury Selivanov4cb93912014-01-29 11:54:12 -0500644 def test_getfullargspec_signature_annos(self):
645 def test(a:'spam') -> 'ham': pass
646 spec = inspect.getfullargspec(test)
647 self.assertEqual(test.__annotations__, spec.annotations)
648
649 def test(): pass
650 spec = inspect.getfullargspec(test)
651 self.assertEqual(test.__annotations__, spec.annotations)
652
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500653 @unittest.skipIf(MISSING_C_DOCSTRINGS,
654 "Signature information for builtins requires docstrings")
655 def test_getfullargspec_builtin_methods(self):
656 self.assertFullArgSpecEquals(_pickle.Pickler.dump,
657 args_e=['self', 'obj'], formatted='(self, obj)')
658
659 self.assertFullArgSpecEquals(_pickle.Pickler(io.BytesIO()).dump,
660 args_e=['self', 'obj'], formatted='(self, obj)')
661
Yury Selivanov8c185ee2014-02-21 01:32:42 -0500662 self.assertFullArgSpecEquals(
663 os.stat,
664 args_e=['path'],
665 kwonlyargs_e=['dir_fd', 'follow_symlinks'],
666 kwonlydefaults_e={'dir_fd': None, 'follow_symlinks': True},
667 formatted='(path, *, dir_fd=None, follow_symlinks=True)')
668
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200669 @cpython_only
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500670 @unittest.skipIf(MISSING_C_DOCSTRINGS,
671 "Signature information for builtins requires docstrings")
672 def test_getfullagrspec_builtin_func(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200673 import _testcapi
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500674 builtin = _testcapi.docstring_with_signature_with_defaults
675 spec = inspect.getfullargspec(builtin)
676 self.assertEqual(spec.defaults[0], 'avocado')
677
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200678 @cpython_only
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500679 @unittest.skipIf(MISSING_C_DOCSTRINGS,
680 "Signature information for builtins requires docstrings")
681 def test_getfullagrspec_builtin_func_no_signature(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200682 import _testcapi
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500683 builtin = _testcapi.docstring_no_signature
684 with self.assertRaises(TypeError):
685 inspect.getfullargspec(builtin)
Christian Heimes3795b532007-11-08 13:48:53 +0000686
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000687 def test_getargspec_method(self):
688 class A(object):
689 def m(self):
690 pass
691 self.assertArgSpecEquals(A.m, ['self'])
Tim Peters13b49d32001-09-23 02:00:29 +0000692
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000693 def test_classify_newstyle(self):
694 class A(object):
Tim Peters13b49d32001-09-23 02:00:29 +0000695
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000696 def s(): pass
697 s = staticmethod(s)
Tim Peters13b49d32001-09-23 02:00:29 +0000698
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000699 def c(cls): pass
700 c = classmethod(c)
Tim Peters13b49d32001-09-23 02:00:29 +0000701
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000702 def getp(self): pass
703 p = property(getp)
Tim Peters13b49d32001-09-23 02:00:29 +0000704
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000705 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000706
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000707 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000708
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000709 datablob = '1'
Tim Peters13b49d32001-09-23 02:00:29 +0000710
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100711 dd = _BrokenDataDescriptor()
712 md = _BrokenMethodDescriptor()
713
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000714 attrs = attrs_wo_objs(A)
Yury Selivanov0860a0b2014-01-31 14:28:44 -0500715
716 self.assertIn(('__new__', 'method', object), attrs, 'missing __new__')
717 self.assertIn(('__init__', 'method', object), attrs, 'missing __init__')
718
Benjamin Peterson577473f2010-01-19 00:09:57 +0000719 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
720 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
721 self.assertIn(('p', 'property', A), attrs, 'missing property')
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000722 self.assertIn(('m', 'method', A), attrs,
723 'missing plain method: %r' % attrs)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000724 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
725 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100726 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
727 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000728
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000729 class B(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000730
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000731 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000732
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000733 attrs = attrs_wo_objs(B)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000734 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
735 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
736 self.assertIn(('p', 'property', A), attrs, 'missing property')
737 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
738 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
739 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100740 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
741 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000742
743
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000744 class C(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000745
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000746 def m(self): pass
747 def c(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000748
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000749 attrs = attrs_wo_objs(C)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000750 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
751 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
752 self.assertIn(('p', 'property', A), attrs, 'missing property')
753 self.assertIn(('m', 'method', C), attrs, 'missing plain method')
754 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
755 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100756 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
757 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000758
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000759 class D(B, C):
Tim Peters13b49d32001-09-23 02:00:29 +0000760
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000761 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000762
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000763 attrs = attrs_wo_objs(D)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000764 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
765 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
766 self.assertIn(('p', 'property', A), attrs, 'missing property')
767 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
768 self.assertIn(('m1', 'method', D), attrs, 'missing plain method')
769 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100770 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
771 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
772
773 def test_classify_builtin_types(self):
774 # Simple sanity check that all built-in types can have their
775 # attributes classified.
776 for name in dir(__builtins__):
777 builtin = getattr(__builtins__, name)
778 if isinstance(builtin, type):
779 inspect.classify_class_attrs(builtin)
780
Ethan Furman63c141c2013-10-18 00:27:39 -0700781 def test_classify_DynamicClassAttribute(self):
782 class Meta(type):
783 def __getattr__(self, name):
784 if name == 'ham':
785 return 'spam'
786 return super().__getattr__(name)
787 class VA(metaclass=Meta):
Ethan Furmane03ea372013-09-25 07:14:41 -0700788 @types.DynamicClassAttribute
789 def ham(self):
790 return 'eggs'
Ethan Furman63c141c2013-10-18 00:27:39 -0700791 should_find_dca = inspect.Attribute('ham', 'data', VA, VA.__dict__['ham'])
792 self.assertIn(should_find_dca, inspect.classify_class_attrs(VA))
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700793 should_find_ga = inspect.Attribute('ham', 'data', Meta, 'spam')
Ethan Furman63c141c2013-10-18 00:27:39 -0700794 self.assertIn(should_find_ga, inspect.classify_class_attrs(VA))
795
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700796 def test_classify_metaclass_class_attribute(self):
797 class Meta(type):
798 fish = 'slap'
799 def __dir__(self):
800 return ['__class__', '__modules__', '__name__', 'fish']
801 class Class(metaclass=Meta):
802 pass
803 should_find = inspect.Attribute('fish', 'data', Meta, 'slap')
804 self.assertIn(should_find, inspect.classify_class_attrs(Class))
805
Ethan Furman63c141c2013-10-18 00:27:39 -0700806 def test_classify_VirtualAttribute(self):
807 class Meta(type):
808 def __dir__(cls):
809 return ['__class__', '__module__', '__name__', 'BOOM']
810 def __getattr__(self, name):
811 if name =='BOOM':
812 return 42
813 return super().__getattr(name)
814 class Class(metaclass=Meta):
815 pass
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700816 should_find = inspect.Attribute('BOOM', 'data', Meta, 42)
Ethan Furman63c141c2013-10-18 00:27:39 -0700817 self.assertIn(should_find, inspect.classify_class_attrs(Class))
818
819 def test_classify_VirtualAttribute_multi_classes(self):
820 class Meta1(type):
821 def __dir__(cls):
822 return ['__class__', '__module__', '__name__', 'one']
823 def __getattr__(self, name):
824 if name =='one':
825 return 1
826 return super().__getattr__(name)
827 class Meta2(type):
828 def __dir__(cls):
829 return ['__class__', '__module__', '__name__', 'two']
830 def __getattr__(self, name):
831 if name =='two':
832 return 2
833 return super().__getattr__(name)
834 class Meta3(Meta1, Meta2):
835 def __dir__(cls):
836 return list(sorted(set(['__class__', '__module__', '__name__', 'three'] +
837 Meta1.__dir__(cls) + Meta2.__dir__(cls))))
838 def __getattr__(self, name):
839 if name =='three':
840 return 3
841 return super().__getattr__(name)
842 class Class1(metaclass=Meta1):
843 pass
844 class Class2(Class1, metaclass=Meta3):
845 pass
846
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700847 should_find1 = inspect.Attribute('one', 'data', Meta1, 1)
848 should_find2 = inspect.Attribute('two', 'data', Meta2, 2)
849 should_find3 = inspect.Attribute('three', 'data', Meta3, 3)
Ethan Furman63c141c2013-10-18 00:27:39 -0700850 cca = inspect.classify_class_attrs(Class2)
851 for sf in (should_find1, should_find2, should_find3):
852 self.assertIn(sf, cca)
853
854 def test_classify_class_attrs_with_buggy_dir(self):
855 class M(type):
856 def __dir__(cls):
857 return ['__class__', '__name__', 'missing']
858 class C(metaclass=M):
859 pass
860 attrs = [a[0] for a in inspect.classify_class_attrs(C)]
861 self.assertNotIn('missing', attrs)
Ethan Furmane03ea372013-09-25 07:14:41 -0700862
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100863 def test_getmembers_descriptors(self):
864 class A(object):
865 dd = _BrokenDataDescriptor()
866 md = _BrokenMethodDescriptor()
867
868 def pred_wrapper(pred):
869 # A quick'n'dirty way to discard standard attributes of new-style
870 # classes.
871 class Empty(object):
872 pass
873 def wrapped(x):
874 if '__name__' in dir(x) and hasattr(Empty, x.__name__):
875 return False
876 return pred(x)
877 return wrapped
878
879 ismethoddescriptor = pred_wrapper(inspect.ismethoddescriptor)
880 isdatadescriptor = pred_wrapper(inspect.isdatadescriptor)
881
882 self.assertEqual(inspect.getmembers(A, ismethoddescriptor),
883 [('md', A.__dict__['md'])])
884 self.assertEqual(inspect.getmembers(A, isdatadescriptor),
885 [('dd', A.__dict__['dd'])])
886
887 class B(A):
888 pass
889
890 self.assertEqual(inspect.getmembers(B, ismethoddescriptor),
891 [('md', A.__dict__['md'])])
892 self.assertEqual(inspect.getmembers(B, isdatadescriptor),
893 [('dd', A.__dict__['dd'])])
894
Antoine Pitrou0c603812012-01-18 17:40:18 +0100895 def test_getmembers_method(self):
896 class B:
897 def f(self):
898 pass
899
900 self.assertIn(('f', B.f), inspect.getmembers(B))
901 self.assertNotIn(('f', B.f), inspect.getmembers(B, inspect.ismethod))
902 b = B()
903 self.assertIn(('f', b.f), inspect.getmembers(b))
904 self.assertIn(('f', b.f), inspect.getmembers(b, inspect.ismethod))
905
Ethan Furmane03ea372013-09-25 07:14:41 -0700906 def test_getmembers_VirtualAttribute(self):
Ethan Furman63c141c2013-10-18 00:27:39 -0700907 class M(type):
908 def __getattr__(cls, name):
909 if name == 'eggs':
910 return 'scrambled'
911 return super().__getattr__(name)
912 class A(metaclass=M):
Ethan Furmane03ea372013-09-25 07:14:41 -0700913 @types.DynamicClassAttribute
914 def eggs(self):
915 return 'spam'
Ethan Furman63c141c2013-10-18 00:27:39 -0700916 self.assertIn(('eggs', 'scrambled'), inspect.getmembers(A))
917 self.assertIn(('eggs', 'spam'), inspect.getmembers(A()))
918
919 def test_getmembers_with_buggy_dir(self):
920 class M(type):
921 def __dir__(cls):
922 return ['__class__', '__name__', 'missing']
923 class C(metaclass=M):
924 pass
925 attrs = [a[0] for a in inspect.getmembers(C)]
926 self.assertNotIn('missing', attrs)
Ethan Furmane03ea372013-09-25 07:14:41 -0700927
Jeremy Hyltonc4bf5ed2003-06-27 18:43:12 +0000928
Nick Coghlan2f92e542012-06-23 19:39:55 +1000929_global_ref = object()
930class TestGetClosureVars(unittest.TestCase):
931
932 def test_name_resolution(self):
933 # Basic test of the 4 different resolution mechanisms
934 def f(nonlocal_ref):
935 def g(local_ref):
936 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
937 return g
938 _arg = object()
939 nonlocal_vars = {"nonlocal_ref": _arg}
940 global_vars = {"_global_ref": _global_ref}
941 builtin_vars = {"print": print}
942 unbound_names = {"unbound_ref"}
943 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
944 builtin_vars, unbound_names)
945 self.assertEqual(inspect.getclosurevars(f(_arg)), expected)
946
947 def test_generator_closure(self):
948 def f(nonlocal_ref):
949 def g(local_ref):
950 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
951 yield
952 return g
953 _arg = object()
954 nonlocal_vars = {"nonlocal_ref": _arg}
955 global_vars = {"_global_ref": _global_ref}
956 builtin_vars = {"print": print}
957 unbound_names = {"unbound_ref"}
958 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
959 builtin_vars, unbound_names)
960 self.assertEqual(inspect.getclosurevars(f(_arg)), expected)
961
962 def test_method_closure(self):
963 class C:
964 def f(self, nonlocal_ref):
965 def g(local_ref):
966 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
967 return g
968 _arg = object()
969 nonlocal_vars = {"nonlocal_ref": _arg}
970 global_vars = {"_global_ref": _global_ref}
971 builtin_vars = {"print": print}
972 unbound_names = {"unbound_ref"}
973 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
974 builtin_vars, unbound_names)
975 self.assertEqual(inspect.getclosurevars(C().f(_arg)), expected)
976
977 def test_nonlocal_vars(self):
978 # More complex tests of nonlocal resolution
979 def _nonlocal_vars(f):
980 return inspect.getclosurevars(f).nonlocals
981
982 def make_adder(x):
983 def add(y):
984 return x + y
985 return add
986
987 def curry(func, arg1):
988 return lambda arg2: func(arg1, arg2)
989
990 def less_than(a, b):
991 return a < b
992
993 # The infamous Y combinator.
994 def Y(le):
995 def g(f):
996 return le(lambda x: f(f)(x))
997 Y.g_ref = g
998 return g(g)
999
1000 def check_y_combinator(func):
1001 self.assertEqual(_nonlocal_vars(func), {'f': Y.g_ref})
1002
1003 inc = make_adder(1)
1004 add_two = make_adder(2)
1005 greater_than_five = curry(less_than, 5)
1006
1007 self.assertEqual(_nonlocal_vars(inc), {'x': 1})
1008 self.assertEqual(_nonlocal_vars(add_two), {'x': 2})
1009 self.assertEqual(_nonlocal_vars(greater_than_five),
1010 {'arg1': 5, 'func': less_than})
1011 self.assertEqual(_nonlocal_vars((lambda x: lambda y: x + y)(3)),
1012 {'x': 3})
1013 Y(check_y_combinator)
1014
1015 def test_getclosurevars_empty(self):
1016 def foo(): pass
1017 _empty = inspect.ClosureVars({}, {}, {}, set())
1018 self.assertEqual(inspect.getclosurevars(lambda: True), _empty)
1019 self.assertEqual(inspect.getclosurevars(foo), _empty)
1020
1021 def test_getclosurevars_error(self):
1022 class T: pass
1023 self.assertRaises(TypeError, inspect.getclosurevars, 1)
1024 self.assertRaises(TypeError, inspect.getclosurevars, list)
1025 self.assertRaises(TypeError, inspect.getclosurevars, {})
1026
Nick Coghlan6c6e2542012-06-23 20:07:39 +10001027 def _private_globals(self):
1028 code = """def f(): print(path)"""
1029 ns = {}
1030 exec(code, ns)
1031 return ns["f"], ns
1032
1033 def test_builtins_fallback(self):
1034 f, ns = self._private_globals()
1035 ns.pop("__builtins__", None)
1036 expected = inspect.ClosureVars({}, {}, {"print":print}, {"path"})
1037 self.assertEqual(inspect.getclosurevars(f), expected)
1038
1039 def test_builtins_as_dict(self):
1040 f, ns = self._private_globals()
1041 ns["__builtins__"] = {"path":1}
1042 expected = inspect.ClosureVars({}, {}, {"path":1}, {"print"})
1043 self.assertEqual(inspect.getclosurevars(f), expected)
1044
1045 def test_builtins_as_module(self):
1046 f, ns = self._private_globals()
1047 ns["__builtins__"] = os
1048 expected = inspect.ClosureVars({}, {}, {"path":os.path}, {"print"})
1049 self.assertEqual(inspect.getclosurevars(f), expected)
1050
Nick Coghlan2f92e542012-06-23 19:39:55 +10001051
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001052class TestGetcallargsFunctions(unittest.TestCase):
1053
1054 def assertEqualCallArgs(self, func, call_params_string, locs=None):
1055 locs = dict(locs or {}, func=func)
1056 r1 = eval('func(%s)' % call_params_string, None, locs)
1057 r2 = eval('inspect.getcallargs(func, %s)' % call_params_string, None,
1058 locs)
1059 self.assertEqual(r1, r2)
1060
1061 def assertEqualException(self, func, call_param_string, locs=None):
1062 locs = dict(locs or {}, func=func)
1063 try:
1064 eval('func(%s)' % call_param_string, None, locs)
1065 except Exception as e:
1066 ex1 = e
1067 else:
1068 self.fail('Exception not raised')
1069 try:
1070 eval('inspect.getcallargs(func, %s)' % call_param_string, None,
1071 locs)
1072 except Exception as e:
1073 ex2 = e
1074 else:
1075 self.fail('Exception not raised')
1076 self.assertIs(type(ex1), type(ex2))
1077 self.assertEqual(str(ex1), str(ex2))
1078 del ex1, ex2
1079
1080 def makeCallable(self, signature):
1081 """Create a function that returns its locals()"""
1082 code = "lambda %s: locals()"
1083 return eval(code % signature)
1084
1085 def test_plain(self):
1086 f = self.makeCallable('a, b=1')
1087 self.assertEqualCallArgs(f, '2')
1088 self.assertEqualCallArgs(f, '2, 3')
1089 self.assertEqualCallArgs(f, 'a=2')
1090 self.assertEqualCallArgs(f, 'b=3, a=2')
1091 self.assertEqualCallArgs(f, '2, b=3')
1092 # expand *iterable / **mapping
1093 self.assertEqualCallArgs(f, '*(2,)')
1094 self.assertEqualCallArgs(f, '*[2]')
1095 self.assertEqualCallArgs(f, '*(2, 3)')
1096 self.assertEqualCallArgs(f, '*[2, 3]')
1097 self.assertEqualCallArgs(f, '**{"a":2}')
1098 self.assertEqualCallArgs(f, 'b=3, **{"a":2}')
1099 self.assertEqualCallArgs(f, '2, **{"b":3}')
1100 self.assertEqualCallArgs(f, '**{"b":3, "a":2}')
1101 # expand UserList / UserDict
1102 self.assertEqualCallArgs(f, '*collections.UserList([2])')
1103 self.assertEqualCallArgs(f, '*collections.UserList([2, 3])')
1104 self.assertEqualCallArgs(f, '**collections.UserDict(a=2)')
1105 self.assertEqualCallArgs(f, '2, **collections.UserDict(b=3)')
1106 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3)')
1107
1108 def test_varargs(self):
1109 f = self.makeCallable('a, b=1, *c')
1110 self.assertEqualCallArgs(f, '2')
1111 self.assertEqualCallArgs(f, '2, 3')
1112 self.assertEqualCallArgs(f, '2, 3, 4')
1113 self.assertEqualCallArgs(f, '*(2,3,4)')
1114 self.assertEqualCallArgs(f, '2, *[3,4]')
1115 self.assertEqualCallArgs(f, '2, 3, *collections.UserList([4])')
1116
1117 def test_varkw(self):
1118 f = self.makeCallable('a, b=1, **c')
1119 self.assertEqualCallArgs(f, 'a=2')
1120 self.assertEqualCallArgs(f, '2, b=3, c=4')
1121 self.assertEqualCallArgs(f, 'b=3, a=2, c=4')
1122 self.assertEqualCallArgs(f, 'c=4, **{"a":2, "b":3}')
1123 self.assertEqualCallArgs(f, '2, c=4, **{"b":3}')
1124 self.assertEqualCallArgs(f, 'b=2, **{"a":3, "c":4}')
1125 self.assertEqualCallArgs(f, '**collections.UserDict(a=2, b=3, c=4)')
1126 self.assertEqualCallArgs(f, '2, c=4, **collections.UserDict(b=3)')
1127 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3, c=4)')
1128
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001129 def test_varkw_only(self):
1130 # issue11256:
1131 f = self.makeCallable('**c')
1132 self.assertEqualCallArgs(f, '')
1133 self.assertEqualCallArgs(f, 'a=1')
1134 self.assertEqualCallArgs(f, 'a=1, b=2')
1135 self.assertEqualCallArgs(f, 'c=3, **{"a": 1, "b": 2}')
1136 self.assertEqualCallArgs(f, '**collections.UserDict(a=1, b=2)')
1137 self.assertEqualCallArgs(f, 'c=3, **collections.UserDict(a=1, b=2)')
1138
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001139 def test_keyword_only(self):
1140 f = self.makeCallable('a=3, *, c, d=2')
1141 self.assertEqualCallArgs(f, 'c=3')
1142 self.assertEqualCallArgs(f, 'c=3, a=3')
1143 self.assertEqualCallArgs(f, 'a=2, c=4')
1144 self.assertEqualCallArgs(f, '4, c=4')
1145 self.assertEqualException(f, '')
1146 self.assertEqualException(f, '3')
1147 self.assertEqualException(f, 'a=3')
1148 self.assertEqualException(f, 'd=4')
1149
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001150 f = self.makeCallable('*, c, d=2')
1151 self.assertEqualCallArgs(f, 'c=3')
1152 self.assertEqualCallArgs(f, 'c=3, d=4')
1153 self.assertEqualCallArgs(f, 'd=4, c=3')
1154
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001155 def test_multiple_features(self):
1156 f = self.makeCallable('a, b=2, *f, **g')
1157 self.assertEqualCallArgs(f, '2, 3, 7')
1158 self.assertEqualCallArgs(f, '2, 3, x=8')
1159 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
1160 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9')
1161 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9')
1162 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
1163 '[2, 3, (4,[5,6])]), **{"y":9, "z":10}')
1164 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
1165 '(4,[5,6])]), **collections.UserDict('
1166 'y=9, z=10)')
1167
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001168 f = self.makeCallable('a, b=2, *f, x, y=99, **g')
1169 self.assertEqualCallArgs(f, '2, 3, x=8')
1170 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
1171 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9, z=10')
1172 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9, z=10')
1173 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
1174 '[2, 3, (4,[5,6])]), q=0, **{"y":9, "z":10}')
1175 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
1176 '(4,[5,6])]), q=0, **collections.UserDict('
1177 'y=9, z=10)')
1178
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001179 def test_errors(self):
1180 f0 = self.makeCallable('')
1181 f1 = self.makeCallable('a, b')
1182 f2 = self.makeCallable('a, b=1')
1183 # f0 takes no arguments
1184 self.assertEqualException(f0, '1')
1185 self.assertEqualException(f0, 'x=1')
1186 self.assertEqualException(f0, '1,x=1')
1187 # f1 takes exactly 2 arguments
1188 self.assertEqualException(f1, '')
1189 self.assertEqualException(f1, '1')
1190 self.assertEqualException(f1, 'a=2')
1191 self.assertEqualException(f1, 'b=3')
1192 # f2 takes at least 1 argument
1193 self.assertEqualException(f2, '')
1194 self.assertEqualException(f2, 'b=3')
1195 for f in f1, f2:
1196 # f1/f2 takes exactly/at most 2 arguments
1197 self.assertEqualException(f, '2, 3, 4')
1198 self.assertEqualException(f, '1, 2, 3, a=1')
1199 self.assertEqualException(f, '2, 3, 4, c=5')
Georg Brandl178e5ea2012-02-21 00:32:36 +01001200 # XXX: success of this one depends on dict order
1201 ## self.assertEqualException(f, '2, 3, 4, a=1, c=5')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001202 # f got an unexpected keyword argument
1203 self.assertEqualException(f, 'c=2')
1204 self.assertEqualException(f, '2, c=3')
1205 self.assertEqualException(f, '2, 3, c=4')
1206 self.assertEqualException(f, '2, c=4, b=3')
1207 self.assertEqualException(f, '**{u"\u03c0\u03b9": 4}')
1208 # f got multiple values for keyword argument
1209 self.assertEqualException(f, '1, a=2')
1210 self.assertEqualException(f, '1, **{"a":2}')
1211 self.assertEqualException(f, '1, 2, b=3')
1212 # XXX: Python inconsistency
1213 # - for functions and bound methods: unexpected keyword 'c'
1214 # - for unbound methods: multiple values for keyword 'a'
1215 #self.assertEqualException(f, '1, c=3, a=2')
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001216 # issue11256:
1217 f3 = self.makeCallable('**c')
1218 self.assertEqualException(f3, '1, 2')
1219 self.assertEqualException(f3, '1, 2, a=1, b=2')
1220 f4 = self.makeCallable('*, a, b=0')
1221 self.assertEqualException(f3, '1, 2')
1222 self.assertEqualException(f3, '1, 2, a=1, b=2')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001223
Yury Selivanov875df202014-03-27 18:23:03 -04001224 # issue #20816: getcallargs() fails to iterate over non-existent
1225 # kwonlydefaults and raises a wrong TypeError
1226 def f5(*, a): pass
1227 with self.assertRaisesRegex(TypeError,
1228 'missing 1 required keyword-only'):
1229 inspect.getcallargs(f5)
1230
1231
Yury Selivanovdccfa132014-03-27 18:42:52 -04001232 # issue20817:
1233 def f6(a, b, c):
1234 pass
1235 with self.assertRaisesRegex(TypeError, "'a', 'b' and 'c'"):
1236 inspect.getcallargs(f6)
1237
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001238class TestGetcallargsMethods(TestGetcallargsFunctions):
1239
1240 def setUp(self):
1241 class Foo(object):
1242 pass
1243 self.cls = Foo
1244 self.inst = Foo()
1245
1246 def makeCallable(self, signature):
1247 assert 'self' not in signature
1248 mk = super(TestGetcallargsMethods, self).makeCallable
1249 self.cls.method = mk('self, ' + signature)
1250 return self.inst.method
1251
1252class TestGetcallargsUnboundMethods(TestGetcallargsMethods):
1253
1254 def makeCallable(self, signature):
1255 super(TestGetcallargsUnboundMethods, self).makeCallable(signature)
1256 return self.cls.method
1257
1258 def assertEqualCallArgs(self, func, call_params_string, locs=None):
1259 return super(TestGetcallargsUnboundMethods, self).assertEqualCallArgs(
1260 *self._getAssertEqualParams(func, call_params_string, locs))
1261
1262 def assertEqualException(self, func, call_params_string, locs=None):
1263 return super(TestGetcallargsUnboundMethods, self).assertEqualException(
1264 *self._getAssertEqualParams(func, call_params_string, locs))
1265
1266 def _getAssertEqualParams(self, func, call_params_string, locs=None):
1267 assert 'inst' not in call_params_string
1268 locs = dict(locs or {}, inst=self.inst)
1269 return (func, 'inst,' + call_params_string, locs)
1270
Michael Foord95fc51d2010-11-20 15:07:30 +00001271
1272class TestGetattrStatic(unittest.TestCase):
1273
1274 def test_basic(self):
1275 class Thing(object):
1276 x = object()
1277
1278 thing = Thing()
1279 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1280 self.assertEqual(inspect.getattr_static(thing, 'x', None), Thing.x)
1281 with self.assertRaises(AttributeError):
1282 inspect.getattr_static(thing, 'y')
1283
1284 self.assertEqual(inspect.getattr_static(thing, 'y', 3), 3)
1285
1286 def test_inherited(self):
1287 class Thing(object):
1288 x = object()
1289 class OtherThing(Thing):
1290 pass
1291
1292 something = OtherThing()
1293 self.assertEqual(inspect.getattr_static(something, 'x'), Thing.x)
1294
1295 def test_instance_attr(self):
1296 class Thing(object):
1297 x = 2
1298 def __init__(self, x):
1299 self.x = x
1300 thing = Thing(3)
1301 self.assertEqual(inspect.getattr_static(thing, 'x'), 3)
1302 del thing.x
1303 self.assertEqual(inspect.getattr_static(thing, 'x'), 2)
1304
1305 def test_property(self):
1306 class Thing(object):
1307 @property
1308 def x(self):
1309 raise AttributeError("I'm pretending not to exist")
1310 thing = Thing()
1311 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1312
Ezio Melotti75cbd732011-04-28 00:59:29 +03001313 def test_descriptor_raises_AttributeError(self):
Michael Foord95fc51d2010-11-20 15:07:30 +00001314 class descriptor(object):
1315 def __get__(*_):
1316 raise AttributeError("I'm pretending not to exist")
1317 desc = descriptor()
1318 class Thing(object):
1319 x = desc
1320 thing = Thing()
1321 self.assertEqual(inspect.getattr_static(thing, 'x'), desc)
1322
1323 def test_classAttribute(self):
1324 class Thing(object):
1325 x = object()
1326
1327 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.x)
1328
Ethan Furmane03ea372013-09-25 07:14:41 -07001329 def test_classVirtualAttribute(self):
1330 class Thing(object):
1331 @types.DynamicClassAttribute
1332 def x(self):
1333 return self._x
1334 _x = object()
1335
1336 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.__dict__['x'])
1337
Michael Foord95fc51d2010-11-20 15:07:30 +00001338 def test_inherited_classattribute(self):
1339 class Thing(object):
1340 x = object()
1341 class OtherThing(Thing):
1342 pass
1343
1344 self.assertEqual(inspect.getattr_static(OtherThing, 'x'), Thing.x)
1345
1346 def test_slots(self):
1347 class Thing(object):
1348 y = 'bar'
1349 __slots__ = ['x']
1350 def __init__(self):
1351 self.x = 'foo'
1352 thing = Thing()
1353 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1354 self.assertEqual(inspect.getattr_static(thing, 'y'), 'bar')
1355
1356 del thing.x
1357 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1358
1359 def test_metaclass(self):
1360 class meta(type):
1361 attr = 'foo'
1362 class Thing(object, metaclass=meta):
1363 pass
1364 self.assertEqual(inspect.getattr_static(Thing, 'attr'), 'foo')
1365
1366 class sub(meta):
1367 pass
1368 class OtherThing(object, metaclass=sub):
1369 x = 3
1370 self.assertEqual(inspect.getattr_static(OtherThing, 'attr'), 'foo')
1371
1372 class OtherOtherThing(OtherThing):
1373 pass
1374 # this test is odd, but it was added as it exposed a bug
1375 self.assertEqual(inspect.getattr_static(OtherOtherThing, 'x'), 3)
1376
1377 def test_no_dict_no_slots(self):
1378 self.assertEqual(inspect.getattr_static(1, 'foo', None), None)
1379 self.assertNotEqual(inspect.getattr_static('foo', 'lower'), None)
1380
1381 def test_no_dict_no_slots_instance_member(self):
1382 # returns descriptor
1383 with open(__file__) as handle:
1384 self.assertEqual(inspect.getattr_static(handle, 'name'), type(handle).name)
1385
1386 def test_inherited_slots(self):
1387 # returns descriptor
1388 class Thing(object):
1389 __slots__ = ['x']
1390 def __init__(self):
1391 self.x = 'foo'
1392
1393 class OtherThing(Thing):
1394 pass
1395 # it would be nice if this worked...
1396 # we get the descriptor instead of the instance attribute
1397 self.assertEqual(inspect.getattr_static(OtherThing(), 'x'), Thing.x)
1398
1399 def test_descriptor(self):
1400 class descriptor(object):
1401 def __get__(self, instance, owner):
1402 return 3
1403 class Foo(object):
1404 d = descriptor()
1405
1406 foo = Foo()
1407
1408 # for a non data descriptor we return the instance attribute
1409 foo.__dict__['d'] = 1
1410 self.assertEqual(inspect.getattr_static(foo, 'd'), 1)
1411
1412 # if the descriptor is a data-desciptor we should return the
1413 # descriptor
1414 descriptor.__set__ = lambda s, i, v: None
1415 self.assertEqual(inspect.getattr_static(foo, 'd'), Foo.__dict__['d'])
1416
1417
1418 def test_metaclass_with_descriptor(self):
1419 class descriptor(object):
1420 def __get__(self, instance, owner):
1421 return 3
1422 class meta(type):
1423 d = descriptor()
1424 class Thing(object, metaclass=meta):
1425 pass
1426 self.assertEqual(inspect.getattr_static(Thing, 'd'), meta.__dict__['d'])
1427
1428
Michael Foordcc7ebb82010-11-20 16:20:16 +00001429 def test_class_as_property(self):
1430 class Base(object):
1431 foo = 3
1432
1433 class Something(Base):
Michael Foord35184ed2010-11-20 16:58:30 +00001434 executed = False
Michael Foordcc7ebb82010-11-20 16:20:16 +00001435 @property
1436 def __class__(self):
Michael Foord35184ed2010-11-20 16:58:30 +00001437 self.executed = True
Michael Foordcc7ebb82010-11-20 16:20:16 +00001438 return object
1439
Michael Foord35184ed2010-11-20 16:58:30 +00001440 instance = Something()
1441 self.assertEqual(inspect.getattr_static(instance, 'foo'), 3)
1442 self.assertFalse(instance.executed)
Michael Foordcc7ebb82010-11-20 16:20:16 +00001443 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1444
Michael Foorde5162652010-11-20 16:40:44 +00001445 def test_mro_as_property(self):
1446 class Meta(type):
1447 @property
1448 def __mro__(self):
1449 return (object,)
1450
1451 class Base(object):
1452 foo = 3
1453
1454 class Something(Base, metaclass=Meta):
1455 pass
1456
1457 self.assertEqual(inspect.getattr_static(Something(), 'foo'), 3)
1458 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1459
Michael Foorddcebe0f2011-03-15 19:20:44 -04001460 def test_dict_as_property(self):
1461 test = self
1462 test.called = False
1463
1464 class Foo(dict):
1465 a = 3
1466 @property
1467 def __dict__(self):
1468 test.called = True
1469 return {}
1470
1471 foo = Foo()
1472 foo.a = 4
1473 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1474 self.assertFalse(test.called)
1475
1476 def test_custom_object_dict(self):
1477 test = self
1478 test.called = False
1479
1480 class Custom(dict):
1481 def get(self, key, default=None):
1482 test.called = True
1483 super().get(key, default)
1484
1485 class Foo(object):
1486 a = 3
1487 foo = Foo()
1488 foo.__dict__ = Custom()
1489 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1490 self.assertFalse(test.called)
1491
1492 def test_metaclass_dict_as_property(self):
1493 class Meta(type):
1494 @property
1495 def __dict__(self):
1496 self.executed = True
1497
1498 class Thing(metaclass=Meta):
1499 executed = False
1500
1501 def __init__(self):
1502 self.spam = 42
1503
1504 instance = Thing()
1505 self.assertEqual(inspect.getattr_static(instance, "spam"), 42)
1506 self.assertFalse(Thing.executed)
Michael Foorde5162652010-11-20 16:40:44 +00001507
Michael Foorda51623b2011-12-18 22:01:40 +00001508 def test_module(self):
1509 sentinel = object()
1510 self.assertIsNot(inspect.getattr_static(sys, "version", sentinel),
1511 sentinel)
1512
Michael Foord3ba95f82011-12-22 01:13:37 +00001513 def test_metaclass_with_metaclass_with_dict_as_property(self):
1514 class MetaMeta(type):
1515 @property
1516 def __dict__(self):
1517 self.executed = True
1518 return dict(spam=42)
1519
1520 class Meta(type, metaclass=MetaMeta):
1521 executed = False
1522
1523 class Thing(metaclass=Meta):
1524 pass
1525
1526 with self.assertRaises(AttributeError):
1527 inspect.getattr_static(Thing, "spam")
1528 self.assertFalse(Thing.executed)
1529
Nick Coghlane0f04652010-11-21 03:44:04 +00001530class TestGetGeneratorState(unittest.TestCase):
1531
1532 def setUp(self):
1533 def number_generator():
1534 for number in range(5):
1535 yield number
1536 self.generator = number_generator()
1537
1538 def _generatorstate(self):
1539 return inspect.getgeneratorstate(self.generator)
1540
1541 def test_created(self):
1542 self.assertEqual(self._generatorstate(), inspect.GEN_CREATED)
1543
1544 def test_suspended(self):
1545 next(self.generator)
1546 self.assertEqual(self._generatorstate(), inspect.GEN_SUSPENDED)
1547
1548 def test_closed_after_exhaustion(self):
1549 for i in self.generator:
1550 pass
1551 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1552
1553 def test_closed_after_immediate_exception(self):
1554 with self.assertRaises(RuntimeError):
1555 self.generator.throw(RuntimeError)
1556 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1557
1558 def test_running(self):
1559 # As mentioned on issue #10220, checking for the RUNNING state only
1560 # makes sense inside the generator itself.
1561 # The following generator checks for this by using the closure's
1562 # reference to self and the generator state checking helper method
1563 def running_check_generator():
1564 for number in range(5):
1565 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1566 yield number
1567 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1568 self.generator = running_check_generator()
1569 # Running up to the first yield
1570 next(self.generator)
1571 # Running after the first yield
1572 next(self.generator)
1573
Nick Coghlan7921b9f2010-11-30 06:36:04 +00001574 def test_easy_debugging(self):
1575 # repr() and str() of a generator state should contain the state name
1576 names = 'GEN_CREATED GEN_RUNNING GEN_SUSPENDED GEN_CLOSED'.split()
1577 for name in names:
1578 state = getattr(inspect, name)
1579 self.assertIn(name, repr(state))
1580 self.assertIn(name, str(state))
1581
Nick Coghlan04e2e3f2012-06-23 19:52:05 +10001582 def test_getgeneratorlocals(self):
1583 def each(lst, a=None):
1584 b=(1, 2, 3)
1585 for v in lst:
1586 if v == 3:
1587 c = 12
1588 yield v
1589
1590 numbers = each([1, 2, 3])
1591 self.assertEqual(inspect.getgeneratorlocals(numbers),
1592 {'a': None, 'lst': [1, 2, 3]})
1593 next(numbers)
1594 self.assertEqual(inspect.getgeneratorlocals(numbers),
1595 {'a': None, 'lst': [1, 2, 3], 'v': 1,
1596 'b': (1, 2, 3)})
1597 next(numbers)
1598 self.assertEqual(inspect.getgeneratorlocals(numbers),
1599 {'a': None, 'lst': [1, 2, 3], 'v': 2,
1600 'b': (1, 2, 3)})
1601 next(numbers)
1602 self.assertEqual(inspect.getgeneratorlocals(numbers),
1603 {'a': None, 'lst': [1, 2, 3], 'v': 3,
1604 'b': (1, 2, 3), 'c': 12})
1605 try:
1606 next(numbers)
1607 except StopIteration:
1608 pass
1609 self.assertEqual(inspect.getgeneratorlocals(numbers), {})
1610
1611 def test_getgeneratorlocals_empty(self):
1612 def yield_one():
1613 yield 1
1614 one = yield_one()
1615 self.assertEqual(inspect.getgeneratorlocals(one), {})
1616 try:
1617 next(one)
1618 except StopIteration:
1619 pass
1620 self.assertEqual(inspect.getgeneratorlocals(one), {})
1621
1622 def test_getgeneratorlocals_error(self):
1623 self.assertRaises(TypeError, inspect.getgeneratorlocals, 1)
1624 self.assertRaises(TypeError, inspect.getgeneratorlocals, lambda x: True)
1625 self.assertRaises(TypeError, inspect.getgeneratorlocals, set)
1626 self.assertRaises(TypeError, inspect.getgeneratorlocals, (2,3))
1627
Nick Coghlane0f04652010-11-21 03:44:04 +00001628
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001629class MySignature(inspect.Signature):
1630 # Top-level to make it picklable;
1631 # used in test_signature_object_pickle
1632 pass
1633
1634class MyParameter(inspect.Parameter):
1635 # Top-level to make it picklable;
1636 # used in test_signature_object_pickle
1637 pass
1638
Nick Coghlanf9e227e2014-08-17 14:01:19 +10001639 @cpython_only
1640 @unittest.skipIf(MISSING_C_DOCSTRINGS,
1641 "Signature information for builtins requires docstrings")
1642 def test_builtins_have_signatures(self):
1643 # This checks all builtin callables in CPython have signatures
1644 # A few have signatures Signature can't yet handle, so we skip those
1645 # since they will have to wait until PEP 457 adds the required
1646 # introspection support to the inspect module
1647 # Some others also haven't been converted yet for various other
1648 # reasons, so we also skip those for the time being, but design
1649 # the test to fail in order to indicate when it needs to be
1650 # updated.
1651 no_signature = set()
1652 # These need PEP 457 groups
1653 needs_groups = ["range", "slice", "dir", "getattr",
1654 "next", "iter", "vars"]
1655 no_signature |= needs_groups
1656 # These need PEP 457 groups or a signature change to accept None
1657 needs_semantic_update = ["round"]
1658 no_signature |= needs_semantic_update
1659 # These need *args support in Argument Clinic
1660 needs_varargs = ["min", "max", "print", "__build_class__"]
1661 no_signature |= needs_varargs
1662 # These simply weren't covered in the initial AC conversion
1663 # for builtin callables
1664 not_converted_yet = ["open", "__import__"]
1665 no_signature |= not_converted_yet
1666 # These builtin types are expected to provide introspection info
1667 types_with_signatures = set()
1668 # Check the signatures we expect to be there
1669 ns = vars(builtins)
1670 for name, obj in sorted(ns.items()):
1671 if not callable(obj):
1672 continue
1673 # The builtin types haven't been converted to AC yet
1674 if isinstance(obj, type) and (name not in types_with_signatures):
1675 # Note that this also skips all the exception types
1676 no_signature.append(name)
1677 if (name in no_signature):
1678 # Not yet converted
1679 continue
1680 with self.subTest(builtin=name):
1681 self.assertIsNotNone(inspect.signature(obj))
1682 # Check callables that haven't been converted don't claim a signature
1683 # This ensures this test will start failing as more signatures are
1684 # added, so the affected items can be moved into the scope of the
1685 # regression test above
1686 for name in no_signature:
1687 with self.subTest(builtin=name):
1688 self.assertIsNone(ns[name].__text_signature__)
1689
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001690
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001691class TestSignatureObject(unittest.TestCase):
1692 @staticmethod
1693 def signature(func):
1694 sig = inspect.signature(func)
1695 return (tuple((param.name,
1696 (... if param.default is param.empty else param.default),
1697 (... if param.annotation is param.empty
1698 else param.annotation),
1699 str(param.kind).lower())
1700 for param in sig.parameters.values()),
1701 (... if sig.return_annotation is sig.empty
1702 else sig.return_annotation))
1703
1704 def test_signature_object(self):
1705 S = inspect.Signature
1706 P = inspect.Parameter
1707
1708 self.assertEqual(str(S()), '()')
1709
Yury Selivanov07a9e452014-01-29 10:58:16 -05001710 def test(po, pk, pod=42, pkd=100, *args, ko, **kwargs):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001711 pass
1712 sig = inspect.signature(test)
1713 po = sig.parameters['po'].replace(kind=P.POSITIONAL_ONLY)
Yury Selivanov07a9e452014-01-29 10:58:16 -05001714 pod = sig.parameters['pod'].replace(kind=P.POSITIONAL_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001715 pk = sig.parameters['pk']
Yury Selivanov07a9e452014-01-29 10:58:16 -05001716 pkd = sig.parameters['pkd']
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001717 args = sig.parameters['args']
1718 ko = sig.parameters['ko']
1719 kwargs = sig.parameters['kwargs']
1720
1721 S((po, pk, args, ko, kwargs))
1722
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001723 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001724 S((pk, po, args, ko, kwargs))
1725
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001726 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001727 S((po, args, pk, ko, kwargs))
1728
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001729 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001730 S((args, po, pk, ko, kwargs))
1731
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001732 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001733 S((po, pk, args, kwargs, ko))
1734
1735 kwargs2 = kwargs.replace(name='args')
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001736 with self.assertRaisesRegex(ValueError, 'duplicate parameter name'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001737 S((po, pk, args, kwargs2, ko))
1738
Yury Selivanov07a9e452014-01-29 10:58:16 -05001739 with self.assertRaisesRegex(ValueError, 'follows default argument'):
1740 S((pod, po))
1741
1742 with self.assertRaisesRegex(ValueError, 'follows default argument'):
1743 S((po, pkd, pk))
1744
1745 with self.assertRaisesRegex(ValueError, 'follows default argument'):
1746 S((pkd, pk))
1747
Yury Selivanov374375d2014-03-27 12:41:53 -04001748 self.assertTrue(repr(sig).startswith('<Signature'))
1749 self.assertTrue('"(po, pk' in repr(sig))
1750
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001751 def test_signature_object_pickle(self):
1752 def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
1753 foo_partial = functools.partial(foo, a=1)
1754
1755 sig = inspect.signature(foo_partial)
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001756
1757 for ver in range(pickle.HIGHEST_PROTOCOL + 1):
1758 with self.subTest(pickle_ver=ver, subclass=False):
1759 sig_pickled = pickle.loads(pickle.dumps(sig, ver))
1760 self.assertEqual(sig, sig_pickled)
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001761
1762 # Test that basic sub-classing works
1763 sig = inspect.signature(foo)
1764 myparam = MyParameter(name='z', kind=inspect.Parameter.POSITIONAL_ONLY)
1765 myparams = collections.OrderedDict(sig.parameters, a=myparam)
1766 mysig = MySignature().replace(parameters=myparams.values(),
1767 return_annotation=sig.return_annotation)
1768 self.assertTrue(isinstance(mysig, MySignature))
1769 self.assertTrue(isinstance(mysig.parameters['z'], MyParameter))
1770
1771 for ver in range(pickle.HIGHEST_PROTOCOL + 1):
1772 with self.subTest(pickle_ver=ver, subclass=True):
1773 sig_pickled = pickle.loads(pickle.dumps(mysig, ver))
1774 self.assertEqual(mysig, sig_pickled)
1775 self.assertTrue(isinstance(sig_pickled, MySignature))
1776 self.assertTrue(isinstance(sig_pickled.parameters['z'],
1777 MyParameter))
1778
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001779 def test_signature_immutability(self):
1780 def test(a):
1781 pass
1782 sig = inspect.signature(test)
1783
1784 with self.assertRaises(AttributeError):
1785 sig.foo = 'bar'
1786
1787 with self.assertRaises(TypeError):
1788 sig.parameters['a'] = None
1789
1790 def test_signature_on_noarg(self):
1791 def test():
1792 pass
1793 self.assertEqual(self.signature(test), ((), ...))
1794
1795 def test_signature_on_wargs(self):
1796 def test(a, b:'foo') -> 123:
1797 pass
1798 self.assertEqual(self.signature(test),
1799 ((('a', ..., ..., "positional_or_keyword"),
1800 ('b', ..., 'foo', "positional_or_keyword")),
1801 123))
1802
1803 def test_signature_on_wkwonly(self):
1804 def test(*, a:float, b:str) -> int:
1805 pass
1806 self.assertEqual(self.signature(test),
1807 ((('a', ..., float, "keyword_only"),
1808 ('b', ..., str, "keyword_only")),
1809 int))
1810
1811 def test_signature_on_complex_args(self):
1812 def test(a, b:'foo'=10, *args:'bar', spam:'baz', ham=123, **kwargs:int):
1813 pass
1814 self.assertEqual(self.signature(test),
1815 ((('a', ..., ..., "positional_or_keyword"),
1816 ('b', 10, 'foo', "positional_or_keyword"),
1817 ('args', ..., 'bar', "var_positional"),
1818 ('spam', ..., 'baz', "keyword_only"),
1819 ('ham', 123, ..., "keyword_only"),
1820 ('kwargs', ..., int, "var_keyword")),
1821 ...))
1822
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02001823 @cpython_only
Larry Hastingsfcafe432013-11-23 17:35:48 -08001824 @unittest.skipIf(MISSING_C_DOCSTRINGS,
1825 "Signature information for builtins requires docstrings")
1826 def test_signature_on_builtins(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02001827 import _testcapi
Larry Hastings16c51912014-01-07 11:53:01 -08001828
Larry Hastings5c661892014-01-24 06:17:25 -08001829 def test_unbound_method(o):
1830 """Use this to test unbound methods (things that should have a self)"""
1831 signature = inspect.signature(o)
1832 self.assertTrue(isinstance(signature, inspect.Signature))
1833 self.assertEqual(list(signature.parameters.values())[0].name, 'self')
1834 return signature
1835
1836 def test_callable(o):
1837 """Use this to test bound methods or normal callables (things that don't expect self)"""
1838 signature = inspect.signature(o)
1839 self.assertTrue(isinstance(signature, inspect.Signature))
1840 if signature.parameters:
1841 self.assertNotEqual(list(signature.parameters.values())[0].name, 'self')
1842 return signature
1843
1844 signature = test_callable(_testcapi.docstring_with_signature_with_defaults)
Larry Hastings16c51912014-01-07 11:53:01 -08001845 def p(name): return signature.parameters[name].default
1846 self.assertEqual(p('s'), 'avocado')
Larry Hastings2a727912014-01-16 11:32:01 -08001847 self.assertEqual(p('b'), b'bytes')
Larry Hastings16c51912014-01-07 11:53:01 -08001848 self.assertEqual(p('d'), 3.14)
1849 self.assertEqual(p('i'), 35)
Larry Hastings16c51912014-01-07 11:53:01 -08001850 self.assertEqual(p('n'), None)
1851 self.assertEqual(p('t'), True)
1852 self.assertEqual(p('f'), False)
Larry Hastings2a727912014-01-16 11:32:01 -08001853 self.assertEqual(p('local'), 3)
1854 self.assertEqual(p('sys'), sys.maxsize)
1855 self.assertEqual(p('exp'), sys.maxsize - 1)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001856
Larry Hastings5c661892014-01-24 06:17:25 -08001857 test_callable(object)
1858
1859 # normal method
1860 # (PyMethodDescr_Type, "method_descriptor")
1861 test_unbound_method(_pickle.Pickler.dump)
1862 d = _pickle.Pickler(io.StringIO())
1863 test_callable(d.dump)
1864
1865 # static method
1866 test_callable(str.maketrans)
1867 test_callable('abc'.maketrans)
1868
1869 # class method
1870 test_callable(dict.fromkeys)
1871 test_callable({}.fromkeys)
1872
1873 # wrapper around slot (PyWrapperDescr_Type, "wrapper_descriptor")
1874 test_unbound_method(type.__call__)
1875 test_unbound_method(int.__add__)
1876 test_callable((3).__add__)
1877
1878 # _PyMethodWrapper_Type
1879 # support for 'method-wrapper'
1880 test_callable(min.__call__)
1881
Larry Hastings2623c8c2014-02-08 22:15:29 -08001882 # This doesn't work now.
1883 # (We don't have a valid signature for "type" in 3.4)
1884 with self.assertRaisesRegex(ValueError, "no signature found"):
1885 class ThisWorksNow:
1886 __call__ = type
1887 test_callable(ThisWorksNow())
Larry Hastings5c661892014-01-24 06:17:25 -08001888
Yury Selivanov056e2652014-03-02 12:25:27 -05001889 # Regression test for issue #20786
1890 test_unbound_method(dict.__delitem__)
1891 test_unbound_method(property.__delete__)
1892
1893
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02001894 @cpython_only
Yury Selivanov76c6c592014-01-29 10:52:57 -05001895 @unittest.skipIf(MISSING_C_DOCSTRINGS,
1896 "Signature information for builtins requires docstrings")
1897 def test_signature_on_decorated_builtins(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02001898 import _testcapi
Yury Selivanov76c6c592014-01-29 10:52:57 -05001899 func = _testcapi.docstring_with_signature_with_defaults
1900
1901 def decorator(func):
1902 @functools.wraps(func)
1903 def wrapper(*args, **kwargs) -> int:
1904 return func(*args, **kwargs)
1905 return wrapper
1906
1907 decorated_func = decorator(func)
1908
1909 self.assertEqual(inspect.signature(func),
1910 inspect.signature(decorated_func))
Larry Hastings5c661892014-01-24 06:17:25 -08001911
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02001912 @cpython_only
Larry Hastings5c661892014-01-24 06:17:25 -08001913 def test_signature_on_builtins_no_signature(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02001914 import _testcapi
Larry Hastings5c661892014-01-24 06:17:25 -08001915 with self.assertRaisesRegex(ValueError, 'no signature found for builtin'):
1916 inspect.signature(_testcapi.docstring_no_signature)
1917
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001918 def test_signature_on_non_function(self):
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001919 with self.assertRaisesRegex(TypeError, 'is not a callable object'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001920 inspect.signature(42)
1921
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001922 with self.assertRaisesRegex(TypeError, 'is not a Python function'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001923 inspect.Signature.from_function(42)
1924
Yury Selivanovb77511d2014-01-29 10:46:14 -05001925 def test_signature_from_builtin_errors(self):
1926 with self.assertRaisesRegex(TypeError, 'is not a Python builtin'):
1927 inspect.Signature.from_builtin(42)
1928
Yury Selivanov63da7c72014-01-31 14:48:37 -05001929 def test_signature_from_functionlike_object(self):
1930 def func(a,b, *args, kwonly=True, kwonlyreq, **kwargs):
1931 pass
1932
1933 class funclike:
1934 # Has to be callable, and have correct
1935 # __code__, __annotations__, __defaults__, __name__,
1936 # and __kwdefaults__ attributes
1937
1938 def __init__(self, func):
1939 self.__name__ = func.__name__
1940 self.__code__ = func.__code__
1941 self.__annotations__ = func.__annotations__
1942 self.__defaults__ = func.__defaults__
1943 self.__kwdefaults__ = func.__kwdefaults__
1944 self.func = func
1945
1946 def __call__(self, *args, **kwargs):
1947 return self.func(*args, **kwargs)
1948
1949 sig_func = inspect.Signature.from_function(func)
1950
1951 sig_funclike = inspect.Signature.from_function(funclike(func))
1952 self.assertEqual(sig_funclike, sig_func)
1953
1954 sig_funclike = inspect.signature(funclike(func))
1955 self.assertEqual(sig_funclike, sig_func)
1956
1957 # If object is not a duck type of function, then
1958 # signature will try to get a signature for its '__call__'
1959 # method
1960 fl = funclike(func)
1961 del fl.__defaults__
1962 self.assertEqual(self.signature(fl),
1963 ((('args', ..., ..., "var_positional"),
1964 ('kwargs', ..., ..., "var_keyword")),
1965 ...))
1966
Yury Selivanova773de02014-02-21 18:30:53 -05001967 # Test with cython-like builtins:
1968 _orig_isdesc = inspect.ismethoddescriptor
1969 def _isdesc(obj):
1970 if hasattr(obj, '_builtinmock'):
1971 return True
1972 return _orig_isdesc(obj)
1973
1974 with unittest.mock.patch('inspect.ismethoddescriptor', _isdesc):
1975 builtin_func = funclike(func)
1976 # Make sure that our mock setup is working
1977 self.assertFalse(inspect.ismethoddescriptor(builtin_func))
1978 builtin_func._builtinmock = True
1979 self.assertTrue(inspect.ismethoddescriptor(builtin_func))
1980 self.assertEqual(inspect.signature(builtin_func), sig_func)
1981
Yury Selivanov63da7c72014-01-31 14:48:37 -05001982 def test_signature_functionlike_class(self):
1983 # We only want to duck type function-like objects,
1984 # not classes.
1985
1986 def func(a,b, *args, kwonly=True, kwonlyreq, **kwargs):
1987 pass
1988
1989 class funclike:
1990 def __init__(self, marker):
1991 pass
1992
1993 __name__ = func.__name__
1994 __code__ = func.__code__
1995 __annotations__ = func.__annotations__
1996 __defaults__ = func.__defaults__
1997 __kwdefaults__ = func.__kwdefaults__
1998
1999 with self.assertRaisesRegex(TypeError, 'is not a Python function'):
2000 inspect.Signature.from_function(funclike)
2001
2002 self.assertEqual(str(inspect.signature(funclike)), '(marker)')
2003
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002004 def test_signature_on_method(self):
2005 class Test:
Yury Selivanov62560fb2014-01-28 12:26:24 -05002006 def __init__(*args):
2007 pass
2008 def m1(self, arg1, arg2=1) -> int:
2009 pass
2010 def m2(*args):
2011 pass
2012 def __call__(*, a):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002013 pass
2014
Yury Selivanov62560fb2014-01-28 12:26:24 -05002015 self.assertEqual(self.signature(Test().m1),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002016 ((('arg1', ..., ..., "positional_or_keyword"),
2017 ('arg2', 1, ..., "positional_or_keyword")),
2018 int))
2019
Yury Selivanov62560fb2014-01-28 12:26:24 -05002020 self.assertEqual(self.signature(Test().m2),
2021 ((('args', ..., ..., "var_positional"),),
2022 ...))
2023
2024 self.assertEqual(self.signature(Test),
2025 ((('args', ..., ..., "var_positional"),),
2026 ...))
2027
2028 with self.assertRaisesRegex(ValueError, 'invalid method signature'):
2029 self.signature(Test())
2030
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002031 def test_signature_on_classmethod(self):
2032 class Test:
2033 @classmethod
2034 def foo(cls, arg1, *, arg2=1):
2035 pass
2036
2037 meth = Test().foo
2038 self.assertEqual(self.signature(meth),
2039 ((('arg1', ..., ..., "positional_or_keyword"),
2040 ('arg2', 1, ..., "keyword_only")),
2041 ...))
2042
2043 meth = Test.foo
2044 self.assertEqual(self.signature(meth),
2045 ((('arg1', ..., ..., "positional_or_keyword"),
2046 ('arg2', 1, ..., "keyword_only")),
2047 ...))
2048
2049 def test_signature_on_staticmethod(self):
2050 class Test:
2051 @staticmethod
2052 def foo(cls, *, arg):
2053 pass
2054
2055 meth = Test().foo
2056 self.assertEqual(self.signature(meth),
2057 ((('cls', ..., ..., "positional_or_keyword"),
2058 ('arg', ..., ..., "keyword_only")),
2059 ...))
2060
2061 meth = Test.foo
2062 self.assertEqual(self.signature(meth),
2063 ((('cls', ..., ..., "positional_or_keyword"),
2064 ('arg', ..., ..., "keyword_only")),
2065 ...))
2066
2067 def test_signature_on_partial(self):
2068 from functools import partial
2069
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002070 Parameter = inspect.Parameter
2071
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002072 def test():
2073 pass
2074
2075 self.assertEqual(self.signature(partial(test)), ((), ...))
2076
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002077 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002078 inspect.signature(partial(test, 1))
2079
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002080 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002081 inspect.signature(partial(test, a=1))
2082
2083 def test(a, b, *, c, d):
2084 pass
2085
2086 self.assertEqual(self.signature(partial(test)),
2087 ((('a', ..., ..., "positional_or_keyword"),
2088 ('b', ..., ..., "positional_or_keyword"),
2089 ('c', ..., ..., "keyword_only"),
2090 ('d', ..., ..., "keyword_only")),
2091 ...))
2092
2093 self.assertEqual(self.signature(partial(test, 1)),
2094 ((('b', ..., ..., "positional_or_keyword"),
2095 ('c', ..., ..., "keyword_only"),
2096 ('d', ..., ..., "keyword_only")),
2097 ...))
2098
2099 self.assertEqual(self.signature(partial(test, 1, c=2)),
2100 ((('b', ..., ..., "positional_or_keyword"),
2101 ('c', 2, ..., "keyword_only"),
2102 ('d', ..., ..., "keyword_only")),
2103 ...))
2104
2105 self.assertEqual(self.signature(partial(test, b=1, c=2)),
2106 ((('a', ..., ..., "positional_or_keyword"),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002107 ('b', 1, ..., "keyword_only"),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002108 ('c', 2, ..., "keyword_only"),
2109 ('d', ..., ..., "keyword_only")),
2110 ...))
2111
2112 self.assertEqual(self.signature(partial(test, 0, b=1, c=2)),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002113 ((('b', 1, ..., "keyword_only"),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002114 ('c', 2, ..., "keyword_only"),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002115 ('d', ..., ..., "keyword_only")),
2116 ...))
2117
2118 self.assertEqual(self.signature(partial(test, a=1)),
2119 ((('a', 1, ..., "keyword_only"),
2120 ('b', ..., ..., "keyword_only"),
2121 ('c', ..., ..., "keyword_only"),
2122 ('d', ..., ..., "keyword_only")),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002123 ...))
2124
2125 def test(a, *args, b, **kwargs):
2126 pass
2127
2128 self.assertEqual(self.signature(partial(test, 1)),
2129 ((('args', ..., ..., "var_positional"),
2130 ('b', ..., ..., "keyword_only"),
2131 ('kwargs', ..., ..., "var_keyword")),
2132 ...))
2133
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002134 self.assertEqual(self.signature(partial(test, a=1)),
2135 ((('a', 1, ..., "keyword_only"),
2136 ('b', ..., ..., "keyword_only"),
2137 ('kwargs', ..., ..., "var_keyword")),
2138 ...))
2139
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002140 self.assertEqual(self.signature(partial(test, 1, 2, 3)),
2141 ((('args', ..., ..., "var_positional"),
2142 ('b', ..., ..., "keyword_only"),
2143 ('kwargs', ..., ..., "var_keyword")),
2144 ...))
2145
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002146 self.assertEqual(self.signature(partial(test, 1, 2, 3, test=True)),
2147 ((('args', ..., ..., "var_positional"),
2148 ('b', ..., ..., "keyword_only"),
2149 ('kwargs', ..., ..., "var_keyword")),
2150 ...))
2151
2152 self.assertEqual(self.signature(partial(test, 1, 2, 3, test=1, b=0)),
2153 ((('args', ..., ..., "var_positional"),
2154 ('b', 0, ..., "keyword_only"),
2155 ('kwargs', ..., ..., "var_keyword")),
2156 ...))
2157
2158 self.assertEqual(self.signature(partial(test, b=0)),
2159 ((('a', ..., ..., "positional_or_keyword"),
2160 ('args', ..., ..., "var_positional"),
2161 ('b', 0, ..., "keyword_only"),
2162 ('kwargs', ..., ..., "var_keyword")),
2163 ...))
2164
2165 self.assertEqual(self.signature(partial(test, b=0, test=1)),
2166 ((('a', ..., ..., "positional_or_keyword"),
2167 ('args', ..., ..., "var_positional"),
2168 ('b', 0, ..., "keyword_only"),
2169 ('kwargs', ..., ..., "var_keyword")),
2170 ...))
2171
2172 def test(a, b, c:int) -> 42:
2173 pass
2174
2175 sig = test.__signature__ = inspect.signature(test)
2176
2177 self.assertEqual(self.signature(partial(partial(test, 1))),
2178 ((('b', ..., ..., "positional_or_keyword"),
2179 ('c', ..., int, "positional_or_keyword")),
2180 42))
2181
2182 self.assertEqual(self.signature(partial(partial(test, 1), 2)),
2183 ((('c', ..., int, "positional_or_keyword"),),
2184 42))
2185
2186 psig = inspect.signature(partial(partial(test, 1), 2))
2187
2188 def foo(a):
2189 return a
2190 _foo = partial(partial(foo, a=10), a=20)
2191 self.assertEqual(self.signature(_foo),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002192 ((('a', 20, ..., "keyword_only"),),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002193 ...))
2194 # check that we don't have any side-effects in signature(),
2195 # and the partial object is still functioning
2196 self.assertEqual(_foo(), 20)
2197
2198 def foo(a, b, c):
2199 return a, b, c
2200 _foo = partial(partial(foo, 1, b=20), b=30)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002201
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002202 self.assertEqual(self.signature(_foo),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002203 ((('b', 30, ..., "keyword_only"),
2204 ('c', ..., ..., "keyword_only")),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002205 ...))
2206 self.assertEqual(_foo(c=10), (1, 30, 10))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002207
2208 def foo(a, b, c, *, d):
2209 return a, b, c, d
2210 _foo = partial(partial(foo, d=20, c=20), b=10, d=30)
2211 self.assertEqual(self.signature(_foo),
2212 ((('a', ..., ..., "positional_or_keyword"),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002213 ('b', 10, ..., "keyword_only"),
2214 ('c', 20, ..., "keyword_only"),
2215 ('d', 30, ..., "keyword_only"),
2216 ),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002217 ...))
2218 ba = inspect.signature(_foo).bind(a=200, b=11)
2219 self.assertEqual(_foo(*ba.args, **ba.kwargs), (200, 11, 20, 30))
2220
2221 def foo(a=1, b=2, c=3):
2222 return a, b, c
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002223 _foo = partial(foo, c=13) # (a=1, b=2, *, c=13)
2224
2225 ba = inspect.signature(_foo).bind(a=11)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002226 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 2, 13))
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002227
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002228 ba = inspect.signature(_foo).bind(11, 12)
2229 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002230
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002231 ba = inspect.signature(_foo).bind(11, b=12)
2232 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002233
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002234 ba = inspect.signature(_foo).bind(b=12)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002235 self.assertEqual(_foo(*ba.args, **ba.kwargs), (1, 12, 13))
2236
2237 _foo = partial(_foo, b=10, c=20)
2238 ba = inspect.signature(_foo).bind(12)
2239 self.assertEqual(_foo(*ba.args, **ba.kwargs), (12, 10, 20))
2240
2241
2242 def foo(a, b, c, d, **kwargs):
2243 pass
2244 sig = inspect.signature(foo)
2245 params = sig.parameters.copy()
2246 params['a'] = params['a'].replace(kind=Parameter.POSITIONAL_ONLY)
2247 params['b'] = params['b'].replace(kind=Parameter.POSITIONAL_ONLY)
2248 foo.__signature__ = inspect.Signature(params.values())
2249 sig = inspect.signature(foo)
2250 self.assertEqual(str(sig), '(a, b, /, c, d, **kwargs)')
2251
2252 self.assertEqual(self.signature(partial(foo, 1)),
2253 ((('b', ..., ..., 'positional_only'),
2254 ('c', ..., ..., 'positional_or_keyword'),
2255 ('d', ..., ..., 'positional_or_keyword'),
2256 ('kwargs', ..., ..., 'var_keyword')),
2257 ...))
2258
2259 self.assertEqual(self.signature(partial(foo, 1, 2)),
2260 ((('c', ..., ..., 'positional_or_keyword'),
2261 ('d', ..., ..., 'positional_or_keyword'),
2262 ('kwargs', ..., ..., 'var_keyword')),
2263 ...))
2264
2265 self.assertEqual(self.signature(partial(foo, 1, 2, 3)),
2266 ((('d', ..., ..., 'positional_or_keyword'),
2267 ('kwargs', ..., ..., 'var_keyword')),
2268 ...))
2269
2270 self.assertEqual(self.signature(partial(foo, 1, 2, c=3)),
2271 ((('c', 3, ..., 'keyword_only'),
2272 ('d', ..., ..., 'keyword_only'),
2273 ('kwargs', ..., ..., 'var_keyword')),
2274 ...))
2275
2276 self.assertEqual(self.signature(partial(foo, 1, c=3)),
2277 ((('b', ..., ..., 'positional_only'),
2278 ('c', 3, ..., 'keyword_only'),
2279 ('d', ..., ..., 'keyword_only'),
2280 ('kwargs', ..., ..., 'var_keyword')),
2281 ...))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002282
Yury Selivanovda5fe4f2014-01-27 17:28:37 -05002283 def test_signature_on_partialmethod(self):
2284 from functools import partialmethod
2285
2286 class Spam:
2287 def test():
2288 pass
2289 ham = partialmethod(test)
2290
2291 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
2292 inspect.signature(Spam.ham)
2293
2294 class Spam:
2295 def test(it, a, *, c) -> 'spam':
2296 pass
2297 ham = partialmethod(test, c=1)
2298
2299 self.assertEqual(self.signature(Spam.ham),
2300 ((('it', ..., ..., 'positional_or_keyword'),
2301 ('a', ..., ..., 'positional_or_keyword'),
2302 ('c', 1, ..., 'keyword_only')),
2303 'spam'))
2304
2305 self.assertEqual(self.signature(Spam().ham),
2306 ((('a', ..., ..., 'positional_or_keyword'),
2307 ('c', 1, ..., 'keyword_only')),
2308 'spam'))
2309
Yury Selivanov0486f812014-01-29 12:18:59 -05002310 def test_signature_on_fake_partialmethod(self):
2311 def foo(a): pass
2312 foo._partialmethod = 'spam'
2313 self.assertEqual(str(inspect.signature(foo)), '(a)')
2314
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002315 def test_signature_on_decorated(self):
2316 import functools
2317
2318 def decorator(func):
2319 @functools.wraps(func)
2320 def wrapper(*args, **kwargs) -> int:
2321 return func(*args, **kwargs)
2322 return wrapper
2323
2324 class Foo:
2325 @decorator
2326 def bar(self, a, b):
2327 pass
2328
2329 self.assertEqual(self.signature(Foo.bar),
2330 ((('self', ..., ..., "positional_or_keyword"),
2331 ('a', ..., ..., "positional_or_keyword"),
2332 ('b', ..., ..., "positional_or_keyword")),
2333 ...))
2334
2335 self.assertEqual(self.signature(Foo().bar),
2336 ((('a', ..., ..., "positional_or_keyword"),
2337 ('b', ..., ..., "positional_or_keyword")),
2338 ...))
2339
2340 # Test that we handle method wrappers correctly
2341 def decorator(func):
2342 @functools.wraps(func)
2343 def wrapper(*args, **kwargs) -> int:
2344 return func(42, *args, **kwargs)
2345 sig = inspect.signature(func)
2346 new_params = tuple(sig.parameters.values())[1:]
2347 wrapper.__signature__ = sig.replace(parameters=new_params)
2348 return wrapper
2349
2350 class Foo:
2351 @decorator
2352 def __call__(self, a, b):
2353 pass
2354
2355 self.assertEqual(self.signature(Foo.__call__),
2356 ((('a', ..., ..., "positional_or_keyword"),
2357 ('b', ..., ..., "positional_or_keyword")),
2358 ...))
2359
2360 self.assertEqual(self.signature(Foo().__call__),
2361 ((('b', ..., ..., "positional_or_keyword"),),
2362 ...))
2363
Nick Coghlane8c45d62013-07-28 20:00:01 +10002364 # Test we handle __signature__ partway down the wrapper stack
2365 def wrapped_foo_call():
2366 pass
2367 wrapped_foo_call.__wrapped__ = Foo.__call__
2368
2369 self.assertEqual(self.signature(wrapped_foo_call),
2370 ((('a', ..., ..., "positional_or_keyword"),
2371 ('b', ..., ..., "positional_or_keyword")),
2372 ...))
2373
2374
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002375 def test_signature_on_class(self):
2376 class C:
2377 def __init__(self, a):
2378 pass
2379
2380 self.assertEqual(self.signature(C),
2381 ((('a', ..., ..., "positional_or_keyword"),),
2382 ...))
2383
2384 class CM(type):
2385 def __call__(cls, a):
2386 pass
2387 class C(metaclass=CM):
2388 def __init__(self, b):
2389 pass
2390
2391 self.assertEqual(self.signature(C),
2392 ((('a', ..., ..., "positional_or_keyword"),),
2393 ...))
2394
2395 class CM(type):
2396 def __new__(mcls, name, bases, dct, *, foo=1):
2397 return super().__new__(mcls, name, bases, dct)
2398 class C(metaclass=CM):
2399 def __init__(self, b):
2400 pass
2401
2402 self.assertEqual(self.signature(C),
2403 ((('b', ..., ..., "positional_or_keyword"),),
2404 ...))
2405
2406 self.assertEqual(self.signature(CM),
2407 ((('name', ..., ..., "positional_or_keyword"),
2408 ('bases', ..., ..., "positional_or_keyword"),
2409 ('dct', ..., ..., "positional_or_keyword"),
2410 ('foo', 1, ..., "keyword_only")),
2411 ...))
2412
2413 class CMM(type):
2414 def __new__(mcls, name, bases, dct, *, foo=1):
2415 return super().__new__(mcls, name, bases, dct)
2416 def __call__(cls, nm, bs, dt):
2417 return type(nm, bs, dt)
2418 class CM(type, metaclass=CMM):
2419 def __new__(mcls, name, bases, dct, *, bar=2):
2420 return super().__new__(mcls, name, bases, dct)
2421 class C(metaclass=CM):
2422 def __init__(self, b):
2423 pass
2424
2425 self.assertEqual(self.signature(CMM),
2426 ((('name', ..., ..., "positional_or_keyword"),
2427 ('bases', ..., ..., "positional_or_keyword"),
2428 ('dct', ..., ..., "positional_or_keyword"),
2429 ('foo', 1, ..., "keyword_only")),
2430 ...))
2431
2432 self.assertEqual(self.signature(CM),
2433 ((('nm', ..., ..., "positional_or_keyword"),
2434 ('bs', ..., ..., "positional_or_keyword"),
2435 ('dt', ..., ..., "positional_or_keyword")),
2436 ...))
2437
2438 self.assertEqual(self.signature(C),
2439 ((('b', ..., ..., "positional_or_keyword"),),
2440 ...))
2441
2442 class CM(type):
2443 def __init__(cls, name, bases, dct, *, bar=2):
2444 return super().__init__(name, bases, dct)
2445 class C(metaclass=CM):
2446 def __init__(self, b):
2447 pass
2448
2449 self.assertEqual(self.signature(CM),
2450 ((('name', ..., ..., "positional_or_keyword"),
2451 ('bases', ..., ..., "positional_or_keyword"),
2452 ('dct', ..., ..., "positional_or_keyword"),
2453 ('bar', 2, ..., "keyword_only")),
2454 ...))
2455
Yury Selivanov145dff82014-02-01 13:49:29 -05002456 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2457 "Signature information for builtins requires docstrings")
2458 def test_signature_on_class_without_init(self):
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002459 # Test classes without user-defined __init__ or __new__
2460 class C: pass
2461 self.assertEqual(str(inspect.signature(C)), '()')
2462 class D(C): pass
2463 self.assertEqual(str(inspect.signature(D)), '()')
2464
2465 # Test meta-classes without user-defined __init__ or __new__
2466 class C(type): pass
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002467 class D(C): pass
Larry Hastings2623c8c2014-02-08 22:15:29 -08002468 with self.assertRaisesRegex(ValueError, "callable.*is not supported"):
2469 self.assertEqual(inspect.signature(C), None)
2470 with self.assertRaisesRegex(ValueError, "callable.*is not supported"):
2471 self.assertEqual(inspect.signature(D), None)
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002472
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002473 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2474 "Signature information for builtins requires docstrings")
2475 def test_signature_on_builtin_class(self):
2476 self.assertEqual(str(inspect.signature(_pickle.Pickler)),
2477 '(file, protocol=None, fix_imports=True)')
2478
2479 class P(_pickle.Pickler): pass
2480 class EmptyTrait: pass
2481 class P2(EmptyTrait, P): pass
2482 self.assertEqual(str(inspect.signature(P)),
2483 '(file, protocol=None, fix_imports=True)')
2484 self.assertEqual(str(inspect.signature(P2)),
2485 '(file, protocol=None, fix_imports=True)')
2486
2487 class P3(P2):
2488 def __init__(self, spam):
2489 pass
2490 self.assertEqual(str(inspect.signature(P3)), '(spam)')
2491
2492 class MetaP(type):
2493 def __call__(cls, foo, bar):
2494 pass
2495 class P4(P2, metaclass=MetaP):
2496 pass
2497 self.assertEqual(str(inspect.signature(P4)), '(foo, bar)')
2498
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002499 def test_signature_on_callable_objects(self):
2500 class Foo:
2501 def __call__(self, a):
2502 pass
2503
2504 self.assertEqual(self.signature(Foo()),
2505 ((('a', ..., ..., "positional_or_keyword"),),
2506 ...))
2507
2508 class Spam:
2509 pass
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002510 with self.assertRaisesRegex(TypeError, "is not a callable object"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002511 inspect.signature(Spam())
2512
2513 class Bar(Spam, Foo):
2514 pass
2515
2516 self.assertEqual(self.signature(Bar()),
2517 ((('a', ..., ..., "positional_or_keyword"),),
2518 ...))
2519
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002520 class Wrapped:
2521 pass
2522 Wrapped.__wrapped__ = lambda a: None
2523 self.assertEqual(self.signature(Wrapped),
2524 ((('a', ..., ..., "positional_or_keyword"),),
2525 ...))
Nick Coghlane8c45d62013-07-28 20:00:01 +10002526 # wrapper loop:
2527 Wrapped.__wrapped__ = Wrapped
2528 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
2529 self.signature(Wrapped)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002530
2531 def test_signature_on_lambdas(self):
2532 self.assertEqual(self.signature((lambda a=10: a)),
2533 ((('a', 10, ..., "positional_or_keyword"),),
2534 ...))
2535
2536 def test_signature_equality(self):
2537 def foo(a, *, b:int) -> float: pass
2538 self.assertNotEqual(inspect.signature(foo), 42)
2539
2540 def bar(a, *, b:int) -> float: pass
2541 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002542 self.assertEqual(
2543 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002544
2545 def bar(a, *, b:int) -> int: pass
2546 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002547 self.assertNotEqual(
2548 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002549
2550 def bar(a, *, b:int): pass
2551 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002552 self.assertNotEqual(
2553 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002554
2555 def bar(a, *, b:int=42) -> float: pass
2556 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002557 self.assertNotEqual(
2558 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002559
2560 def bar(a, *, c) -> float: pass
2561 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002562 self.assertNotEqual(
2563 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002564
2565 def bar(a, b:int) -> float: pass
2566 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002567 self.assertNotEqual(
2568 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002569 def spam(b:int, a) -> float: pass
2570 self.assertNotEqual(inspect.signature(spam), inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002571 self.assertNotEqual(
2572 hash(inspect.signature(spam)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002573
2574 def foo(*, a, b, c): pass
2575 def bar(*, c, b, a): pass
2576 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002577 self.assertEqual(
2578 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002579
2580 def foo(*, a=1, b, c): pass
2581 def bar(*, c, b, a=1): pass
2582 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002583 self.assertEqual(
2584 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002585
2586 def foo(pos, *, a=1, b, c): pass
2587 def bar(pos, *, c, b, a=1): pass
2588 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002589 self.assertEqual(
2590 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002591
2592 def foo(pos, *, a, b, c): pass
2593 def bar(pos, *, c, b, a=1): pass
2594 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002595 self.assertNotEqual(
2596 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002597
2598 def foo(pos, *args, a=42, b, c, **kwargs:int): pass
2599 def bar(pos, *args, c, b, a=42, **kwargs:int): pass
2600 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002601 self.assertEqual(
2602 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002603
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002604 def test_signature_hashable(self):
2605 S = inspect.Signature
2606 P = inspect.Parameter
2607
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002608 def foo(a): pass
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002609 foo_sig = inspect.signature(foo)
2610
2611 manual_sig = S(parameters=[P('a', P.POSITIONAL_OR_KEYWORD)])
2612
2613 self.assertEqual(hash(foo_sig), hash(manual_sig))
2614 self.assertNotEqual(hash(foo_sig),
2615 hash(manual_sig.replace(return_annotation='spam')))
2616
2617 def bar(a) -> 1: pass
2618 self.assertNotEqual(hash(foo_sig), hash(inspect.signature(bar)))
2619
2620 def foo(a={}): pass
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002621 with self.assertRaisesRegex(TypeError, 'unhashable type'):
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002622 hash(inspect.signature(foo))
2623
2624 def foo(a) -> {}: pass
2625 with self.assertRaisesRegex(TypeError, 'unhashable type'):
2626 hash(inspect.signature(foo))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002627
2628 def test_signature_str(self):
2629 def foo(a:int=1, *, b, c=None, **kwargs) -> 42:
2630 pass
2631 self.assertEqual(str(inspect.signature(foo)),
2632 '(a:int=1, *, b, c=None, **kwargs) -> 42')
2633
2634 def foo(a:int=1, *args, b, c=None, **kwargs) -> 42:
2635 pass
2636 self.assertEqual(str(inspect.signature(foo)),
2637 '(a:int=1, *args, b, c=None, **kwargs) -> 42')
2638
2639 def foo():
2640 pass
2641 self.assertEqual(str(inspect.signature(foo)), '()')
2642
2643 def test_signature_str_positional_only(self):
2644 P = inspect.Parameter
Yury Selivanov2393dca2014-01-27 15:07:58 -05002645 S = inspect.Signature
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002646
2647 def test(a_po, *, b, **kwargs):
2648 return a_po, kwargs
2649
2650 sig = inspect.signature(test)
2651 new_params = list(sig.parameters.values())
2652 new_params[0] = new_params[0].replace(kind=P.POSITIONAL_ONLY)
2653 test.__signature__ = sig.replace(parameters=new_params)
2654
2655 self.assertEqual(str(inspect.signature(test)),
Yury Selivanov2393dca2014-01-27 15:07:58 -05002656 '(a_po, /, *, b, **kwargs)')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002657
Yury Selivanov2393dca2014-01-27 15:07:58 -05002658 self.assertEqual(str(S(parameters=[P('foo', P.POSITIONAL_ONLY)])),
2659 '(foo, /)')
2660
2661 self.assertEqual(str(S(parameters=[
2662 P('foo', P.POSITIONAL_ONLY),
2663 P('bar', P.VAR_KEYWORD)])),
2664 '(foo, /, **bar)')
2665
2666 self.assertEqual(str(S(parameters=[
2667 P('foo', P.POSITIONAL_ONLY),
2668 P('bar', P.VAR_POSITIONAL)])),
2669 '(foo, /, *bar)')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002670
2671 def test_signature_replace_anno(self):
2672 def test() -> 42:
2673 pass
2674
2675 sig = inspect.signature(test)
2676 sig = sig.replace(return_annotation=None)
2677 self.assertIs(sig.return_annotation, None)
2678 sig = sig.replace(return_annotation=sig.empty)
2679 self.assertIs(sig.return_annotation, sig.empty)
2680 sig = sig.replace(return_annotation=42)
2681 self.assertEqual(sig.return_annotation, 42)
2682 self.assertEqual(sig, inspect.signature(test))
2683
Yury Selivanov34ce99f2014-02-18 12:49:41 -05002684 def test_signature_on_mangled_parameters(self):
2685 class Spam:
2686 def foo(self, __p1:1=2, *, __p2:2=3):
2687 pass
2688 class Ham(Spam):
2689 pass
2690
2691 self.assertEqual(self.signature(Spam.foo),
2692 ((('self', ..., ..., "positional_or_keyword"),
2693 ('_Spam__p1', 2, 1, "positional_or_keyword"),
2694 ('_Spam__p2', 3, 2, "keyword_only")),
2695 ...))
2696
2697 self.assertEqual(self.signature(Spam.foo),
2698 self.signature(Ham.foo))
2699
Yury Selivanovda396452014-03-27 12:09:24 -04002700 def test_signature_from_callable_python_obj(self):
2701 class MySignature(inspect.Signature): pass
2702 def foo(a, *, b:1): pass
2703 foo_sig = MySignature.from_callable(foo)
2704 self.assertTrue(isinstance(foo_sig, MySignature))
2705
2706 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2707 "Signature information for builtins requires docstrings")
2708 def test_signature_from_callable_builtin_obj(self):
2709 class MySignature(inspect.Signature): pass
2710 sig = MySignature.from_callable(_pickle.Pickler)
2711 self.assertTrue(isinstance(sig, MySignature))
2712
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002713
2714class TestParameterObject(unittest.TestCase):
2715 def test_signature_parameter_kinds(self):
2716 P = inspect.Parameter
2717 self.assertTrue(P.POSITIONAL_ONLY < P.POSITIONAL_OR_KEYWORD < \
2718 P.VAR_POSITIONAL < P.KEYWORD_ONLY < P.VAR_KEYWORD)
2719
2720 self.assertEqual(str(P.POSITIONAL_ONLY), 'POSITIONAL_ONLY')
2721 self.assertTrue('POSITIONAL_ONLY' in repr(P.POSITIONAL_ONLY))
2722
2723 def test_signature_parameter_object(self):
2724 p = inspect.Parameter('foo', default=10,
2725 kind=inspect.Parameter.POSITIONAL_ONLY)
2726 self.assertEqual(p.name, 'foo')
2727 self.assertEqual(p.default, 10)
2728 self.assertIs(p.annotation, p.empty)
2729 self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY)
2730
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002731 with self.assertRaisesRegex(ValueError, 'invalid value'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002732 inspect.Parameter('foo', default=10, kind='123')
2733
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002734 with self.assertRaisesRegex(ValueError, 'not a valid parameter name'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002735 inspect.Parameter('1', kind=inspect.Parameter.VAR_KEYWORD)
2736
Yury Selivanov2393dca2014-01-27 15:07:58 -05002737 with self.assertRaisesRegex(TypeError, 'name must be a str'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002738 inspect.Parameter(None, kind=inspect.Parameter.VAR_KEYWORD)
2739
Yury Selivanov2393dca2014-01-27 15:07:58 -05002740 with self.assertRaisesRegex(ValueError,
2741 'is not a valid parameter name'):
2742 inspect.Parameter('$', kind=inspect.Parameter.VAR_KEYWORD)
2743
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002744 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002745 inspect.Parameter('a', default=42,
2746 kind=inspect.Parameter.VAR_KEYWORD)
2747
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002748 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002749 inspect.Parameter('a', default=42,
2750 kind=inspect.Parameter.VAR_POSITIONAL)
2751
2752 p = inspect.Parameter('a', default=42,
2753 kind=inspect.Parameter.POSITIONAL_OR_KEYWORD)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002754 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002755 p.replace(kind=inspect.Parameter.VAR_POSITIONAL)
2756
2757 self.assertTrue(repr(p).startswith('<Parameter'))
Yury Selivanov374375d2014-03-27 12:41:53 -04002758 self.assertTrue('"a=42"' in repr(p))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002759
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002760 def test_signature_parameter_hashable(self):
2761 P = inspect.Parameter
2762 foo = P('foo', kind=P.POSITIONAL_ONLY)
2763 self.assertEqual(hash(foo), hash(P('foo', kind=P.POSITIONAL_ONLY)))
2764 self.assertNotEqual(hash(foo), hash(P('foo', kind=P.POSITIONAL_ONLY,
2765 default=42)))
2766 self.assertNotEqual(hash(foo),
2767 hash(foo.replace(kind=P.VAR_POSITIONAL)))
2768
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002769 def test_signature_parameter_equality(self):
2770 P = inspect.Parameter
2771 p = P('foo', default=42, kind=inspect.Parameter.KEYWORD_ONLY)
2772
2773 self.assertEqual(p, p)
2774 self.assertNotEqual(p, 42)
2775
2776 self.assertEqual(p, P('foo', default=42,
2777 kind=inspect.Parameter.KEYWORD_ONLY))
2778
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002779 def test_signature_parameter_replace(self):
2780 p = inspect.Parameter('foo', default=42,
2781 kind=inspect.Parameter.KEYWORD_ONLY)
2782
2783 self.assertIsNot(p, p.replace())
2784 self.assertEqual(p, p.replace())
2785
2786 p2 = p.replace(annotation=1)
2787 self.assertEqual(p2.annotation, 1)
2788 p2 = p2.replace(annotation=p2.empty)
2789 self.assertEqual(p, p2)
2790
2791 p2 = p2.replace(name='bar')
2792 self.assertEqual(p2.name, 'bar')
2793 self.assertNotEqual(p2, p)
2794
Yury Selivanov2393dca2014-01-27 15:07:58 -05002795 with self.assertRaisesRegex(ValueError,
2796 'name is a required attribute'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002797 p2 = p2.replace(name=p2.empty)
2798
2799 p2 = p2.replace(name='foo', default=None)
2800 self.assertIs(p2.default, None)
2801 self.assertNotEqual(p2, p)
2802
2803 p2 = p2.replace(name='foo', default=p2.empty)
2804 self.assertIs(p2.default, p2.empty)
2805
2806
2807 p2 = p2.replace(default=42, kind=p2.POSITIONAL_OR_KEYWORD)
2808 self.assertEqual(p2.kind, p2.POSITIONAL_OR_KEYWORD)
2809 self.assertNotEqual(p2, p)
2810
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002811 with self.assertRaisesRegex(ValueError, 'invalid value for'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002812 p2 = p2.replace(kind=p2.empty)
2813
2814 p2 = p2.replace(kind=p2.KEYWORD_ONLY)
2815 self.assertEqual(p2, p)
2816
2817 def test_signature_parameter_positional_only(self):
Yury Selivanov2393dca2014-01-27 15:07:58 -05002818 with self.assertRaisesRegex(TypeError, 'name must be a str'):
2819 inspect.Parameter(None, kind=inspect.Parameter.POSITIONAL_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002820
2821 def test_signature_parameter_immutability(self):
Yury Selivanov2393dca2014-01-27 15:07:58 -05002822 p = inspect.Parameter('spam', kind=inspect.Parameter.KEYWORD_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002823
2824 with self.assertRaises(AttributeError):
2825 p.foo = 'bar'
2826
2827 with self.assertRaises(AttributeError):
2828 p.kind = 123
2829
2830
2831class TestSignatureBind(unittest.TestCase):
2832 @staticmethod
2833 def call(func, *args, **kwargs):
2834 sig = inspect.signature(func)
2835 ba = sig.bind(*args, **kwargs)
2836 return func(*ba.args, **ba.kwargs)
2837
2838 def test_signature_bind_empty(self):
2839 def test():
2840 return 42
2841
2842 self.assertEqual(self.call(test), 42)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002843 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002844 self.call(test, 1)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002845 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002846 self.call(test, 1, spam=10)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002847 with self.assertRaisesRegex(TypeError, 'too many keyword arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002848 self.call(test, spam=1)
2849
2850 def test_signature_bind_var(self):
2851 def test(*args, **kwargs):
2852 return args, kwargs
2853
2854 self.assertEqual(self.call(test), ((), {}))
2855 self.assertEqual(self.call(test, 1), ((1,), {}))
2856 self.assertEqual(self.call(test, 1, 2), ((1, 2), {}))
2857 self.assertEqual(self.call(test, foo='bar'), ((), {'foo': 'bar'}))
2858 self.assertEqual(self.call(test, 1, foo='bar'), ((1,), {'foo': 'bar'}))
2859 self.assertEqual(self.call(test, args=10), ((), {'args': 10}))
2860 self.assertEqual(self.call(test, 1, 2, foo='bar'),
2861 ((1, 2), {'foo': 'bar'}))
2862
2863 def test_signature_bind_just_args(self):
2864 def test(a, b, c):
2865 return a, b, c
2866
2867 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
2868
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002869 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002870 self.call(test, 1, 2, 3, 4)
2871
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002872 with self.assertRaisesRegex(TypeError, "'b' parameter lacking default"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002873 self.call(test, 1)
2874
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002875 with self.assertRaisesRegex(TypeError, "'a' parameter lacking default"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002876 self.call(test)
2877
2878 def test(a, b, c=10):
2879 return a, b, c
2880 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
2881 self.assertEqual(self.call(test, 1, 2), (1, 2, 10))
2882
2883 def test(a=1, b=2, c=3):
2884 return a, b, c
2885 self.assertEqual(self.call(test, a=10, c=13), (10, 2, 13))
2886 self.assertEqual(self.call(test, a=10), (10, 2, 3))
2887 self.assertEqual(self.call(test, b=10), (1, 10, 3))
2888
2889 def test_signature_bind_varargs_order(self):
2890 def test(*args):
2891 return args
2892
2893 self.assertEqual(self.call(test), ())
2894 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
2895
2896 def test_signature_bind_args_and_varargs(self):
2897 def test(a, b, c=3, *args):
2898 return a, b, c, args
2899
2900 self.assertEqual(self.call(test, 1, 2, 3, 4, 5), (1, 2, 3, (4, 5)))
2901 self.assertEqual(self.call(test, 1, 2), (1, 2, 3, ()))
2902 self.assertEqual(self.call(test, b=1, a=2), (2, 1, 3, ()))
2903 self.assertEqual(self.call(test, 1, b=2), (1, 2, 3, ()))
2904
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002905 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002906 "multiple values for argument 'c'"):
2907 self.call(test, 1, 2, 3, c=4)
2908
2909 def test_signature_bind_just_kwargs(self):
2910 def test(**kwargs):
2911 return kwargs
2912
2913 self.assertEqual(self.call(test), {})
2914 self.assertEqual(self.call(test, foo='bar', spam='ham'),
2915 {'foo': 'bar', 'spam': 'ham'})
2916
2917 def test_signature_bind_args_and_kwargs(self):
2918 def test(a, b, c=3, **kwargs):
2919 return a, b, c, kwargs
2920
2921 self.assertEqual(self.call(test, 1, 2), (1, 2, 3, {}))
2922 self.assertEqual(self.call(test, 1, 2, foo='bar', spam='ham'),
2923 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
2924 self.assertEqual(self.call(test, b=2, a=1, foo='bar', spam='ham'),
2925 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
2926 self.assertEqual(self.call(test, a=1, b=2, foo='bar', spam='ham'),
2927 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
2928 self.assertEqual(self.call(test, 1, b=2, foo='bar', spam='ham'),
2929 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
2930 self.assertEqual(self.call(test, 1, b=2, c=4, foo='bar', spam='ham'),
2931 (1, 2, 4, {'foo': 'bar', 'spam': 'ham'}))
2932 self.assertEqual(self.call(test, 1, 2, 4, foo='bar'),
2933 (1, 2, 4, {'foo': 'bar'}))
2934 self.assertEqual(self.call(test, c=5, a=4, b=3),
2935 (4, 3, 5, {}))
2936
2937 def test_signature_bind_kwonly(self):
2938 def test(*, foo):
2939 return foo
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002940 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002941 'too many positional arguments'):
2942 self.call(test, 1)
2943 self.assertEqual(self.call(test, foo=1), 1)
2944
2945 def test(a, *, foo=1, bar):
2946 return foo
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002947 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002948 "'bar' parameter lacking default value"):
2949 self.call(test, 1)
2950
2951 def test(foo, *, bar):
2952 return foo, bar
2953 self.assertEqual(self.call(test, 1, bar=2), (1, 2))
2954 self.assertEqual(self.call(test, bar=2, foo=1), (1, 2))
2955
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002956 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002957 'too many keyword arguments'):
2958 self.call(test, bar=2, foo=1, spam=10)
2959
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002960 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002961 'too many positional arguments'):
2962 self.call(test, 1, 2)
2963
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002964 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002965 'too many positional arguments'):
2966 self.call(test, 1, 2, bar=2)
2967
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002968 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002969 'too many keyword arguments'):
2970 self.call(test, 1, bar=2, spam='ham')
2971
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002972 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002973 "'bar' parameter lacking default value"):
2974 self.call(test, 1)
2975
2976 def test(foo, *, bar, **bin):
2977 return foo, bar, bin
2978 self.assertEqual(self.call(test, 1, bar=2), (1, 2, {}))
2979 self.assertEqual(self.call(test, foo=1, bar=2), (1, 2, {}))
2980 self.assertEqual(self.call(test, 1, bar=2, spam='ham'),
2981 (1, 2, {'spam': 'ham'}))
2982 self.assertEqual(self.call(test, spam='ham', foo=1, bar=2),
2983 (1, 2, {'spam': 'ham'}))
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002984 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002985 "'foo' parameter lacking default value"):
2986 self.call(test, spam='ham', bar=2)
2987 self.assertEqual(self.call(test, 1, bar=2, bin=1, spam=10),
2988 (1, 2, {'bin': 1, 'spam': 10}))
2989
2990 def test_signature_bind_arguments(self):
2991 def test(a, *args, b, z=100, **kwargs):
2992 pass
2993 sig = inspect.signature(test)
2994 ba = sig.bind(10, 20, b=30, c=40, args=50, kwargs=60)
2995 # we won't have 'z' argument in the bound arguments object, as we didn't
2996 # pass it to the 'bind'
2997 self.assertEqual(tuple(ba.arguments.items()),
2998 (('a', 10), ('args', (20,)), ('b', 30),
2999 ('kwargs', {'c': 40, 'args': 50, 'kwargs': 60})))
3000 self.assertEqual(ba.kwargs,
3001 {'b': 30, 'c': 40, 'args': 50, 'kwargs': 60})
3002 self.assertEqual(ba.args, (10, 20))
3003
3004 def test_signature_bind_positional_only(self):
3005 P = inspect.Parameter
3006
3007 def test(a_po, b_po, c_po=3, foo=42, *, bar=50, **kwargs):
3008 return a_po, b_po, c_po, foo, bar, kwargs
3009
3010 sig = inspect.signature(test)
3011 new_params = collections.OrderedDict(tuple(sig.parameters.items()))
3012 for name in ('a_po', 'b_po', 'c_po'):
3013 new_params[name] = new_params[name].replace(kind=P.POSITIONAL_ONLY)
3014 new_sig = sig.replace(parameters=new_params.values())
3015 test.__signature__ = new_sig
3016
3017 self.assertEqual(self.call(test, 1, 2, 4, 5, bar=6),
3018 (1, 2, 4, 5, 6, {}))
3019
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05003020 self.assertEqual(self.call(test, 1, 2),
3021 (1, 2, 3, 42, 50, {}))
3022
3023 self.assertEqual(self.call(test, 1, 2, foo=4, bar=5),
3024 (1, 2, 3, 4, 5, {}))
3025
3026 with self.assertRaisesRegex(TypeError, "but was passed as a keyword"):
3027 self.call(test, 1, 2, foo=4, bar=5, c_po=10)
3028
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003029 with self.assertRaisesRegex(TypeError, "parameter is positional only"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003030 self.call(test, 1, 2, c_po=4)
3031
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003032 with self.assertRaisesRegex(TypeError, "parameter is positional only"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003033 self.call(test, a_po=1, b_po=2)
3034
Antoine Pitroubd41d1b2013-01-29 21:20:57 +01003035 def test_signature_bind_with_self_arg(self):
3036 # Issue #17071: one of the parameters is named "self
3037 def test(a, self, b):
3038 pass
3039 sig = inspect.signature(test)
3040 ba = sig.bind(1, 2, 3)
3041 self.assertEqual(ba.args, (1, 2, 3))
3042 ba = sig.bind(1, self=2, b=3)
3043 self.assertEqual(ba.args, (1, 2, 3))
3044
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05003045 def test_signature_bind_vararg_name(self):
3046 def test(a, *args):
3047 return a, args
3048 sig = inspect.signature(test)
3049
3050 with self.assertRaisesRegex(TypeError, "too many keyword arguments"):
3051 sig.bind(a=0, args=1)
3052
3053 def test(*args, **kwargs):
3054 return args, kwargs
3055 self.assertEqual(self.call(test, args=1), ((), {'args': 1}))
3056
3057 sig = inspect.signature(test)
3058 ba = sig.bind(args=1)
3059 self.assertEqual(ba.arguments, {'kwargs': {'args': 1}})
3060
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003061
3062class TestBoundArguments(unittest.TestCase):
3063 def test_signature_bound_arguments_unhashable(self):
3064 def foo(a): pass
3065 ba = inspect.signature(foo).bind(1)
3066
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003067 with self.assertRaisesRegex(TypeError, 'unhashable type'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003068 hash(ba)
3069
3070 def test_signature_bound_arguments_equality(self):
3071 def foo(a): pass
3072 ba = inspect.signature(foo).bind(1)
3073 self.assertEqual(ba, ba)
3074
3075 ba2 = inspect.signature(foo).bind(1)
3076 self.assertEqual(ba, ba2)
3077
3078 ba3 = inspect.signature(foo).bind(2)
3079 self.assertNotEqual(ba, ba3)
3080 ba3.arguments['a'] = 1
3081 self.assertEqual(ba, ba3)
3082
3083 def bar(b): pass
3084 ba4 = inspect.signature(bar).bind(1)
3085 self.assertNotEqual(ba, ba4)
3086
Yury Selivanova5d63dd2014-03-27 11:31:43 -04003087 def test_signature_bound_arguments_pickle(self):
3088 def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
3089 sig = inspect.signature(foo)
3090 ba = sig.bind(20, 30, z={})
3091
3092 for ver in range(pickle.HIGHEST_PROTOCOL + 1):
3093 with self.subTest(pickle_ver=ver):
3094 ba_pickled = pickle.loads(pickle.dumps(ba, ver))
3095 self.assertEqual(ba, ba_pickled)
3096
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003097
Yury Selivanovd82eddc2014-01-29 11:24:39 -05003098class TestSignaturePrivateHelpers(unittest.TestCase):
3099 def test_signature_get_bound_param(self):
3100 getter = inspect._signature_get_bound_param
3101
3102 self.assertEqual(getter('($self)'), 'self')
3103 self.assertEqual(getter('($self, obj)'), 'self')
3104 self.assertEqual(getter('($cls, /, obj)'), 'cls')
3105
Larry Hastings2623c8c2014-02-08 22:15:29 -08003106 def _strip_non_python_syntax(self, input,
3107 clean_signature, self_parameter, last_positional_only):
3108 computed_clean_signature, \
3109 computed_self_parameter, \
3110 computed_last_positional_only = \
3111 inspect._signature_strip_non_python_syntax(input)
3112 self.assertEqual(computed_clean_signature, clean_signature)
3113 self.assertEqual(computed_self_parameter, self_parameter)
3114 self.assertEqual(computed_last_positional_only, last_positional_only)
3115
3116 def test_signature_strip_non_python_syntax(self):
3117 self._strip_non_python_syntax(
3118 "($module, /, path, mode, *, dir_fd=None, " +
3119 "effective_ids=False,\n follow_symlinks=True)",
3120 "(module, path, mode, *, dir_fd=None, " +
3121 "effective_ids=False, follow_symlinks=True)",
3122 0,
3123 0)
3124
3125 self._strip_non_python_syntax(
3126 "($module, word, salt, /)",
3127 "(module, word, salt)",
3128 0,
3129 2)
3130
3131 self._strip_non_python_syntax(
3132 "(x, y=None, z=None, /)",
3133 "(x, y=None, z=None)",
3134 None,
3135 2)
3136
3137 self._strip_non_python_syntax(
3138 "(x, y=None, z=None)",
3139 "(x, y=None, z=None)",
3140 None,
3141 None)
3142
3143 self._strip_non_python_syntax(
3144 "(x,\n y=None,\n z = None )",
3145 "(x, y=None, z=None)",
3146 None,
3147 None)
3148
3149 self._strip_non_python_syntax(
3150 "",
3151 "",
3152 None,
3153 None)
3154
3155 self._strip_non_python_syntax(
3156 None,
3157 None,
3158 None,
3159 None)
3160
Yury Selivanovd82eddc2014-01-29 11:24:39 -05003161
Nick Coghlane8c45d62013-07-28 20:00:01 +10003162class TestUnwrap(unittest.TestCase):
3163
3164 def test_unwrap_one(self):
3165 def func(a, b):
3166 return a + b
3167 wrapper = functools.lru_cache(maxsize=20)(func)
3168 self.assertIs(inspect.unwrap(wrapper), func)
3169
3170 def test_unwrap_several(self):
3171 def func(a, b):
3172 return a + b
3173 wrapper = func
3174 for __ in range(10):
3175 @functools.wraps(wrapper)
3176 def wrapper():
3177 pass
3178 self.assertIsNot(wrapper.__wrapped__, func)
3179 self.assertIs(inspect.unwrap(wrapper), func)
3180
3181 def test_stop(self):
3182 def func1(a, b):
3183 return a + b
3184 @functools.wraps(func1)
3185 def func2():
3186 pass
3187 @functools.wraps(func2)
3188 def wrapper():
3189 pass
3190 func2.stop_here = 1
3191 unwrapped = inspect.unwrap(wrapper,
3192 stop=(lambda f: hasattr(f, "stop_here")))
3193 self.assertIs(unwrapped, func2)
3194
3195 def test_cycle(self):
3196 def func1(): pass
3197 func1.__wrapped__ = func1
3198 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3199 inspect.unwrap(func1)
3200
3201 def func2(): pass
3202 func2.__wrapped__ = func1
3203 func1.__wrapped__ = func2
3204 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3205 inspect.unwrap(func1)
3206 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3207 inspect.unwrap(func2)
3208
3209 def test_unhashable(self):
3210 def func(): pass
3211 func.__wrapped__ = None
3212 class C:
3213 __hash__ = None
3214 __wrapped__ = func
3215 self.assertIsNone(inspect.unwrap(C()))
3216
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003217class TestMain(unittest.TestCase):
3218 def test_only_source(self):
3219 module = importlib.import_module('unittest')
3220 rc, out, err = assert_python_ok('-m', 'inspect',
3221 'unittest')
3222 lines = out.decode().splitlines()
3223 # ignore the final newline
3224 self.assertEqual(lines[:-1], inspect.getsource(module).splitlines())
3225 self.assertEqual(err, b'')
3226
Yury Selivanov42407ab2014-06-23 10:23:50 -07003227 def test_custom_getattr(self):
3228 def foo():
3229 pass
3230 foo.__signature__ = 42
3231 with self.assertRaises(TypeError):
3232 inspect.signature(foo)
3233
Brett Cannon634a8fc2013-10-02 10:25:42 -04003234 @unittest.skipIf(ThreadPoolExecutor is None,
Brett Cannon0de3f012013-10-02 10:58:58 -04003235 'threads required to test __qualname__ for source files')
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003236 def test_qualname_source(self):
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003237 rc, out, err = assert_python_ok('-m', 'inspect',
3238 'concurrent.futures:ThreadPoolExecutor')
3239 lines = out.decode().splitlines()
3240 # ignore the final newline
3241 self.assertEqual(lines[:-1],
Brett Cannon634a8fc2013-10-02 10:25:42 -04003242 inspect.getsource(ThreadPoolExecutor).splitlines())
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003243 self.assertEqual(err, b'')
3244
3245 def test_builtins(self):
3246 module = importlib.import_module('unittest')
3247 _, out, err = assert_python_failure('-m', 'inspect',
3248 'sys')
3249 lines = err.decode().splitlines()
3250 self.assertEqual(lines, ["Can't get info for builtin modules."])
3251
3252 def test_details(self):
3253 module = importlib.import_module('unittest')
3254 rc, out, err = assert_python_ok('-m', 'inspect',
3255 'unittest', '--details')
3256 output = out.decode()
3257 # Just a quick sanity check on the output
3258 self.assertIn(module.__name__, output)
3259 self.assertIn(module.__file__, output)
Serhiy Storchakab12cb6a2013-12-08 18:16:18 +02003260 if not sys.flags.optimize:
3261 self.assertIn(module.__cached__, output)
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003262 self.assertEqual(err, b'')
3263
3264
3265
Nick Coghlane8c45d62013-07-28 20:00:01 +10003266
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00003267def test_main():
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00003268 run_unittest(
3269 TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBuggyCases,
3270 TestInterpreterStack, TestClassesAndFunctions, TestPredicates,
3271 TestGetcallargsFunctions, TestGetcallargsMethods,
Alexander Belopolskyf546e702010-12-02 00:10:11 +00003272 TestGetcallargsUnboundMethods, TestGetattrStatic, TestGetGeneratorState,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003273 TestNoEOL, TestSignatureObject, TestSignatureBind, TestParameterObject,
Yury Selivanovd82eddc2014-01-29 11:24:39 -05003274 TestBoundArguments, TestSignaturePrivateHelpers, TestGetClosureVars,
3275 TestUnwrap, TestMain
Michael Foord95fc51d2010-11-20 15:07:30 +00003276 )
Martin v. Löwis893ffa42003-10-31 15:35:53 +00003277
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00003278if __name__ == "__main__":
3279 test_main()