blob: 401e6cf4d4916c8604fe5f0da3529a44bde48395 [file] [log] [blame]
Nick Coghlanf9e227e2014-08-17 14:01:19 +10001import builtins
Guido van Rossum813b0e52007-05-21 18:11:34 +00002import collections
Larry Hastings5c661892014-01-24 06:17:25 -08003import datetime
Nick Coghlane8c45d62013-07-28 20:00:01 +10004import functools
Nick Coghlanf94a16b2013-09-22 22:46:49 +10005import importlib
Larry Hastings5c661892014-01-24 06:17:25 -08006import inspect
7import io
8import linecache
9import os
Christian Heimesa3538eb2007-11-06 11:44:48 +000010from os.path import normcase
Larry Hastings5c661892014-01-24 06:17:25 -080011import _pickle
Yury Selivanova5d63dd2014-03-27 11:31:43 -040012import pickle
Larry Hastings5c661892014-01-24 06:17:25 -080013import re
14import shutil
15import sys
16import types
Yury Selivanovef1e7502014-12-08 16:05:34 -050017import textwrap
Larry Hastings5c661892014-01-24 06:17:25 -080018import unicodedata
19import unittest
Yury Selivanova773de02014-02-21 18:30:53 -050020import unittest.mock
Larry Hastings5c661892014-01-24 06:17:25 -080021
Brett Cannon634a8fc2013-10-02 10:25:42 -040022try:
23 from concurrent.futures import ThreadPoolExecutor
24except ImportError:
25 ThreadPoolExecutor = None
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000026
Serhiy Storchakaf28ba362014-02-07 10:10:55 +020027from test.support import run_unittest, TESTFN, DirsOnSysPath, cpython_only
Nick Coghlanf9e227e2014-08-17 14:01:19 +100028from test.support import MISSING_C_DOCSTRINGS, cpython_only
Nick Coghlanf94a16b2013-09-22 22:46:49 +100029from test.script_helper import assert_python_ok, assert_python_failure
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000030from test import inspect_fodder as mod
31from test import inspect_fodder2 as mod2
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000032
Yury Selivanovef1e7502014-12-08 16:05:34 -050033from test.test_import import _ready_to_import
34
R. David Murray74b89242009-05-13 17:33:03 +000035
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000036# Functions tested in this suite:
37# ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode,
Christian Heimes7131fd92008-02-19 14:21:46 +000038# isbuiltin, isroutine, isgenerator, isgeneratorfunction, getmembers,
39# getdoc, getfile, getmodule, getsourcefile, getcomments, getsource,
40# getclasstree, getargspec, getargvalues, formatargspec, formatargvalues,
41# currentframe, stack, trace, isdatadescriptor
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000042
Nick Coghlanf088e5e2008-12-14 11:50:48 +000043# NOTE: There are some additional tests relating to interaction with
44# zipimport in the test_zipimport_support test module.
45
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000046modfile = mod.__file__
Thomas Wouters0e3f5912006-08-11 14:57:12 +000047if modfile.endswith(('c', 'o')):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000048 modfile = modfile[:-1]
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000049
Christian Heimesa3538eb2007-11-06 11:44:48 +000050# Normalize file names: on Windows, the case of file names of compiled
51# modules depends on the path used to start the python executable.
52modfile = normcase(modfile)
53
54def revise(filename, *args):
55 return (normcase(filename),) + args
56
Georg Brandl1a3284e2007-12-02 09:40:06 +000057import builtins
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000058
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000059git = mod.StupidGit()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000060
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000061class IsTestBase(unittest.TestCase):
62 predicates = set([inspect.isbuiltin, inspect.isclass, inspect.iscode,
63 inspect.isframe, inspect.isfunction, inspect.ismethod,
Christian Heimes7131fd92008-02-19 14:21:46 +000064 inspect.ismodule, inspect.istraceback,
65 inspect.isgenerator, inspect.isgeneratorfunction])
Tim Peters5a9fb3c2005-01-07 16:01:32 +000066
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000067 def istest(self, predicate, exp):
68 obj = eval(exp)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000069 self.assertTrue(predicate(obj), '%s(%s)' % (predicate.__name__, exp))
Tim Peters5a9fb3c2005-01-07 16:01:32 +000070
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000071 for other in self.predicates - set([predicate]):
Christian Heimes7131fd92008-02-19 14:21:46 +000072 if predicate == inspect.isgeneratorfunction and\
73 other == inspect.isfunction:
74 continue
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000075 self.assertFalse(other(obj), 'not %s(%s)' % (other.__name__, exp))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000076
Christian Heimes7131fd92008-02-19 14:21:46 +000077def generator_function_example(self):
78 for i in range(2):
79 yield i
80
Yury Selivanova5d63dd2014-03-27 11:31:43 -040081
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000082class TestPredicates(IsTestBase):
Christian Heimes227c8002008-03-03 20:34:40 +000083 def test_sixteen(self):
Guido van Rossumc1f779c2007-07-03 08:25:58 +000084 count = len([x for x in dir(inspect) if x.startswith('is')])
Christian Heimes7131fd92008-02-19 14:21:46 +000085 # This test is here for remember you to update Doc/library/inspect.rst
Christian Heimes78644762008-03-04 23:39:23 +000086 # which claims there are 16 such functions
Christian Heimes227c8002008-03-03 20:34:40 +000087 expected = 16
Thomas Wouters0e3f5912006-08-11 14:57:12 +000088 err_msg = "There are %d (not %d) is* functions" % (count, expected)
89 self.assertEqual(count, expected, err_msg)
Tim Peters5a9fb3c2005-01-07 16:01:32 +000090
Christian Heimes7131fd92008-02-19 14:21:46 +000091
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000092 def test_excluding_predicates(self):
Antoine Pitroud5a1a212012-06-17 23:18:07 +020093 global tb
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000094 self.istest(inspect.isbuiltin, 'sys.exit')
95 self.istest(inspect.isbuiltin, '[].append')
Neal Norwitz221085d2007-02-25 20:55:47 +000096 self.istest(inspect.iscode, 'mod.spam.__code__')
Antoine Pitroud5a1a212012-06-17 23:18:07 +020097 try:
98 1/0
99 except:
100 tb = sys.exc_info()[2]
101 self.istest(inspect.isframe, 'tb.tb_frame')
102 self.istest(inspect.istraceback, 'tb')
103 if hasattr(types, 'GetSetDescriptorType'):
104 self.istest(inspect.isgetsetdescriptor,
105 'type(tb.tb_frame).f_locals')
106 else:
107 self.assertFalse(inspect.isgetsetdescriptor(type(tb.tb_frame).f_locals))
108 finally:
109 # Clear traceback and all the frames and local variables hanging to it.
110 tb = None
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000111 self.istest(inspect.isfunction, 'mod.spam')
Christian Heimes4a22b5d2007-11-25 09:39:14 +0000112 self.istest(inspect.isfunction, 'mod.StupidGit.abuse')
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000113 self.istest(inspect.ismethod, 'git.argue')
114 self.istest(inspect.ismodule, 'mod')
Guido van Rossum813b0e52007-05-21 18:11:34 +0000115 self.istest(inspect.isdatadescriptor, 'collections.defaultdict.default_factory')
Christian Heimes7131fd92008-02-19 14:21:46 +0000116 self.istest(inspect.isgenerator, '(x for x in range(2))')
117 self.istest(inspect.isgeneratorfunction, 'generator_function_example')
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000118 if hasattr(types, 'MemberDescriptorType'):
119 self.istest(inspect.ismemberdescriptor, 'datetime.timedelta.days')
120 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000121 self.assertFalse(inspect.ismemberdescriptor(datetime.timedelta.days))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000122
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000123 def test_isroutine(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000124 self.assertTrue(inspect.isroutine(mod.spam))
125 self.assertTrue(inspect.isroutine([].count))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000126
Benjamin Petersonc4656002009-01-17 22:41:18 +0000127 def test_isclass(self):
128 self.istest(inspect.isclass, 'mod.StupidGit')
129 self.assertTrue(inspect.isclass(list))
130
131 class CustomGetattr(object):
132 def __getattr__(self, attr):
133 return None
134 self.assertFalse(inspect.isclass(CustomGetattr()))
135
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000136 def test_get_slot_members(self):
137 class C(object):
138 __slots__ = ("a", "b")
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000139 x = C()
140 x.a = 42
141 members = dict(inspect.getmembers(x))
Benjamin Peterson577473f2010-01-19 00:09:57 +0000142 self.assertIn('a', members)
143 self.assertNotIn('b', members)
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000144
Benjamin Petersona0dfa822009-11-13 02:25:08 +0000145 def test_isabstract(self):
146 from abc import ABCMeta, abstractmethod
147
148 class AbstractClassExample(metaclass=ABCMeta):
149
150 @abstractmethod
151 def foo(self):
152 pass
153
154 class ClassExample(AbstractClassExample):
155 def foo(self):
156 pass
157
158 a = ClassExample()
159
160 # Test general behaviour.
161 self.assertTrue(inspect.isabstract(AbstractClassExample))
162 self.assertFalse(inspect.isabstract(ClassExample))
163 self.assertFalse(inspect.isabstract(a))
164 self.assertFalse(inspect.isabstract(int))
165 self.assertFalse(inspect.isabstract(5))
166
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000167
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000168class TestInterpreterStack(IsTestBase):
169 def __init__(self, *args, **kwargs):
170 unittest.TestCase.__init__(self, *args, **kwargs)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000171
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000172 git.abuse(7, 8, 9)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000173
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000174 def test_abuse_done(self):
175 self.istest(inspect.istraceback, 'git.ex[2]')
176 self.istest(inspect.isframe, 'mod.fr')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000177
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000178 def test_stack(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000179 self.assertTrue(len(mod.st) >= 5)
Christian Heimesa3538eb2007-11-06 11:44:48 +0000180 self.assertEqual(revise(*mod.st[0][1:]),
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000181 (modfile, 16, 'eggs', [' st = inspect.stack()\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000182 self.assertEqual(revise(*mod.st[1][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000183 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000184 self.assertEqual(revise(*mod.st[2][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000185 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000186 self.assertEqual(revise(*mod.st[3][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000187 (modfile, 39, 'abuse', [' self.argue(a, b, c)\n'], 0))
Antoine Pitroucdcafb72014-08-24 10:50:28 -0400188 # Test named tuple fields
189 record = mod.st[0]
190 self.assertIs(record.frame, mod.fr)
191 self.assertEqual(record.lineno, 16)
192 self.assertEqual(record.filename, mod.__file__)
193 self.assertEqual(record.function, 'eggs')
194 self.assertIn('inspect.stack()', record.code_context[0])
195 self.assertEqual(record.index, 0)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000196
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000197 def test_trace(self):
198 self.assertEqual(len(git.tr), 3)
Florent Xiclunac8575922010-03-24 17:37:49 +0000199 self.assertEqual(revise(*git.tr[0][1:]),
200 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
201 self.assertEqual(revise(*git.tr[1][1:]),
202 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
203 self.assertEqual(revise(*git.tr[2][1:]),
204 (modfile, 18, 'eggs', [' q = y / 0\n'], 0))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000205
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000206 def test_frame(self):
207 args, varargs, varkw, locals = inspect.getargvalues(mod.fr)
208 self.assertEqual(args, ['x', 'y'])
209 self.assertEqual(varargs, None)
210 self.assertEqual(varkw, None)
211 self.assertEqual(locals, {'x': 11, 'p': 11, 'y': 14})
212 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
213 '(x=11, y=14)')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000214
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000215 def test_previous_frame(self):
216 args, varargs, varkw, locals = inspect.getargvalues(mod.fr.f_back)
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000217 self.assertEqual(args, ['a', 'b', 'c', 'd', 'e', 'f'])
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000218 self.assertEqual(varargs, 'g')
219 self.assertEqual(varkw, 'h')
220 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000221 '(a=7, b=8, c=9, d=3, e=4, f=5, *g=(), **h={})')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000222
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000223class GetSourceBase(unittest.TestCase):
224 # Subclasses must override.
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000225 fodderModule = None
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000226
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000227 def __init__(self, *args, **kwargs):
228 unittest.TestCase.__init__(self, *args, **kwargs)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000229
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000230 with open(inspect.getsourcefile(self.fodderModule)) as fp:
Philip Jenveya27c5bd2009-05-28 06:09:08 +0000231 self.source = fp.read()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000232
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000233 def sourcerange(self, top, bottom):
234 lines = self.source.split("\n")
235 return "\n".join(lines[top-1:bottom]) + "\n"
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000236
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000237 def assertSourceEqual(self, obj, top, bottom):
238 self.assertEqual(inspect.getsource(obj),
239 self.sourcerange(top, bottom))
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000240
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000241class TestRetrievingSourceCode(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000242 fodderModule = mod
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000243
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000244 def test_getclasses(self):
245 classes = inspect.getmembers(mod, inspect.isclass)
246 self.assertEqual(classes,
247 [('FesteringGob', mod.FesteringGob),
248 ('MalodorousPervert', mod.MalodorousPervert),
249 ('ParrotDroppings', mod.ParrotDroppings),
Serhiy Storchaka362c1b52013-09-05 17:14:32 +0300250 ('StupidGit', mod.StupidGit),
251 ('Tit', mod.MalodorousPervert),
252 ])
253 tree = inspect.getclasstree([cls[1] for cls in classes])
254 self.assertEqual(tree,
255 [(object, ()),
256 [(mod.ParrotDroppings, (object,)),
257 [(mod.FesteringGob, (mod.MalodorousPervert,
258 mod.ParrotDroppings))
259 ],
260 (mod.StupidGit, (object,)),
261 [(mod.MalodorousPervert, (mod.StupidGit,)),
262 [(mod.FesteringGob, (mod.MalodorousPervert,
263 mod.ParrotDroppings))
264 ]
265 ]
266 ]
267 ])
268 tree = inspect.getclasstree([cls[1] for cls in classes], True)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000269 self.assertEqual(tree,
Thomas Wouters725af872006-04-15 09:13:19 +0000270 [(object, ()),
271 [(mod.ParrotDroppings, (object,)),
272 (mod.StupidGit, (object,)),
273 [(mod.MalodorousPervert, (mod.StupidGit,)),
274 [(mod.FesteringGob, (mod.MalodorousPervert,
275 mod.ParrotDroppings))
276 ]
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000277 ]
278 ]
279 ])
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000280
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000281 def test_getfunctions(self):
282 functions = inspect.getmembers(mod, inspect.isfunction)
283 self.assertEqual(functions, [('eggs', mod.eggs),
284 ('spam', mod.spam)])
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000285
R. David Murray378c0cf2010-02-24 01:46:21 +0000286 @unittest.skipIf(sys.flags.optimize >= 2,
287 "Docstrings are omitted with -O2 and above")
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000288 def test_getdoc(self):
289 self.assertEqual(inspect.getdoc(mod), 'A module docstring.')
290 self.assertEqual(inspect.getdoc(mod.StupidGit),
291 'A longer,\n\nindented\n\ndocstring.')
292 self.assertEqual(inspect.getdoc(git.abuse),
293 'Another\n\ndocstring\n\ncontaining\n\ntabs')
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000294
Georg Brandl0c77a822008-06-10 16:37:50 +0000295 def test_cleandoc(self):
296 self.assertEqual(inspect.cleandoc('An\n indented\n docstring.'),
297 'An\nindented\ndocstring.')
298
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000299 def test_getcomments(self):
300 self.assertEqual(inspect.getcomments(mod), '# line 1\n')
301 self.assertEqual(inspect.getcomments(mod.StupidGit), '# line 20\n')
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000302
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000303 def test_getmodule(self):
Thomas Wouters89f507f2006-12-13 04:49:30 +0000304 # Check actual module
305 self.assertEqual(inspect.getmodule(mod), mod)
306 # Check class (uses __module__ attribute)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000307 self.assertEqual(inspect.getmodule(mod.StupidGit), mod)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000308 # Check a method (no __module__ attribute, falls back to filename)
309 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
310 # Do it again (check the caching isn't broken)
311 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
312 # Check a builtin
Georg Brandl1a3284e2007-12-02 09:40:06 +0000313 self.assertEqual(inspect.getmodule(str), sys.modules["builtins"])
Thomas Wouters89f507f2006-12-13 04:49:30 +0000314 # Check filename override
315 self.assertEqual(inspect.getmodule(None, modfile), mod)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000316
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000317 def test_getsource(self):
318 self.assertSourceEqual(git.abuse, 29, 39)
319 self.assertSourceEqual(mod.StupidGit, 21, 46)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000320
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000321 def test_getsourcefile(self):
Christian Heimesa3538eb2007-11-06 11:44:48 +0000322 self.assertEqual(normcase(inspect.getsourcefile(mod.spam)), modfile)
323 self.assertEqual(normcase(inspect.getsourcefile(git.abuse)), modfile)
R. David Murraya1b37402010-06-17 02:04:29 +0000324 fn = "_non_existing_filename_used_for_sourcefile_test.py"
325 co = compile("None", fn, "exec")
R. David Murray4155f972010-06-17 13:23:18 +0000326 self.assertEqual(inspect.getsourcefile(co), None)
R. David Murraya1b37402010-06-17 02:04:29 +0000327 linecache.cache[co.co_filename] = (1, None, "None", co.co_filename)
Antoine Pitrou5d62a612012-07-08 13:48:46 +0200328 try:
329 self.assertEqual(normcase(inspect.getsourcefile(co)), fn)
330 finally:
331 del linecache.cache[co.co_filename]
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000332
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000333 def test_getfile(self):
334 self.assertEqual(inspect.getfile(mod.StupidGit), mod.__file__)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000335
Yury Selivanov2eed8b72014-01-27 13:24:56 -0500336 def test_getfile_class_without_module(self):
337 class CM(type):
338 @property
339 def __module__(cls):
340 raise AttributeError
341 class C(metaclass=CM):
342 pass
343 with self.assertRaises(TypeError):
344 inspect.getfile(C)
345
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000346 def test_getmodule_recursion(self):
Christian Heimes45f9af32007-11-27 21:50:00 +0000347 from types import ModuleType
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000348 name = '__inspect_dummy'
Christian Heimes45f9af32007-11-27 21:50:00 +0000349 m = sys.modules[name] = ModuleType(name)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000350 m.__file__ = "<string>" # hopefully not a real filename...
351 m.__loader__ = "dummy" # pretend the filename is understood by a loader
Georg Brandl7cae87c2006-09-06 06:51:57 +0000352 exec("def x(): pass", m.__dict__)
Neal Norwitz221085d2007-02-25 20:55:47 +0000353 self.assertEqual(inspect.getsourcefile(m.x.__code__), '<string>')
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000354 del sys.modules[name]
355 inspect.getmodule(compile('a=10','','single'))
356
Benjamin Peterson9620cc02011-06-11 15:53:11 -0500357 def test_proceed_with_fake_filename(self):
358 '''doctest monkeypatches linecache to enable inspection'''
359 fn, source = '<test>', 'def x(): pass\n'
360 getlines = linecache.getlines
361 def monkey(filename, module_globals=None):
362 if filename == fn:
Ezio Melottid8b509b2011-09-28 17:37:55 +0300363 return source.splitlines(keepends=True)
Benjamin Peterson9620cc02011-06-11 15:53:11 -0500364 else:
365 return getlines(filename, module_globals)
366 linecache.getlines = monkey
367 try:
368 ns = {}
369 exec(compile(source, fn, 'single'), ns)
370 inspect.getsource(ns["x"])
371 finally:
372 linecache.getlines = getlines
373
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000374class TestDecorators(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000375 fodderModule = mod2
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000376
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000377 def test_wrapped_decorator(self):
Christian Heimes09aaa882008-02-23 15:01:06 +0000378 self.assertSourceEqual(mod2.wrapped, 14, 17)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000379
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000380 def test_replacing_decorator(self):
381 self.assertSourceEqual(mod2.gone, 9, 10)
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000382
Yury Selivanov081bbf62014-09-26 17:34:54 -0400383 def test_getsource_unwrap(self):
384 self.assertSourceEqual(mod2.real, 122, 124)
385
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000386class TestOneliners(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000387 fodderModule = mod2
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000388 def test_oneline_lambda(self):
389 # Test inspect.getsource with a one-line lambda function.
390 self.assertSourceEqual(mod2.oll, 25, 25)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000391
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000392 def test_threeline_lambda(self):
393 # Test inspect.getsource with a three-line lambda function,
394 # where the second and third lines are _not_ indented.
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000395 self.assertSourceEqual(mod2.tll, 28, 30)
396
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000397 def test_twoline_indented_lambda(self):
398 # Test inspect.getsource with a two-line lambda function,
399 # where the second line _is_ indented.
400 self.assertSourceEqual(mod2.tlli, 33, 34)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000401
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000402 def test_onelinefunc(self):
403 # Test inspect.getsource with a regular one-line function.
404 self.assertSourceEqual(mod2.onelinefunc, 37, 37)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000405
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000406 def test_manyargs(self):
407 # Test inspect.getsource with a regular function where
408 # the arguments are on two lines and _not_ indented and
409 # the body on the second line with the last arguments.
410 self.assertSourceEqual(mod2.manyargs, 40, 41)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000411
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000412 def test_twolinefunc(self):
413 # Test inspect.getsource with a regular function where
414 # the body is on two lines, following the argument list and
415 # continued on the next line by a \\.
416 self.assertSourceEqual(mod2.twolinefunc, 44, 45)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000417
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000418 def test_lambda_in_list(self):
419 # Test inspect.getsource with a one-line lambda function
420 # defined in a list, indented.
421 self.assertSourceEqual(mod2.a[1], 49, 49)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000422
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000423 def test_anonymous(self):
424 # Test inspect.getsource with a lambda function defined
425 # as argument to another function.
426 self.assertSourceEqual(mod2.anonymous, 55, 55)
427
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000428class TestBuggyCases(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000429 fodderModule = mod2
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000430
431 def test_with_comment(self):
432 self.assertSourceEqual(mod2.with_comment, 58, 59)
433
434 def test_multiline_sig(self):
435 self.assertSourceEqual(mod2.multiline_sig[0], 63, 64)
436
Armin Rigodd5c0232005-09-25 11:45:45 +0000437 def test_nested_class(self):
438 self.assertSourceEqual(mod2.func69().func71, 71, 72)
439
440 def test_one_liner_followed_by_non_name(self):
441 self.assertSourceEqual(mod2.func77, 77, 77)
442
443 def test_one_liner_dedent_non_name(self):
444 self.assertSourceEqual(mod2.cls82.func83, 83, 83)
445
446 def test_with_comment_instead_of_docstring(self):
447 self.assertSourceEqual(mod2.func88, 88, 90)
448
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000449 def test_method_in_dynamic_class(self):
450 self.assertSourceEqual(mod2.method_in_dynamic_class, 95, 97)
451
R David Murray32562d72014-10-03 11:15:38 -0400452 # This should not skip for CPython, but might on a repackaged python where
453 # unicodedata is not an external module, or on pypy.
454 @unittest.skipIf(not hasattr(unicodedata, '__file__') or
455 unicodedata.__file__.endswith('.py'),
456 "unicodedata is not an external binary module")
R. David Murray74b89242009-05-13 17:33:03 +0000457 def test_findsource_binary(self):
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200458 self.assertRaises(OSError, inspect.getsource, unicodedata)
459 self.assertRaises(OSError, inspect.findsource, unicodedata)
R. David Murray74b89242009-05-13 17:33:03 +0000460
R. David Murraya1b37402010-06-17 02:04:29 +0000461 def test_findsource_code_in_linecache(self):
462 lines = ["x=1"]
463 co = compile(lines[0], "_dynamically_created_file", "exec")
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200464 self.assertRaises(OSError, inspect.findsource, co)
465 self.assertRaises(OSError, inspect.getsource, co)
R. David Murraya1b37402010-06-17 02:04:29 +0000466 linecache.cache[co.co_filename] = (1, None, lines, co.co_filename)
Antoine Pitrou5d62a612012-07-08 13:48:46 +0200467 try:
468 self.assertEqual(inspect.findsource(co), (lines,0))
469 self.assertEqual(inspect.getsource(co), lines[0])
470 finally:
471 del linecache.cache[co.co_filename]
R. David Murraya1b37402010-06-17 02:04:29 +0000472
Ezio Melotti1b145922013-03-30 05:17:24 +0200473 def test_findsource_without_filename(self):
474 for fname in ['', '<string>']:
475 co = compile('x=1', fname, "exec")
476 self.assertRaises(IOError, inspect.findsource, co)
477 self.assertRaises(IOError, inspect.getsource, co)
478
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000479class TestNoEOL(GetSourceBase):
480 def __init__(self, *args, **kwargs):
481 self.tempdir = TESTFN + '_dir'
482 os.mkdir(self.tempdir)
483 with open(os.path.join(self.tempdir,
484 'inspect_fodder3%spy' % os.extsep), 'w') as f:
485 f.write("class X:\n pass # No EOL")
486 with DirsOnSysPath(self.tempdir):
487 import inspect_fodder3 as mod3
488 self.fodderModule = mod3
489 GetSourceBase.__init__(self, *args, **kwargs)
490
491 def tearDown(self):
492 shutil.rmtree(self.tempdir)
493
494 def test_class(self):
495 self.assertSourceEqual(self.fodderModule.X, 1, 2)
496
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100497
498class _BrokenDataDescriptor(object):
499 """
500 A broken data descriptor. See bug #1785.
501 """
502 def __get__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700503 raise AttributeError("broken data descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100504
505 def __set__(*args):
506 raise RuntimeError
507
508 def __getattr__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700509 raise AttributeError("broken data descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100510
511
512class _BrokenMethodDescriptor(object):
513 """
514 A broken method descriptor. See bug #1785.
515 """
516 def __get__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700517 raise AttributeError("broken method descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100518
519 def __getattr__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700520 raise AttributeError("broken method descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100521
522
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000523# Helper for testing classify_class_attrs.
Tim Peters13b49d32001-09-23 02:00:29 +0000524def attrs_wo_objs(cls):
525 return [t[:3] for t in inspect.classify_class_attrs(cls)]
526
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100527
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000528class TestClassesAndFunctions(unittest.TestCase):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000529 def test_newstyle_mro(self):
530 # The same w/ new-class MRO.
531 class A(object): pass
532 class B(A): pass
533 class C(A): pass
534 class D(B, C): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000535
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000536 expected = (D, B, C, A, object)
537 got = inspect.getmro(D)
538 self.assertEqual(expected, got)
Tim Peters13b49d32001-09-23 02:00:29 +0000539
Christian Heimes3795b532007-11-08 13:48:53 +0000540 def assertArgSpecEquals(self, routine, args_e, varargs_e=None,
541 varkw_e=None, defaults_e=None, formatted=None):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000542 args, varargs, varkw, defaults = inspect.getargspec(routine)
543 self.assertEqual(args, args_e)
544 self.assertEqual(varargs, varargs_e)
545 self.assertEqual(varkw, varkw_e)
546 self.assertEqual(defaults, defaults_e)
547 if formatted is not None:
548 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults),
549 formatted)
Tim Peters13b49d32001-09-23 02:00:29 +0000550
Christian Heimes3795b532007-11-08 13:48:53 +0000551 def assertFullArgSpecEquals(self, routine, args_e, varargs_e=None,
552 varkw_e=None, defaults_e=None,
553 kwonlyargs_e=[], kwonlydefaults_e=None,
554 ann_e={}, formatted=None):
555 args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \
556 inspect.getfullargspec(routine)
557 self.assertEqual(args, args_e)
558 self.assertEqual(varargs, varargs_e)
559 self.assertEqual(varkw, varkw_e)
560 self.assertEqual(defaults, defaults_e)
561 self.assertEqual(kwonlyargs, kwonlyargs_e)
562 self.assertEqual(kwonlydefaults, kwonlydefaults_e)
563 self.assertEqual(ann, ann_e)
564 if formatted is not None:
565 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults,
566 kwonlyargs, kwonlydefaults, ann),
567 formatted)
568
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000569 def test_getargspec(self):
Christian Heimes3795b532007-11-08 13:48:53 +0000570 self.assertArgSpecEquals(mod.eggs, ['x', 'y'], formatted='(x, y)')
Tim Peters13b49d32001-09-23 02:00:29 +0000571
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000572 self.assertArgSpecEquals(mod.spam,
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000573 ['a', 'b', 'c', 'd', 'e', 'f'],
574 'g', 'h', (3, 4, 5),
575 '(a, b, c, d=3, e=4, f=5, *g, **h)')
Tim Peters13b49d32001-09-23 02:00:29 +0000576
Christian Heimes3795b532007-11-08 13:48:53 +0000577 self.assertRaises(ValueError, self.assertArgSpecEquals,
578 mod2.keyworded, [])
579
580 self.assertRaises(ValueError, self.assertArgSpecEquals,
581 mod2.annotated, [])
Benjamin Peterson9953a8d2009-01-17 04:15:01 +0000582 self.assertRaises(ValueError, self.assertArgSpecEquals,
583 mod2.keyword_only_arg, [])
584
Christian Heimes3795b532007-11-08 13:48:53 +0000585
586 def test_getfullargspec(self):
587 self.assertFullArgSpecEquals(mod2.keyworded, [], varargs_e='arg1',
588 kwonlyargs_e=['arg2'],
589 kwonlydefaults_e={'arg2':1},
590 formatted='(*arg1, arg2=1)')
591
592 self.assertFullArgSpecEquals(mod2.annotated, ['arg1'],
Christian Heimesc9543e42007-11-28 08:28:28 +0000593 ann_e={'arg1' : list},
Christian Heimes3795b532007-11-08 13:48:53 +0000594 formatted='(arg1: list)')
Benjamin Peterson9953a8d2009-01-17 04:15:01 +0000595 self.assertFullArgSpecEquals(mod2.keyword_only_arg, [],
596 kwonlyargs_e=['arg'],
597 formatted='(*, arg)')
598
Yury Selivanov57d240e2014-02-19 16:27:23 -0500599 def test_argspec_api_ignores_wrapped(self):
600 # Issue 20684: low level introspection API must ignore __wrapped__
601 @functools.wraps(mod.spam)
602 def ham(x, y):
603 pass
604 # Basic check
605 self.assertArgSpecEquals(ham, ['x', 'y'], formatted='(x, y)')
606 self.assertFullArgSpecEquals(ham, ['x', 'y'], formatted='(x, y)')
607 self.assertFullArgSpecEquals(functools.partial(ham),
608 ['x', 'y'], formatted='(x, y)')
609 # Other variants
610 def check_method(f):
611 self.assertArgSpecEquals(f, ['self', 'x', 'y'],
612 formatted='(self, x, y)')
613 class C:
614 @functools.wraps(mod.spam)
615 def ham(self, x, y):
616 pass
617 pham = functools.partialmethod(ham)
618 @functools.wraps(mod.spam)
619 def __call__(self, x, y):
620 pass
621 check_method(C())
622 check_method(C.ham)
623 check_method(C().ham)
624 check_method(C.pham)
625 check_method(C().pham)
626
627 class C_new:
628 @functools.wraps(mod.spam)
629 def __new__(self, x, y):
630 pass
631 check_method(C_new)
632
633 class C_init:
634 @functools.wraps(mod.spam)
635 def __init__(self, x, y):
636 pass
637 check_method(C_init)
638
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500639 def test_getfullargspec_signature_attr(self):
640 def test():
641 pass
642 spam_param = inspect.Parameter('spam', inspect.Parameter.POSITIONAL_ONLY)
643 test.__signature__ = inspect.Signature(parameters=(spam_param,))
644
645 self.assertFullArgSpecEquals(test, args_e=['spam'], formatted='(spam)')
646
Yury Selivanov4cb93912014-01-29 11:54:12 -0500647 def test_getfullargspec_signature_annos(self):
648 def test(a:'spam') -> 'ham': pass
649 spec = inspect.getfullargspec(test)
650 self.assertEqual(test.__annotations__, spec.annotations)
651
652 def test(): pass
653 spec = inspect.getfullargspec(test)
654 self.assertEqual(test.__annotations__, spec.annotations)
655
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500656 @unittest.skipIf(MISSING_C_DOCSTRINGS,
657 "Signature information for builtins requires docstrings")
658 def test_getfullargspec_builtin_methods(self):
659 self.assertFullArgSpecEquals(_pickle.Pickler.dump,
660 args_e=['self', 'obj'], formatted='(self, obj)')
661
662 self.assertFullArgSpecEquals(_pickle.Pickler(io.BytesIO()).dump,
663 args_e=['self', 'obj'], formatted='(self, obj)')
664
Yury Selivanov8c185ee2014-02-21 01:32:42 -0500665 self.assertFullArgSpecEquals(
666 os.stat,
667 args_e=['path'],
668 kwonlyargs_e=['dir_fd', 'follow_symlinks'],
669 kwonlydefaults_e={'dir_fd': None, 'follow_symlinks': True},
670 formatted='(path, *, dir_fd=None, follow_symlinks=True)')
671
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200672 @cpython_only
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500673 @unittest.skipIf(MISSING_C_DOCSTRINGS,
674 "Signature information for builtins requires docstrings")
675 def test_getfullagrspec_builtin_func(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200676 import _testcapi
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500677 builtin = _testcapi.docstring_with_signature_with_defaults
678 spec = inspect.getfullargspec(builtin)
679 self.assertEqual(spec.defaults[0], 'avocado')
680
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200681 @cpython_only
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500682 @unittest.skipIf(MISSING_C_DOCSTRINGS,
683 "Signature information for builtins requires docstrings")
684 def test_getfullagrspec_builtin_func_no_signature(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200685 import _testcapi
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500686 builtin = _testcapi.docstring_no_signature
687 with self.assertRaises(TypeError):
688 inspect.getfullargspec(builtin)
Christian Heimes3795b532007-11-08 13:48:53 +0000689
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000690 def test_getargspec_method(self):
691 class A(object):
692 def m(self):
693 pass
694 self.assertArgSpecEquals(A.m, ['self'])
Tim Peters13b49d32001-09-23 02:00:29 +0000695
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000696 def test_classify_newstyle(self):
697 class A(object):
Tim Peters13b49d32001-09-23 02:00:29 +0000698
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000699 def s(): pass
700 s = staticmethod(s)
Tim Peters13b49d32001-09-23 02:00:29 +0000701
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000702 def c(cls): pass
703 c = classmethod(c)
Tim Peters13b49d32001-09-23 02:00:29 +0000704
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000705 def getp(self): pass
706 p = property(getp)
Tim Peters13b49d32001-09-23 02:00:29 +0000707
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000708 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000709
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000710 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000711
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000712 datablob = '1'
Tim Peters13b49d32001-09-23 02:00:29 +0000713
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100714 dd = _BrokenDataDescriptor()
715 md = _BrokenMethodDescriptor()
716
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000717 attrs = attrs_wo_objs(A)
Yury Selivanov0860a0b2014-01-31 14:28:44 -0500718
719 self.assertIn(('__new__', 'method', object), attrs, 'missing __new__')
720 self.assertIn(('__init__', 'method', object), attrs, 'missing __init__')
721
Benjamin Peterson577473f2010-01-19 00:09:57 +0000722 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
723 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
724 self.assertIn(('p', 'property', A), attrs, 'missing property')
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000725 self.assertIn(('m', 'method', A), attrs,
726 'missing plain method: %r' % attrs)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000727 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
728 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100729 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
730 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000731
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000732 class B(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000733
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000734 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000735
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000736 attrs = attrs_wo_objs(B)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000737 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
738 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
739 self.assertIn(('p', 'property', A), attrs, 'missing property')
740 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
741 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
742 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100743 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
744 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000745
746
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000747 class C(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000748
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000749 def m(self): pass
750 def c(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000751
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000752 attrs = attrs_wo_objs(C)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000753 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
754 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
755 self.assertIn(('p', 'property', A), attrs, 'missing property')
756 self.assertIn(('m', 'method', C), attrs, 'missing plain method')
757 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
758 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100759 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
760 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000761
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000762 class D(B, C):
Tim Peters13b49d32001-09-23 02:00:29 +0000763
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000764 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000765
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000766 attrs = attrs_wo_objs(D)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000767 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
768 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
769 self.assertIn(('p', 'property', A), attrs, 'missing property')
770 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
771 self.assertIn(('m1', 'method', D), attrs, 'missing plain method')
772 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100773 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
774 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
775
776 def test_classify_builtin_types(self):
777 # Simple sanity check that all built-in types can have their
778 # attributes classified.
779 for name in dir(__builtins__):
780 builtin = getattr(__builtins__, name)
781 if isinstance(builtin, type):
782 inspect.classify_class_attrs(builtin)
783
Ethan Furman63c141c2013-10-18 00:27:39 -0700784 def test_classify_DynamicClassAttribute(self):
785 class Meta(type):
786 def __getattr__(self, name):
787 if name == 'ham':
788 return 'spam'
789 return super().__getattr__(name)
790 class VA(metaclass=Meta):
Ethan Furmane03ea372013-09-25 07:14:41 -0700791 @types.DynamicClassAttribute
792 def ham(self):
793 return 'eggs'
Ethan Furman63c141c2013-10-18 00:27:39 -0700794 should_find_dca = inspect.Attribute('ham', 'data', VA, VA.__dict__['ham'])
795 self.assertIn(should_find_dca, inspect.classify_class_attrs(VA))
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700796 should_find_ga = inspect.Attribute('ham', 'data', Meta, 'spam')
Ethan Furman63c141c2013-10-18 00:27:39 -0700797 self.assertIn(should_find_ga, inspect.classify_class_attrs(VA))
798
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700799 def test_classify_metaclass_class_attribute(self):
800 class Meta(type):
801 fish = 'slap'
802 def __dir__(self):
Serhiy Storchakaa60c2fe2015-03-12 21:56:08 +0200803 return ['__class__', '__module__', '__name__', 'fish']
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700804 class Class(metaclass=Meta):
805 pass
806 should_find = inspect.Attribute('fish', 'data', Meta, 'slap')
807 self.assertIn(should_find, inspect.classify_class_attrs(Class))
808
Ethan Furman63c141c2013-10-18 00:27:39 -0700809 def test_classify_VirtualAttribute(self):
810 class Meta(type):
811 def __dir__(cls):
812 return ['__class__', '__module__', '__name__', 'BOOM']
813 def __getattr__(self, name):
814 if name =='BOOM':
815 return 42
816 return super().__getattr(name)
817 class Class(metaclass=Meta):
818 pass
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700819 should_find = inspect.Attribute('BOOM', 'data', Meta, 42)
Ethan Furman63c141c2013-10-18 00:27:39 -0700820 self.assertIn(should_find, inspect.classify_class_attrs(Class))
821
822 def test_classify_VirtualAttribute_multi_classes(self):
823 class Meta1(type):
824 def __dir__(cls):
825 return ['__class__', '__module__', '__name__', 'one']
826 def __getattr__(self, name):
827 if name =='one':
828 return 1
829 return super().__getattr__(name)
830 class Meta2(type):
831 def __dir__(cls):
832 return ['__class__', '__module__', '__name__', 'two']
833 def __getattr__(self, name):
834 if name =='two':
835 return 2
836 return super().__getattr__(name)
837 class Meta3(Meta1, Meta2):
838 def __dir__(cls):
839 return list(sorted(set(['__class__', '__module__', '__name__', 'three'] +
840 Meta1.__dir__(cls) + Meta2.__dir__(cls))))
841 def __getattr__(self, name):
842 if name =='three':
843 return 3
844 return super().__getattr__(name)
845 class Class1(metaclass=Meta1):
846 pass
847 class Class2(Class1, metaclass=Meta3):
848 pass
849
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700850 should_find1 = inspect.Attribute('one', 'data', Meta1, 1)
851 should_find2 = inspect.Attribute('two', 'data', Meta2, 2)
852 should_find3 = inspect.Attribute('three', 'data', Meta3, 3)
Ethan Furman63c141c2013-10-18 00:27:39 -0700853 cca = inspect.classify_class_attrs(Class2)
854 for sf in (should_find1, should_find2, should_find3):
855 self.assertIn(sf, cca)
856
857 def test_classify_class_attrs_with_buggy_dir(self):
858 class M(type):
859 def __dir__(cls):
860 return ['__class__', '__name__', 'missing']
861 class C(metaclass=M):
862 pass
863 attrs = [a[0] for a in inspect.classify_class_attrs(C)]
864 self.assertNotIn('missing', attrs)
Ethan Furmane03ea372013-09-25 07:14:41 -0700865
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100866 def test_getmembers_descriptors(self):
867 class A(object):
868 dd = _BrokenDataDescriptor()
869 md = _BrokenMethodDescriptor()
870
871 def pred_wrapper(pred):
872 # A quick'n'dirty way to discard standard attributes of new-style
873 # classes.
874 class Empty(object):
875 pass
876 def wrapped(x):
877 if '__name__' in dir(x) and hasattr(Empty, x.__name__):
878 return False
879 return pred(x)
880 return wrapped
881
882 ismethoddescriptor = pred_wrapper(inspect.ismethoddescriptor)
883 isdatadescriptor = pred_wrapper(inspect.isdatadescriptor)
884
885 self.assertEqual(inspect.getmembers(A, ismethoddescriptor),
886 [('md', A.__dict__['md'])])
887 self.assertEqual(inspect.getmembers(A, isdatadescriptor),
888 [('dd', A.__dict__['dd'])])
889
890 class B(A):
891 pass
892
893 self.assertEqual(inspect.getmembers(B, ismethoddescriptor),
894 [('md', A.__dict__['md'])])
895 self.assertEqual(inspect.getmembers(B, isdatadescriptor),
896 [('dd', A.__dict__['dd'])])
897
Antoine Pitrou0c603812012-01-18 17:40:18 +0100898 def test_getmembers_method(self):
899 class B:
900 def f(self):
901 pass
902
903 self.assertIn(('f', B.f), inspect.getmembers(B))
904 self.assertNotIn(('f', B.f), inspect.getmembers(B, inspect.ismethod))
905 b = B()
906 self.assertIn(('f', b.f), inspect.getmembers(b))
907 self.assertIn(('f', b.f), inspect.getmembers(b, inspect.ismethod))
908
Ethan Furmane03ea372013-09-25 07:14:41 -0700909 def test_getmembers_VirtualAttribute(self):
Ethan Furman63c141c2013-10-18 00:27:39 -0700910 class M(type):
911 def __getattr__(cls, name):
912 if name == 'eggs':
913 return 'scrambled'
914 return super().__getattr__(name)
915 class A(metaclass=M):
Ethan Furmane03ea372013-09-25 07:14:41 -0700916 @types.DynamicClassAttribute
917 def eggs(self):
918 return 'spam'
Ethan Furman63c141c2013-10-18 00:27:39 -0700919 self.assertIn(('eggs', 'scrambled'), inspect.getmembers(A))
920 self.assertIn(('eggs', 'spam'), inspect.getmembers(A()))
921
922 def test_getmembers_with_buggy_dir(self):
923 class M(type):
924 def __dir__(cls):
925 return ['__class__', '__name__', 'missing']
926 class C(metaclass=M):
927 pass
928 attrs = [a[0] for a in inspect.getmembers(C)]
929 self.assertNotIn('missing', attrs)
Ethan Furmane03ea372013-09-25 07:14:41 -0700930
Jeremy Hyltonc4bf5ed2003-06-27 18:43:12 +0000931
Nick Coghlan2f92e542012-06-23 19:39:55 +1000932_global_ref = object()
933class TestGetClosureVars(unittest.TestCase):
934
935 def test_name_resolution(self):
936 # Basic test of the 4 different resolution mechanisms
937 def f(nonlocal_ref):
938 def g(local_ref):
939 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
940 return g
941 _arg = object()
942 nonlocal_vars = {"nonlocal_ref": _arg}
943 global_vars = {"_global_ref": _global_ref}
944 builtin_vars = {"print": print}
945 unbound_names = {"unbound_ref"}
946 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
947 builtin_vars, unbound_names)
948 self.assertEqual(inspect.getclosurevars(f(_arg)), expected)
949
950 def test_generator_closure(self):
951 def f(nonlocal_ref):
952 def g(local_ref):
953 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
954 yield
955 return g
956 _arg = object()
957 nonlocal_vars = {"nonlocal_ref": _arg}
958 global_vars = {"_global_ref": _global_ref}
959 builtin_vars = {"print": print}
960 unbound_names = {"unbound_ref"}
961 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
962 builtin_vars, unbound_names)
963 self.assertEqual(inspect.getclosurevars(f(_arg)), expected)
964
965 def test_method_closure(self):
966 class C:
967 def f(self, nonlocal_ref):
968 def g(local_ref):
969 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
970 return g
971 _arg = object()
972 nonlocal_vars = {"nonlocal_ref": _arg}
973 global_vars = {"_global_ref": _global_ref}
974 builtin_vars = {"print": print}
975 unbound_names = {"unbound_ref"}
976 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
977 builtin_vars, unbound_names)
978 self.assertEqual(inspect.getclosurevars(C().f(_arg)), expected)
979
980 def test_nonlocal_vars(self):
981 # More complex tests of nonlocal resolution
982 def _nonlocal_vars(f):
983 return inspect.getclosurevars(f).nonlocals
984
985 def make_adder(x):
986 def add(y):
987 return x + y
988 return add
989
990 def curry(func, arg1):
991 return lambda arg2: func(arg1, arg2)
992
993 def less_than(a, b):
994 return a < b
995
996 # The infamous Y combinator.
997 def Y(le):
998 def g(f):
999 return le(lambda x: f(f)(x))
1000 Y.g_ref = g
1001 return g(g)
1002
1003 def check_y_combinator(func):
1004 self.assertEqual(_nonlocal_vars(func), {'f': Y.g_ref})
1005
1006 inc = make_adder(1)
1007 add_two = make_adder(2)
1008 greater_than_five = curry(less_than, 5)
1009
1010 self.assertEqual(_nonlocal_vars(inc), {'x': 1})
1011 self.assertEqual(_nonlocal_vars(add_two), {'x': 2})
1012 self.assertEqual(_nonlocal_vars(greater_than_five),
1013 {'arg1': 5, 'func': less_than})
1014 self.assertEqual(_nonlocal_vars((lambda x: lambda y: x + y)(3)),
1015 {'x': 3})
1016 Y(check_y_combinator)
1017
1018 def test_getclosurevars_empty(self):
1019 def foo(): pass
1020 _empty = inspect.ClosureVars({}, {}, {}, set())
1021 self.assertEqual(inspect.getclosurevars(lambda: True), _empty)
1022 self.assertEqual(inspect.getclosurevars(foo), _empty)
1023
1024 def test_getclosurevars_error(self):
1025 class T: pass
1026 self.assertRaises(TypeError, inspect.getclosurevars, 1)
1027 self.assertRaises(TypeError, inspect.getclosurevars, list)
1028 self.assertRaises(TypeError, inspect.getclosurevars, {})
1029
Nick Coghlan6c6e2542012-06-23 20:07:39 +10001030 def _private_globals(self):
1031 code = """def f(): print(path)"""
1032 ns = {}
1033 exec(code, ns)
1034 return ns["f"], ns
1035
1036 def test_builtins_fallback(self):
1037 f, ns = self._private_globals()
1038 ns.pop("__builtins__", None)
1039 expected = inspect.ClosureVars({}, {}, {"print":print}, {"path"})
1040 self.assertEqual(inspect.getclosurevars(f), expected)
1041
1042 def test_builtins_as_dict(self):
1043 f, ns = self._private_globals()
1044 ns["__builtins__"] = {"path":1}
1045 expected = inspect.ClosureVars({}, {}, {"path":1}, {"print"})
1046 self.assertEqual(inspect.getclosurevars(f), expected)
1047
1048 def test_builtins_as_module(self):
1049 f, ns = self._private_globals()
1050 ns["__builtins__"] = os
1051 expected = inspect.ClosureVars({}, {}, {"path":os.path}, {"print"})
1052 self.assertEqual(inspect.getclosurevars(f), expected)
1053
Nick Coghlan2f92e542012-06-23 19:39:55 +10001054
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001055class TestGetcallargsFunctions(unittest.TestCase):
1056
1057 def assertEqualCallArgs(self, func, call_params_string, locs=None):
1058 locs = dict(locs or {}, func=func)
1059 r1 = eval('func(%s)' % call_params_string, None, locs)
1060 r2 = eval('inspect.getcallargs(func, %s)' % call_params_string, None,
1061 locs)
1062 self.assertEqual(r1, r2)
1063
1064 def assertEqualException(self, func, call_param_string, locs=None):
1065 locs = dict(locs or {}, func=func)
1066 try:
1067 eval('func(%s)' % call_param_string, None, locs)
1068 except Exception as e:
1069 ex1 = e
1070 else:
1071 self.fail('Exception not raised')
1072 try:
1073 eval('inspect.getcallargs(func, %s)' % call_param_string, None,
1074 locs)
1075 except Exception as e:
1076 ex2 = e
1077 else:
1078 self.fail('Exception not raised')
1079 self.assertIs(type(ex1), type(ex2))
1080 self.assertEqual(str(ex1), str(ex2))
1081 del ex1, ex2
1082
1083 def makeCallable(self, signature):
1084 """Create a function that returns its locals()"""
1085 code = "lambda %s: locals()"
1086 return eval(code % signature)
1087
1088 def test_plain(self):
1089 f = self.makeCallable('a, b=1')
1090 self.assertEqualCallArgs(f, '2')
1091 self.assertEqualCallArgs(f, '2, 3')
1092 self.assertEqualCallArgs(f, 'a=2')
1093 self.assertEqualCallArgs(f, 'b=3, a=2')
1094 self.assertEqualCallArgs(f, '2, b=3')
1095 # expand *iterable / **mapping
1096 self.assertEqualCallArgs(f, '*(2,)')
1097 self.assertEqualCallArgs(f, '*[2]')
1098 self.assertEqualCallArgs(f, '*(2, 3)')
1099 self.assertEqualCallArgs(f, '*[2, 3]')
1100 self.assertEqualCallArgs(f, '**{"a":2}')
1101 self.assertEqualCallArgs(f, 'b=3, **{"a":2}')
1102 self.assertEqualCallArgs(f, '2, **{"b":3}')
1103 self.assertEqualCallArgs(f, '**{"b":3, "a":2}')
1104 # expand UserList / UserDict
1105 self.assertEqualCallArgs(f, '*collections.UserList([2])')
1106 self.assertEqualCallArgs(f, '*collections.UserList([2, 3])')
1107 self.assertEqualCallArgs(f, '**collections.UserDict(a=2)')
1108 self.assertEqualCallArgs(f, '2, **collections.UserDict(b=3)')
1109 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3)')
1110
1111 def test_varargs(self):
1112 f = self.makeCallable('a, b=1, *c')
1113 self.assertEqualCallArgs(f, '2')
1114 self.assertEqualCallArgs(f, '2, 3')
1115 self.assertEqualCallArgs(f, '2, 3, 4')
1116 self.assertEqualCallArgs(f, '*(2,3,4)')
1117 self.assertEqualCallArgs(f, '2, *[3,4]')
1118 self.assertEqualCallArgs(f, '2, 3, *collections.UserList([4])')
1119
1120 def test_varkw(self):
1121 f = self.makeCallable('a, b=1, **c')
1122 self.assertEqualCallArgs(f, 'a=2')
1123 self.assertEqualCallArgs(f, '2, b=3, c=4')
1124 self.assertEqualCallArgs(f, 'b=3, a=2, c=4')
1125 self.assertEqualCallArgs(f, 'c=4, **{"a":2, "b":3}')
1126 self.assertEqualCallArgs(f, '2, c=4, **{"b":3}')
1127 self.assertEqualCallArgs(f, 'b=2, **{"a":3, "c":4}')
1128 self.assertEqualCallArgs(f, '**collections.UserDict(a=2, b=3, c=4)')
1129 self.assertEqualCallArgs(f, '2, c=4, **collections.UserDict(b=3)')
1130 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3, c=4)')
1131
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001132 def test_varkw_only(self):
1133 # issue11256:
1134 f = self.makeCallable('**c')
1135 self.assertEqualCallArgs(f, '')
1136 self.assertEqualCallArgs(f, 'a=1')
1137 self.assertEqualCallArgs(f, 'a=1, b=2')
1138 self.assertEqualCallArgs(f, 'c=3, **{"a": 1, "b": 2}')
1139 self.assertEqualCallArgs(f, '**collections.UserDict(a=1, b=2)')
1140 self.assertEqualCallArgs(f, 'c=3, **collections.UserDict(a=1, b=2)')
1141
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001142 def test_keyword_only(self):
1143 f = self.makeCallable('a=3, *, c, d=2')
1144 self.assertEqualCallArgs(f, 'c=3')
1145 self.assertEqualCallArgs(f, 'c=3, a=3')
1146 self.assertEqualCallArgs(f, 'a=2, c=4')
1147 self.assertEqualCallArgs(f, '4, c=4')
1148 self.assertEqualException(f, '')
1149 self.assertEqualException(f, '3')
1150 self.assertEqualException(f, 'a=3')
1151 self.assertEqualException(f, 'd=4')
1152
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001153 f = self.makeCallable('*, c, d=2')
1154 self.assertEqualCallArgs(f, 'c=3')
1155 self.assertEqualCallArgs(f, 'c=3, d=4')
1156 self.assertEqualCallArgs(f, 'd=4, c=3')
1157
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001158 def test_multiple_features(self):
1159 f = self.makeCallable('a, b=2, *f, **g')
1160 self.assertEqualCallArgs(f, '2, 3, 7')
1161 self.assertEqualCallArgs(f, '2, 3, x=8')
1162 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
1163 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9')
1164 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9')
1165 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
1166 '[2, 3, (4,[5,6])]), **{"y":9, "z":10}')
1167 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
1168 '(4,[5,6])]), **collections.UserDict('
1169 'y=9, z=10)')
1170
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001171 f = self.makeCallable('a, b=2, *f, x, y=99, **g')
1172 self.assertEqualCallArgs(f, '2, 3, x=8')
1173 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
1174 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9, z=10')
1175 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9, z=10')
1176 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
1177 '[2, 3, (4,[5,6])]), q=0, **{"y":9, "z":10}')
1178 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
1179 '(4,[5,6])]), q=0, **collections.UserDict('
1180 'y=9, z=10)')
1181
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001182 def test_errors(self):
1183 f0 = self.makeCallable('')
1184 f1 = self.makeCallable('a, b')
1185 f2 = self.makeCallable('a, b=1')
1186 # f0 takes no arguments
1187 self.assertEqualException(f0, '1')
1188 self.assertEqualException(f0, 'x=1')
1189 self.assertEqualException(f0, '1,x=1')
1190 # f1 takes exactly 2 arguments
1191 self.assertEqualException(f1, '')
1192 self.assertEqualException(f1, '1')
1193 self.assertEqualException(f1, 'a=2')
1194 self.assertEqualException(f1, 'b=3')
1195 # f2 takes at least 1 argument
1196 self.assertEqualException(f2, '')
1197 self.assertEqualException(f2, 'b=3')
1198 for f in f1, f2:
1199 # f1/f2 takes exactly/at most 2 arguments
1200 self.assertEqualException(f, '2, 3, 4')
1201 self.assertEqualException(f, '1, 2, 3, a=1')
1202 self.assertEqualException(f, '2, 3, 4, c=5')
Georg Brandl178e5ea2012-02-21 00:32:36 +01001203 # XXX: success of this one depends on dict order
1204 ## self.assertEqualException(f, '2, 3, 4, a=1, c=5')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001205 # f got an unexpected keyword argument
1206 self.assertEqualException(f, 'c=2')
1207 self.assertEqualException(f, '2, c=3')
1208 self.assertEqualException(f, '2, 3, c=4')
1209 self.assertEqualException(f, '2, c=4, b=3')
1210 self.assertEqualException(f, '**{u"\u03c0\u03b9": 4}')
1211 # f got multiple values for keyword argument
1212 self.assertEqualException(f, '1, a=2')
1213 self.assertEqualException(f, '1, **{"a":2}')
1214 self.assertEqualException(f, '1, 2, b=3')
1215 # XXX: Python inconsistency
1216 # - for functions and bound methods: unexpected keyword 'c'
1217 # - for unbound methods: multiple values for keyword 'a'
1218 #self.assertEqualException(f, '1, c=3, a=2')
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001219 # issue11256:
1220 f3 = self.makeCallable('**c')
1221 self.assertEqualException(f3, '1, 2')
1222 self.assertEqualException(f3, '1, 2, a=1, b=2')
1223 f4 = self.makeCallable('*, a, b=0')
1224 self.assertEqualException(f3, '1, 2')
1225 self.assertEqualException(f3, '1, 2, a=1, b=2')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001226
Yury Selivanov875df202014-03-27 18:23:03 -04001227 # issue #20816: getcallargs() fails to iterate over non-existent
1228 # kwonlydefaults and raises a wrong TypeError
1229 def f5(*, a): pass
1230 with self.assertRaisesRegex(TypeError,
1231 'missing 1 required keyword-only'):
1232 inspect.getcallargs(f5)
1233
1234
Yury Selivanovdccfa132014-03-27 18:42:52 -04001235 # issue20817:
1236 def f6(a, b, c):
1237 pass
1238 with self.assertRaisesRegex(TypeError, "'a', 'b' and 'c'"):
1239 inspect.getcallargs(f6)
1240
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001241class TestGetcallargsMethods(TestGetcallargsFunctions):
1242
1243 def setUp(self):
1244 class Foo(object):
1245 pass
1246 self.cls = Foo
1247 self.inst = Foo()
1248
1249 def makeCallable(self, signature):
1250 assert 'self' not in signature
1251 mk = super(TestGetcallargsMethods, self).makeCallable
1252 self.cls.method = mk('self, ' + signature)
1253 return self.inst.method
1254
1255class TestGetcallargsUnboundMethods(TestGetcallargsMethods):
1256
1257 def makeCallable(self, signature):
1258 super(TestGetcallargsUnboundMethods, self).makeCallable(signature)
1259 return self.cls.method
1260
1261 def assertEqualCallArgs(self, func, call_params_string, locs=None):
1262 return super(TestGetcallargsUnboundMethods, self).assertEqualCallArgs(
1263 *self._getAssertEqualParams(func, call_params_string, locs))
1264
1265 def assertEqualException(self, func, call_params_string, locs=None):
1266 return super(TestGetcallargsUnboundMethods, self).assertEqualException(
1267 *self._getAssertEqualParams(func, call_params_string, locs))
1268
1269 def _getAssertEqualParams(self, func, call_params_string, locs=None):
1270 assert 'inst' not in call_params_string
1271 locs = dict(locs or {}, inst=self.inst)
1272 return (func, 'inst,' + call_params_string, locs)
1273
Michael Foord95fc51d2010-11-20 15:07:30 +00001274
1275class TestGetattrStatic(unittest.TestCase):
1276
1277 def test_basic(self):
1278 class Thing(object):
1279 x = object()
1280
1281 thing = Thing()
1282 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1283 self.assertEqual(inspect.getattr_static(thing, 'x', None), Thing.x)
1284 with self.assertRaises(AttributeError):
1285 inspect.getattr_static(thing, 'y')
1286
1287 self.assertEqual(inspect.getattr_static(thing, 'y', 3), 3)
1288
1289 def test_inherited(self):
1290 class Thing(object):
1291 x = object()
1292 class OtherThing(Thing):
1293 pass
1294
1295 something = OtherThing()
1296 self.assertEqual(inspect.getattr_static(something, 'x'), Thing.x)
1297
1298 def test_instance_attr(self):
1299 class Thing(object):
1300 x = 2
1301 def __init__(self, x):
1302 self.x = x
1303 thing = Thing(3)
1304 self.assertEqual(inspect.getattr_static(thing, 'x'), 3)
1305 del thing.x
1306 self.assertEqual(inspect.getattr_static(thing, 'x'), 2)
1307
1308 def test_property(self):
1309 class Thing(object):
1310 @property
1311 def x(self):
1312 raise AttributeError("I'm pretending not to exist")
1313 thing = Thing()
1314 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1315
Ezio Melotti75cbd732011-04-28 00:59:29 +03001316 def test_descriptor_raises_AttributeError(self):
Michael Foord95fc51d2010-11-20 15:07:30 +00001317 class descriptor(object):
1318 def __get__(*_):
1319 raise AttributeError("I'm pretending not to exist")
1320 desc = descriptor()
1321 class Thing(object):
1322 x = desc
1323 thing = Thing()
1324 self.assertEqual(inspect.getattr_static(thing, 'x'), desc)
1325
1326 def test_classAttribute(self):
1327 class Thing(object):
1328 x = object()
1329
1330 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.x)
1331
Ethan Furmane03ea372013-09-25 07:14:41 -07001332 def test_classVirtualAttribute(self):
1333 class Thing(object):
1334 @types.DynamicClassAttribute
1335 def x(self):
1336 return self._x
1337 _x = object()
1338
1339 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.__dict__['x'])
1340
Michael Foord95fc51d2010-11-20 15:07:30 +00001341 def test_inherited_classattribute(self):
1342 class Thing(object):
1343 x = object()
1344 class OtherThing(Thing):
1345 pass
1346
1347 self.assertEqual(inspect.getattr_static(OtherThing, 'x'), Thing.x)
1348
1349 def test_slots(self):
1350 class Thing(object):
1351 y = 'bar'
1352 __slots__ = ['x']
1353 def __init__(self):
1354 self.x = 'foo'
1355 thing = Thing()
1356 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1357 self.assertEqual(inspect.getattr_static(thing, 'y'), 'bar')
1358
1359 del thing.x
1360 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1361
1362 def test_metaclass(self):
1363 class meta(type):
1364 attr = 'foo'
1365 class Thing(object, metaclass=meta):
1366 pass
1367 self.assertEqual(inspect.getattr_static(Thing, 'attr'), 'foo')
1368
1369 class sub(meta):
1370 pass
1371 class OtherThing(object, metaclass=sub):
1372 x = 3
1373 self.assertEqual(inspect.getattr_static(OtherThing, 'attr'), 'foo')
1374
1375 class OtherOtherThing(OtherThing):
1376 pass
1377 # this test is odd, but it was added as it exposed a bug
1378 self.assertEqual(inspect.getattr_static(OtherOtherThing, 'x'), 3)
1379
1380 def test_no_dict_no_slots(self):
1381 self.assertEqual(inspect.getattr_static(1, 'foo', None), None)
1382 self.assertNotEqual(inspect.getattr_static('foo', 'lower'), None)
1383
1384 def test_no_dict_no_slots_instance_member(self):
1385 # returns descriptor
1386 with open(__file__) as handle:
1387 self.assertEqual(inspect.getattr_static(handle, 'name'), type(handle).name)
1388
1389 def test_inherited_slots(self):
1390 # returns descriptor
1391 class Thing(object):
1392 __slots__ = ['x']
1393 def __init__(self):
1394 self.x = 'foo'
1395
1396 class OtherThing(Thing):
1397 pass
1398 # it would be nice if this worked...
1399 # we get the descriptor instead of the instance attribute
1400 self.assertEqual(inspect.getattr_static(OtherThing(), 'x'), Thing.x)
1401
1402 def test_descriptor(self):
1403 class descriptor(object):
1404 def __get__(self, instance, owner):
1405 return 3
1406 class Foo(object):
1407 d = descriptor()
1408
1409 foo = Foo()
1410
1411 # for a non data descriptor we return the instance attribute
1412 foo.__dict__['d'] = 1
1413 self.assertEqual(inspect.getattr_static(foo, 'd'), 1)
1414
1415 # if the descriptor is a data-desciptor we should return the
1416 # descriptor
1417 descriptor.__set__ = lambda s, i, v: None
1418 self.assertEqual(inspect.getattr_static(foo, 'd'), Foo.__dict__['d'])
1419
1420
1421 def test_metaclass_with_descriptor(self):
1422 class descriptor(object):
1423 def __get__(self, instance, owner):
1424 return 3
1425 class meta(type):
1426 d = descriptor()
1427 class Thing(object, metaclass=meta):
1428 pass
1429 self.assertEqual(inspect.getattr_static(Thing, 'd'), meta.__dict__['d'])
1430
1431
Michael Foordcc7ebb82010-11-20 16:20:16 +00001432 def test_class_as_property(self):
1433 class Base(object):
1434 foo = 3
1435
1436 class Something(Base):
Michael Foord35184ed2010-11-20 16:58:30 +00001437 executed = False
Michael Foordcc7ebb82010-11-20 16:20:16 +00001438 @property
1439 def __class__(self):
Michael Foord35184ed2010-11-20 16:58:30 +00001440 self.executed = True
Michael Foordcc7ebb82010-11-20 16:20:16 +00001441 return object
1442
Michael Foord35184ed2010-11-20 16:58:30 +00001443 instance = Something()
1444 self.assertEqual(inspect.getattr_static(instance, 'foo'), 3)
1445 self.assertFalse(instance.executed)
Michael Foordcc7ebb82010-11-20 16:20:16 +00001446 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1447
Michael Foorde5162652010-11-20 16:40:44 +00001448 def test_mro_as_property(self):
1449 class Meta(type):
1450 @property
1451 def __mro__(self):
1452 return (object,)
1453
1454 class Base(object):
1455 foo = 3
1456
1457 class Something(Base, metaclass=Meta):
1458 pass
1459
1460 self.assertEqual(inspect.getattr_static(Something(), 'foo'), 3)
1461 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1462
Michael Foorddcebe0f2011-03-15 19:20:44 -04001463 def test_dict_as_property(self):
1464 test = self
1465 test.called = False
1466
1467 class Foo(dict):
1468 a = 3
1469 @property
1470 def __dict__(self):
1471 test.called = True
1472 return {}
1473
1474 foo = Foo()
1475 foo.a = 4
1476 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1477 self.assertFalse(test.called)
1478
1479 def test_custom_object_dict(self):
1480 test = self
1481 test.called = False
1482
1483 class Custom(dict):
1484 def get(self, key, default=None):
1485 test.called = True
1486 super().get(key, default)
1487
1488 class Foo(object):
1489 a = 3
1490 foo = Foo()
1491 foo.__dict__ = Custom()
1492 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1493 self.assertFalse(test.called)
1494
1495 def test_metaclass_dict_as_property(self):
1496 class Meta(type):
1497 @property
1498 def __dict__(self):
1499 self.executed = True
1500
1501 class Thing(metaclass=Meta):
1502 executed = False
1503
1504 def __init__(self):
1505 self.spam = 42
1506
1507 instance = Thing()
1508 self.assertEqual(inspect.getattr_static(instance, "spam"), 42)
1509 self.assertFalse(Thing.executed)
Michael Foorde5162652010-11-20 16:40:44 +00001510
Michael Foorda51623b2011-12-18 22:01:40 +00001511 def test_module(self):
1512 sentinel = object()
1513 self.assertIsNot(inspect.getattr_static(sys, "version", sentinel),
1514 sentinel)
1515
Michael Foord3ba95f82011-12-22 01:13:37 +00001516 def test_metaclass_with_metaclass_with_dict_as_property(self):
1517 class MetaMeta(type):
1518 @property
1519 def __dict__(self):
1520 self.executed = True
1521 return dict(spam=42)
1522
1523 class Meta(type, metaclass=MetaMeta):
1524 executed = False
1525
1526 class Thing(metaclass=Meta):
1527 pass
1528
1529 with self.assertRaises(AttributeError):
1530 inspect.getattr_static(Thing, "spam")
1531 self.assertFalse(Thing.executed)
1532
Nick Coghlane0f04652010-11-21 03:44:04 +00001533class TestGetGeneratorState(unittest.TestCase):
1534
1535 def setUp(self):
1536 def number_generator():
1537 for number in range(5):
1538 yield number
1539 self.generator = number_generator()
1540
1541 def _generatorstate(self):
1542 return inspect.getgeneratorstate(self.generator)
1543
1544 def test_created(self):
1545 self.assertEqual(self._generatorstate(), inspect.GEN_CREATED)
1546
1547 def test_suspended(self):
1548 next(self.generator)
1549 self.assertEqual(self._generatorstate(), inspect.GEN_SUSPENDED)
1550
1551 def test_closed_after_exhaustion(self):
1552 for i in self.generator:
1553 pass
1554 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1555
1556 def test_closed_after_immediate_exception(self):
1557 with self.assertRaises(RuntimeError):
1558 self.generator.throw(RuntimeError)
1559 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1560
1561 def test_running(self):
1562 # As mentioned on issue #10220, checking for the RUNNING state only
1563 # makes sense inside the generator itself.
1564 # The following generator checks for this by using the closure's
1565 # reference to self and the generator state checking helper method
1566 def running_check_generator():
1567 for number in range(5):
1568 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1569 yield number
1570 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1571 self.generator = running_check_generator()
1572 # Running up to the first yield
1573 next(self.generator)
1574 # Running after the first yield
1575 next(self.generator)
1576
Nick Coghlan7921b9f2010-11-30 06:36:04 +00001577 def test_easy_debugging(self):
1578 # repr() and str() of a generator state should contain the state name
1579 names = 'GEN_CREATED GEN_RUNNING GEN_SUSPENDED GEN_CLOSED'.split()
1580 for name in names:
1581 state = getattr(inspect, name)
1582 self.assertIn(name, repr(state))
1583 self.assertIn(name, str(state))
1584
Nick Coghlan04e2e3f2012-06-23 19:52:05 +10001585 def test_getgeneratorlocals(self):
1586 def each(lst, a=None):
1587 b=(1, 2, 3)
1588 for v in lst:
1589 if v == 3:
1590 c = 12
1591 yield v
1592
1593 numbers = each([1, 2, 3])
1594 self.assertEqual(inspect.getgeneratorlocals(numbers),
1595 {'a': None, 'lst': [1, 2, 3]})
1596 next(numbers)
1597 self.assertEqual(inspect.getgeneratorlocals(numbers),
1598 {'a': None, 'lst': [1, 2, 3], 'v': 1,
1599 'b': (1, 2, 3)})
1600 next(numbers)
1601 self.assertEqual(inspect.getgeneratorlocals(numbers),
1602 {'a': None, 'lst': [1, 2, 3], 'v': 2,
1603 'b': (1, 2, 3)})
1604 next(numbers)
1605 self.assertEqual(inspect.getgeneratorlocals(numbers),
1606 {'a': None, 'lst': [1, 2, 3], 'v': 3,
1607 'b': (1, 2, 3), 'c': 12})
1608 try:
1609 next(numbers)
1610 except StopIteration:
1611 pass
1612 self.assertEqual(inspect.getgeneratorlocals(numbers), {})
1613
1614 def test_getgeneratorlocals_empty(self):
1615 def yield_one():
1616 yield 1
1617 one = yield_one()
1618 self.assertEqual(inspect.getgeneratorlocals(one), {})
1619 try:
1620 next(one)
1621 except StopIteration:
1622 pass
1623 self.assertEqual(inspect.getgeneratorlocals(one), {})
1624
1625 def test_getgeneratorlocals_error(self):
1626 self.assertRaises(TypeError, inspect.getgeneratorlocals, 1)
1627 self.assertRaises(TypeError, inspect.getgeneratorlocals, lambda x: True)
1628 self.assertRaises(TypeError, inspect.getgeneratorlocals, set)
1629 self.assertRaises(TypeError, inspect.getgeneratorlocals, (2,3))
1630
Nick Coghlane0f04652010-11-21 03:44:04 +00001631
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001632class MySignature(inspect.Signature):
1633 # Top-level to make it picklable;
1634 # used in test_signature_object_pickle
1635 pass
1636
1637class MyParameter(inspect.Parameter):
1638 # Top-level to make it picklable;
1639 # used in test_signature_object_pickle
1640 pass
1641
Nick Coghlanf9e227e2014-08-17 14:01:19 +10001642 @cpython_only
1643 @unittest.skipIf(MISSING_C_DOCSTRINGS,
1644 "Signature information for builtins requires docstrings")
1645 def test_builtins_have_signatures(self):
1646 # This checks all builtin callables in CPython have signatures
1647 # A few have signatures Signature can't yet handle, so we skip those
1648 # since they will have to wait until PEP 457 adds the required
1649 # introspection support to the inspect module
1650 # Some others also haven't been converted yet for various other
1651 # reasons, so we also skip those for the time being, but design
1652 # the test to fail in order to indicate when it needs to be
1653 # updated.
1654 no_signature = set()
1655 # These need PEP 457 groups
1656 needs_groups = ["range", "slice", "dir", "getattr",
1657 "next", "iter", "vars"]
1658 no_signature |= needs_groups
1659 # These need PEP 457 groups or a signature change to accept None
1660 needs_semantic_update = ["round"]
1661 no_signature |= needs_semantic_update
1662 # These need *args support in Argument Clinic
1663 needs_varargs = ["min", "max", "print", "__build_class__"]
1664 no_signature |= needs_varargs
1665 # These simply weren't covered in the initial AC conversion
1666 # for builtin callables
1667 not_converted_yet = ["open", "__import__"]
1668 no_signature |= not_converted_yet
1669 # These builtin types are expected to provide introspection info
1670 types_with_signatures = set()
1671 # Check the signatures we expect to be there
1672 ns = vars(builtins)
1673 for name, obj in sorted(ns.items()):
1674 if not callable(obj):
1675 continue
1676 # The builtin types haven't been converted to AC yet
1677 if isinstance(obj, type) and (name not in types_with_signatures):
1678 # Note that this also skips all the exception types
1679 no_signature.append(name)
1680 if (name in no_signature):
1681 # Not yet converted
1682 continue
1683 with self.subTest(builtin=name):
1684 self.assertIsNotNone(inspect.signature(obj))
1685 # Check callables that haven't been converted don't claim a signature
1686 # This ensures this test will start failing as more signatures are
1687 # added, so the affected items can be moved into the scope of the
1688 # regression test above
1689 for name in no_signature:
1690 with self.subTest(builtin=name):
1691 self.assertIsNone(ns[name].__text_signature__)
1692
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001693
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001694class TestSignatureObject(unittest.TestCase):
1695 @staticmethod
1696 def signature(func):
1697 sig = inspect.signature(func)
1698 return (tuple((param.name,
1699 (... if param.default is param.empty else param.default),
1700 (... if param.annotation is param.empty
1701 else param.annotation),
1702 str(param.kind).lower())
1703 for param in sig.parameters.values()),
1704 (... if sig.return_annotation is sig.empty
1705 else sig.return_annotation))
1706
1707 def test_signature_object(self):
1708 S = inspect.Signature
1709 P = inspect.Parameter
1710
1711 self.assertEqual(str(S()), '()')
1712
Yury Selivanov07a9e452014-01-29 10:58:16 -05001713 def test(po, pk, pod=42, pkd=100, *args, ko, **kwargs):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001714 pass
1715 sig = inspect.signature(test)
1716 po = sig.parameters['po'].replace(kind=P.POSITIONAL_ONLY)
Yury Selivanov07a9e452014-01-29 10:58:16 -05001717 pod = sig.parameters['pod'].replace(kind=P.POSITIONAL_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001718 pk = sig.parameters['pk']
Yury Selivanov07a9e452014-01-29 10:58:16 -05001719 pkd = sig.parameters['pkd']
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001720 args = sig.parameters['args']
1721 ko = sig.parameters['ko']
1722 kwargs = sig.parameters['kwargs']
1723
1724 S((po, pk, args, ko, kwargs))
1725
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001726 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001727 S((pk, po, args, ko, kwargs))
1728
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001729 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001730 S((po, args, pk, ko, kwargs))
1731
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001732 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001733 S((args, po, pk, ko, kwargs))
1734
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001735 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001736 S((po, pk, args, kwargs, ko))
1737
1738 kwargs2 = kwargs.replace(name='args')
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001739 with self.assertRaisesRegex(ValueError, 'duplicate parameter name'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001740 S((po, pk, args, kwargs2, ko))
1741
Yury Selivanov07a9e452014-01-29 10:58:16 -05001742 with self.assertRaisesRegex(ValueError, 'follows default argument'):
1743 S((pod, po))
1744
1745 with self.assertRaisesRegex(ValueError, 'follows default argument'):
1746 S((po, pkd, pk))
1747
1748 with self.assertRaisesRegex(ValueError, 'follows default argument'):
1749 S((pkd, pk))
1750
Yury Selivanov374375d2014-03-27 12:41:53 -04001751 self.assertTrue(repr(sig).startswith('<Signature'))
1752 self.assertTrue('"(po, pk' in repr(sig))
1753
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001754 def test_signature_object_pickle(self):
1755 def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
1756 foo_partial = functools.partial(foo, a=1)
1757
1758 sig = inspect.signature(foo_partial)
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001759
1760 for ver in range(pickle.HIGHEST_PROTOCOL + 1):
1761 with self.subTest(pickle_ver=ver, subclass=False):
1762 sig_pickled = pickle.loads(pickle.dumps(sig, ver))
1763 self.assertEqual(sig, sig_pickled)
Yury Selivanova5d63dd2014-03-27 11:31:43 -04001764
1765 # Test that basic sub-classing works
1766 sig = inspect.signature(foo)
1767 myparam = MyParameter(name='z', kind=inspect.Parameter.POSITIONAL_ONLY)
1768 myparams = collections.OrderedDict(sig.parameters, a=myparam)
1769 mysig = MySignature().replace(parameters=myparams.values(),
1770 return_annotation=sig.return_annotation)
1771 self.assertTrue(isinstance(mysig, MySignature))
1772 self.assertTrue(isinstance(mysig.parameters['z'], MyParameter))
1773
1774 for ver in range(pickle.HIGHEST_PROTOCOL + 1):
1775 with self.subTest(pickle_ver=ver, subclass=True):
1776 sig_pickled = pickle.loads(pickle.dumps(mysig, ver))
1777 self.assertEqual(mysig, sig_pickled)
1778 self.assertTrue(isinstance(sig_pickled, MySignature))
1779 self.assertTrue(isinstance(sig_pickled.parameters['z'],
1780 MyParameter))
1781
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001782 def test_signature_immutability(self):
1783 def test(a):
1784 pass
1785 sig = inspect.signature(test)
1786
1787 with self.assertRaises(AttributeError):
1788 sig.foo = 'bar'
1789
1790 with self.assertRaises(TypeError):
1791 sig.parameters['a'] = None
1792
1793 def test_signature_on_noarg(self):
1794 def test():
1795 pass
1796 self.assertEqual(self.signature(test), ((), ...))
1797
1798 def test_signature_on_wargs(self):
1799 def test(a, b:'foo') -> 123:
1800 pass
1801 self.assertEqual(self.signature(test),
1802 ((('a', ..., ..., "positional_or_keyword"),
1803 ('b', ..., 'foo', "positional_or_keyword")),
1804 123))
1805
1806 def test_signature_on_wkwonly(self):
1807 def test(*, a:float, b:str) -> int:
1808 pass
1809 self.assertEqual(self.signature(test),
1810 ((('a', ..., float, "keyword_only"),
1811 ('b', ..., str, "keyword_only")),
1812 int))
1813
1814 def test_signature_on_complex_args(self):
1815 def test(a, b:'foo'=10, *args:'bar', spam:'baz', ham=123, **kwargs:int):
1816 pass
1817 self.assertEqual(self.signature(test),
1818 ((('a', ..., ..., "positional_or_keyword"),
1819 ('b', 10, 'foo', "positional_or_keyword"),
1820 ('args', ..., 'bar', "var_positional"),
1821 ('spam', ..., 'baz', "keyword_only"),
1822 ('ham', 123, ..., "keyword_only"),
1823 ('kwargs', ..., int, "var_keyword")),
1824 ...))
1825
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02001826 @cpython_only
Larry Hastingsfcafe432013-11-23 17:35:48 -08001827 @unittest.skipIf(MISSING_C_DOCSTRINGS,
1828 "Signature information for builtins requires docstrings")
1829 def test_signature_on_builtins(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02001830 import _testcapi
Larry Hastings16c51912014-01-07 11:53:01 -08001831
Larry Hastings5c661892014-01-24 06:17:25 -08001832 def test_unbound_method(o):
1833 """Use this to test unbound methods (things that should have a self)"""
1834 signature = inspect.signature(o)
1835 self.assertTrue(isinstance(signature, inspect.Signature))
1836 self.assertEqual(list(signature.parameters.values())[0].name, 'self')
1837 return signature
1838
1839 def test_callable(o):
1840 """Use this to test bound methods or normal callables (things that don't expect self)"""
1841 signature = inspect.signature(o)
1842 self.assertTrue(isinstance(signature, inspect.Signature))
1843 if signature.parameters:
1844 self.assertNotEqual(list(signature.parameters.values())[0].name, 'self')
1845 return signature
1846
1847 signature = test_callable(_testcapi.docstring_with_signature_with_defaults)
Larry Hastings16c51912014-01-07 11:53:01 -08001848 def p(name): return signature.parameters[name].default
1849 self.assertEqual(p('s'), 'avocado')
Larry Hastings2a727912014-01-16 11:32:01 -08001850 self.assertEqual(p('b'), b'bytes')
Larry Hastings16c51912014-01-07 11:53:01 -08001851 self.assertEqual(p('d'), 3.14)
1852 self.assertEqual(p('i'), 35)
Larry Hastings16c51912014-01-07 11:53:01 -08001853 self.assertEqual(p('n'), None)
1854 self.assertEqual(p('t'), True)
1855 self.assertEqual(p('f'), False)
Larry Hastings2a727912014-01-16 11:32:01 -08001856 self.assertEqual(p('local'), 3)
1857 self.assertEqual(p('sys'), sys.maxsize)
1858 self.assertEqual(p('exp'), sys.maxsize - 1)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001859
Larry Hastings5c661892014-01-24 06:17:25 -08001860 test_callable(object)
1861
1862 # normal method
1863 # (PyMethodDescr_Type, "method_descriptor")
1864 test_unbound_method(_pickle.Pickler.dump)
1865 d = _pickle.Pickler(io.StringIO())
1866 test_callable(d.dump)
1867
1868 # static method
1869 test_callable(str.maketrans)
1870 test_callable('abc'.maketrans)
1871
1872 # class method
1873 test_callable(dict.fromkeys)
1874 test_callable({}.fromkeys)
1875
1876 # wrapper around slot (PyWrapperDescr_Type, "wrapper_descriptor")
1877 test_unbound_method(type.__call__)
1878 test_unbound_method(int.__add__)
1879 test_callable((3).__add__)
1880
1881 # _PyMethodWrapper_Type
1882 # support for 'method-wrapper'
1883 test_callable(min.__call__)
1884
Larry Hastings2623c8c2014-02-08 22:15:29 -08001885 # This doesn't work now.
1886 # (We don't have a valid signature for "type" in 3.4)
1887 with self.assertRaisesRegex(ValueError, "no signature found"):
1888 class ThisWorksNow:
1889 __call__ = type
1890 test_callable(ThisWorksNow())
Larry Hastings5c661892014-01-24 06:17:25 -08001891
Yury Selivanov056e2652014-03-02 12:25:27 -05001892 # Regression test for issue #20786
1893 test_unbound_method(dict.__delitem__)
1894 test_unbound_method(property.__delete__)
1895
1896
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02001897 @cpython_only
Yury Selivanov76c6c592014-01-29 10:52:57 -05001898 @unittest.skipIf(MISSING_C_DOCSTRINGS,
1899 "Signature information for builtins requires docstrings")
1900 def test_signature_on_decorated_builtins(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02001901 import _testcapi
Yury Selivanov76c6c592014-01-29 10:52:57 -05001902 func = _testcapi.docstring_with_signature_with_defaults
1903
1904 def decorator(func):
1905 @functools.wraps(func)
1906 def wrapper(*args, **kwargs) -> int:
1907 return func(*args, **kwargs)
1908 return wrapper
1909
1910 decorated_func = decorator(func)
1911
1912 self.assertEqual(inspect.signature(func),
1913 inspect.signature(decorated_func))
Larry Hastings5c661892014-01-24 06:17:25 -08001914
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02001915 @cpython_only
Larry Hastings5c661892014-01-24 06:17:25 -08001916 def test_signature_on_builtins_no_signature(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02001917 import _testcapi
Larry Hastings5c661892014-01-24 06:17:25 -08001918 with self.assertRaisesRegex(ValueError, 'no signature found for builtin'):
1919 inspect.signature(_testcapi.docstring_no_signature)
1920
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001921 def test_signature_on_non_function(self):
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001922 with self.assertRaisesRegex(TypeError, 'is not a callable object'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001923 inspect.signature(42)
1924
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001925 with self.assertRaisesRegex(TypeError, 'is not a Python function'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001926 inspect.Signature.from_function(42)
1927
Yury Selivanovb77511d2014-01-29 10:46:14 -05001928 def test_signature_from_builtin_errors(self):
1929 with self.assertRaisesRegex(TypeError, 'is not a Python builtin'):
1930 inspect.Signature.from_builtin(42)
1931
Yury Selivanov63da7c72014-01-31 14:48:37 -05001932 def test_signature_from_functionlike_object(self):
1933 def func(a,b, *args, kwonly=True, kwonlyreq, **kwargs):
1934 pass
1935
1936 class funclike:
1937 # Has to be callable, and have correct
1938 # __code__, __annotations__, __defaults__, __name__,
1939 # and __kwdefaults__ attributes
1940
1941 def __init__(self, func):
1942 self.__name__ = func.__name__
1943 self.__code__ = func.__code__
1944 self.__annotations__ = func.__annotations__
1945 self.__defaults__ = func.__defaults__
1946 self.__kwdefaults__ = func.__kwdefaults__
1947 self.func = func
1948
1949 def __call__(self, *args, **kwargs):
1950 return self.func(*args, **kwargs)
1951
1952 sig_func = inspect.Signature.from_function(func)
1953
1954 sig_funclike = inspect.Signature.from_function(funclike(func))
1955 self.assertEqual(sig_funclike, sig_func)
1956
1957 sig_funclike = inspect.signature(funclike(func))
1958 self.assertEqual(sig_funclike, sig_func)
1959
1960 # If object is not a duck type of function, then
1961 # signature will try to get a signature for its '__call__'
1962 # method
1963 fl = funclike(func)
1964 del fl.__defaults__
1965 self.assertEqual(self.signature(fl),
1966 ((('args', ..., ..., "var_positional"),
1967 ('kwargs', ..., ..., "var_keyword")),
1968 ...))
1969
Yury Selivanova773de02014-02-21 18:30:53 -05001970 # Test with cython-like builtins:
1971 _orig_isdesc = inspect.ismethoddescriptor
1972 def _isdesc(obj):
1973 if hasattr(obj, '_builtinmock'):
1974 return True
1975 return _orig_isdesc(obj)
1976
1977 with unittest.mock.patch('inspect.ismethoddescriptor', _isdesc):
1978 builtin_func = funclike(func)
1979 # Make sure that our mock setup is working
1980 self.assertFalse(inspect.ismethoddescriptor(builtin_func))
1981 builtin_func._builtinmock = True
1982 self.assertTrue(inspect.ismethoddescriptor(builtin_func))
1983 self.assertEqual(inspect.signature(builtin_func), sig_func)
1984
Yury Selivanov63da7c72014-01-31 14:48:37 -05001985 def test_signature_functionlike_class(self):
1986 # We only want to duck type function-like objects,
1987 # not classes.
1988
1989 def func(a,b, *args, kwonly=True, kwonlyreq, **kwargs):
1990 pass
1991
1992 class funclike:
1993 def __init__(self, marker):
1994 pass
1995
1996 __name__ = func.__name__
1997 __code__ = func.__code__
1998 __annotations__ = func.__annotations__
1999 __defaults__ = func.__defaults__
2000 __kwdefaults__ = func.__kwdefaults__
2001
2002 with self.assertRaisesRegex(TypeError, 'is not a Python function'):
2003 inspect.Signature.from_function(funclike)
2004
2005 self.assertEqual(str(inspect.signature(funclike)), '(marker)')
2006
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002007 def test_signature_on_method(self):
2008 class Test:
Yury Selivanov62560fb2014-01-28 12:26:24 -05002009 def __init__(*args):
2010 pass
2011 def m1(self, arg1, arg2=1) -> int:
2012 pass
2013 def m2(*args):
2014 pass
2015 def __call__(*, a):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002016 pass
2017
Yury Selivanov62560fb2014-01-28 12:26:24 -05002018 self.assertEqual(self.signature(Test().m1),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002019 ((('arg1', ..., ..., "positional_or_keyword"),
2020 ('arg2', 1, ..., "positional_or_keyword")),
2021 int))
2022
Yury Selivanov62560fb2014-01-28 12:26:24 -05002023 self.assertEqual(self.signature(Test().m2),
2024 ((('args', ..., ..., "var_positional"),),
2025 ...))
2026
2027 self.assertEqual(self.signature(Test),
2028 ((('args', ..., ..., "var_positional"),),
2029 ...))
2030
2031 with self.assertRaisesRegex(ValueError, 'invalid method signature'):
2032 self.signature(Test())
2033
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002034 def test_signature_on_classmethod(self):
2035 class Test:
2036 @classmethod
2037 def foo(cls, arg1, *, arg2=1):
2038 pass
2039
2040 meth = Test().foo
2041 self.assertEqual(self.signature(meth),
2042 ((('arg1', ..., ..., "positional_or_keyword"),
2043 ('arg2', 1, ..., "keyword_only")),
2044 ...))
2045
2046 meth = Test.foo
2047 self.assertEqual(self.signature(meth),
2048 ((('arg1', ..., ..., "positional_or_keyword"),
2049 ('arg2', 1, ..., "keyword_only")),
2050 ...))
2051
2052 def test_signature_on_staticmethod(self):
2053 class Test:
2054 @staticmethod
2055 def foo(cls, *, arg):
2056 pass
2057
2058 meth = Test().foo
2059 self.assertEqual(self.signature(meth),
2060 ((('cls', ..., ..., "positional_or_keyword"),
2061 ('arg', ..., ..., "keyword_only")),
2062 ...))
2063
2064 meth = Test.foo
2065 self.assertEqual(self.signature(meth),
2066 ((('cls', ..., ..., "positional_or_keyword"),
2067 ('arg', ..., ..., "keyword_only")),
2068 ...))
2069
2070 def test_signature_on_partial(self):
2071 from functools import partial
2072
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002073 Parameter = inspect.Parameter
2074
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002075 def test():
2076 pass
2077
2078 self.assertEqual(self.signature(partial(test)), ((), ...))
2079
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002080 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002081 inspect.signature(partial(test, 1))
2082
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002083 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002084 inspect.signature(partial(test, a=1))
2085
2086 def test(a, b, *, c, d):
2087 pass
2088
2089 self.assertEqual(self.signature(partial(test)),
2090 ((('a', ..., ..., "positional_or_keyword"),
2091 ('b', ..., ..., "positional_or_keyword"),
2092 ('c', ..., ..., "keyword_only"),
2093 ('d', ..., ..., "keyword_only")),
2094 ...))
2095
2096 self.assertEqual(self.signature(partial(test, 1)),
2097 ((('b', ..., ..., "positional_or_keyword"),
2098 ('c', ..., ..., "keyword_only"),
2099 ('d', ..., ..., "keyword_only")),
2100 ...))
2101
2102 self.assertEqual(self.signature(partial(test, 1, c=2)),
2103 ((('b', ..., ..., "positional_or_keyword"),
2104 ('c', 2, ..., "keyword_only"),
2105 ('d', ..., ..., "keyword_only")),
2106 ...))
2107
2108 self.assertEqual(self.signature(partial(test, b=1, c=2)),
2109 ((('a', ..., ..., "positional_or_keyword"),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002110 ('b', 1, ..., "keyword_only"),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002111 ('c', 2, ..., "keyword_only"),
2112 ('d', ..., ..., "keyword_only")),
2113 ...))
2114
2115 self.assertEqual(self.signature(partial(test, 0, b=1, c=2)),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002116 ((('b', 1, ..., "keyword_only"),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002117 ('c', 2, ..., "keyword_only"),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002118 ('d', ..., ..., "keyword_only")),
2119 ...))
2120
2121 self.assertEqual(self.signature(partial(test, a=1)),
2122 ((('a', 1, ..., "keyword_only"),
2123 ('b', ..., ..., "keyword_only"),
2124 ('c', ..., ..., "keyword_only"),
2125 ('d', ..., ..., "keyword_only")),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002126 ...))
2127
2128 def test(a, *args, b, **kwargs):
2129 pass
2130
2131 self.assertEqual(self.signature(partial(test, 1)),
2132 ((('args', ..., ..., "var_positional"),
2133 ('b', ..., ..., "keyword_only"),
2134 ('kwargs', ..., ..., "var_keyword")),
2135 ...))
2136
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002137 self.assertEqual(self.signature(partial(test, a=1)),
2138 ((('a', 1, ..., "keyword_only"),
2139 ('b', ..., ..., "keyword_only"),
2140 ('kwargs', ..., ..., "var_keyword")),
2141 ...))
2142
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002143 self.assertEqual(self.signature(partial(test, 1, 2, 3)),
2144 ((('args', ..., ..., "var_positional"),
2145 ('b', ..., ..., "keyword_only"),
2146 ('kwargs', ..., ..., "var_keyword")),
2147 ...))
2148
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002149 self.assertEqual(self.signature(partial(test, 1, 2, 3, test=True)),
2150 ((('args', ..., ..., "var_positional"),
2151 ('b', ..., ..., "keyword_only"),
2152 ('kwargs', ..., ..., "var_keyword")),
2153 ...))
2154
2155 self.assertEqual(self.signature(partial(test, 1, 2, 3, test=1, b=0)),
2156 ((('args', ..., ..., "var_positional"),
2157 ('b', 0, ..., "keyword_only"),
2158 ('kwargs', ..., ..., "var_keyword")),
2159 ...))
2160
2161 self.assertEqual(self.signature(partial(test, b=0)),
2162 ((('a', ..., ..., "positional_or_keyword"),
2163 ('args', ..., ..., "var_positional"),
2164 ('b', 0, ..., "keyword_only"),
2165 ('kwargs', ..., ..., "var_keyword")),
2166 ...))
2167
2168 self.assertEqual(self.signature(partial(test, b=0, test=1)),
2169 ((('a', ..., ..., "positional_or_keyword"),
2170 ('args', ..., ..., "var_positional"),
2171 ('b', 0, ..., "keyword_only"),
2172 ('kwargs', ..., ..., "var_keyword")),
2173 ...))
2174
2175 def test(a, b, c:int) -> 42:
2176 pass
2177
2178 sig = test.__signature__ = inspect.signature(test)
2179
2180 self.assertEqual(self.signature(partial(partial(test, 1))),
2181 ((('b', ..., ..., "positional_or_keyword"),
2182 ('c', ..., int, "positional_or_keyword")),
2183 42))
2184
2185 self.assertEqual(self.signature(partial(partial(test, 1), 2)),
2186 ((('c', ..., int, "positional_or_keyword"),),
2187 42))
2188
2189 psig = inspect.signature(partial(partial(test, 1), 2))
2190
2191 def foo(a):
2192 return a
2193 _foo = partial(partial(foo, a=10), a=20)
2194 self.assertEqual(self.signature(_foo),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002195 ((('a', 20, ..., "keyword_only"),),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002196 ...))
2197 # check that we don't have any side-effects in signature(),
2198 # and the partial object is still functioning
2199 self.assertEqual(_foo(), 20)
2200
2201 def foo(a, b, c):
2202 return a, b, c
2203 _foo = partial(partial(foo, 1, b=20), b=30)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002204
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002205 self.assertEqual(self.signature(_foo),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002206 ((('b', 30, ..., "keyword_only"),
2207 ('c', ..., ..., "keyword_only")),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002208 ...))
2209 self.assertEqual(_foo(c=10), (1, 30, 10))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002210
2211 def foo(a, b, c, *, d):
2212 return a, b, c, d
2213 _foo = partial(partial(foo, d=20, c=20), b=10, d=30)
2214 self.assertEqual(self.signature(_foo),
2215 ((('a', ..., ..., "positional_or_keyword"),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002216 ('b', 10, ..., "keyword_only"),
2217 ('c', 20, ..., "keyword_only"),
2218 ('d', 30, ..., "keyword_only"),
2219 ),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002220 ...))
2221 ba = inspect.signature(_foo).bind(a=200, b=11)
2222 self.assertEqual(_foo(*ba.args, **ba.kwargs), (200, 11, 20, 30))
2223
2224 def foo(a=1, b=2, c=3):
2225 return a, b, c
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002226 _foo = partial(foo, c=13) # (a=1, b=2, *, c=13)
2227
2228 ba = inspect.signature(_foo).bind(a=11)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002229 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 2, 13))
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002230
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002231 ba = inspect.signature(_foo).bind(11, 12)
2232 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002233
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002234 ba = inspect.signature(_foo).bind(11, b=12)
2235 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002236
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002237 ba = inspect.signature(_foo).bind(b=12)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002238 self.assertEqual(_foo(*ba.args, **ba.kwargs), (1, 12, 13))
2239
2240 _foo = partial(_foo, b=10, c=20)
2241 ba = inspect.signature(_foo).bind(12)
2242 self.assertEqual(_foo(*ba.args, **ba.kwargs), (12, 10, 20))
2243
2244
2245 def foo(a, b, c, d, **kwargs):
2246 pass
2247 sig = inspect.signature(foo)
2248 params = sig.parameters.copy()
2249 params['a'] = params['a'].replace(kind=Parameter.POSITIONAL_ONLY)
2250 params['b'] = params['b'].replace(kind=Parameter.POSITIONAL_ONLY)
2251 foo.__signature__ = inspect.Signature(params.values())
2252 sig = inspect.signature(foo)
2253 self.assertEqual(str(sig), '(a, b, /, c, d, **kwargs)')
2254
2255 self.assertEqual(self.signature(partial(foo, 1)),
2256 ((('b', ..., ..., 'positional_only'),
2257 ('c', ..., ..., 'positional_or_keyword'),
2258 ('d', ..., ..., 'positional_or_keyword'),
2259 ('kwargs', ..., ..., 'var_keyword')),
2260 ...))
2261
2262 self.assertEqual(self.signature(partial(foo, 1, 2)),
2263 ((('c', ..., ..., 'positional_or_keyword'),
2264 ('d', ..., ..., 'positional_or_keyword'),
2265 ('kwargs', ..., ..., 'var_keyword')),
2266 ...))
2267
2268 self.assertEqual(self.signature(partial(foo, 1, 2, 3)),
2269 ((('d', ..., ..., 'positional_or_keyword'),
2270 ('kwargs', ..., ..., 'var_keyword')),
2271 ...))
2272
2273 self.assertEqual(self.signature(partial(foo, 1, 2, c=3)),
2274 ((('c', 3, ..., 'keyword_only'),
2275 ('d', ..., ..., 'keyword_only'),
2276 ('kwargs', ..., ..., 'var_keyword')),
2277 ...))
2278
2279 self.assertEqual(self.signature(partial(foo, 1, c=3)),
2280 ((('b', ..., ..., 'positional_only'),
2281 ('c', 3, ..., 'keyword_only'),
2282 ('d', ..., ..., 'keyword_only'),
2283 ('kwargs', ..., ..., 'var_keyword')),
2284 ...))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002285
Yury Selivanovda5fe4f2014-01-27 17:28:37 -05002286 def test_signature_on_partialmethod(self):
2287 from functools import partialmethod
2288
2289 class Spam:
2290 def test():
2291 pass
2292 ham = partialmethod(test)
2293
2294 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
2295 inspect.signature(Spam.ham)
2296
2297 class Spam:
2298 def test(it, a, *, c) -> 'spam':
2299 pass
2300 ham = partialmethod(test, c=1)
2301
2302 self.assertEqual(self.signature(Spam.ham),
2303 ((('it', ..., ..., 'positional_or_keyword'),
2304 ('a', ..., ..., 'positional_or_keyword'),
2305 ('c', 1, ..., 'keyword_only')),
2306 'spam'))
2307
2308 self.assertEqual(self.signature(Spam().ham),
2309 ((('a', ..., ..., 'positional_or_keyword'),
2310 ('c', 1, ..., 'keyword_only')),
2311 'spam'))
2312
Yury Selivanov0486f812014-01-29 12:18:59 -05002313 def test_signature_on_fake_partialmethod(self):
2314 def foo(a): pass
2315 foo._partialmethod = 'spam'
2316 self.assertEqual(str(inspect.signature(foo)), '(a)')
2317
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002318 def test_signature_on_decorated(self):
2319 import functools
2320
2321 def decorator(func):
2322 @functools.wraps(func)
2323 def wrapper(*args, **kwargs) -> int:
2324 return func(*args, **kwargs)
2325 return wrapper
2326
2327 class Foo:
2328 @decorator
2329 def bar(self, a, b):
2330 pass
2331
2332 self.assertEqual(self.signature(Foo.bar),
2333 ((('self', ..., ..., "positional_or_keyword"),
2334 ('a', ..., ..., "positional_or_keyword"),
2335 ('b', ..., ..., "positional_or_keyword")),
2336 ...))
2337
2338 self.assertEqual(self.signature(Foo().bar),
2339 ((('a', ..., ..., "positional_or_keyword"),
2340 ('b', ..., ..., "positional_or_keyword")),
2341 ...))
2342
2343 # Test that we handle method wrappers correctly
2344 def decorator(func):
2345 @functools.wraps(func)
2346 def wrapper(*args, **kwargs) -> int:
2347 return func(42, *args, **kwargs)
2348 sig = inspect.signature(func)
2349 new_params = tuple(sig.parameters.values())[1:]
2350 wrapper.__signature__ = sig.replace(parameters=new_params)
2351 return wrapper
2352
2353 class Foo:
2354 @decorator
2355 def __call__(self, a, b):
2356 pass
2357
2358 self.assertEqual(self.signature(Foo.__call__),
2359 ((('a', ..., ..., "positional_or_keyword"),
2360 ('b', ..., ..., "positional_or_keyword")),
2361 ...))
2362
2363 self.assertEqual(self.signature(Foo().__call__),
2364 ((('b', ..., ..., "positional_or_keyword"),),
2365 ...))
2366
Nick Coghlane8c45d62013-07-28 20:00:01 +10002367 # Test we handle __signature__ partway down the wrapper stack
2368 def wrapped_foo_call():
2369 pass
2370 wrapped_foo_call.__wrapped__ = Foo.__call__
2371
2372 self.assertEqual(self.signature(wrapped_foo_call),
2373 ((('a', ..., ..., "positional_or_keyword"),
2374 ('b', ..., ..., "positional_or_keyword")),
2375 ...))
2376
2377
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002378 def test_signature_on_class(self):
2379 class C:
2380 def __init__(self, a):
2381 pass
2382
2383 self.assertEqual(self.signature(C),
2384 ((('a', ..., ..., "positional_or_keyword"),),
2385 ...))
2386
2387 class CM(type):
2388 def __call__(cls, a):
2389 pass
2390 class C(metaclass=CM):
2391 def __init__(self, b):
2392 pass
2393
2394 self.assertEqual(self.signature(C),
2395 ((('a', ..., ..., "positional_or_keyword"),),
2396 ...))
2397
2398 class CM(type):
2399 def __new__(mcls, name, bases, dct, *, foo=1):
2400 return super().__new__(mcls, name, bases, dct)
2401 class C(metaclass=CM):
2402 def __init__(self, b):
2403 pass
2404
2405 self.assertEqual(self.signature(C),
2406 ((('b', ..., ..., "positional_or_keyword"),),
2407 ...))
2408
2409 self.assertEqual(self.signature(CM),
2410 ((('name', ..., ..., "positional_or_keyword"),
2411 ('bases', ..., ..., "positional_or_keyword"),
2412 ('dct', ..., ..., "positional_or_keyword"),
2413 ('foo', 1, ..., "keyword_only")),
2414 ...))
2415
2416 class CMM(type):
2417 def __new__(mcls, name, bases, dct, *, foo=1):
2418 return super().__new__(mcls, name, bases, dct)
2419 def __call__(cls, nm, bs, dt):
2420 return type(nm, bs, dt)
2421 class CM(type, metaclass=CMM):
2422 def __new__(mcls, name, bases, dct, *, bar=2):
2423 return super().__new__(mcls, name, bases, dct)
2424 class C(metaclass=CM):
2425 def __init__(self, b):
2426 pass
2427
2428 self.assertEqual(self.signature(CMM),
2429 ((('name', ..., ..., "positional_or_keyword"),
2430 ('bases', ..., ..., "positional_or_keyword"),
2431 ('dct', ..., ..., "positional_or_keyword"),
2432 ('foo', 1, ..., "keyword_only")),
2433 ...))
2434
2435 self.assertEqual(self.signature(CM),
2436 ((('nm', ..., ..., "positional_or_keyword"),
2437 ('bs', ..., ..., "positional_or_keyword"),
2438 ('dt', ..., ..., "positional_or_keyword")),
2439 ...))
2440
2441 self.assertEqual(self.signature(C),
2442 ((('b', ..., ..., "positional_or_keyword"),),
2443 ...))
2444
2445 class CM(type):
2446 def __init__(cls, name, bases, dct, *, bar=2):
2447 return super().__init__(name, bases, dct)
2448 class C(metaclass=CM):
2449 def __init__(self, b):
2450 pass
2451
2452 self.assertEqual(self.signature(CM),
2453 ((('name', ..., ..., "positional_or_keyword"),
2454 ('bases', ..., ..., "positional_or_keyword"),
2455 ('dct', ..., ..., "positional_or_keyword"),
2456 ('bar', 2, ..., "keyword_only")),
2457 ...))
2458
Yury Selivanov145dff82014-02-01 13:49:29 -05002459 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2460 "Signature information for builtins requires docstrings")
2461 def test_signature_on_class_without_init(self):
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002462 # Test classes without user-defined __init__ or __new__
2463 class C: pass
2464 self.assertEqual(str(inspect.signature(C)), '()')
2465 class D(C): pass
2466 self.assertEqual(str(inspect.signature(D)), '()')
2467
2468 # Test meta-classes without user-defined __init__ or __new__
2469 class C(type): pass
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002470 class D(C): pass
Larry Hastings2623c8c2014-02-08 22:15:29 -08002471 with self.assertRaisesRegex(ValueError, "callable.*is not supported"):
2472 self.assertEqual(inspect.signature(C), None)
2473 with self.assertRaisesRegex(ValueError, "callable.*is not supported"):
2474 self.assertEqual(inspect.signature(D), None)
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002475
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002476 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2477 "Signature information for builtins requires docstrings")
2478 def test_signature_on_builtin_class(self):
2479 self.assertEqual(str(inspect.signature(_pickle.Pickler)),
2480 '(file, protocol=None, fix_imports=True)')
2481
2482 class P(_pickle.Pickler): pass
2483 class EmptyTrait: pass
2484 class P2(EmptyTrait, P): pass
2485 self.assertEqual(str(inspect.signature(P)),
2486 '(file, protocol=None, fix_imports=True)')
2487 self.assertEqual(str(inspect.signature(P2)),
2488 '(file, protocol=None, fix_imports=True)')
2489
2490 class P3(P2):
2491 def __init__(self, spam):
2492 pass
2493 self.assertEqual(str(inspect.signature(P3)), '(spam)')
2494
2495 class MetaP(type):
2496 def __call__(cls, foo, bar):
2497 pass
2498 class P4(P2, metaclass=MetaP):
2499 pass
2500 self.assertEqual(str(inspect.signature(P4)), '(foo, bar)')
2501
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002502 def test_signature_on_callable_objects(self):
2503 class Foo:
2504 def __call__(self, a):
2505 pass
2506
2507 self.assertEqual(self.signature(Foo()),
2508 ((('a', ..., ..., "positional_or_keyword"),),
2509 ...))
2510
2511 class Spam:
2512 pass
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002513 with self.assertRaisesRegex(TypeError, "is not a callable object"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002514 inspect.signature(Spam())
2515
2516 class Bar(Spam, Foo):
2517 pass
2518
2519 self.assertEqual(self.signature(Bar()),
2520 ((('a', ..., ..., "positional_or_keyword"),),
2521 ...))
2522
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002523 class Wrapped:
2524 pass
2525 Wrapped.__wrapped__ = lambda a: None
2526 self.assertEqual(self.signature(Wrapped),
2527 ((('a', ..., ..., "positional_or_keyword"),),
2528 ...))
Nick Coghlane8c45d62013-07-28 20:00:01 +10002529 # wrapper loop:
2530 Wrapped.__wrapped__ = Wrapped
2531 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
2532 self.signature(Wrapped)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002533
2534 def test_signature_on_lambdas(self):
2535 self.assertEqual(self.signature((lambda a=10: a)),
2536 ((('a', 10, ..., "positional_or_keyword"),),
2537 ...))
2538
2539 def test_signature_equality(self):
2540 def foo(a, *, b:int) -> float: pass
2541 self.assertNotEqual(inspect.signature(foo), 42)
2542
2543 def bar(a, *, b:int) -> float: pass
2544 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002545 self.assertEqual(
2546 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002547
2548 def bar(a, *, b:int) -> int: pass
2549 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002550 self.assertNotEqual(
2551 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002552
2553 def bar(a, *, b:int): pass
2554 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002555 self.assertNotEqual(
2556 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002557
2558 def bar(a, *, b:int=42) -> float: pass
2559 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002560 self.assertNotEqual(
2561 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002562
2563 def bar(a, *, c) -> float: pass
2564 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002565 self.assertNotEqual(
2566 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002567
2568 def bar(a, b:int) -> float: pass
2569 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002570 self.assertNotEqual(
2571 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002572 def spam(b:int, a) -> float: pass
2573 self.assertNotEqual(inspect.signature(spam), inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002574 self.assertNotEqual(
2575 hash(inspect.signature(spam)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002576
2577 def foo(*, a, b, c): pass
2578 def bar(*, c, b, a): pass
2579 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002580 self.assertEqual(
2581 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002582
2583 def foo(*, a=1, b, c): pass
2584 def bar(*, c, b, a=1): pass
2585 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002586 self.assertEqual(
2587 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002588
2589 def foo(pos, *, a=1, b, c): pass
2590 def bar(pos, *, c, b, a=1): pass
2591 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002592 self.assertEqual(
2593 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002594
2595 def foo(pos, *, a, b, c): pass
2596 def bar(pos, *, c, b, a=1): pass
2597 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002598 self.assertNotEqual(
2599 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002600
2601 def foo(pos, *args, a=42, b, c, **kwargs:int): pass
2602 def bar(pos, *args, c, b, a=42, **kwargs:int): pass
2603 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002604 self.assertEqual(
2605 hash(inspect.signature(foo)), hash(inspect.signature(bar)))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002606
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002607 def test_signature_hashable(self):
2608 S = inspect.Signature
2609 P = inspect.Parameter
2610
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002611 def foo(a): pass
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002612 foo_sig = inspect.signature(foo)
2613
2614 manual_sig = S(parameters=[P('a', P.POSITIONAL_OR_KEYWORD)])
2615
2616 self.assertEqual(hash(foo_sig), hash(manual_sig))
2617 self.assertNotEqual(hash(foo_sig),
2618 hash(manual_sig.replace(return_annotation='spam')))
2619
2620 def bar(a) -> 1: pass
2621 self.assertNotEqual(hash(foo_sig), hash(inspect.signature(bar)))
2622
2623 def foo(a={}): pass
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002624 with self.assertRaisesRegex(TypeError, 'unhashable type'):
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002625 hash(inspect.signature(foo))
2626
2627 def foo(a) -> {}: pass
2628 with self.assertRaisesRegex(TypeError, 'unhashable type'):
2629 hash(inspect.signature(foo))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002630
2631 def test_signature_str(self):
2632 def foo(a:int=1, *, b, c=None, **kwargs) -> 42:
2633 pass
2634 self.assertEqual(str(inspect.signature(foo)),
2635 '(a:int=1, *, b, c=None, **kwargs) -> 42')
2636
2637 def foo(a:int=1, *args, b, c=None, **kwargs) -> 42:
2638 pass
2639 self.assertEqual(str(inspect.signature(foo)),
2640 '(a:int=1, *args, b, c=None, **kwargs) -> 42')
2641
2642 def foo():
2643 pass
2644 self.assertEqual(str(inspect.signature(foo)), '()')
2645
2646 def test_signature_str_positional_only(self):
2647 P = inspect.Parameter
Yury Selivanov2393dca2014-01-27 15:07:58 -05002648 S = inspect.Signature
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002649
2650 def test(a_po, *, b, **kwargs):
2651 return a_po, kwargs
2652
2653 sig = inspect.signature(test)
2654 new_params = list(sig.parameters.values())
2655 new_params[0] = new_params[0].replace(kind=P.POSITIONAL_ONLY)
2656 test.__signature__ = sig.replace(parameters=new_params)
2657
2658 self.assertEqual(str(inspect.signature(test)),
Yury Selivanov2393dca2014-01-27 15:07:58 -05002659 '(a_po, /, *, b, **kwargs)')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002660
Yury Selivanov2393dca2014-01-27 15:07:58 -05002661 self.assertEqual(str(S(parameters=[P('foo', P.POSITIONAL_ONLY)])),
2662 '(foo, /)')
2663
2664 self.assertEqual(str(S(parameters=[
2665 P('foo', P.POSITIONAL_ONLY),
2666 P('bar', P.VAR_KEYWORD)])),
2667 '(foo, /, **bar)')
2668
2669 self.assertEqual(str(S(parameters=[
2670 P('foo', P.POSITIONAL_ONLY),
2671 P('bar', P.VAR_POSITIONAL)])),
2672 '(foo, /, *bar)')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002673
2674 def test_signature_replace_anno(self):
2675 def test() -> 42:
2676 pass
2677
2678 sig = inspect.signature(test)
2679 sig = sig.replace(return_annotation=None)
2680 self.assertIs(sig.return_annotation, None)
2681 sig = sig.replace(return_annotation=sig.empty)
2682 self.assertIs(sig.return_annotation, sig.empty)
2683 sig = sig.replace(return_annotation=42)
2684 self.assertEqual(sig.return_annotation, 42)
2685 self.assertEqual(sig, inspect.signature(test))
2686
Yury Selivanov34ce99f2014-02-18 12:49:41 -05002687 def test_signature_on_mangled_parameters(self):
2688 class Spam:
2689 def foo(self, __p1:1=2, *, __p2:2=3):
2690 pass
2691 class Ham(Spam):
2692 pass
2693
2694 self.assertEqual(self.signature(Spam.foo),
2695 ((('self', ..., ..., "positional_or_keyword"),
2696 ('_Spam__p1', 2, 1, "positional_or_keyword"),
2697 ('_Spam__p2', 3, 2, "keyword_only")),
2698 ...))
2699
2700 self.assertEqual(self.signature(Spam.foo),
2701 self.signature(Ham.foo))
2702
Yury Selivanovda396452014-03-27 12:09:24 -04002703 def test_signature_from_callable_python_obj(self):
2704 class MySignature(inspect.Signature): pass
2705 def foo(a, *, b:1): pass
2706 foo_sig = MySignature.from_callable(foo)
2707 self.assertTrue(isinstance(foo_sig, MySignature))
2708
2709 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2710 "Signature information for builtins requires docstrings")
2711 def test_signature_from_callable_builtin_obj(self):
2712 class MySignature(inspect.Signature): pass
2713 sig = MySignature.from_callable(_pickle.Pickler)
2714 self.assertTrue(isinstance(sig, MySignature))
2715
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002716
2717class TestParameterObject(unittest.TestCase):
2718 def test_signature_parameter_kinds(self):
2719 P = inspect.Parameter
2720 self.assertTrue(P.POSITIONAL_ONLY < P.POSITIONAL_OR_KEYWORD < \
2721 P.VAR_POSITIONAL < P.KEYWORD_ONLY < P.VAR_KEYWORD)
2722
2723 self.assertEqual(str(P.POSITIONAL_ONLY), 'POSITIONAL_ONLY')
2724 self.assertTrue('POSITIONAL_ONLY' in repr(P.POSITIONAL_ONLY))
2725
2726 def test_signature_parameter_object(self):
2727 p = inspect.Parameter('foo', default=10,
2728 kind=inspect.Parameter.POSITIONAL_ONLY)
2729 self.assertEqual(p.name, 'foo')
2730 self.assertEqual(p.default, 10)
2731 self.assertIs(p.annotation, p.empty)
2732 self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY)
2733
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002734 with self.assertRaisesRegex(ValueError, 'invalid value'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002735 inspect.Parameter('foo', default=10, kind='123')
2736
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002737 with self.assertRaisesRegex(ValueError, 'not a valid parameter name'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002738 inspect.Parameter('1', kind=inspect.Parameter.VAR_KEYWORD)
2739
Yury Selivanov2393dca2014-01-27 15:07:58 -05002740 with self.assertRaisesRegex(TypeError, 'name must be a str'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002741 inspect.Parameter(None, kind=inspect.Parameter.VAR_KEYWORD)
2742
Yury Selivanov2393dca2014-01-27 15:07:58 -05002743 with self.assertRaisesRegex(ValueError,
2744 'is not a valid parameter name'):
2745 inspect.Parameter('$', kind=inspect.Parameter.VAR_KEYWORD)
2746
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002747 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002748 inspect.Parameter('a', default=42,
2749 kind=inspect.Parameter.VAR_KEYWORD)
2750
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002751 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002752 inspect.Parameter('a', default=42,
2753 kind=inspect.Parameter.VAR_POSITIONAL)
2754
2755 p = inspect.Parameter('a', default=42,
2756 kind=inspect.Parameter.POSITIONAL_OR_KEYWORD)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002757 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002758 p.replace(kind=inspect.Parameter.VAR_POSITIONAL)
2759
2760 self.assertTrue(repr(p).startswith('<Parameter'))
Yury Selivanov374375d2014-03-27 12:41:53 -04002761 self.assertTrue('"a=42"' in repr(p))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002762
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002763 def test_signature_parameter_hashable(self):
2764 P = inspect.Parameter
2765 foo = P('foo', kind=P.POSITIONAL_ONLY)
2766 self.assertEqual(hash(foo), hash(P('foo', kind=P.POSITIONAL_ONLY)))
2767 self.assertNotEqual(hash(foo), hash(P('foo', kind=P.POSITIONAL_ONLY,
2768 default=42)))
2769 self.assertNotEqual(hash(foo),
2770 hash(foo.replace(kind=P.VAR_POSITIONAL)))
2771
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002772 def test_signature_parameter_equality(self):
2773 P = inspect.Parameter
2774 p = P('foo', default=42, kind=inspect.Parameter.KEYWORD_ONLY)
2775
2776 self.assertEqual(p, p)
2777 self.assertNotEqual(p, 42)
2778
2779 self.assertEqual(p, P('foo', default=42,
2780 kind=inspect.Parameter.KEYWORD_ONLY))
2781
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002782 def test_signature_parameter_replace(self):
2783 p = inspect.Parameter('foo', default=42,
2784 kind=inspect.Parameter.KEYWORD_ONLY)
2785
2786 self.assertIsNot(p, p.replace())
2787 self.assertEqual(p, p.replace())
2788
2789 p2 = p.replace(annotation=1)
2790 self.assertEqual(p2.annotation, 1)
2791 p2 = p2.replace(annotation=p2.empty)
2792 self.assertEqual(p, p2)
2793
2794 p2 = p2.replace(name='bar')
2795 self.assertEqual(p2.name, 'bar')
2796 self.assertNotEqual(p2, p)
2797
Yury Selivanov2393dca2014-01-27 15:07:58 -05002798 with self.assertRaisesRegex(ValueError,
2799 'name is a required attribute'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002800 p2 = p2.replace(name=p2.empty)
2801
2802 p2 = p2.replace(name='foo', default=None)
2803 self.assertIs(p2.default, None)
2804 self.assertNotEqual(p2, p)
2805
2806 p2 = p2.replace(name='foo', default=p2.empty)
2807 self.assertIs(p2.default, p2.empty)
2808
2809
2810 p2 = p2.replace(default=42, kind=p2.POSITIONAL_OR_KEYWORD)
2811 self.assertEqual(p2.kind, p2.POSITIONAL_OR_KEYWORD)
2812 self.assertNotEqual(p2, p)
2813
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002814 with self.assertRaisesRegex(ValueError, 'invalid value for'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002815 p2 = p2.replace(kind=p2.empty)
2816
2817 p2 = p2.replace(kind=p2.KEYWORD_ONLY)
2818 self.assertEqual(p2, p)
2819
2820 def test_signature_parameter_positional_only(self):
Yury Selivanov2393dca2014-01-27 15:07:58 -05002821 with self.assertRaisesRegex(TypeError, 'name must be a str'):
2822 inspect.Parameter(None, kind=inspect.Parameter.POSITIONAL_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002823
2824 def test_signature_parameter_immutability(self):
Yury Selivanov2393dca2014-01-27 15:07:58 -05002825 p = inspect.Parameter('spam', kind=inspect.Parameter.KEYWORD_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002826
2827 with self.assertRaises(AttributeError):
2828 p.foo = 'bar'
2829
2830 with self.assertRaises(AttributeError):
2831 p.kind = 123
2832
2833
2834class TestSignatureBind(unittest.TestCase):
2835 @staticmethod
2836 def call(func, *args, **kwargs):
2837 sig = inspect.signature(func)
2838 ba = sig.bind(*args, **kwargs)
2839 return func(*ba.args, **ba.kwargs)
2840
2841 def test_signature_bind_empty(self):
2842 def test():
2843 return 42
2844
2845 self.assertEqual(self.call(test), 42)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002846 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002847 self.call(test, 1)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002848 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002849 self.call(test, 1, spam=10)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002850 with self.assertRaisesRegex(TypeError, 'too many keyword arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002851 self.call(test, spam=1)
2852
2853 def test_signature_bind_var(self):
2854 def test(*args, **kwargs):
2855 return args, kwargs
2856
2857 self.assertEqual(self.call(test), ((), {}))
2858 self.assertEqual(self.call(test, 1), ((1,), {}))
2859 self.assertEqual(self.call(test, 1, 2), ((1, 2), {}))
2860 self.assertEqual(self.call(test, foo='bar'), ((), {'foo': 'bar'}))
2861 self.assertEqual(self.call(test, 1, foo='bar'), ((1,), {'foo': 'bar'}))
2862 self.assertEqual(self.call(test, args=10), ((), {'args': 10}))
2863 self.assertEqual(self.call(test, 1, 2, foo='bar'),
2864 ((1, 2), {'foo': 'bar'}))
2865
2866 def test_signature_bind_just_args(self):
2867 def test(a, b, c):
2868 return a, b, c
2869
2870 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
2871
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002872 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002873 self.call(test, 1, 2, 3, 4)
2874
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002875 with self.assertRaisesRegex(TypeError, "'b' parameter lacking default"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002876 self.call(test, 1)
2877
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002878 with self.assertRaisesRegex(TypeError, "'a' parameter lacking default"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002879 self.call(test)
2880
2881 def test(a, b, c=10):
2882 return a, b, c
2883 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
2884 self.assertEqual(self.call(test, 1, 2), (1, 2, 10))
2885
2886 def test(a=1, b=2, c=3):
2887 return a, b, c
2888 self.assertEqual(self.call(test, a=10, c=13), (10, 2, 13))
2889 self.assertEqual(self.call(test, a=10), (10, 2, 3))
2890 self.assertEqual(self.call(test, b=10), (1, 10, 3))
2891
2892 def test_signature_bind_varargs_order(self):
2893 def test(*args):
2894 return args
2895
2896 self.assertEqual(self.call(test), ())
2897 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
2898
2899 def test_signature_bind_args_and_varargs(self):
2900 def test(a, b, c=3, *args):
2901 return a, b, c, args
2902
2903 self.assertEqual(self.call(test, 1, 2, 3, 4, 5), (1, 2, 3, (4, 5)))
2904 self.assertEqual(self.call(test, 1, 2), (1, 2, 3, ()))
2905 self.assertEqual(self.call(test, b=1, a=2), (2, 1, 3, ()))
2906 self.assertEqual(self.call(test, 1, b=2), (1, 2, 3, ()))
2907
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002908 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002909 "multiple values for argument 'c'"):
2910 self.call(test, 1, 2, 3, c=4)
2911
2912 def test_signature_bind_just_kwargs(self):
2913 def test(**kwargs):
2914 return kwargs
2915
2916 self.assertEqual(self.call(test), {})
2917 self.assertEqual(self.call(test, foo='bar', spam='ham'),
2918 {'foo': 'bar', 'spam': 'ham'})
2919
2920 def test_signature_bind_args_and_kwargs(self):
2921 def test(a, b, c=3, **kwargs):
2922 return a, b, c, kwargs
2923
2924 self.assertEqual(self.call(test, 1, 2), (1, 2, 3, {}))
2925 self.assertEqual(self.call(test, 1, 2, foo='bar', spam='ham'),
2926 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
2927 self.assertEqual(self.call(test, b=2, a=1, foo='bar', spam='ham'),
2928 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
2929 self.assertEqual(self.call(test, a=1, b=2, foo='bar', spam='ham'),
2930 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
2931 self.assertEqual(self.call(test, 1, b=2, foo='bar', spam='ham'),
2932 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
2933 self.assertEqual(self.call(test, 1, b=2, c=4, foo='bar', spam='ham'),
2934 (1, 2, 4, {'foo': 'bar', 'spam': 'ham'}))
2935 self.assertEqual(self.call(test, 1, 2, 4, foo='bar'),
2936 (1, 2, 4, {'foo': 'bar'}))
2937 self.assertEqual(self.call(test, c=5, a=4, b=3),
2938 (4, 3, 5, {}))
2939
2940 def test_signature_bind_kwonly(self):
2941 def test(*, foo):
2942 return foo
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002943 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002944 'too many positional arguments'):
2945 self.call(test, 1)
2946 self.assertEqual(self.call(test, foo=1), 1)
2947
2948 def test(a, *, foo=1, bar):
2949 return foo
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002950 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002951 "'bar' parameter lacking default value"):
2952 self.call(test, 1)
2953
2954 def test(foo, *, bar):
2955 return foo, bar
2956 self.assertEqual(self.call(test, 1, bar=2), (1, 2))
2957 self.assertEqual(self.call(test, bar=2, foo=1), (1, 2))
2958
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002959 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002960 'too many keyword arguments'):
2961 self.call(test, bar=2, foo=1, spam=10)
2962
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002963 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002964 'too many positional arguments'):
2965 self.call(test, 1, 2)
2966
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002967 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002968 'too many positional arguments'):
2969 self.call(test, 1, 2, bar=2)
2970
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002971 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002972 'too many keyword arguments'):
2973 self.call(test, 1, bar=2, spam='ham')
2974
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002975 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002976 "'bar' parameter lacking default value"):
2977 self.call(test, 1)
2978
2979 def test(foo, *, bar, **bin):
2980 return foo, bar, bin
2981 self.assertEqual(self.call(test, 1, bar=2), (1, 2, {}))
2982 self.assertEqual(self.call(test, foo=1, bar=2), (1, 2, {}))
2983 self.assertEqual(self.call(test, 1, bar=2, spam='ham'),
2984 (1, 2, {'spam': 'ham'}))
2985 self.assertEqual(self.call(test, spam='ham', foo=1, bar=2),
2986 (1, 2, {'spam': 'ham'}))
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002987 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002988 "'foo' parameter lacking default value"):
2989 self.call(test, spam='ham', bar=2)
2990 self.assertEqual(self.call(test, 1, bar=2, bin=1, spam=10),
2991 (1, 2, {'bin': 1, 'spam': 10}))
2992
2993 def test_signature_bind_arguments(self):
2994 def test(a, *args, b, z=100, **kwargs):
2995 pass
2996 sig = inspect.signature(test)
2997 ba = sig.bind(10, 20, b=30, c=40, args=50, kwargs=60)
2998 # we won't have 'z' argument in the bound arguments object, as we didn't
2999 # pass it to the 'bind'
3000 self.assertEqual(tuple(ba.arguments.items()),
3001 (('a', 10), ('args', (20,)), ('b', 30),
3002 ('kwargs', {'c': 40, 'args': 50, 'kwargs': 60})))
3003 self.assertEqual(ba.kwargs,
3004 {'b': 30, 'c': 40, 'args': 50, 'kwargs': 60})
3005 self.assertEqual(ba.args, (10, 20))
3006
3007 def test_signature_bind_positional_only(self):
3008 P = inspect.Parameter
3009
3010 def test(a_po, b_po, c_po=3, foo=42, *, bar=50, **kwargs):
3011 return a_po, b_po, c_po, foo, bar, kwargs
3012
3013 sig = inspect.signature(test)
3014 new_params = collections.OrderedDict(tuple(sig.parameters.items()))
3015 for name in ('a_po', 'b_po', 'c_po'):
3016 new_params[name] = new_params[name].replace(kind=P.POSITIONAL_ONLY)
3017 new_sig = sig.replace(parameters=new_params.values())
3018 test.__signature__ = new_sig
3019
3020 self.assertEqual(self.call(test, 1, 2, 4, 5, bar=6),
3021 (1, 2, 4, 5, 6, {}))
3022
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05003023 self.assertEqual(self.call(test, 1, 2),
3024 (1, 2, 3, 42, 50, {}))
3025
3026 self.assertEqual(self.call(test, 1, 2, foo=4, bar=5),
3027 (1, 2, 3, 4, 5, {}))
3028
3029 with self.assertRaisesRegex(TypeError, "but was passed as a keyword"):
3030 self.call(test, 1, 2, foo=4, bar=5, c_po=10)
3031
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003032 with self.assertRaisesRegex(TypeError, "parameter is positional only"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003033 self.call(test, 1, 2, c_po=4)
3034
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003035 with self.assertRaisesRegex(TypeError, "parameter is positional only"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003036 self.call(test, a_po=1, b_po=2)
3037
Antoine Pitroubd41d1b2013-01-29 21:20:57 +01003038 def test_signature_bind_with_self_arg(self):
3039 # Issue #17071: one of the parameters is named "self
3040 def test(a, self, b):
3041 pass
3042 sig = inspect.signature(test)
3043 ba = sig.bind(1, 2, 3)
3044 self.assertEqual(ba.args, (1, 2, 3))
3045 ba = sig.bind(1, self=2, b=3)
3046 self.assertEqual(ba.args, (1, 2, 3))
3047
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05003048 def test_signature_bind_vararg_name(self):
3049 def test(a, *args):
3050 return a, args
3051 sig = inspect.signature(test)
3052
3053 with self.assertRaisesRegex(TypeError, "too many keyword arguments"):
3054 sig.bind(a=0, args=1)
3055
3056 def test(*args, **kwargs):
3057 return args, kwargs
3058 self.assertEqual(self.call(test, args=1), ((), {'args': 1}))
3059
3060 sig = inspect.signature(test)
3061 ba = sig.bind(args=1)
3062 self.assertEqual(ba.arguments, {'kwargs': {'args': 1}})
3063
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003064
3065class TestBoundArguments(unittest.TestCase):
3066 def test_signature_bound_arguments_unhashable(self):
3067 def foo(a): pass
3068 ba = inspect.signature(foo).bind(1)
3069
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02003070 with self.assertRaisesRegex(TypeError, 'unhashable type'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003071 hash(ba)
3072
3073 def test_signature_bound_arguments_equality(self):
3074 def foo(a): pass
3075 ba = inspect.signature(foo).bind(1)
3076 self.assertEqual(ba, ba)
3077
3078 ba2 = inspect.signature(foo).bind(1)
3079 self.assertEqual(ba, ba2)
3080
3081 ba3 = inspect.signature(foo).bind(2)
3082 self.assertNotEqual(ba, ba3)
3083 ba3.arguments['a'] = 1
3084 self.assertEqual(ba, ba3)
3085
3086 def bar(b): pass
3087 ba4 = inspect.signature(bar).bind(1)
3088 self.assertNotEqual(ba, ba4)
3089
Yury Selivanova5d63dd2014-03-27 11:31:43 -04003090 def test_signature_bound_arguments_pickle(self):
3091 def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
3092 sig = inspect.signature(foo)
3093 ba = sig.bind(20, 30, z={})
3094
3095 for ver in range(pickle.HIGHEST_PROTOCOL + 1):
3096 with self.subTest(pickle_ver=ver):
3097 ba_pickled = pickle.loads(pickle.dumps(ba, ver))
3098 self.assertEqual(ba, ba_pickled)
3099
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003100
Yury Selivanovd82eddc2014-01-29 11:24:39 -05003101class TestSignaturePrivateHelpers(unittest.TestCase):
3102 def test_signature_get_bound_param(self):
3103 getter = inspect._signature_get_bound_param
3104
3105 self.assertEqual(getter('($self)'), 'self')
3106 self.assertEqual(getter('($self, obj)'), 'self')
3107 self.assertEqual(getter('($cls, /, obj)'), 'cls')
3108
Larry Hastings2623c8c2014-02-08 22:15:29 -08003109 def _strip_non_python_syntax(self, input,
3110 clean_signature, self_parameter, last_positional_only):
3111 computed_clean_signature, \
3112 computed_self_parameter, \
3113 computed_last_positional_only = \
3114 inspect._signature_strip_non_python_syntax(input)
3115 self.assertEqual(computed_clean_signature, clean_signature)
3116 self.assertEqual(computed_self_parameter, self_parameter)
3117 self.assertEqual(computed_last_positional_only, last_positional_only)
3118
3119 def test_signature_strip_non_python_syntax(self):
3120 self._strip_non_python_syntax(
3121 "($module, /, path, mode, *, dir_fd=None, " +
3122 "effective_ids=False,\n follow_symlinks=True)",
3123 "(module, path, mode, *, dir_fd=None, " +
3124 "effective_ids=False, follow_symlinks=True)",
3125 0,
3126 0)
3127
3128 self._strip_non_python_syntax(
3129 "($module, word, salt, /)",
3130 "(module, word, salt)",
3131 0,
3132 2)
3133
3134 self._strip_non_python_syntax(
3135 "(x, y=None, z=None, /)",
3136 "(x, y=None, z=None)",
3137 None,
3138 2)
3139
3140 self._strip_non_python_syntax(
3141 "(x, y=None, z=None)",
3142 "(x, y=None, z=None)",
3143 None,
3144 None)
3145
3146 self._strip_non_python_syntax(
3147 "(x,\n y=None,\n z = None )",
3148 "(x, y=None, z=None)",
3149 None,
3150 None)
3151
3152 self._strip_non_python_syntax(
3153 "",
3154 "",
3155 None,
3156 None)
3157
3158 self._strip_non_python_syntax(
3159 None,
3160 None,
3161 None,
3162 None)
3163
Yury Selivanovd82eddc2014-01-29 11:24:39 -05003164
Nick Coghlane8c45d62013-07-28 20:00:01 +10003165class TestUnwrap(unittest.TestCase):
3166
3167 def test_unwrap_one(self):
3168 def func(a, b):
3169 return a + b
3170 wrapper = functools.lru_cache(maxsize=20)(func)
3171 self.assertIs(inspect.unwrap(wrapper), func)
3172
3173 def test_unwrap_several(self):
3174 def func(a, b):
3175 return a + b
3176 wrapper = func
3177 for __ in range(10):
3178 @functools.wraps(wrapper)
3179 def wrapper():
3180 pass
3181 self.assertIsNot(wrapper.__wrapped__, func)
3182 self.assertIs(inspect.unwrap(wrapper), func)
3183
3184 def test_stop(self):
3185 def func1(a, b):
3186 return a + b
3187 @functools.wraps(func1)
3188 def func2():
3189 pass
3190 @functools.wraps(func2)
3191 def wrapper():
3192 pass
3193 func2.stop_here = 1
3194 unwrapped = inspect.unwrap(wrapper,
3195 stop=(lambda f: hasattr(f, "stop_here")))
3196 self.assertIs(unwrapped, func2)
3197
3198 def test_cycle(self):
3199 def func1(): pass
3200 func1.__wrapped__ = func1
3201 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3202 inspect.unwrap(func1)
3203
3204 def func2(): pass
3205 func2.__wrapped__ = func1
3206 func1.__wrapped__ = func2
3207 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3208 inspect.unwrap(func1)
3209 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3210 inspect.unwrap(func2)
3211
3212 def test_unhashable(self):
3213 def func(): pass
3214 func.__wrapped__ = None
3215 class C:
3216 __hash__ = None
3217 __wrapped__ = func
3218 self.assertIsNone(inspect.unwrap(C()))
3219
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003220class TestMain(unittest.TestCase):
3221 def test_only_source(self):
3222 module = importlib.import_module('unittest')
3223 rc, out, err = assert_python_ok('-m', 'inspect',
3224 'unittest')
3225 lines = out.decode().splitlines()
3226 # ignore the final newline
3227 self.assertEqual(lines[:-1], inspect.getsource(module).splitlines())
3228 self.assertEqual(err, b'')
3229
Yury Selivanov42407ab2014-06-23 10:23:50 -07003230 def test_custom_getattr(self):
3231 def foo():
3232 pass
3233 foo.__signature__ = 42
3234 with self.assertRaises(TypeError):
3235 inspect.signature(foo)
3236
Brett Cannon634a8fc2013-10-02 10:25:42 -04003237 @unittest.skipIf(ThreadPoolExecutor is None,
Brett Cannon0de3f012013-10-02 10:58:58 -04003238 'threads required to test __qualname__ for source files')
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003239 def test_qualname_source(self):
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003240 rc, out, err = assert_python_ok('-m', 'inspect',
3241 'concurrent.futures:ThreadPoolExecutor')
3242 lines = out.decode().splitlines()
3243 # ignore the final newline
3244 self.assertEqual(lines[:-1],
Brett Cannon634a8fc2013-10-02 10:25:42 -04003245 inspect.getsource(ThreadPoolExecutor).splitlines())
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003246 self.assertEqual(err, b'')
3247
3248 def test_builtins(self):
3249 module = importlib.import_module('unittest')
3250 _, out, err = assert_python_failure('-m', 'inspect',
3251 'sys')
3252 lines = err.decode().splitlines()
3253 self.assertEqual(lines, ["Can't get info for builtin modules."])
3254
3255 def test_details(self):
3256 module = importlib.import_module('unittest')
3257 rc, out, err = assert_python_ok('-m', 'inspect',
3258 'unittest', '--details')
3259 output = out.decode()
3260 # Just a quick sanity check on the output
3261 self.assertIn(module.__name__, output)
3262 self.assertIn(module.__file__, output)
Serhiy Storchakab12cb6a2013-12-08 18:16:18 +02003263 if not sys.flags.optimize:
3264 self.assertIn(module.__cached__, output)
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003265 self.assertEqual(err, b'')
3266
3267
Yury Selivanovef1e7502014-12-08 16:05:34 -05003268class TestReload(unittest.TestCase):
3269
3270 src_before = textwrap.dedent("""\
3271def foo():
3272 print("Bla")
3273 """)
3274
3275 src_after = textwrap.dedent("""\
3276def foo():
3277 print("Oh no!")
3278 """)
3279
3280 def assertInspectEqual(self, path, source):
3281 inspected_src = inspect.getsource(source)
3282 with open(path) as src:
3283 self.assertEqual(
3284 src.read().splitlines(True),
3285 inspected_src.splitlines(True)
3286 )
3287
3288 def test_getsource_reload(self):
3289 # see issue 1218234
3290 with _ready_to_import('reload_bug', self.src_before) as (name, path):
3291 module = importlib.import_module(name)
3292 self.assertInspectEqual(path, module)
3293 with open(path, 'w') as src:
3294 src.write(self.src_after)
3295 self.assertInspectEqual(path, module)
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003296
Nick Coghlane8c45d62013-07-28 20:00:01 +10003297
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00003298def test_main():
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00003299 run_unittest(
3300 TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBuggyCases,
3301 TestInterpreterStack, TestClassesAndFunctions, TestPredicates,
3302 TestGetcallargsFunctions, TestGetcallargsMethods,
Alexander Belopolskyf546e702010-12-02 00:10:11 +00003303 TestGetcallargsUnboundMethods, TestGetattrStatic, TestGetGeneratorState,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003304 TestNoEOL, TestSignatureObject, TestSignatureBind, TestParameterObject,
Yury Selivanovd82eddc2014-01-29 11:24:39 -05003305 TestBoundArguments, TestSignaturePrivateHelpers, TestGetClosureVars,
Yury Selivanovef1e7502014-12-08 16:05:34 -05003306 TestUnwrap, TestMain, TestReload
Michael Foord95fc51d2010-11-20 15:07:30 +00003307 )
Martin v. Löwis893ffa42003-10-31 15:35:53 +00003308
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00003309if __name__ == "__main__":
3310 test_main()