blob: 6da58227689a0b7f55af6daa74a52949daa1a6dc [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
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000380class TestOneliners(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000381 fodderModule = mod2
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000382 def test_oneline_lambda(self):
383 # Test inspect.getsource with a one-line lambda function.
384 self.assertSourceEqual(mod2.oll, 25, 25)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000385
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000386 def test_threeline_lambda(self):
387 # Test inspect.getsource with a three-line lambda function,
388 # where the second and third lines are _not_ indented.
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000389 self.assertSourceEqual(mod2.tll, 28, 30)
390
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000391 def test_twoline_indented_lambda(self):
392 # Test inspect.getsource with a two-line lambda function,
393 # where the second line _is_ indented.
394 self.assertSourceEqual(mod2.tlli, 33, 34)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000395
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000396 def test_onelinefunc(self):
397 # Test inspect.getsource with a regular one-line function.
398 self.assertSourceEqual(mod2.onelinefunc, 37, 37)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000399
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000400 def test_manyargs(self):
401 # Test inspect.getsource with a regular function where
402 # the arguments are on two lines and _not_ indented and
403 # the body on the second line with the last arguments.
404 self.assertSourceEqual(mod2.manyargs, 40, 41)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000405
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000406 def test_twolinefunc(self):
407 # Test inspect.getsource with a regular function where
408 # the body is on two lines, following the argument list and
409 # continued on the next line by a \\.
410 self.assertSourceEqual(mod2.twolinefunc, 44, 45)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000411
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000412 def test_lambda_in_list(self):
413 # Test inspect.getsource with a one-line lambda function
414 # defined in a list, indented.
415 self.assertSourceEqual(mod2.a[1], 49, 49)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000416
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000417 def test_anonymous(self):
418 # Test inspect.getsource with a lambda function defined
419 # as argument to another function.
420 self.assertSourceEqual(mod2.anonymous, 55, 55)
421
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000422class TestBuggyCases(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000423 fodderModule = mod2
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000424
425 def test_with_comment(self):
426 self.assertSourceEqual(mod2.with_comment, 58, 59)
427
428 def test_multiline_sig(self):
429 self.assertSourceEqual(mod2.multiline_sig[0], 63, 64)
430
Armin Rigodd5c0232005-09-25 11:45:45 +0000431 def test_nested_class(self):
432 self.assertSourceEqual(mod2.func69().func71, 71, 72)
433
434 def test_one_liner_followed_by_non_name(self):
435 self.assertSourceEqual(mod2.func77, 77, 77)
436
437 def test_one_liner_dedent_non_name(self):
438 self.assertSourceEqual(mod2.cls82.func83, 83, 83)
439
440 def test_with_comment_instead_of_docstring(self):
441 self.assertSourceEqual(mod2.func88, 88, 90)
442
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000443 def test_method_in_dynamic_class(self):
444 self.assertSourceEqual(mod2.method_in_dynamic_class, 95, 97)
445
R. David Murrayb5655772009-05-14 16:17:50 +0000446 @unittest.skipIf(
447 not hasattr(unicodedata, '__file__') or
448 unicodedata.__file__[-4:] in (".pyc", ".pyo"),
449 "unicodedata is not an external binary module")
R. David Murray74b89242009-05-13 17:33:03 +0000450 def test_findsource_binary(self):
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200451 self.assertRaises(OSError, inspect.getsource, unicodedata)
452 self.assertRaises(OSError, inspect.findsource, unicodedata)
R. David Murray74b89242009-05-13 17:33:03 +0000453
R. David Murraya1b37402010-06-17 02:04:29 +0000454 def test_findsource_code_in_linecache(self):
455 lines = ["x=1"]
456 co = compile(lines[0], "_dynamically_created_file", "exec")
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200457 self.assertRaises(OSError, inspect.findsource, co)
458 self.assertRaises(OSError, inspect.getsource, co)
R. David Murraya1b37402010-06-17 02:04:29 +0000459 linecache.cache[co.co_filename] = (1, None, lines, co.co_filename)
Antoine Pitrou5d62a612012-07-08 13:48:46 +0200460 try:
461 self.assertEqual(inspect.findsource(co), (lines,0))
462 self.assertEqual(inspect.getsource(co), lines[0])
463 finally:
464 del linecache.cache[co.co_filename]
R. David Murraya1b37402010-06-17 02:04:29 +0000465
Ezio Melotti1b145922013-03-30 05:17:24 +0200466 def test_findsource_without_filename(self):
467 for fname in ['', '<string>']:
468 co = compile('x=1', fname, "exec")
469 self.assertRaises(IOError, inspect.findsource, co)
470 self.assertRaises(IOError, inspect.getsource, co)
471
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000472class TestNoEOL(GetSourceBase):
473 def __init__(self, *args, **kwargs):
474 self.tempdir = TESTFN + '_dir'
475 os.mkdir(self.tempdir)
476 with open(os.path.join(self.tempdir,
477 'inspect_fodder3%spy' % os.extsep), 'w') as f:
478 f.write("class X:\n pass # No EOL")
479 with DirsOnSysPath(self.tempdir):
480 import inspect_fodder3 as mod3
481 self.fodderModule = mod3
482 GetSourceBase.__init__(self, *args, **kwargs)
483
484 def tearDown(self):
485 shutil.rmtree(self.tempdir)
486
487 def test_class(self):
488 self.assertSourceEqual(self.fodderModule.X, 1, 2)
489
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100490
491class _BrokenDataDescriptor(object):
492 """
493 A broken data descriptor. See bug #1785.
494 """
495 def __get__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700496 raise AttributeError("broken data descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100497
498 def __set__(*args):
499 raise RuntimeError
500
501 def __getattr__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700502 raise AttributeError("broken data descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100503
504
505class _BrokenMethodDescriptor(object):
506 """
507 A broken method descriptor. See bug #1785.
508 """
509 def __get__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700510 raise AttributeError("broken method descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100511
512 def __getattr__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700513 raise AttributeError("broken method descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100514
515
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000516# Helper for testing classify_class_attrs.
Tim Peters13b49d32001-09-23 02:00:29 +0000517def attrs_wo_objs(cls):
518 return [t[:3] for t in inspect.classify_class_attrs(cls)]
519
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100520
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000521class TestClassesAndFunctions(unittest.TestCase):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000522 def test_newstyle_mro(self):
523 # The same w/ new-class MRO.
524 class A(object): pass
525 class B(A): pass
526 class C(A): pass
527 class D(B, C): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000528
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000529 expected = (D, B, C, A, object)
530 got = inspect.getmro(D)
531 self.assertEqual(expected, got)
Tim Peters13b49d32001-09-23 02:00:29 +0000532
Christian Heimes3795b532007-11-08 13:48:53 +0000533 def assertArgSpecEquals(self, routine, args_e, varargs_e=None,
534 varkw_e=None, defaults_e=None, formatted=None):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000535 args, varargs, varkw, defaults = inspect.getargspec(routine)
536 self.assertEqual(args, args_e)
537 self.assertEqual(varargs, varargs_e)
538 self.assertEqual(varkw, varkw_e)
539 self.assertEqual(defaults, defaults_e)
540 if formatted is not None:
541 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults),
542 formatted)
Tim Peters13b49d32001-09-23 02:00:29 +0000543
Christian Heimes3795b532007-11-08 13:48:53 +0000544 def assertFullArgSpecEquals(self, routine, args_e, varargs_e=None,
545 varkw_e=None, defaults_e=None,
546 kwonlyargs_e=[], kwonlydefaults_e=None,
547 ann_e={}, formatted=None):
548 args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \
549 inspect.getfullargspec(routine)
550 self.assertEqual(args, args_e)
551 self.assertEqual(varargs, varargs_e)
552 self.assertEqual(varkw, varkw_e)
553 self.assertEqual(defaults, defaults_e)
554 self.assertEqual(kwonlyargs, kwonlyargs_e)
555 self.assertEqual(kwonlydefaults, kwonlydefaults_e)
556 self.assertEqual(ann, ann_e)
557 if formatted is not None:
558 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults,
559 kwonlyargs, kwonlydefaults, ann),
560 formatted)
561
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000562 def test_getargspec(self):
Christian Heimes3795b532007-11-08 13:48:53 +0000563 self.assertArgSpecEquals(mod.eggs, ['x', 'y'], formatted='(x, y)')
Tim Peters13b49d32001-09-23 02:00:29 +0000564
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000565 self.assertArgSpecEquals(mod.spam,
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000566 ['a', 'b', 'c', 'd', 'e', 'f'],
567 'g', 'h', (3, 4, 5),
568 '(a, b, c, d=3, e=4, f=5, *g, **h)')
Tim Peters13b49d32001-09-23 02:00:29 +0000569
Christian Heimes3795b532007-11-08 13:48:53 +0000570 self.assertRaises(ValueError, self.assertArgSpecEquals,
571 mod2.keyworded, [])
572
573 self.assertRaises(ValueError, self.assertArgSpecEquals,
574 mod2.annotated, [])
Benjamin Peterson9953a8d2009-01-17 04:15:01 +0000575 self.assertRaises(ValueError, self.assertArgSpecEquals,
576 mod2.keyword_only_arg, [])
577
Christian Heimes3795b532007-11-08 13:48:53 +0000578
579 def test_getfullargspec(self):
580 self.assertFullArgSpecEquals(mod2.keyworded, [], varargs_e='arg1',
581 kwonlyargs_e=['arg2'],
582 kwonlydefaults_e={'arg2':1},
583 formatted='(*arg1, arg2=1)')
584
585 self.assertFullArgSpecEquals(mod2.annotated, ['arg1'],
Christian Heimesc9543e42007-11-28 08:28:28 +0000586 ann_e={'arg1' : list},
Christian Heimes3795b532007-11-08 13:48:53 +0000587 formatted='(arg1: list)')
Benjamin Peterson9953a8d2009-01-17 04:15:01 +0000588 self.assertFullArgSpecEquals(mod2.keyword_only_arg, [],
589 kwonlyargs_e=['arg'],
590 formatted='(*, arg)')
591
Yury Selivanov57d240e2014-02-19 16:27:23 -0500592 def test_argspec_api_ignores_wrapped(self):
593 # Issue 20684: low level introspection API must ignore __wrapped__
594 @functools.wraps(mod.spam)
595 def ham(x, y):
596 pass
597 # Basic check
598 self.assertArgSpecEquals(ham, ['x', 'y'], formatted='(x, y)')
599 self.assertFullArgSpecEquals(ham, ['x', 'y'], formatted='(x, y)')
600 self.assertFullArgSpecEquals(functools.partial(ham),
601 ['x', 'y'], formatted='(x, y)')
602 # Other variants
603 def check_method(f):
604 self.assertArgSpecEquals(f, ['self', 'x', 'y'],
605 formatted='(self, x, y)')
606 class C:
607 @functools.wraps(mod.spam)
608 def ham(self, x, y):
609 pass
610 pham = functools.partialmethod(ham)
611 @functools.wraps(mod.spam)
612 def __call__(self, x, y):
613 pass
614 check_method(C())
615 check_method(C.ham)
616 check_method(C().ham)
617 check_method(C.pham)
618 check_method(C().pham)
619
620 class C_new:
621 @functools.wraps(mod.spam)
622 def __new__(self, x, y):
623 pass
624 check_method(C_new)
625
626 class C_init:
627 @functools.wraps(mod.spam)
628 def __init__(self, x, y):
629 pass
630 check_method(C_init)
631
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500632 def test_getfullargspec_signature_attr(self):
633 def test():
634 pass
635 spam_param = inspect.Parameter('spam', inspect.Parameter.POSITIONAL_ONLY)
636 test.__signature__ = inspect.Signature(parameters=(spam_param,))
637
638 self.assertFullArgSpecEquals(test, args_e=['spam'], formatted='(spam)')
639
Yury Selivanov4cb93912014-01-29 11:54:12 -0500640 def test_getfullargspec_signature_annos(self):
641 def test(a:'spam') -> 'ham': pass
642 spec = inspect.getfullargspec(test)
643 self.assertEqual(test.__annotations__, spec.annotations)
644
645 def test(): pass
646 spec = inspect.getfullargspec(test)
647 self.assertEqual(test.__annotations__, spec.annotations)
648
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500649 @unittest.skipIf(MISSING_C_DOCSTRINGS,
650 "Signature information for builtins requires docstrings")
651 def test_getfullargspec_builtin_methods(self):
652 self.assertFullArgSpecEquals(_pickle.Pickler.dump,
653 args_e=['self', 'obj'], formatted='(self, obj)')
654
655 self.assertFullArgSpecEquals(_pickle.Pickler(io.BytesIO()).dump,
656 args_e=['self', 'obj'], formatted='(self, obj)')
657
Yury Selivanov8c185ee2014-02-21 01:32:42 -0500658 self.assertFullArgSpecEquals(
659 os.stat,
660 args_e=['path'],
661 kwonlyargs_e=['dir_fd', 'follow_symlinks'],
662 kwonlydefaults_e={'dir_fd': None, 'follow_symlinks': True},
663 formatted='(path, *, dir_fd=None, follow_symlinks=True)')
664
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200665 @cpython_only
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500666 @unittest.skipIf(MISSING_C_DOCSTRINGS,
667 "Signature information for builtins requires docstrings")
668 def test_getfullagrspec_builtin_func(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200669 import _testcapi
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500670 builtin = _testcapi.docstring_with_signature_with_defaults
671 spec = inspect.getfullargspec(builtin)
672 self.assertEqual(spec.defaults[0], 'avocado')
673
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200674 @cpython_only
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500675 @unittest.skipIf(MISSING_C_DOCSTRINGS,
676 "Signature information for builtins requires docstrings")
677 def test_getfullagrspec_builtin_func_no_signature(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200678 import _testcapi
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500679 builtin = _testcapi.docstring_no_signature
680 with self.assertRaises(TypeError):
681 inspect.getfullargspec(builtin)
Christian Heimes3795b532007-11-08 13:48:53 +0000682
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000683 def test_getargspec_method(self):
684 class A(object):
685 def m(self):
686 pass
687 self.assertArgSpecEquals(A.m, ['self'])
Tim Peters13b49d32001-09-23 02:00:29 +0000688
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000689 def test_classify_newstyle(self):
690 class A(object):
Tim Peters13b49d32001-09-23 02:00:29 +0000691
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000692 def s(): pass
693 s = staticmethod(s)
Tim Peters13b49d32001-09-23 02:00:29 +0000694
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000695 def c(cls): pass
696 c = classmethod(c)
Tim Peters13b49d32001-09-23 02:00:29 +0000697
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000698 def getp(self): pass
699 p = property(getp)
Tim Peters13b49d32001-09-23 02:00:29 +0000700
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000701 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000702
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000703 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000704
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000705 datablob = '1'
Tim Peters13b49d32001-09-23 02:00:29 +0000706
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100707 dd = _BrokenDataDescriptor()
708 md = _BrokenMethodDescriptor()
709
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000710 attrs = attrs_wo_objs(A)
Yury Selivanov0860a0b2014-01-31 14:28:44 -0500711
712 self.assertIn(('__new__', 'method', object), attrs, 'missing __new__')
713 self.assertIn(('__init__', 'method', object), attrs, 'missing __init__')
714
Benjamin Peterson577473f2010-01-19 00:09:57 +0000715 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
716 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
717 self.assertIn(('p', 'property', A), attrs, 'missing property')
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000718 self.assertIn(('m', 'method', A), attrs,
719 'missing plain method: %r' % attrs)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000720 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
721 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100722 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
723 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000724
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000725 class B(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000726
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000727 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000728
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000729 attrs = attrs_wo_objs(B)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000730 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
731 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
732 self.assertIn(('p', 'property', A), attrs, 'missing property')
733 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
734 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
735 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100736 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
737 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000738
739
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000740 class C(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000741
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000742 def m(self): pass
743 def c(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000744
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000745 attrs = attrs_wo_objs(C)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000746 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
747 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
748 self.assertIn(('p', 'property', A), attrs, 'missing property')
749 self.assertIn(('m', 'method', C), attrs, 'missing plain method')
750 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
751 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100752 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
753 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000754
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000755 class D(B, C):
Tim Peters13b49d32001-09-23 02:00:29 +0000756
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000757 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000758
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000759 attrs = attrs_wo_objs(D)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000760 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
761 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
762 self.assertIn(('p', 'property', A), attrs, 'missing property')
763 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
764 self.assertIn(('m1', 'method', D), attrs, 'missing plain method')
765 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100766 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
767 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
768
769 def test_classify_builtin_types(self):
770 # Simple sanity check that all built-in types can have their
771 # attributes classified.
772 for name in dir(__builtins__):
773 builtin = getattr(__builtins__, name)
774 if isinstance(builtin, type):
775 inspect.classify_class_attrs(builtin)
776
Ethan Furman63c141c2013-10-18 00:27:39 -0700777 def test_classify_DynamicClassAttribute(self):
778 class Meta(type):
779 def __getattr__(self, name):
780 if name == 'ham':
781 return 'spam'
782 return super().__getattr__(name)
783 class VA(metaclass=Meta):
Ethan Furmane03ea372013-09-25 07:14:41 -0700784 @types.DynamicClassAttribute
785 def ham(self):
786 return 'eggs'
Ethan Furman63c141c2013-10-18 00:27:39 -0700787 should_find_dca = inspect.Attribute('ham', 'data', VA, VA.__dict__['ham'])
788 self.assertIn(should_find_dca, inspect.classify_class_attrs(VA))
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700789 should_find_ga = inspect.Attribute('ham', 'data', Meta, 'spam')
Ethan Furman63c141c2013-10-18 00:27:39 -0700790 self.assertIn(should_find_ga, inspect.classify_class_attrs(VA))
791
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700792 def test_classify_metaclass_class_attribute(self):
793 class Meta(type):
794 fish = 'slap'
795 def __dir__(self):
796 return ['__class__', '__modules__', '__name__', 'fish']
797 class Class(metaclass=Meta):
798 pass
799 should_find = inspect.Attribute('fish', 'data', Meta, 'slap')
800 self.assertIn(should_find, inspect.classify_class_attrs(Class))
801
Ethan Furman63c141c2013-10-18 00:27:39 -0700802 def test_classify_VirtualAttribute(self):
803 class Meta(type):
804 def __dir__(cls):
805 return ['__class__', '__module__', '__name__', 'BOOM']
806 def __getattr__(self, name):
807 if name =='BOOM':
808 return 42
809 return super().__getattr(name)
810 class Class(metaclass=Meta):
811 pass
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700812 should_find = inspect.Attribute('BOOM', 'data', Meta, 42)
Ethan Furman63c141c2013-10-18 00:27:39 -0700813 self.assertIn(should_find, inspect.classify_class_attrs(Class))
814
815 def test_classify_VirtualAttribute_multi_classes(self):
816 class Meta1(type):
817 def __dir__(cls):
818 return ['__class__', '__module__', '__name__', 'one']
819 def __getattr__(self, name):
820 if name =='one':
821 return 1
822 return super().__getattr__(name)
823 class Meta2(type):
824 def __dir__(cls):
825 return ['__class__', '__module__', '__name__', 'two']
826 def __getattr__(self, name):
827 if name =='two':
828 return 2
829 return super().__getattr__(name)
830 class Meta3(Meta1, Meta2):
831 def __dir__(cls):
832 return list(sorted(set(['__class__', '__module__', '__name__', 'three'] +
833 Meta1.__dir__(cls) + Meta2.__dir__(cls))))
834 def __getattr__(self, name):
835 if name =='three':
836 return 3
837 return super().__getattr__(name)
838 class Class1(metaclass=Meta1):
839 pass
840 class Class2(Class1, metaclass=Meta3):
841 pass
842
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700843 should_find1 = inspect.Attribute('one', 'data', Meta1, 1)
844 should_find2 = inspect.Attribute('two', 'data', Meta2, 2)
845 should_find3 = inspect.Attribute('three', 'data', Meta3, 3)
Ethan Furman63c141c2013-10-18 00:27:39 -0700846 cca = inspect.classify_class_attrs(Class2)
847 for sf in (should_find1, should_find2, should_find3):
848 self.assertIn(sf, cca)
849
850 def test_classify_class_attrs_with_buggy_dir(self):
851 class M(type):
852 def __dir__(cls):
853 return ['__class__', '__name__', 'missing']
854 class C(metaclass=M):
855 pass
856 attrs = [a[0] for a in inspect.classify_class_attrs(C)]
857 self.assertNotIn('missing', attrs)
Ethan Furmane03ea372013-09-25 07:14:41 -0700858
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100859 def test_getmembers_descriptors(self):
860 class A(object):
861 dd = _BrokenDataDescriptor()
862 md = _BrokenMethodDescriptor()
863
864 def pred_wrapper(pred):
865 # A quick'n'dirty way to discard standard attributes of new-style
866 # classes.
867 class Empty(object):
868 pass
869 def wrapped(x):
870 if '__name__' in dir(x) and hasattr(Empty, x.__name__):
871 return False
872 return pred(x)
873 return wrapped
874
875 ismethoddescriptor = pred_wrapper(inspect.ismethoddescriptor)
876 isdatadescriptor = pred_wrapper(inspect.isdatadescriptor)
877
878 self.assertEqual(inspect.getmembers(A, ismethoddescriptor),
879 [('md', A.__dict__['md'])])
880 self.assertEqual(inspect.getmembers(A, isdatadescriptor),
881 [('dd', A.__dict__['dd'])])
882
883 class B(A):
884 pass
885
886 self.assertEqual(inspect.getmembers(B, ismethoddescriptor),
887 [('md', A.__dict__['md'])])
888 self.assertEqual(inspect.getmembers(B, isdatadescriptor),
889 [('dd', A.__dict__['dd'])])
890
Antoine Pitrou0c603812012-01-18 17:40:18 +0100891 def test_getmembers_method(self):
892 class B:
893 def f(self):
894 pass
895
896 self.assertIn(('f', B.f), inspect.getmembers(B))
897 self.assertNotIn(('f', B.f), inspect.getmembers(B, inspect.ismethod))
898 b = B()
899 self.assertIn(('f', b.f), inspect.getmembers(b))
900 self.assertIn(('f', b.f), inspect.getmembers(b, inspect.ismethod))
901
Ethan Furmane03ea372013-09-25 07:14:41 -0700902 def test_getmembers_VirtualAttribute(self):
Ethan Furman63c141c2013-10-18 00:27:39 -0700903 class M(type):
904 def __getattr__(cls, name):
905 if name == 'eggs':
906 return 'scrambled'
907 return super().__getattr__(name)
908 class A(metaclass=M):
Ethan Furmane03ea372013-09-25 07:14:41 -0700909 @types.DynamicClassAttribute
910 def eggs(self):
911 return 'spam'
Ethan Furman63c141c2013-10-18 00:27:39 -0700912 self.assertIn(('eggs', 'scrambled'), inspect.getmembers(A))
913 self.assertIn(('eggs', 'spam'), inspect.getmembers(A()))
914
915 def test_getmembers_with_buggy_dir(self):
916 class M(type):
917 def __dir__(cls):
918 return ['__class__', '__name__', 'missing']
919 class C(metaclass=M):
920 pass
921 attrs = [a[0] for a in inspect.getmembers(C)]
922 self.assertNotIn('missing', attrs)
Ethan Furmane03ea372013-09-25 07:14:41 -0700923
Jeremy Hyltonc4bf5ed2003-06-27 18:43:12 +0000924
Nick Coghlan2f92e542012-06-23 19:39:55 +1000925_global_ref = object()
926class TestGetClosureVars(unittest.TestCase):
927
928 def test_name_resolution(self):
929 # Basic test of the 4 different resolution mechanisms
930 def f(nonlocal_ref):
931 def g(local_ref):
932 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
933 return g
934 _arg = object()
935 nonlocal_vars = {"nonlocal_ref": _arg}
936 global_vars = {"_global_ref": _global_ref}
937 builtin_vars = {"print": print}
938 unbound_names = {"unbound_ref"}
939 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
940 builtin_vars, unbound_names)
941 self.assertEqual(inspect.getclosurevars(f(_arg)), expected)
942
943 def test_generator_closure(self):
944 def f(nonlocal_ref):
945 def g(local_ref):
946 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
947 yield
948 return g
949 _arg = object()
950 nonlocal_vars = {"nonlocal_ref": _arg}
951 global_vars = {"_global_ref": _global_ref}
952 builtin_vars = {"print": print}
953 unbound_names = {"unbound_ref"}
954 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
955 builtin_vars, unbound_names)
956 self.assertEqual(inspect.getclosurevars(f(_arg)), expected)
957
958 def test_method_closure(self):
959 class C:
960 def f(self, nonlocal_ref):
961 def g(local_ref):
962 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
963 return g
964 _arg = object()
965 nonlocal_vars = {"nonlocal_ref": _arg}
966 global_vars = {"_global_ref": _global_ref}
967 builtin_vars = {"print": print}
968 unbound_names = {"unbound_ref"}
969 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
970 builtin_vars, unbound_names)
971 self.assertEqual(inspect.getclosurevars(C().f(_arg)), expected)
972
973 def test_nonlocal_vars(self):
974 # More complex tests of nonlocal resolution
975 def _nonlocal_vars(f):
976 return inspect.getclosurevars(f).nonlocals
977
978 def make_adder(x):
979 def add(y):
980 return x + y
981 return add
982
983 def curry(func, arg1):
984 return lambda arg2: func(arg1, arg2)
985
986 def less_than(a, b):
987 return a < b
988
989 # The infamous Y combinator.
990 def Y(le):
991 def g(f):
992 return le(lambda x: f(f)(x))
993 Y.g_ref = g
994 return g(g)
995
996 def check_y_combinator(func):
997 self.assertEqual(_nonlocal_vars(func), {'f': Y.g_ref})
998
999 inc = make_adder(1)
1000 add_two = make_adder(2)
1001 greater_than_five = curry(less_than, 5)
1002
1003 self.assertEqual(_nonlocal_vars(inc), {'x': 1})
1004 self.assertEqual(_nonlocal_vars(add_two), {'x': 2})
1005 self.assertEqual(_nonlocal_vars(greater_than_five),
1006 {'arg1': 5, 'func': less_than})
1007 self.assertEqual(_nonlocal_vars((lambda x: lambda y: x + y)(3)),
1008 {'x': 3})
1009 Y(check_y_combinator)
1010
1011 def test_getclosurevars_empty(self):
1012 def foo(): pass
1013 _empty = inspect.ClosureVars({}, {}, {}, set())
1014 self.assertEqual(inspect.getclosurevars(lambda: True), _empty)
1015 self.assertEqual(inspect.getclosurevars(foo), _empty)
1016
1017 def test_getclosurevars_error(self):
1018 class T: pass
1019 self.assertRaises(TypeError, inspect.getclosurevars, 1)
1020 self.assertRaises(TypeError, inspect.getclosurevars, list)
1021 self.assertRaises(TypeError, inspect.getclosurevars, {})
1022
Nick Coghlan6c6e2542012-06-23 20:07:39 +10001023 def _private_globals(self):
1024 code = """def f(): print(path)"""
1025 ns = {}
1026 exec(code, ns)
1027 return ns["f"], ns
1028
1029 def test_builtins_fallback(self):
1030 f, ns = self._private_globals()
1031 ns.pop("__builtins__", None)
1032 expected = inspect.ClosureVars({}, {}, {"print":print}, {"path"})
1033 self.assertEqual(inspect.getclosurevars(f), expected)
1034
1035 def test_builtins_as_dict(self):
1036 f, ns = self._private_globals()
1037 ns["__builtins__"] = {"path":1}
1038 expected = inspect.ClosureVars({}, {}, {"path":1}, {"print"})
1039 self.assertEqual(inspect.getclosurevars(f), expected)
1040
1041 def test_builtins_as_module(self):
1042 f, ns = self._private_globals()
1043 ns["__builtins__"] = os
1044 expected = inspect.ClosureVars({}, {}, {"path":os.path}, {"print"})
1045 self.assertEqual(inspect.getclosurevars(f), expected)
1046
Nick Coghlan2f92e542012-06-23 19:39:55 +10001047
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001048class TestGetcallargsFunctions(unittest.TestCase):
1049
1050 def assertEqualCallArgs(self, func, call_params_string, locs=None):
1051 locs = dict(locs or {}, func=func)
1052 r1 = eval('func(%s)' % call_params_string, None, locs)
1053 r2 = eval('inspect.getcallargs(func, %s)' % call_params_string, None,
1054 locs)
1055 self.assertEqual(r1, r2)
1056
1057 def assertEqualException(self, func, call_param_string, locs=None):
1058 locs = dict(locs or {}, func=func)
1059 try:
1060 eval('func(%s)' % call_param_string, None, locs)
1061 except Exception as e:
1062 ex1 = e
1063 else:
1064 self.fail('Exception not raised')
1065 try:
1066 eval('inspect.getcallargs(func, %s)' % call_param_string, None,
1067 locs)
1068 except Exception as e:
1069 ex2 = e
1070 else:
1071 self.fail('Exception not raised')
1072 self.assertIs(type(ex1), type(ex2))
1073 self.assertEqual(str(ex1), str(ex2))
1074 del ex1, ex2
1075
1076 def makeCallable(self, signature):
1077 """Create a function that returns its locals()"""
1078 code = "lambda %s: locals()"
1079 return eval(code % signature)
1080
1081 def test_plain(self):
1082 f = self.makeCallable('a, b=1')
1083 self.assertEqualCallArgs(f, '2')
1084 self.assertEqualCallArgs(f, '2, 3')
1085 self.assertEqualCallArgs(f, 'a=2')
1086 self.assertEqualCallArgs(f, 'b=3, a=2')
1087 self.assertEqualCallArgs(f, '2, b=3')
1088 # expand *iterable / **mapping
1089 self.assertEqualCallArgs(f, '*(2,)')
1090 self.assertEqualCallArgs(f, '*[2]')
1091 self.assertEqualCallArgs(f, '*(2, 3)')
1092 self.assertEqualCallArgs(f, '*[2, 3]')
1093 self.assertEqualCallArgs(f, '**{"a":2}')
1094 self.assertEqualCallArgs(f, 'b=3, **{"a":2}')
1095 self.assertEqualCallArgs(f, '2, **{"b":3}')
1096 self.assertEqualCallArgs(f, '**{"b":3, "a":2}')
1097 # expand UserList / UserDict
1098 self.assertEqualCallArgs(f, '*collections.UserList([2])')
1099 self.assertEqualCallArgs(f, '*collections.UserList([2, 3])')
1100 self.assertEqualCallArgs(f, '**collections.UserDict(a=2)')
1101 self.assertEqualCallArgs(f, '2, **collections.UserDict(b=3)')
1102 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3)')
1103
1104 def test_varargs(self):
1105 f = self.makeCallable('a, b=1, *c')
1106 self.assertEqualCallArgs(f, '2')
1107 self.assertEqualCallArgs(f, '2, 3')
1108 self.assertEqualCallArgs(f, '2, 3, 4')
1109 self.assertEqualCallArgs(f, '*(2,3,4)')
1110 self.assertEqualCallArgs(f, '2, *[3,4]')
1111 self.assertEqualCallArgs(f, '2, 3, *collections.UserList([4])')
1112
1113 def test_varkw(self):
1114 f = self.makeCallable('a, b=1, **c')
1115 self.assertEqualCallArgs(f, 'a=2')
1116 self.assertEqualCallArgs(f, '2, b=3, c=4')
1117 self.assertEqualCallArgs(f, 'b=3, a=2, c=4')
1118 self.assertEqualCallArgs(f, 'c=4, **{"a":2, "b":3}')
1119 self.assertEqualCallArgs(f, '2, c=4, **{"b":3}')
1120 self.assertEqualCallArgs(f, 'b=2, **{"a":3, "c":4}')
1121 self.assertEqualCallArgs(f, '**collections.UserDict(a=2, b=3, c=4)')
1122 self.assertEqualCallArgs(f, '2, c=4, **collections.UserDict(b=3)')
1123 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3, c=4)')
1124
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001125 def test_varkw_only(self):
1126 # issue11256:
1127 f = self.makeCallable('**c')
1128 self.assertEqualCallArgs(f, '')
1129 self.assertEqualCallArgs(f, 'a=1')
1130 self.assertEqualCallArgs(f, 'a=1, b=2')
1131 self.assertEqualCallArgs(f, 'c=3, **{"a": 1, "b": 2}')
1132 self.assertEqualCallArgs(f, '**collections.UserDict(a=1, b=2)')
1133 self.assertEqualCallArgs(f, 'c=3, **collections.UserDict(a=1, b=2)')
1134
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001135 def test_keyword_only(self):
1136 f = self.makeCallable('a=3, *, c, d=2')
1137 self.assertEqualCallArgs(f, 'c=3')
1138 self.assertEqualCallArgs(f, 'c=3, a=3')
1139 self.assertEqualCallArgs(f, 'a=2, c=4')
1140 self.assertEqualCallArgs(f, '4, c=4')
1141 self.assertEqualException(f, '')
1142 self.assertEqualException(f, '3')
1143 self.assertEqualException(f, 'a=3')
1144 self.assertEqualException(f, 'd=4')
1145
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001146 f = self.makeCallable('*, c, d=2')
1147 self.assertEqualCallArgs(f, 'c=3')
1148 self.assertEqualCallArgs(f, 'c=3, d=4')
1149 self.assertEqualCallArgs(f, 'd=4, c=3')
1150
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001151 def test_multiple_features(self):
1152 f = self.makeCallable('a, b=2, *f, **g')
1153 self.assertEqualCallArgs(f, '2, 3, 7')
1154 self.assertEqualCallArgs(f, '2, 3, x=8')
1155 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
1156 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9')
1157 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9')
1158 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
1159 '[2, 3, (4,[5,6])]), **{"y":9, "z":10}')
1160 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
1161 '(4,[5,6])]), **collections.UserDict('
1162 'y=9, z=10)')
1163
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001164 f = self.makeCallable('a, b=2, *f, x, y=99, **g')
1165 self.assertEqualCallArgs(f, '2, 3, x=8')
1166 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
1167 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9, z=10')
1168 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9, z=10')
1169 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
1170 '[2, 3, (4,[5,6])]), q=0, **{"y":9, "z":10}')
1171 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
1172 '(4,[5,6])]), q=0, **collections.UserDict('
1173 'y=9, z=10)')
1174
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001175 def test_errors(self):
1176 f0 = self.makeCallable('')
1177 f1 = self.makeCallable('a, b')
1178 f2 = self.makeCallable('a, b=1')
1179 # f0 takes no arguments
1180 self.assertEqualException(f0, '1')
1181 self.assertEqualException(f0, 'x=1')
1182 self.assertEqualException(f0, '1,x=1')
1183 # f1 takes exactly 2 arguments
1184 self.assertEqualException(f1, '')
1185 self.assertEqualException(f1, '1')
1186 self.assertEqualException(f1, 'a=2')
1187 self.assertEqualException(f1, 'b=3')
1188 # f2 takes at least 1 argument
1189 self.assertEqualException(f2, '')
1190 self.assertEqualException(f2, 'b=3')
1191 for f in f1, f2:
1192 # f1/f2 takes exactly/at most 2 arguments
1193 self.assertEqualException(f, '2, 3, 4')
1194 self.assertEqualException(f, '1, 2, 3, a=1')
1195 self.assertEqualException(f, '2, 3, 4, c=5')
Georg Brandl178e5ea2012-02-21 00:32:36 +01001196 # XXX: success of this one depends on dict order
1197 ## self.assertEqualException(f, '2, 3, 4, a=1, c=5')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001198 # f got an unexpected keyword argument
1199 self.assertEqualException(f, 'c=2')
1200 self.assertEqualException(f, '2, c=3')
1201 self.assertEqualException(f, '2, 3, c=4')
1202 self.assertEqualException(f, '2, c=4, b=3')
1203 self.assertEqualException(f, '**{u"\u03c0\u03b9": 4}')
1204 # f got multiple values for keyword argument
1205 self.assertEqualException(f, '1, a=2')
1206 self.assertEqualException(f, '1, **{"a":2}')
1207 self.assertEqualException(f, '1, 2, b=3')
1208 # XXX: Python inconsistency
1209 # - for functions and bound methods: unexpected keyword 'c'
1210 # - for unbound methods: multiple values for keyword 'a'
1211 #self.assertEqualException(f, '1, c=3, a=2')
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001212 # issue11256:
1213 f3 = self.makeCallable('**c')
1214 self.assertEqualException(f3, '1, 2')
1215 self.assertEqualException(f3, '1, 2, a=1, b=2')
1216 f4 = self.makeCallable('*, a, b=0')
1217 self.assertEqualException(f3, '1, 2')
1218 self.assertEqualException(f3, '1, 2, a=1, b=2')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001219
Yury Selivanov875df202014-03-27 18:23:03 -04001220 # issue #20816: getcallargs() fails to iterate over non-existent
1221 # kwonlydefaults and raises a wrong TypeError
1222 def f5(*, a): pass
1223 with self.assertRaisesRegex(TypeError,
1224 'missing 1 required keyword-only'):
1225 inspect.getcallargs(f5)
1226
1227
Yury Selivanovdccfa132014-03-27 18:42:52 -04001228 # issue20817:
1229 def f6(a, b, c):
1230 pass
1231 with self.assertRaisesRegex(TypeError, "'a', 'b' and 'c'"):
1232 inspect.getcallargs(f6)
1233
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001234class TestGetcallargsMethods(TestGetcallargsFunctions):
1235
1236 def setUp(self):
1237 class Foo(object):
1238 pass
1239 self.cls = Foo
1240 self.inst = Foo()
1241
1242 def makeCallable(self, signature):
1243 assert 'self' not in signature
1244 mk = super(TestGetcallargsMethods, self).makeCallable
1245 self.cls.method = mk('self, ' + signature)
1246 return self.inst.method
1247
1248class TestGetcallargsUnboundMethods(TestGetcallargsMethods):
1249
1250 def makeCallable(self, signature):
1251 super(TestGetcallargsUnboundMethods, self).makeCallable(signature)
1252 return self.cls.method
1253
1254 def assertEqualCallArgs(self, func, call_params_string, locs=None):
1255 return super(TestGetcallargsUnboundMethods, self).assertEqualCallArgs(
1256 *self._getAssertEqualParams(func, call_params_string, locs))
1257
1258 def assertEqualException(self, func, call_params_string, locs=None):
1259 return super(TestGetcallargsUnboundMethods, self).assertEqualException(
1260 *self._getAssertEqualParams(func, call_params_string, locs))
1261
1262 def _getAssertEqualParams(self, func, call_params_string, locs=None):
1263 assert 'inst' not in call_params_string
1264 locs = dict(locs or {}, inst=self.inst)
1265 return (func, 'inst,' + call_params_string, locs)
1266
Michael Foord95fc51d2010-11-20 15:07:30 +00001267
1268class TestGetattrStatic(unittest.TestCase):
1269
1270 def test_basic(self):
1271 class Thing(object):
1272 x = object()
1273
1274 thing = Thing()
1275 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1276 self.assertEqual(inspect.getattr_static(thing, 'x', None), Thing.x)
1277 with self.assertRaises(AttributeError):
1278 inspect.getattr_static(thing, 'y')
1279
1280 self.assertEqual(inspect.getattr_static(thing, 'y', 3), 3)
1281
1282 def test_inherited(self):
1283 class Thing(object):
1284 x = object()
1285 class OtherThing(Thing):
1286 pass
1287
1288 something = OtherThing()
1289 self.assertEqual(inspect.getattr_static(something, 'x'), Thing.x)
1290
1291 def test_instance_attr(self):
1292 class Thing(object):
1293 x = 2
1294 def __init__(self, x):
1295 self.x = x
1296 thing = Thing(3)
1297 self.assertEqual(inspect.getattr_static(thing, 'x'), 3)
1298 del thing.x
1299 self.assertEqual(inspect.getattr_static(thing, 'x'), 2)
1300
1301 def test_property(self):
1302 class Thing(object):
1303 @property
1304 def x(self):
1305 raise AttributeError("I'm pretending not to exist")
1306 thing = Thing()
1307 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1308
Ezio Melotti75cbd732011-04-28 00:59:29 +03001309 def test_descriptor_raises_AttributeError(self):
Michael Foord95fc51d2010-11-20 15:07:30 +00001310 class descriptor(object):
1311 def __get__(*_):
1312 raise AttributeError("I'm pretending not to exist")
1313 desc = descriptor()
1314 class Thing(object):
1315 x = desc
1316 thing = Thing()
1317 self.assertEqual(inspect.getattr_static(thing, 'x'), desc)
1318
1319 def test_classAttribute(self):
1320 class Thing(object):
1321 x = object()
1322
1323 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.x)
1324
Ethan Furmane03ea372013-09-25 07:14:41 -07001325 def test_classVirtualAttribute(self):
1326 class Thing(object):
1327 @types.DynamicClassAttribute
1328 def x(self):
1329 return self._x
1330 _x = object()
1331
1332 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.__dict__['x'])
1333
Michael Foord95fc51d2010-11-20 15:07:30 +00001334 def test_inherited_classattribute(self):
1335 class Thing(object):
1336 x = object()
1337 class OtherThing(Thing):
1338 pass
1339
1340 self.assertEqual(inspect.getattr_static(OtherThing, 'x'), Thing.x)
1341
1342 def test_slots(self):
1343 class Thing(object):
1344 y = 'bar'
1345 __slots__ = ['x']
1346 def __init__(self):
1347 self.x = 'foo'
1348 thing = Thing()
1349 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1350 self.assertEqual(inspect.getattr_static(thing, 'y'), 'bar')
1351
1352 del thing.x
1353 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1354
1355 def test_metaclass(self):
1356 class meta(type):
1357 attr = 'foo'
1358 class Thing(object, metaclass=meta):
1359 pass
1360 self.assertEqual(inspect.getattr_static(Thing, 'attr'), 'foo')
1361
1362 class sub(meta):
1363 pass
1364 class OtherThing(object, metaclass=sub):
1365 x = 3
1366 self.assertEqual(inspect.getattr_static(OtherThing, 'attr'), 'foo')
1367
1368 class OtherOtherThing(OtherThing):
1369 pass
1370 # this test is odd, but it was added as it exposed a bug
1371 self.assertEqual(inspect.getattr_static(OtherOtherThing, 'x'), 3)
1372
1373 def test_no_dict_no_slots(self):
1374 self.assertEqual(inspect.getattr_static(1, 'foo', None), None)
1375 self.assertNotEqual(inspect.getattr_static('foo', 'lower'), None)
1376
1377 def test_no_dict_no_slots_instance_member(self):
1378 # returns descriptor
1379 with open(__file__) as handle:
1380 self.assertEqual(inspect.getattr_static(handle, 'name'), type(handle).name)
1381
1382 def test_inherited_slots(self):
1383 # returns descriptor
1384 class Thing(object):
1385 __slots__ = ['x']
1386 def __init__(self):
1387 self.x = 'foo'
1388
1389 class OtherThing(Thing):
1390 pass
1391 # it would be nice if this worked...
1392 # we get the descriptor instead of the instance attribute
1393 self.assertEqual(inspect.getattr_static(OtherThing(), 'x'), Thing.x)
1394
1395 def test_descriptor(self):
1396 class descriptor(object):
1397 def __get__(self, instance, owner):
1398 return 3
1399 class Foo(object):
1400 d = descriptor()
1401
1402 foo = Foo()
1403
1404 # for a non data descriptor we return the instance attribute
1405 foo.__dict__['d'] = 1
1406 self.assertEqual(inspect.getattr_static(foo, 'd'), 1)
1407
1408 # if the descriptor is a data-desciptor we should return the
1409 # descriptor
1410 descriptor.__set__ = lambda s, i, v: None
1411 self.assertEqual(inspect.getattr_static(foo, 'd'), Foo.__dict__['d'])
1412
1413
1414 def test_metaclass_with_descriptor(self):
1415 class descriptor(object):
1416 def __get__(self, instance, owner):
1417 return 3
1418 class meta(type):
1419 d = descriptor()
1420 class Thing(object, metaclass=meta):
1421 pass
1422 self.assertEqual(inspect.getattr_static(Thing, 'd'), meta.__dict__['d'])
1423
1424
Michael Foordcc7ebb82010-11-20 16:20:16 +00001425 def test_class_as_property(self):
1426 class Base(object):
1427 foo = 3
1428
1429 class Something(Base):
Michael Foord35184ed2010-11-20 16:58:30 +00001430 executed = False
Michael Foordcc7ebb82010-11-20 16:20:16 +00001431 @property
1432 def __class__(self):
Michael Foord35184ed2010-11-20 16:58:30 +00001433 self.executed = True
Michael Foordcc7ebb82010-11-20 16:20:16 +00001434 return object
1435
Michael Foord35184ed2010-11-20 16:58:30 +00001436 instance = Something()
1437 self.assertEqual(inspect.getattr_static(instance, 'foo'), 3)
1438 self.assertFalse(instance.executed)
Michael Foordcc7ebb82010-11-20 16:20:16 +00001439 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1440
Michael Foorde5162652010-11-20 16:40:44 +00001441 def test_mro_as_property(self):
1442 class Meta(type):
1443 @property
1444 def __mro__(self):
1445 return (object,)
1446
1447 class Base(object):
1448 foo = 3
1449
1450 class Something(Base, metaclass=Meta):
1451 pass
1452
1453 self.assertEqual(inspect.getattr_static(Something(), 'foo'), 3)
1454 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1455
Michael Foorddcebe0f2011-03-15 19:20:44 -04001456 def test_dict_as_property(self):
1457 test = self
1458 test.called = False
1459
1460 class Foo(dict):
1461 a = 3
1462 @property
1463 def __dict__(self):
1464 test.called = True
1465 return {}
1466
1467 foo = Foo()
1468 foo.a = 4
1469 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1470 self.assertFalse(test.called)
1471
1472 def test_custom_object_dict(self):
1473 test = self
1474 test.called = False
1475
1476 class Custom(dict):
1477 def get(self, key, default=None):
1478 test.called = True
1479 super().get(key, default)
1480
1481 class Foo(object):
1482 a = 3
1483 foo = Foo()
1484 foo.__dict__ = Custom()
1485 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1486 self.assertFalse(test.called)
1487
1488 def test_metaclass_dict_as_property(self):
1489 class Meta(type):
1490 @property
1491 def __dict__(self):
1492 self.executed = True
1493
1494 class Thing(metaclass=Meta):
1495 executed = False
1496
1497 def __init__(self):
1498 self.spam = 42
1499
1500 instance = Thing()
1501 self.assertEqual(inspect.getattr_static(instance, "spam"), 42)
1502 self.assertFalse(Thing.executed)
Michael Foorde5162652010-11-20 16:40:44 +00001503
Michael Foorda51623b2011-12-18 22:01:40 +00001504 def test_module(self):
1505 sentinel = object()
1506 self.assertIsNot(inspect.getattr_static(sys, "version", sentinel),
1507 sentinel)
1508
Michael Foord3ba95f82011-12-22 01:13:37 +00001509 def test_metaclass_with_metaclass_with_dict_as_property(self):
1510 class MetaMeta(type):
1511 @property
1512 def __dict__(self):
1513 self.executed = True
1514 return dict(spam=42)
1515
1516 class Meta(type, metaclass=MetaMeta):
1517 executed = False
1518
1519 class Thing(metaclass=Meta):
1520 pass
1521
1522 with self.assertRaises(AttributeError):
1523 inspect.getattr_static(Thing, "spam")
1524 self.assertFalse(Thing.executed)
1525
Nick Coghlane0f04652010-11-21 03:44:04 +00001526class TestGetGeneratorState(unittest.TestCase):
1527
1528 def setUp(self):
1529 def number_generator():
1530 for number in range(5):
1531 yield number
1532 self.generator = number_generator()
1533
1534 def _generatorstate(self):
1535 return inspect.getgeneratorstate(self.generator)
1536
1537 def test_created(self):
1538 self.assertEqual(self._generatorstate(), inspect.GEN_CREATED)
1539
1540 def test_suspended(self):
1541 next(self.generator)
1542 self.assertEqual(self._generatorstate(), inspect.GEN_SUSPENDED)
1543
1544 def test_closed_after_exhaustion(self):
1545 for i in self.generator:
1546 pass
1547 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1548
1549 def test_closed_after_immediate_exception(self):
1550 with self.assertRaises(RuntimeError):
1551 self.generator.throw(RuntimeError)
1552 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1553
1554 def test_running(self):
1555 # As mentioned on issue #10220, checking for the RUNNING state only
1556 # makes sense inside the generator itself.
1557 # The following generator checks for this by using the closure's
1558 # reference to self and the generator state checking helper method
1559 def running_check_generator():
1560 for number in range(5):
1561 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1562 yield number
1563 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1564 self.generator = running_check_generator()
1565 # Running up to the first yield
1566 next(self.generator)
1567 # Running after the first yield
1568 next(self.generator)
1569
Nick Coghlan7921b9f2010-11-30 06:36:04 +00001570 def test_easy_debugging(self):
1571 # repr() and str() of a generator state should contain the state name
1572 names = 'GEN_CREATED GEN_RUNNING GEN_SUSPENDED GEN_CLOSED'.split()
1573 for name in names:
1574 state = getattr(inspect, name)
1575 self.assertIn(name, repr(state))
1576 self.assertIn(name, str(state))
1577
Nick Coghlan04e2e3f2012-06-23 19:52:05 +10001578 def test_getgeneratorlocals(self):
1579 def each(lst, a=None):
1580 b=(1, 2, 3)
1581 for v in lst:
1582 if v == 3:
1583 c = 12
1584 yield v
1585
1586 numbers = each([1, 2, 3])
1587 self.assertEqual(inspect.getgeneratorlocals(numbers),
1588 {'a': None, 'lst': [1, 2, 3]})
1589 next(numbers)
1590 self.assertEqual(inspect.getgeneratorlocals(numbers),
1591 {'a': None, 'lst': [1, 2, 3], 'v': 1,
1592 'b': (1, 2, 3)})
1593 next(numbers)
1594 self.assertEqual(inspect.getgeneratorlocals(numbers),
1595 {'a': None, 'lst': [1, 2, 3], 'v': 2,
1596 'b': (1, 2, 3)})
1597 next(numbers)
1598 self.assertEqual(inspect.getgeneratorlocals(numbers),
1599 {'a': None, 'lst': [1, 2, 3], 'v': 3,
1600 'b': (1, 2, 3), 'c': 12})
1601 try:
1602 next(numbers)
1603 except StopIteration:
1604 pass
1605 self.assertEqual(inspect.getgeneratorlocals(numbers), {})
1606
1607 def test_getgeneratorlocals_empty(self):
1608 def yield_one():
1609 yield 1
1610 one = yield_one()
1611 self.assertEqual(inspect.getgeneratorlocals(one), {})
1612 try:
1613 next(one)
1614 except StopIteration:
1615 pass
1616 self.assertEqual(inspect.getgeneratorlocals(one), {})
1617
1618 def test_getgeneratorlocals_error(self):
1619 self.assertRaises(TypeError, inspect.getgeneratorlocals, 1)
1620 self.assertRaises(TypeError, inspect.getgeneratorlocals, lambda x: True)
1621 self.assertRaises(TypeError, inspect.getgeneratorlocals, set)
1622 self.assertRaises(TypeError, inspect.getgeneratorlocals, (2,3))
1623
Nick Coghlane0f04652010-11-21 03:44:04 +00001624
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001625class MySignature(inspect.Signature):
1626 # Top-level to make it picklable;
1627 # used in test_signature_object_pickle
1628 pass
1629
1630class MyParameter(inspect.Parameter):
1631 # Top-level to make it picklable;
1632 # used in test_signature_object_pickle
1633 pass
1634
Nick Coghlanf9e227e2014-08-17 14:01:19 +10001635 @cpython_only
1636 @unittest.skipIf(MISSING_C_DOCSTRINGS,
1637 "Signature information for builtins requires docstrings")
1638 def test_builtins_have_signatures(self):
1639 # This checks all builtin callables in CPython have signatures
1640 # A few have signatures Signature can't yet handle, so we skip those
1641 # since they will have to wait until PEP 457 adds the required
1642 # introspection support to the inspect module
1643 # Some others also haven't been converted yet for various other
1644 # reasons, so we also skip those for the time being, but design
1645 # the test to fail in order to indicate when it needs to be
1646 # updated.
1647 no_signature = set()
1648 # These need PEP 457 groups
1649 needs_groups = ["range", "slice", "dir", "getattr",
1650 "next", "iter", "vars"]
1651 no_signature |= needs_groups
1652 # These need PEP 457 groups or a signature change to accept None
1653 needs_semantic_update = ["round"]
1654 no_signature |= needs_semantic_update
1655 # These need *args support in Argument Clinic
1656 needs_varargs = ["min", "max", "print", "__build_class__"]
1657 no_signature |= needs_varargs
1658 # These simply weren't covered in the initial AC conversion
1659 # for builtin callables
1660 not_converted_yet = ["open", "__import__"]
1661 no_signature |= not_converted_yet
1662 # These builtin types are expected to provide introspection info
1663 types_with_signatures = set()
1664 # Check the signatures we expect to be there
1665 ns = vars(builtins)
1666 for name, obj in sorted(ns.items()):
1667 if not callable(obj):
1668 continue
1669 # The builtin types haven't been converted to AC yet
1670 if isinstance(obj, type) and (name not in types_with_signatures):
1671 # Note that this also skips all the exception types
1672 no_signature.append(name)
1673 if (name in no_signature):
1674 # Not yet converted
1675 continue
1676 with self.subTest(builtin=name):
1677 self.assertIsNotNone(inspect.signature(obj))
1678 # Check callables that haven't been converted don't claim a signature
1679 # This ensures this test will start failing as more signatures are
1680 # added, so the affected items can be moved into the scope of the
1681 # regression test above
1682 for name in no_signature:
1683 with self.subTest(builtin=name):
1684 self.assertIsNone(ns[name].__text_signature__)
1685
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001686
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001687class TestSignatureObject(unittest.TestCase):
1688 @staticmethod
1689 def signature(func):
1690 sig = inspect.signature(func)
1691 return (tuple((param.name,
1692 (... if param.default is param.empty else param.default),
1693 (... if param.annotation is param.empty
1694 else param.annotation),
1695 str(param.kind).lower())
1696 for param in sig.parameters.values()),
1697 (... if sig.return_annotation is sig.empty
1698 else sig.return_annotation))
1699
1700 def test_signature_object(self):
1701 S = inspect.Signature
1702 P = inspect.Parameter
1703
1704 self.assertEqual(str(S()), '()')
1705
Yury Selivanov07a9e452014-01-29 10:58:16 -05001706 def test(po, pk, pod=42, pkd=100, *args, ko, **kwargs):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001707 pass
1708 sig = inspect.signature(test)
1709 po = sig.parameters['po'].replace(kind=P.POSITIONAL_ONLY)
Yury Selivanov07a9e452014-01-29 10:58:16 -05001710 pod = sig.parameters['pod'].replace(kind=P.POSITIONAL_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001711 pk = sig.parameters['pk']
Yury Selivanov07a9e452014-01-29 10:58:16 -05001712 pkd = sig.parameters['pkd']
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001713 args = sig.parameters['args']
1714 ko = sig.parameters['ko']
1715 kwargs = sig.parameters['kwargs']
1716
1717 S((po, pk, args, ko, kwargs))
1718
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001719 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001720 S((pk, po, args, ko, kwargs))
1721
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001722 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001723 S((po, args, pk, ko, kwargs))
1724
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001725 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001726 S((args, po, pk, ko, kwargs))
1727
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001728 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001729 S((po, pk, args, kwargs, ko))
1730
1731 kwargs2 = kwargs.replace(name='args')
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001732 with self.assertRaisesRegex(ValueError, 'duplicate parameter name'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001733 S((po, pk, args, kwargs2, ko))
1734
Yury Selivanov07a9e452014-01-29 10:58:16 -05001735 with self.assertRaisesRegex(ValueError, 'follows default argument'):
1736 S((pod, po))
1737
1738 with self.assertRaisesRegex(ValueError, 'follows default argument'):
1739 S((po, pkd, pk))
1740
1741 with self.assertRaisesRegex(ValueError, 'follows default argument'):
1742 S((pkd, pk))
1743
Yury Selivanov374375d2014-03-27 12:41:53 -04001744 self.assertTrue(repr(sig).startswith('<Signature'))
1745 self.assertTrue('"(po, pk' in repr(sig))
1746
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001747 def test_signature_object_pickle(self):
1748 def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
1749 foo_partial = functools.partial(foo, a=1)
1750
1751 sig = inspect.signature(foo_partial)
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001752
1753 for ver in range(pickle.HIGHEST_PROTOCOL + 1):
1754 with self.subTest(pickle_ver=ver, subclass=False):
1755 sig_pickled = pickle.loads(pickle.dumps(sig, ver))
1756 self.assertEqual(sig, sig_pickled)
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001757
1758 # Test that basic sub-classing works
1759 sig = inspect.signature(foo)
1760 myparam = MyParameter(name='z', kind=inspect.Parameter.POSITIONAL_ONLY)
1761 myparams = collections.OrderedDict(sig.parameters, a=myparam)
1762 mysig = MySignature().replace(parameters=myparams.values(),
1763 return_annotation=sig.return_annotation)
1764 self.assertTrue(isinstance(mysig, MySignature))
1765 self.assertTrue(isinstance(mysig.parameters['z'], MyParameter))
1766
1767 for ver in range(pickle.HIGHEST_PROTOCOL + 1):
1768 with self.subTest(pickle_ver=ver, subclass=True):
1769 sig_pickled = pickle.loads(pickle.dumps(mysig, ver))
1770 self.assertEqual(mysig, sig_pickled)
1771 self.assertTrue(isinstance(sig_pickled, MySignature))
1772 self.assertTrue(isinstance(sig_pickled.parameters['z'],
1773 MyParameter))
1774
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001775 def test_signature_immutability(self):
1776 def test(a):
1777 pass
1778 sig = inspect.signature(test)
1779
1780 with self.assertRaises(AttributeError):
1781 sig.foo = 'bar'
1782
1783 with self.assertRaises(TypeError):
1784 sig.parameters['a'] = None
1785
1786 def test_signature_on_noarg(self):
1787 def test():
1788 pass
1789 self.assertEqual(self.signature(test), ((), ...))
1790
1791 def test_signature_on_wargs(self):
1792 def test(a, b:'foo') -> 123:
1793 pass
1794 self.assertEqual(self.signature(test),
1795 ((('a', ..., ..., "positional_or_keyword"),
1796 ('b', ..., 'foo', "positional_or_keyword")),
1797 123))
1798
1799 def test_signature_on_wkwonly(self):
1800 def test(*, a:float, b:str) -> int:
1801 pass
1802 self.assertEqual(self.signature(test),
1803 ((('a', ..., float, "keyword_only"),
1804 ('b', ..., str, "keyword_only")),
1805 int))
1806
1807 def test_signature_on_complex_args(self):
1808 def test(a, b:'foo'=10, *args:'bar', spam:'baz', ham=123, **kwargs:int):
1809 pass
1810 self.assertEqual(self.signature(test),
1811 ((('a', ..., ..., "positional_or_keyword"),
1812 ('b', 10, 'foo', "positional_or_keyword"),
1813 ('args', ..., 'bar', "var_positional"),
1814 ('spam', ..., 'baz', "keyword_only"),
1815 ('ham', 123, ..., "keyword_only"),
1816 ('kwargs', ..., int, "var_keyword")),
1817 ...))
1818
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02001819 @cpython_only
Larry Hastingsfcafe432013-11-23 17:35:48 -08001820 @unittest.skipIf(MISSING_C_DOCSTRINGS,
1821 "Signature information for builtins requires docstrings")
1822 def test_signature_on_builtins(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02001823 import _testcapi
Larry Hastings16c51912014-01-07 11:53:01 -08001824
Larry Hastings5c661892014-01-24 06:17:25 -08001825 def test_unbound_method(o):
1826 """Use this to test unbound methods (things that should have a self)"""
1827 signature = inspect.signature(o)
1828 self.assertTrue(isinstance(signature, inspect.Signature))
1829 self.assertEqual(list(signature.parameters.values())[0].name, 'self')
1830 return signature
1831
1832 def test_callable(o):
1833 """Use this to test bound methods or normal callables (things that don't expect self)"""
1834 signature = inspect.signature(o)
1835 self.assertTrue(isinstance(signature, inspect.Signature))
1836 if signature.parameters:
1837 self.assertNotEqual(list(signature.parameters.values())[0].name, 'self')
1838 return signature
1839
1840 signature = test_callable(_testcapi.docstring_with_signature_with_defaults)
Larry Hastings16c51912014-01-07 11:53:01 -08001841 def p(name): return signature.parameters[name].default
1842 self.assertEqual(p('s'), 'avocado')
Larry Hastings2a727912014-01-16 11:32:01 -08001843 self.assertEqual(p('b'), b'bytes')
Larry Hastings16c51912014-01-07 11:53:01 -08001844 self.assertEqual(p('d'), 3.14)
1845 self.assertEqual(p('i'), 35)
Larry Hastings16c51912014-01-07 11:53:01 -08001846 self.assertEqual(p('n'), None)
1847 self.assertEqual(p('t'), True)
1848 self.assertEqual(p('f'), False)
Larry Hastings2a727912014-01-16 11:32:01 -08001849 self.assertEqual(p('local'), 3)
1850 self.assertEqual(p('sys'), sys.maxsize)
1851 self.assertEqual(p('exp'), sys.maxsize - 1)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001852
Larry Hastings5c661892014-01-24 06:17:25 -08001853 test_callable(object)
1854
1855 # normal method
1856 # (PyMethodDescr_Type, "method_descriptor")
1857 test_unbound_method(_pickle.Pickler.dump)
1858 d = _pickle.Pickler(io.StringIO())
1859 test_callable(d.dump)
1860
1861 # static method
1862 test_callable(str.maketrans)
1863 test_callable('abc'.maketrans)
1864
1865 # class method
1866 test_callable(dict.fromkeys)
1867 test_callable({}.fromkeys)
1868
1869 # wrapper around slot (PyWrapperDescr_Type, "wrapper_descriptor")
1870 test_unbound_method(type.__call__)
1871 test_unbound_method(int.__add__)
1872 test_callable((3).__add__)
1873
1874 # _PyMethodWrapper_Type
1875 # support for 'method-wrapper'
1876 test_callable(min.__call__)
1877
Larry Hastings2623c8c2014-02-08 22:15:29 -08001878 # This doesn't work now.
1879 # (We don't have a valid signature for "type" in 3.4)
1880 with self.assertRaisesRegex(ValueError, "no signature found"):
1881 class ThisWorksNow:
1882 __call__ = type
1883 test_callable(ThisWorksNow())
Larry Hastings5c661892014-01-24 06:17:25 -08001884
Yury Selivanov056e2652014-03-02 12:25:27 -05001885 # Regression test for issue #20786
1886 test_unbound_method(dict.__delitem__)
1887 test_unbound_method(property.__delete__)
1888
1889
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02001890 @cpython_only
Yury Selivanov76c6c592014-01-29 10:52:57 -05001891 @unittest.skipIf(MISSING_C_DOCSTRINGS,
1892 "Signature information for builtins requires docstrings")
1893 def test_signature_on_decorated_builtins(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02001894 import _testcapi
Yury Selivanov76c6c592014-01-29 10:52:57 -05001895 func = _testcapi.docstring_with_signature_with_defaults
1896
1897 def decorator(func):
1898 @functools.wraps(func)
1899 def wrapper(*args, **kwargs) -> int:
1900 return func(*args, **kwargs)
1901 return wrapper
1902
1903 decorated_func = decorator(func)
1904
1905 self.assertEqual(inspect.signature(func),
1906 inspect.signature(decorated_func))
Larry Hastings5c661892014-01-24 06:17:25 -08001907
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02001908 @cpython_only
Larry Hastings5c661892014-01-24 06:17:25 -08001909 def test_signature_on_builtins_no_signature(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02001910 import _testcapi
Larry Hastings5c661892014-01-24 06:17:25 -08001911 with self.assertRaisesRegex(ValueError, 'no signature found for builtin'):
1912 inspect.signature(_testcapi.docstring_no_signature)
1913
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001914 def test_signature_on_non_function(self):
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001915 with self.assertRaisesRegex(TypeError, 'is not a callable object'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001916 inspect.signature(42)
1917
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001918 with self.assertRaisesRegex(TypeError, 'is not a Python function'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001919 inspect.Signature.from_function(42)
1920
Yury Selivanovb77511d2014-01-29 10:46:14 -05001921 def test_signature_from_builtin_errors(self):
1922 with self.assertRaisesRegex(TypeError, 'is not a Python builtin'):
1923 inspect.Signature.from_builtin(42)
1924
Yury Selivanov63da7c72014-01-31 14:48:37 -05001925 def test_signature_from_functionlike_object(self):
1926 def func(a,b, *args, kwonly=True, kwonlyreq, **kwargs):
1927 pass
1928
1929 class funclike:
1930 # Has to be callable, and have correct
1931 # __code__, __annotations__, __defaults__, __name__,
1932 # and __kwdefaults__ attributes
1933
1934 def __init__(self, func):
1935 self.__name__ = func.__name__
1936 self.__code__ = func.__code__
1937 self.__annotations__ = func.__annotations__
1938 self.__defaults__ = func.__defaults__
1939 self.__kwdefaults__ = func.__kwdefaults__
1940 self.func = func
1941
1942 def __call__(self, *args, **kwargs):
1943 return self.func(*args, **kwargs)
1944
1945 sig_func = inspect.Signature.from_function(func)
1946
1947 sig_funclike = inspect.Signature.from_function(funclike(func))
1948 self.assertEqual(sig_funclike, sig_func)
1949
1950 sig_funclike = inspect.signature(funclike(func))
1951 self.assertEqual(sig_funclike, sig_func)
1952
1953 # If object is not a duck type of function, then
1954 # signature will try to get a signature for its '__call__'
1955 # method
1956 fl = funclike(func)
1957 del fl.__defaults__
1958 self.assertEqual(self.signature(fl),
1959 ((('args', ..., ..., "var_positional"),
1960 ('kwargs', ..., ..., "var_keyword")),
1961 ...))
1962
Yury Selivanova773de02014-02-21 18:30:53 -05001963 # Test with cython-like builtins:
1964 _orig_isdesc = inspect.ismethoddescriptor
1965 def _isdesc(obj):
1966 if hasattr(obj, '_builtinmock'):
1967 return True
1968 return _orig_isdesc(obj)
1969
1970 with unittest.mock.patch('inspect.ismethoddescriptor', _isdesc):
1971 builtin_func = funclike(func)
1972 # Make sure that our mock setup is working
1973 self.assertFalse(inspect.ismethoddescriptor(builtin_func))
1974 builtin_func._builtinmock = True
1975 self.assertTrue(inspect.ismethoddescriptor(builtin_func))
1976 self.assertEqual(inspect.signature(builtin_func), sig_func)
1977
Yury Selivanov63da7c72014-01-31 14:48:37 -05001978 def test_signature_functionlike_class(self):
1979 # We only want to duck type function-like objects,
1980 # not classes.
1981
1982 def func(a,b, *args, kwonly=True, kwonlyreq, **kwargs):
1983 pass
1984
1985 class funclike:
1986 def __init__(self, marker):
1987 pass
1988
1989 __name__ = func.__name__
1990 __code__ = func.__code__
1991 __annotations__ = func.__annotations__
1992 __defaults__ = func.__defaults__
1993 __kwdefaults__ = func.__kwdefaults__
1994
1995 with self.assertRaisesRegex(TypeError, 'is not a Python function'):
1996 inspect.Signature.from_function(funclike)
1997
1998 self.assertEqual(str(inspect.signature(funclike)), '(marker)')
1999
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002000 def test_signature_on_method(self):
2001 class Test:
Yury Selivanov62560fb2014-01-28 12:26:24 -05002002 def __init__(*args):
2003 pass
2004 def m1(self, arg1, arg2=1) -> int:
2005 pass
2006 def m2(*args):
2007 pass
2008 def __call__(*, a):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002009 pass
2010
Yury Selivanov62560fb2014-01-28 12:26:24 -05002011 self.assertEqual(self.signature(Test().m1),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002012 ((('arg1', ..., ..., "positional_or_keyword"),
2013 ('arg2', 1, ..., "positional_or_keyword")),
2014 int))
2015
Yury Selivanov62560fb2014-01-28 12:26:24 -05002016 self.assertEqual(self.signature(Test().m2),
2017 ((('args', ..., ..., "var_positional"),),
2018 ...))
2019
2020 self.assertEqual(self.signature(Test),
2021 ((('args', ..., ..., "var_positional"),),
2022 ...))
2023
2024 with self.assertRaisesRegex(ValueError, 'invalid method signature'):
2025 self.signature(Test())
2026
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002027 def test_signature_on_classmethod(self):
2028 class Test:
2029 @classmethod
2030 def foo(cls, arg1, *, arg2=1):
2031 pass
2032
2033 meth = Test().foo
2034 self.assertEqual(self.signature(meth),
2035 ((('arg1', ..., ..., "positional_or_keyword"),
2036 ('arg2', 1, ..., "keyword_only")),
2037 ...))
2038
2039 meth = Test.foo
2040 self.assertEqual(self.signature(meth),
2041 ((('arg1', ..., ..., "positional_or_keyword"),
2042 ('arg2', 1, ..., "keyword_only")),
2043 ...))
2044
2045 def test_signature_on_staticmethod(self):
2046 class Test:
2047 @staticmethod
2048 def foo(cls, *, arg):
2049 pass
2050
2051 meth = Test().foo
2052 self.assertEqual(self.signature(meth),
2053 ((('cls', ..., ..., "positional_or_keyword"),
2054 ('arg', ..., ..., "keyword_only")),
2055 ...))
2056
2057 meth = Test.foo
2058 self.assertEqual(self.signature(meth),
2059 ((('cls', ..., ..., "positional_or_keyword"),
2060 ('arg', ..., ..., "keyword_only")),
2061 ...))
2062
2063 def test_signature_on_partial(self):
2064 from functools import partial
2065
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002066 Parameter = inspect.Parameter
2067
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002068 def test():
2069 pass
2070
2071 self.assertEqual(self.signature(partial(test)), ((), ...))
2072
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002073 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002074 inspect.signature(partial(test, 1))
2075
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002076 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002077 inspect.signature(partial(test, a=1))
2078
2079 def test(a, b, *, c, d):
2080 pass
2081
2082 self.assertEqual(self.signature(partial(test)),
2083 ((('a', ..., ..., "positional_or_keyword"),
2084 ('b', ..., ..., "positional_or_keyword"),
2085 ('c', ..., ..., "keyword_only"),
2086 ('d', ..., ..., "keyword_only")),
2087 ...))
2088
2089 self.assertEqual(self.signature(partial(test, 1)),
2090 ((('b', ..., ..., "positional_or_keyword"),
2091 ('c', ..., ..., "keyword_only"),
2092 ('d', ..., ..., "keyword_only")),
2093 ...))
2094
2095 self.assertEqual(self.signature(partial(test, 1, c=2)),
2096 ((('b', ..., ..., "positional_or_keyword"),
2097 ('c', 2, ..., "keyword_only"),
2098 ('d', ..., ..., "keyword_only")),
2099 ...))
2100
2101 self.assertEqual(self.signature(partial(test, b=1, c=2)),
2102 ((('a', ..., ..., "positional_or_keyword"),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002103 ('b', 1, ..., "keyword_only"),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002104 ('c', 2, ..., "keyword_only"),
2105 ('d', ..., ..., "keyword_only")),
2106 ...))
2107
2108 self.assertEqual(self.signature(partial(test, 0, b=1, c=2)),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002109 ((('b', 1, ..., "keyword_only"),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002110 ('c', 2, ..., "keyword_only"),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002111 ('d', ..., ..., "keyword_only")),
2112 ...))
2113
2114 self.assertEqual(self.signature(partial(test, a=1)),
2115 ((('a', 1, ..., "keyword_only"),
2116 ('b', ..., ..., "keyword_only"),
2117 ('c', ..., ..., "keyword_only"),
2118 ('d', ..., ..., "keyword_only")),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002119 ...))
2120
2121 def test(a, *args, b, **kwargs):
2122 pass
2123
2124 self.assertEqual(self.signature(partial(test, 1)),
2125 ((('args', ..., ..., "var_positional"),
2126 ('b', ..., ..., "keyword_only"),
2127 ('kwargs', ..., ..., "var_keyword")),
2128 ...))
2129
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002130 self.assertEqual(self.signature(partial(test, a=1)),
2131 ((('a', 1, ..., "keyword_only"),
2132 ('b', ..., ..., "keyword_only"),
2133 ('kwargs', ..., ..., "var_keyword")),
2134 ...))
2135
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002136 self.assertEqual(self.signature(partial(test, 1, 2, 3)),
2137 ((('args', ..., ..., "var_positional"),
2138 ('b', ..., ..., "keyword_only"),
2139 ('kwargs', ..., ..., "var_keyword")),
2140 ...))
2141
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002142 self.assertEqual(self.signature(partial(test, 1, 2, 3, test=True)),
2143 ((('args', ..., ..., "var_positional"),
2144 ('b', ..., ..., "keyword_only"),
2145 ('kwargs', ..., ..., "var_keyword")),
2146 ...))
2147
2148 self.assertEqual(self.signature(partial(test, 1, 2, 3, test=1, b=0)),
2149 ((('args', ..., ..., "var_positional"),
2150 ('b', 0, ..., "keyword_only"),
2151 ('kwargs', ..., ..., "var_keyword")),
2152 ...))
2153
2154 self.assertEqual(self.signature(partial(test, b=0)),
2155 ((('a', ..., ..., "positional_or_keyword"),
2156 ('args', ..., ..., "var_positional"),
2157 ('b', 0, ..., "keyword_only"),
2158 ('kwargs', ..., ..., "var_keyword")),
2159 ...))
2160
2161 self.assertEqual(self.signature(partial(test, b=0, test=1)),
2162 ((('a', ..., ..., "positional_or_keyword"),
2163 ('args', ..., ..., "var_positional"),
2164 ('b', 0, ..., "keyword_only"),
2165 ('kwargs', ..., ..., "var_keyword")),
2166 ...))
2167
2168 def test(a, b, c:int) -> 42:
2169 pass
2170
2171 sig = test.__signature__ = inspect.signature(test)
2172
2173 self.assertEqual(self.signature(partial(partial(test, 1))),
2174 ((('b', ..., ..., "positional_or_keyword"),
2175 ('c', ..., int, "positional_or_keyword")),
2176 42))
2177
2178 self.assertEqual(self.signature(partial(partial(test, 1), 2)),
2179 ((('c', ..., int, "positional_or_keyword"),),
2180 42))
2181
2182 psig = inspect.signature(partial(partial(test, 1), 2))
2183
2184 def foo(a):
2185 return a
2186 _foo = partial(partial(foo, a=10), a=20)
2187 self.assertEqual(self.signature(_foo),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002188 ((('a', 20, ..., "keyword_only"),),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002189 ...))
2190 # check that we don't have any side-effects in signature(),
2191 # and the partial object is still functioning
2192 self.assertEqual(_foo(), 20)
2193
2194 def foo(a, b, c):
2195 return a, b, c
2196 _foo = partial(partial(foo, 1, b=20), b=30)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002197
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002198 self.assertEqual(self.signature(_foo),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002199 ((('b', 30, ..., "keyword_only"),
2200 ('c', ..., ..., "keyword_only")),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002201 ...))
2202 self.assertEqual(_foo(c=10), (1, 30, 10))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002203
2204 def foo(a, b, c, *, d):
2205 return a, b, c, d
2206 _foo = partial(partial(foo, d=20, c=20), b=10, d=30)
2207 self.assertEqual(self.signature(_foo),
2208 ((('a', ..., ..., "positional_or_keyword"),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002209 ('b', 10, ..., "keyword_only"),
2210 ('c', 20, ..., "keyword_only"),
2211 ('d', 30, ..., "keyword_only"),
2212 ),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002213 ...))
2214 ba = inspect.signature(_foo).bind(a=200, b=11)
2215 self.assertEqual(_foo(*ba.args, **ba.kwargs), (200, 11, 20, 30))
2216
2217 def foo(a=1, b=2, c=3):
2218 return a, b, c
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002219 _foo = partial(foo, c=13) # (a=1, b=2, *, c=13)
2220
2221 ba = inspect.signature(_foo).bind(a=11)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002222 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 2, 13))
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002223
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002224 ba = inspect.signature(_foo).bind(11, 12)
2225 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002226
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002227 ba = inspect.signature(_foo).bind(11, b=12)
2228 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002229
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002230 ba = inspect.signature(_foo).bind(b=12)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002231 self.assertEqual(_foo(*ba.args, **ba.kwargs), (1, 12, 13))
2232
2233 _foo = partial(_foo, b=10, c=20)
2234 ba = inspect.signature(_foo).bind(12)
2235 self.assertEqual(_foo(*ba.args, **ba.kwargs), (12, 10, 20))
2236
2237
2238 def foo(a, b, c, d, **kwargs):
2239 pass
2240 sig = inspect.signature(foo)
2241 params = sig.parameters.copy()
2242 params['a'] = params['a'].replace(kind=Parameter.POSITIONAL_ONLY)
2243 params['b'] = params['b'].replace(kind=Parameter.POSITIONAL_ONLY)
2244 foo.__signature__ = inspect.Signature(params.values())
2245 sig = inspect.signature(foo)
2246 self.assertEqual(str(sig), '(a, b, /, c, d, **kwargs)')
2247
2248 self.assertEqual(self.signature(partial(foo, 1)),
2249 ((('b', ..., ..., 'positional_only'),
2250 ('c', ..., ..., 'positional_or_keyword'),
2251 ('d', ..., ..., 'positional_or_keyword'),
2252 ('kwargs', ..., ..., 'var_keyword')),
2253 ...))
2254
2255 self.assertEqual(self.signature(partial(foo, 1, 2)),
2256 ((('c', ..., ..., 'positional_or_keyword'),
2257 ('d', ..., ..., 'positional_or_keyword'),
2258 ('kwargs', ..., ..., 'var_keyword')),
2259 ...))
2260
2261 self.assertEqual(self.signature(partial(foo, 1, 2, 3)),
2262 ((('d', ..., ..., 'positional_or_keyword'),
2263 ('kwargs', ..., ..., 'var_keyword')),
2264 ...))
2265
2266 self.assertEqual(self.signature(partial(foo, 1, 2, c=3)),
2267 ((('c', 3, ..., 'keyword_only'),
2268 ('d', ..., ..., 'keyword_only'),
2269 ('kwargs', ..., ..., 'var_keyword')),
2270 ...))
2271
2272 self.assertEqual(self.signature(partial(foo, 1, c=3)),
2273 ((('b', ..., ..., 'positional_only'),
2274 ('c', 3, ..., 'keyword_only'),
2275 ('d', ..., ..., 'keyword_only'),
2276 ('kwargs', ..., ..., 'var_keyword')),
2277 ...))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002278
Yury Selivanovda5fe4f2014-01-27 17:28:37 -05002279 def test_signature_on_partialmethod(self):
2280 from functools import partialmethod
2281
2282 class Spam:
2283 def test():
2284 pass
2285 ham = partialmethod(test)
2286
2287 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
2288 inspect.signature(Spam.ham)
2289
2290 class Spam:
2291 def test(it, a, *, c) -> 'spam':
2292 pass
2293 ham = partialmethod(test, c=1)
2294
2295 self.assertEqual(self.signature(Spam.ham),
2296 ((('it', ..., ..., 'positional_or_keyword'),
2297 ('a', ..., ..., 'positional_or_keyword'),
2298 ('c', 1, ..., 'keyword_only')),
2299 'spam'))
2300
2301 self.assertEqual(self.signature(Spam().ham),
2302 ((('a', ..., ..., 'positional_or_keyword'),
2303 ('c', 1, ..., 'keyword_only')),
2304 'spam'))
2305
Yury Selivanov0486f812014-01-29 12:18:59 -05002306 def test_signature_on_fake_partialmethod(self):
2307 def foo(a): pass
2308 foo._partialmethod = 'spam'
2309 self.assertEqual(str(inspect.signature(foo)), '(a)')
2310
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002311 def test_signature_on_decorated(self):
2312 import functools
2313
2314 def decorator(func):
2315 @functools.wraps(func)
2316 def wrapper(*args, **kwargs) -> int:
2317 return func(*args, **kwargs)
2318 return wrapper
2319
2320 class Foo:
2321 @decorator
2322 def bar(self, a, b):
2323 pass
2324
2325 self.assertEqual(self.signature(Foo.bar),
2326 ((('self', ..., ..., "positional_or_keyword"),
2327 ('a', ..., ..., "positional_or_keyword"),
2328 ('b', ..., ..., "positional_or_keyword")),
2329 ...))
2330
2331 self.assertEqual(self.signature(Foo().bar),
2332 ((('a', ..., ..., "positional_or_keyword"),
2333 ('b', ..., ..., "positional_or_keyword")),
2334 ...))
2335
2336 # Test that we handle method wrappers correctly
2337 def decorator(func):
2338 @functools.wraps(func)
2339 def wrapper(*args, **kwargs) -> int:
2340 return func(42, *args, **kwargs)
2341 sig = inspect.signature(func)
2342 new_params = tuple(sig.parameters.values())[1:]
2343 wrapper.__signature__ = sig.replace(parameters=new_params)
2344 return wrapper
2345
2346 class Foo:
2347 @decorator
2348 def __call__(self, a, b):
2349 pass
2350
2351 self.assertEqual(self.signature(Foo.__call__),
2352 ((('a', ..., ..., "positional_or_keyword"),
2353 ('b', ..., ..., "positional_or_keyword")),
2354 ...))
2355
2356 self.assertEqual(self.signature(Foo().__call__),
2357 ((('b', ..., ..., "positional_or_keyword"),),
2358 ...))
2359
Nick Coghlane8c45d62013-07-28 20:00:01 +10002360 # Test we handle __signature__ partway down the wrapper stack
2361 def wrapped_foo_call():
2362 pass
2363 wrapped_foo_call.__wrapped__ = Foo.__call__
2364
2365 self.assertEqual(self.signature(wrapped_foo_call),
2366 ((('a', ..., ..., "positional_or_keyword"),
2367 ('b', ..., ..., "positional_or_keyword")),
2368 ...))
2369
2370
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002371 def test_signature_on_class(self):
2372 class C:
2373 def __init__(self, a):
2374 pass
2375
2376 self.assertEqual(self.signature(C),
2377 ((('a', ..., ..., "positional_or_keyword"),),
2378 ...))
2379
2380 class CM(type):
2381 def __call__(cls, a):
2382 pass
2383 class C(metaclass=CM):
2384 def __init__(self, b):
2385 pass
2386
2387 self.assertEqual(self.signature(C),
2388 ((('a', ..., ..., "positional_or_keyword"),),
2389 ...))
2390
2391 class CM(type):
2392 def __new__(mcls, name, bases, dct, *, foo=1):
2393 return super().__new__(mcls, name, bases, dct)
2394 class C(metaclass=CM):
2395 def __init__(self, b):
2396 pass
2397
2398 self.assertEqual(self.signature(C),
2399 ((('b', ..., ..., "positional_or_keyword"),),
2400 ...))
2401
2402 self.assertEqual(self.signature(CM),
2403 ((('name', ..., ..., "positional_or_keyword"),
2404 ('bases', ..., ..., "positional_or_keyword"),
2405 ('dct', ..., ..., "positional_or_keyword"),
2406 ('foo', 1, ..., "keyword_only")),
2407 ...))
2408
2409 class CMM(type):
2410 def __new__(mcls, name, bases, dct, *, foo=1):
2411 return super().__new__(mcls, name, bases, dct)
2412 def __call__(cls, nm, bs, dt):
2413 return type(nm, bs, dt)
2414 class CM(type, metaclass=CMM):
2415 def __new__(mcls, name, bases, dct, *, bar=2):
2416 return super().__new__(mcls, name, bases, dct)
2417 class C(metaclass=CM):
2418 def __init__(self, b):
2419 pass
2420
2421 self.assertEqual(self.signature(CMM),
2422 ((('name', ..., ..., "positional_or_keyword"),
2423 ('bases', ..., ..., "positional_or_keyword"),
2424 ('dct', ..., ..., "positional_or_keyword"),
2425 ('foo', 1, ..., "keyword_only")),
2426 ...))
2427
2428 self.assertEqual(self.signature(CM),
2429 ((('nm', ..., ..., "positional_or_keyword"),
2430 ('bs', ..., ..., "positional_or_keyword"),
2431 ('dt', ..., ..., "positional_or_keyword")),
2432 ...))
2433
2434 self.assertEqual(self.signature(C),
2435 ((('b', ..., ..., "positional_or_keyword"),),
2436 ...))
2437
2438 class CM(type):
2439 def __init__(cls, name, bases, dct, *, bar=2):
2440 return super().__init__(name, bases, dct)
2441 class C(metaclass=CM):
2442 def __init__(self, b):
2443 pass
2444
2445 self.assertEqual(self.signature(CM),
2446 ((('name', ..., ..., "positional_or_keyword"),
2447 ('bases', ..., ..., "positional_or_keyword"),
2448 ('dct', ..., ..., "positional_or_keyword"),
2449 ('bar', 2, ..., "keyword_only")),
2450 ...))
2451
Yury Selivanov145dff82014-02-01 13:49:29 -05002452 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2453 "Signature information for builtins requires docstrings")
2454 def test_signature_on_class_without_init(self):
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002455 # Test classes without user-defined __init__ or __new__
2456 class C: pass
2457 self.assertEqual(str(inspect.signature(C)), '()')
2458 class D(C): pass
2459 self.assertEqual(str(inspect.signature(D)), '()')
2460
2461 # Test meta-classes without user-defined __init__ or __new__
2462 class C(type): pass
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002463 class D(C): pass
Larry Hastings2623c8c2014-02-08 22:15:29 -08002464 with self.assertRaisesRegex(ValueError, "callable.*is not supported"):
2465 self.assertEqual(inspect.signature(C), None)
2466 with self.assertRaisesRegex(ValueError, "callable.*is not supported"):
2467 self.assertEqual(inspect.signature(D), None)
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002468
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002469 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2470 "Signature information for builtins requires docstrings")
2471 def test_signature_on_builtin_class(self):
2472 self.assertEqual(str(inspect.signature(_pickle.Pickler)),
2473 '(file, protocol=None, fix_imports=True)')
2474
2475 class P(_pickle.Pickler): pass
2476 class EmptyTrait: pass
2477 class P2(EmptyTrait, P): pass
2478 self.assertEqual(str(inspect.signature(P)),
2479 '(file, protocol=None, fix_imports=True)')
2480 self.assertEqual(str(inspect.signature(P2)),
2481 '(file, protocol=None, fix_imports=True)')
2482
2483 class P3(P2):
2484 def __init__(self, spam):
2485 pass
2486 self.assertEqual(str(inspect.signature(P3)), '(spam)')
2487
2488 class MetaP(type):
2489 def __call__(cls, foo, bar):
2490 pass
2491 class P4(P2, metaclass=MetaP):
2492 pass
2493 self.assertEqual(str(inspect.signature(P4)), '(foo, bar)')
2494
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002495 def test_signature_on_callable_objects(self):
2496 class Foo:
2497 def __call__(self, a):
2498 pass
2499
2500 self.assertEqual(self.signature(Foo()),
2501 ((('a', ..., ..., "positional_or_keyword"),),
2502 ...))
2503
2504 class Spam:
2505 pass
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002506 with self.assertRaisesRegex(TypeError, "is not a callable object"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002507 inspect.signature(Spam())
2508
2509 class Bar(Spam, Foo):
2510 pass
2511
2512 self.assertEqual(self.signature(Bar()),
2513 ((('a', ..., ..., "positional_or_keyword"),),
2514 ...))
2515
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002516 class Wrapped:
2517 pass
2518 Wrapped.__wrapped__ = lambda a: None
2519 self.assertEqual(self.signature(Wrapped),
2520 ((('a', ..., ..., "positional_or_keyword"),),
2521 ...))
Nick Coghlane8c45d62013-07-28 20:00:01 +10002522 # wrapper loop:
2523 Wrapped.__wrapped__ = Wrapped
2524 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
2525 self.signature(Wrapped)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002526
2527 def test_signature_on_lambdas(self):
2528 self.assertEqual(self.signature((lambda a=10: a)),
2529 ((('a', 10, ..., "positional_or_keyword"),),
2530 ...))
2531
2532 def test_signature_equality(self):
2533 def foo(a, *, b:int) -> float: pass
2534 self.assertNotEqual(inspect.signature(foo), 42)
2535
2536 def bar(a, *, b:int) -> float: pass
2537 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002538 self.assertEqual(
2539 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002540
2541 def bar(a, *, b:int) -> int: pass
2542 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002543 self.assertNotEqual(
2544 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002545
2546 def bar(a, *, b:int): pass
2547 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002548 self.assertNotEqual(
2549 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002550
2551 def bar(a, *, b:int=42) -> float: pass
2552 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002553 self.assertNotEqual(
2554 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002555
2556 def bar(a, *, c) -> float: pass
2557 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002558 self.assertNotEqual(
2559 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002560
2561 def bar(a, b:int) -> float: pass
2562 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002563 self.assertNotEqual(
2564 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002565 def spam(b:int, a) -> float: pass
2566 self.assertNotEqual(inspect.signature(spam), inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002567 self.assertNotEqual(
2568 hash(inspect.signature(spam)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002569
2570 def foo(*, a, b, c): pass
2571 def bar(*, c, b, a): pass
2572 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002573 self.assertEqual(
2574 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002575
2576 def foo(*, a=1, b, c): pass
2577 def bar(*, c, b, a=1): pass
2578 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002579 self.assertEqual(
2580 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002581
2582 def foo(pos, *, a=1, b, c): pass
2583 def bar(pos, *, c, b, a=1): pass
2584 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002585 self.assertEqual(
2586 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002587
2588 def foo(pos, *, a, b, c): pass
2589 def bar(pos, *, c, b, a=1): pass
2590 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002591 self.assertNotEqual(
2592 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002593
2594 def foo(pos, *args, a=42, b, c, **kwargs:int): pass
2595 def bar(pos, *args, c, b, a=42, **kwargs:int): pass
2596 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002597 self.assertEqual(
2598 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002599
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002600 def test_signature_hashable(self):
2601 S = inspect.Signature
2602 P = inspect.Parameter
2603
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002604 def foo(a): pass
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002605 foo_sig = inspect.signature(foo)
2606
2607 manual_sig = S(parameters=[P('a', P.POSITIONAL_OR_KEYWORD)])
2608
2609 self.assertEqual(hash(foo_sig), hash(manual_sig))
2610 self.assertNotEqual(hash(foo_sig),
2611 hash(manual_sig.replace(return_annotation='spam')))
2612
2613 def bar(a) -> 1: pass
2614 self.assertNotEqual(hash(foo_sig), hash(inspect.signature(bar)))
2615
2616 def foo(a={}): pass
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002617 with self.assertRaisesRegex(TypeError, 'unhashable type'):
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002618 hash(inspect.signature(foo))
2619
2620 def foo(a) -> {}: pass
2621 with self.assertRaisesRegex(TypeError, 'unhashable type'):
2622 hash(inspect.signature(foo))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002623
2624 def test_signature_str(self):
2625 def foo(a:int=1, *, b, c=None, **kwargs) -> 42:
2626 pass
2627 self.assertEqual(str(inspect.signature(foo)),
2628 '(a:int=1, *, b, c=None, **kwargs) -> 42')
2629
2630 def foo(a:int=1, *args, b, c=None, **kwargs) -> 42:
2631 pass
2632 self.assertEqual(str(inspect.signature(foo)),
2633 '(a:int=1, *args, b, c=None, **kwargs) -> 42')
2634
2635 def foo():
2636 pass
2637 self.assertEqual(str(inspect.signature(foo)), '()')
2638
2639 def test_signature_str_positional_only(self):
2640 P = inspect.Parameter
Yury Selivanov2393dca2014-01-27 15:07:58 -05002641 S = inspect.Signature
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002642
2643 def test(a_po, *, b, **kwargs):
2644 return a_po, kwargs
2645
2646 sig = inspect.signature(test)
2647 new_params = list(sig.parameters.values())
2648 new_params[0] = new_params[0].replace(kind=P.POSITIONAL_ONLY)
2649 test.__signature__ = sig.replace(parameters=new_params)
2650
2651 self.assertEqual(str(inspect.signature(test)),
Yury Selivanov2393dca2014-01-27 15:07:58 -05002652 '(a_po, /, *, b, **kwargs)')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002653
Yury Selivanov2393dca2014-01-27 15:07:58 -05002654 self.assertEqual(str(S(parameters=[P('foo', P.POSITIONAL_ONLY)])),
2655 '(foo, /)')
2656
2657 self.assertEqual(str(S(parameters=[
2658 P('foo', P.POSITIONAL_ONLY),
2659 P('bar', P.VAR_KEYWORD)])),
2660 '(foo, /, **bar)')
2661
2662 self.assertEqual(str(S(parameters=[
2663 P('foo', P.POSITIONAL_ONLY),
2664 P('bar', P.VAR_POSITIONAL)])),
2665 '(foo, /, *bar)')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002666
2667 def test_signature_replace_anno(self):
2668 def test() -> 42:
2669 pass
2670
2671 sig = inspect.signature(test)
2672 sig = sig.replace(return_annotation=None)
2673 self.assertIs(sig.return_annotation, None)
2674 sig = sig.replace(return_annotation=sig.empty)
2675 self.assertIs(sig.return_annotation, sig.empty)
2676 sig = sig.replace(return_annotation=42)
2677 self.assertEqual(sig.return_annotation, 42)
2678 self.assertEqual(sig, inspect.signature(test))
2679
Yury Selivanov34ce99f2014-02-18 12:49:41 -05002680 def test_signature_on_mangled_parameters(self):
2681 class Spam:
2682 def foo(self, __p1:1=2, *, __p2:2=3):
2683 pass
2684 class Ham(Spam):
2685 pass
2686
2687 self.assertEqual(self.signature(Spam.foo),
2688 ((('self', ..., ..., "positional_or_keyword"),
2689 ('_Spam__p1', 2, 1, "positional_or_keyword"),
2690 ('_Spam__p2', 3, 2, "keyword_only")),
2691 ...))
2692
2693 self.assertEqual(self.signature(Spam.foo),
2694 self.signature(Ham.foo))
2695
Yury Selivanovda396452014-03-27 12:09:24 -04002696 def test_signature_from_callable_python_obj(self):
2697 class MySignature(inspect.Signature): pass
2698 def foo(a, *, b:1): pass
2699 foo_sig = MySignature.from_callable(foo)
2700 self.assertTrue(isinstance(foo_sig, MySignature))
2701
2702 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2703 "Signature information for builtins requires docstrings")
2704 def test_signature_from_callable_builtin_obj(self):
2705 class MySignature(inspect.Signature): pass
2706 sig = MySignature.from_callable(_pickle.Pickler)
2707 self.assertTrue(isinstance(sig, MySignature))
2708
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002709
2710class TestParameterObject(unittest.TestCase):
2711 def test_signature_parameter_kinds(self):
2712 P = inspect.Parameter
2713 self.assertTrue(P.POSITIONAL_ONLY < P.POSITIONAL_OR_KEYWORD < \
2714 P.VAR_POSITIONAL < P.KEYWORD_ONLY < P.VAR_KEYWORD)
2715
2716 self.assertEqual(str(P.POSITIONAL_ONLY), 'POSITIONAL_ONLY')
2717 self.assertTrue('POSITIONAL_ONLY' in repr(P.POSITIONAL_ONLY))
2718
2719 def test_signature_parameter_object(self):
2720 p = inspect.Parameter('foo', default=10,
2721 kind=inspect.Parameter.POSITIONAL_ONLY)
2722 self.assertEqual(p.name, 'foo')
2723 self.assertEqual(p.default, 10)
2724 self.assertIs(p.annotation, p.empty)
2725 self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY)
2726
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002727 with self.assertRaisesRegex(ValueError, 'invalid value'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002728 inspect.Parameter('foo', default=10, kind='123')
2729
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002730 with self.assertRaisesRegex(ValueError, 'not a valid parameter name'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002731 inspect.Parameter('1', kind=inspect.Parameter.VAR_KEYWORD)
2732
Yury Selivanov2393dca2014-01-27 15:07:58 -05002733 with self.assertRaisesRegex(TypeError, 'name must be a str'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002734 inspect.Parameter(None, kind=inspect.Parameter.VAR_KEYWORD)
2735
Yury Selivanov2393dca2014-01-27 15:07:58 -05002736 with self.assertRaisesRegex(ValueError,
2737 'is not a valid parameter name'):
2738 inspect.Parameter('$', kind=inspect.Parameter.VAR_KEYWORD)
2739
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002740 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002741 inspect.Parameter('a', default=42,
2742 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_POSITIONAL)
2747
2748 p = inspect.Parameter('a', default=42,
2749 kind=inspect.Parameter.POSITIONAL_OR_KEYWORD)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002750 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002751 p.replace(kind=inspect.Parameter.VAR_POSITIONAL)
2752
2753 self.assertTrue(repr(p).startswith('<Parameter'))
Yury Selivanov374375d2014-03-27 12:41:53 -04002754 self.assertTrue('"a=42"' in repr(p))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002755
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002756 def test_signature_parameter_hashable(self):
2757 P = inspect.Parameter
2758 foo = P('foo', kind=P.POSITIONAL_ONLY)
2759 self.assertEqual(hash(foo), hash(P('foo', kind=P.POSITIONAL_ONLY)))
2760 self.assertNotEqual(hash(foo), hash(P('foo', kind=P.POSITIONAL_ONLY,
2761 default=42)))
2762 self.assertNotEqual(hash(foo),
2763 hash(foo.replace(kind=P.VAR_POSITIONAL)))
2764
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002765 def test_signature_parameter_equality(self):
2766 P = inspect.Parameter
2767 p = P('foo', default=42, kind=inspect.Parameter.KEYWORD_ONLY)
2768
2769 self.assertEqual(p, p)
2770 self.assertNotEqual(p, 42)
2771
2772 self.assertEqual(p, P('foo', default=42,
2773 kind=inspect.Parameter.KEYWORD_ONLY))
2774
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002775 def test_signature_parameter_replace(self):
2776 p = inspect.Parameter('foo', default=42,
2777 kind=inspect.Parameter.KEYWORD_ONLY)
2778
2779 self.assertIsNot(p, p.replace())
2780 self.assertEqual(p, p.replace())
2781
2782 p2 = p.replace(annotation=1)
2783 self.assertEqual(p2.annotation, 1)
2784 p2 = p2.replace(annotation=p2.empty)
2785 self.assertEqual(p, p2)
2786
2787 p2 = p2.replace(name='bar')
2788 self.assertEqual(p2.name, 'bar')
2789 self.assertNotEqual(p2, p)
2790
Yury Selivanov2393dca2014-01-27 15:07:58 -05002791 with self.assertRaisesRegex(ValueError,
2792 'name is a required attribute'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002793 p2 = p2.replace(name=p2.empty)
2794
2795 p2 = p2.replace(name='foo', default=None)
2796 self.assertIs(p2.default, None)
2797 self.assertNotEqual(p2, p)
2798
2799 p2 = p2.replace(name='foo', default=p2.empty)
2800 self.assertIs(p2.default, p2.empty)
2801
2802
2803 p2 = p2.replace(default=42, kind=p2.POSITIONAL_OR_KEYWORD)
2804 self.assertEqual(p2.kind, p2.POSITIONAL_OR_KEYWORD)
2805 self.assertNotEqual(p2, p)
2806
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002807 with self.assertRaisesRegex(ValueError, 'invalid value for'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002808 p2 = p2.replace(kind=p2.empty)
2809
2810 p2 = p2.replace(kind=p2.KEYWORD_ONLY)
2811 self.assertEqual(p2, p)
2812
2813 def test_signature_parameter_positional_only(self):
Yury Selivanov2393dca2014-01-27 15:07:58 -05002814 with self.assertRaisesRegex(TypeError, 'name must be a str'):
2815 inspect.Parameter(None, kind=inspect.Parameter.POSITIONAL_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002816
2817 def test_signature_parameter_immutability(self):
Yury Selivanov2393dca2014-01-27 15:07:58 -05002818 p = inspect.Parameter('spam', kind=inspect.Parameter.KEYWORD_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002819
2820 with self.assertRaises(AttributeError):
2821 p.foo = 'bar'
2822
2823 with self.assertRaises(AttributeError):
2824 p.kind = 123
2825
2826
2827class TestSignatureBind(unittest.TestCase):
2828 @staticmethod
2829 def call(func, *args, **kwargs):
2830 sig = inspect.signature(func)
2831 ba = sig.bind(*args, **kwargs)
2832 return func(*ba.args, **ba.kwargs)
2833
2834 def test_signature_bind_empty(self):
2835 def test():
2836 return 42
2837
2838 self.assertEqual(self.call(test), 42)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002839 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002840 self.call(test, 1)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002841 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002842 self.call(test, 1, spam=10)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002843 with self.assertRaisesRegex(TypeError, 'too many keyword arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002844 self.call(test, spam=1)
2845
2846 def test_signature_bind_var(self):
2847 def test(*args, **kwargs):
2848 return args, kwargs
2849
2850 self.assertEqual(self.call(test), ((), {}))
2851 self.assertEqual(self.call(test, 1), ((1,), {}))
2852 self.assertEqual(self.call(test, 1, 2), ((1, 2), {}))
2853 self.assertEqual(self.call(test, foo='bar'), ((), {'foo': 'bar'}))
2854 self.assertEqual(self.call(test, 1, foo='bar'), ((1,), {'foo': 'bar'}))
2855 self.assertEqual(self.call(test, args=10), ((), {'args': 10}))
2856 self.assertEqual(self.call(test, 1, 2, foo='bar'),
2857 ((1, 2), {'foo': 'bar'}))
2858
2859 def test_signature_bind_just_args(self):
2860 def test(a, b, c):
2861 return a, b, c
2862
2863 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
2864
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002865 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002866 self.call(test, 1, 2, 3, 4)
2867
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002868 with self.assertRaisesRegex(TypeError, "'b' parameter lacking default"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002869 self.call(test, 1)
2870
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002871 with self.assertRaisesRegex(TypeError, "'a' parameter lacking default"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002872 self.call(test)
2873
2874 def test(a, b, c=10):
2875 return a, b, c
2876 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
2877 self.assertEqual(self.call(test, 1, 2), (1, 2, 10))
2878
2879 def test(a=1, b=2, c=3):
2880 return a, b, c
2881 self.assertEqual(self.call(test, a=10, c=13), (10, 2, 13))
2882 self.assertEqual(self.call(test, a=10), (10, 2, 3))
2883 self.assertEqual(self.call(test, b=10), (1, 10, 3))
2884
2885 def test_signature_bind_varargs_order(self):
2886 def test(*args):
2887 return args
2888
2889 self.assertEqual(self.call(test), ())
2890 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
2891
2892 def test_signature_bind_args_and_varargs(self):
2893 def test(a, b, c=3, *args):
2894 return a, b, c, args
2895
2896 self.assertEqual(self.call(test, 1, 2, 3, 4, 5), (1, 2, 3, (4, 5)))
2897 self.assertEqual(self.call(test, 1, 2), (1, 2, 3, ()))
2898 self.assertEqual(self.call(test, b=1, a=2), (2, 1, 3, ()))
2899 self.assertEqual(self.call(test, 1, b=2), (1, 2, 3, ()))
2900
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002901 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002902 "multiple values for argument 'c'"):
2903 self.call(test, 1, 2, 3, c=4)
2904
2905 def test_signature_bind_just_kwargs(self):
2906 def test(**kwargs):
2907 return kwargs
2908
2909 self.assertEqual(self.call(test), {})
2910 self.assertEqual(self.call(test, foo='bar', spam='ham'),
2911 {'foo': 'bar', 'spam': 'ham'})
2912
2913 def test_signature_bind_args_and_kwargs(self):
2914 def test(a, b, c=3, **kwargs):
2915 return a, b, c, kwargs
2916
2917 self.assertEqual(self.call(test, 1, 2), (1, 2, 3, {}))
2918 self.assertEqual(self.call(test, 1, 2, foo='bar', spam='ham'),
2919 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
2920 self.assertEqual(self.call(test, b=2, a=1, foo='bar', spam='ham'),
2921 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
2922 self.assertEqual(self.call(test, a=1, b=2, foo='bar', spam='ham'),
2923 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
2924 self.assertEqual(self.call(test, 1, b=2, foo='bar', spam='ham'),
2925 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
2926 self.assertEqual(self.call(test, 1, b=2, c=4, foo='bar', spam='ham'),
2927 (1, 2, 4, {'foo': 'bar', 'spam': 'ham'}))
2928 self.assertEqual(self.call(test, 1, 2, 4, foo='bar'),
2929 (1, 2, 4, {'foo': 'bar'}))
2930 self.assertEqual(self.call(test, c=5, a=4, b=3),
2931 (4, 3, 5, {}))
2932
2933 def test_signature_bind_kwonly(self):
2934 def test(*, foo):
2935 return foo
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002936 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002937 'too many positional arguments'):
2938 self.call(test, 1)
2939 self.assertEqual(self.call(test, foo=1), 1)
2940
2941 def test(a, *, foo=1, bar):
2942 return foo
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002943 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002944 "'bar' parameter lacking default value"):
2945 self.call(test, 1)
2946
2947 def test(foo, *, bar):
2948 return foo, bar
2949 self.assertEqual(self.call(test, 1, bar=2), (1, 2))
2950 self.assertEqual(self.call(test, bar=2, foo=1), (1, 2))
2951
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002952 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002953 'too many keyword arguments'):
2954 self.call(test, bar=2, foo=1, spam=10)
2955
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002956 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002957 'too many positional arguments'):
2958 self.call(test, 1, 2)
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, bar=2)
2963
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002964 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002965 'too many keyword arguments'):
2966 self.call(test, 1, bar=2, spam='ham')
2967
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002968 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002969 "'bar' parameter lacking default value"):
2970 self.call(test, 1)
2971
2972 def test(foo, *, bar, **bin):
2973 return foo, bar, bin
2974 self.assertEqual(self.call(test, 1, bar=2), (1, 2, {}))
2975 self.assertEqual(self.call(test, foo=1, bar=2), (1, 2, {}))
2976 self.assertEqual(self.call(test, 1, bar=2, spam='ham'),
2977 (1, 2, {'spam': 'ham'}))
2978 self.assertEqual(self.call(test, spam='ham', foo=1, bar=2),
2979 (1, 2, {'spam': 'ham'}))
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002980 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002981 "'foo' parameter lacking default value"):
2982 self.call(test, spam='ham', bar=2)
2983 self.assertEqual(self.call(test, 1, bar=2, bin=1, spam=10),
2984 (1, 2, {'bin': 1, 'spam': 10}))
2985
2986 def test_signature_bind_arguments(self):
2987 def test(a, *args, b, z=100, **kwargs):
2988 pass
2989 sig = inspect.signature(test)
2990 ba = sig.bind(10, 20, b=30, c=40, args=50, kwargs=60)
2991 # we won't have 'z' argument in the bound arguments object, as we didn't
2992 # pass it to the 'bind'
2993 self.assertEqual(tuple(ba.arguments.items()),
2994 (('a', 10), ('args', (20,)), ('b', 30),
2995 ('kwargs', {'c': 40, 'args': 50, 'kwargs': 60})))
2996 self.assertEqual(ba.kwargs,
2997 {'b': 30, 'c': 40, 'args': 50, 'kwargs': 60})
2998 self.assertEqual(ba.args, (10, 20))
2999
3000 def test_signature_bind_positional_only(self):
3001 P = inspect.Parameter
3002
3003 def test(a_po, b_po, c_po=3, foo=42, *, bar=50, **kwargs):
3004 return a_po, b_po, c_po, foo, bar, kwargs
3005
3006 sig = inspect.signature(test)
3007 new_params = collections.OrderedDict(tuple(sig.parameters.items()))
3008 for name in ('a_po', 'b_po', 'c_po'):
3009 new_params[name] = new_params[name].replace(kind=P.POSITIONAL_ONLY)
3010 new_sig = sig.replace(parameters=new_params.values())
3011 test.__signature__ = new_sig
3012
3013 self.assertEqual(self.call(test, 1, 2, 4, 5, bar=6),
3014 (1, 2, 4, 5, 6, {}))
3015
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05003016 self.assertEqual(self.call(test, 1, 2),
3017 (1, 2, 3, 42, 50, {}))
3018
3019 self.assertEqual(self.call(test, 1, 2, foo=4, bar=5),
3020 (1, 2, 3, 4, 5, {}))
3021
3022 with self.assertRaisesRegex(TypeError, "but was passed as a keyword"):
3023 self.call(test, 1, 2, foo=4, bar=5, c_po=10)
3024
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003025 with self.assertRaisesRegex(TypeError, "parameter is positional only"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003026 self.call(test, 1, 2, c_po=4)
3027
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003028 with self.assertRaisesRegex(TypeError, "parameter is positional only"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003029 self.call(test, a_po=1, b_po=2)
3030
Antoine Pitroubd41d1b2013-01-29 21:20:57 +01003031 def test_signature_bind_with_self_arg(self):
3032 # Issue #17071: one of the parameters is named "self
3033 def test(a, self, b):
3034 pass
3035 sig = inspect.signature(test)
3036 ba = sig.bind(1, 2, 3)
3037 self.assertEqual(ba.args, (1, 2, 3))
3038 ba = sig.bind(1, self=2, b=3)
3039 self.assertEqual(ba.args, (1, 2, 3))
3040
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05003041 def test_signature_bind_vararg_name(self):
3042 def test(a, *args):
3043 return a, args
3044 sig = inspect.signature(test)
3045
3046 with self.assertRaisesRegex(TypeError, "too many keyword arguments"):
3047 sig.bind(a=0, args=1)
3048
3049 def test(*args, **kwargs):
3050 return args, kwargs
3051 self.assertEqual(self.call(test, args=1), ((), {'args': 1}))
3052
3053 sig = inspect.signature(test)
3054 ba = sig.bind(args=1)
3055 self.assertEqual(ba.arguments, {'kwargs': {'args': 1}})
3056
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003057
3058class TestBoundArguments(unittest.TestCase):
3059 def test_signature_bound_arguments_unhashable(self):
3060 def foo(a): pass
3061 ba = inspect.signature(foo).bind(1)
3062
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003063 with self.assertRaisesRegex(TypeError, 'unhashable type'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003064 hash(ba)
3065
3066 def test_signature_bound_arguments_equality(self):
3067 def foo(a): pass
3068 ba = inspect.signature(foo).bind(1)
3069 self.assertEqual(ba, ba)
3070
3071 ba2 = inspect.signature(foo).bind(1)
3072 self.assertEqual(ba, ba2)
3073
3074 ba3 = inspect.signature(foo).bind(2)
3075 self.assertNotEqual(ba, ba3)
3076 ba3.arguments['a'] = 1
3077 self.assertEqual(ba, ba3)
3078
3079 def bar(b): pass
3080 ba4 = inspect.signature(bar).bind(1)
3081 self.assertNotEqual(ba, ba4)
3082
Yury Selivanova5d63dd2014-03-27 11:31:43 -04003083 def test_signature_bound_arguments_pickle(self):
3084 def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
3085 sig = inspect.signature(foo)
3086 ba = sig.bind(20, 30, z={})
3087
3088 for ver in range(pickle.HIGHEST_PROTOCOL + 1):
3089 with self.subTest(pickle_ver=ver):
3090 ba_pickled = pickle.loads(pickle.dumps(ba, ver))
3091 self.assertEqual(ba, ba_pickled)
3092
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003093
Yury Selivanovd82eddc2014-01-29 11:24:39 -05003094class TestSignaturePrivateHelpers(unittest.TestCase):
3095 def test_signature_get_bound_param(self):
3096 getter = inspect._signature_get_bound_param
3097
3098 self.assertEqual(getter('($self)'), 'self')
3099 self.assertEqual(getter('($self, obj)'), 'self')
3100 self.assertEqual(getter('($cls, /, obj)'), 'cls')
3101
Larry Hastings2623c8c2014-02-08 22:15:29 -08003102 def _strip_non_python_syntax(self, input,
3103 clean_signature, self_parameter, last_positional_only):
3104 computed_clean_signature, \
3105 computed_self_parameter, \
3106 computed_last_positional_only = \
3107 inspect._signature_strip_non_python_syntax(input)
3108 self.assertEqual(computed_clean_signature, clean_signature)
3109 self.assertEqual(computed_self_parameter, self_parameter)
3110 self.assertEqual(computed_last_positional_only, last_positional_only)
3111
3112 def test_signature_strip_non_python_syntax(self):
3113 self._strip_non_python_syntax(
3114 "($module, /, path, mode, *, dir_fd=None, " +
3115 "effective_ids=False,\n follow_symlinks=True)",
3116 "(module, path, mode, *, dir_fd=None, " +
3117 "effective_ids=False, follow_symlinks=True)",
3118 0,
3119 0)
3120
3121 self._strip_non_python_syntax(
3122 "($module, word, salt, /)",
3123 "(module, word, salt)",
3124 0,
3125 2)
3126
3127 self._strip_non_python_syntax(
3128 "(x, y=None, z=None, /)",
3129 "(x, y=None, z=None)",
3130 None,
3131 2)
3132
3133 self._strip_non_python_syntax(
3134 "(x, y=None, z=None)",
3135 "(x, y=None, z=None)",
3136 None,
3137 None)
3138
3139 self._strip_non_python_syntax(
3140 "(x,\n y=None,\n z = None )",
3141 "(x, y=None, z=None)",
3142 None,
3143 None)
3144
3145 self._strip_non_python_syntax(
3146 "",
3147 "",
3148 None,
3149 None)
3150
3151 self._strip_non_python_syntax(
3152 None,
3153 None,
3154 None,
3155 None)
3156
Yury Selivanovd82eddc2014-01-29 11:24:39 -05003157
Nick Coghlane8c45d62013-07-28 20:00:01 +10003158class TestUnwrap(unittest.TestCase):
3159
3160 def test_unwrap_one(self):
3161 def func(a, b):
3162 return a + b
3163 wrapper = functools.lru_cache(maxsize=20)(func)
3164 self.assertIs(inspect.unwrap(wrapper), func)
3165
3166 def test_unwrap_several(self):
3167 def func(a, b):
3168 return a + b
3169 wrapper = func
3170 for __ in range(10):
3171 @functools.wraps(wrapper)
3172 def wrapper():
3173 pass
3174 self.assertIsNot(wrapper.__wrapped__, func)
3175 self.assertIs(inspect.unwrap(wrapper), func)
3176
3177 def test_stop(self):
3178 def func1(a, b):
3179 return a + b
3180 @functools.wraps(func1)
3181 def func2():
3182 pass
3183 @functools.wraps(func2)
3184 def wrapper():
3185 pass
3186 func2.stop_here = 1
3187 unwrapped = inspect.unwrap(wrapper,
3188 stop=(lambda f: hasattr(f, "stop_here")))
3189 self.assertIs(unwrapped, func2)
3190
3191 def test_cycle(self):
3192 def func1(): pass
3193 func1.__wrapped__ = func1
3194 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3195 inspect.unwrap(func1)
3196
3197 def func2(): pass
3198 func2.__wrapped__ = func1
3199 func1.__wrapped__ = func2
3200 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3201 inspect.unwrap(func1)
3202 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3203 inspect.unwrap(func2)
3204
3205 def test_unhashable(self):
3206 def func(): pass
3207 func.__wrapped__ = None
3208 class C:
3209 __hash__ = None
3210 __wrapped__ = func
3211 self.assertIsNone(inspect.unwrap(C()))
3212
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003213class TestMain(unittest.TestCase):
3214 def test_only_source(self):
3215 module = importlib.import_module('unittest')
3216 rc, out, err = assert_python_ok('-m', 'inspect',
3217 'unittest')
3218 lines = out.decode().splitlines()
3219 # ignore the final newline
3220 self.assertEqual(lines[:-1], inspect.getsource(module).splitlines())
3221 self.assertEqual(err, b'')
3222
Yury Selivanov42407ab2014-06-23 10:23:50 -07003223 def test_custom_getattr(self):
3224 def foo():
3225 pass
3226 foo.__signature__ = 42
3227 with self.assertRaises(TypeError):
3228 inspect.signature(foo)
3229
Brett Cannon634a8fc2013-10-02 10:25:42 -04003230 @unittest.skipIf(ThreadPoolExecutor is None,
Brett Cannon0de3f012013-10-02 10:58:58 -04003231 'threads required to test __qualname__ for source files')
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003232 def test_qualname_source(self):
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003233 rc, out, err = assert_python_ok('-m', 'inspect',
3234 'concurrent.futures:ThreadPoolExecutor')
3235 lines = out.decode().splitlines()
3236 # ignore the final newline
3237 self.assertEqual(lines[:-1],
Brett Cannon634a8fc2013-10-02 10:25:42 -04003238 inspect.getsource(ThreadPoolExecutor).splitlines())
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003239 self.assertEqual(err, b'')
3240
3241 def test_builtins(self):
3242 module = importlib.import_module('unittest')
3243 _, out, err = assert_python_failure('-m', 'inspect',
3244 'sys')
3245 lines = err.decode().splitlines()
3246 self.assertEqual(lines, ["Can't get info for builtin modules."])
3247
3248 def test_details(self):
3249 module = importlib.import_module('unittest')
3250 rc, out, err = assert_python_ok('-m', 'inspect',
3251 'unittest', '--details')
3252 output = out.decode()
3253 # Just a quick sanity check on the output
3254 self.assertIn(module.__name__, output)
3255 self.assertIn(module.__file__, output)
Serhiy Storchakab12cb6a2013-12-08 18:16:18 +02003256 if not sys.flags.optimize:
3257 self.assertIn(module.__cached__, output)
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003258 self.assertEqual(err, b'')
3259
3260
3261
Nick Coghlane8c45d62013-07-28 20:00:01 +10003262
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00003263def test_main():
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00003264 run_unittest(
3265 TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBuggyCases,
3266 TestInterpreterStack, TestClassesAndFunctions, TestPredicates,
3267 TestGetcallargsFunctions, TestGetcallargsMethods,
Alexander Belopolskyf546e702010-12-02 00:10:11 +00003268 TestGetcallargsUnboundMethods, TestGetattrStatic, TestGetGeneratorState,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003269 TestNoEOL, TestSignatureObject, TestSignatureBind, TestParameterObject,
Yury Selivanovd82eddc2014-01-29 11:24:39 -05003270 TestBoundArguments, TestSignaturePrivateHelpers, TestGetClosureVars,
3271 TestUnwrap, TestMain
Michael Foord95fc51d2010-11-20 15:07:30 +00003272 )
Martin v. Löwis893ffa42003-10-31 15:35:53 +00003273
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00003274if __name__ == "__main__":
3275 test_main()