blob: 83277215a8bdd9c5c1b1abaadb3c0677bb0672db [file] [log] [blame]
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001import re
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00002import sys
Thomas Wouters0e3f5912006-08-11 14:57:12 +00003import types
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00004import unittest
5import inspect
R. David Murraya1b37402010-06-17 02:04:29 +00006import linecache
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007import datetime
Guido van Rossum813b0e52007-05-21 18:11:34 +00008import collections
Alexander Belopolskyf546e702010-12-02 00:10:11 +00009import os
10import shutil
Christian Heimesa3538eb2007-11-06 11:44:48 +000011from os.path import normcase
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000012
Alexander Belopolskyf546e702010-12-02 00:10:11 +000013from test.support import run_unittest, TESTFN, DirsOnSysPath
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000014
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000015from test import inspect_fodder as mod
16from test import inspect_fodder2 as mod2
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000017
R. David Murray74b89242009-05-13 17:33:03 +000018# C module for test_findsource_binary
R. David Murrayb5655772009-05-14 16:17:50 +000019import unicodedata
R. David Murray74b89242009-05-13 17:33:03 +000020
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000021# Functions tested in this suite:
22# ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode,
Christian Heimes7131fd92008-02-19 14:21:46 +000023# isbuiltin, isroutine, isgenerator, isgeneratorfunction, getmembers,
24# getdoc, getfile, getmodule, getsourcefile, getcomments, getsource,
25# getclasstree, getargspec, getargvalues, formatargspec, formatargvalues,
26# currentframe, stack, trace, isdatadescriptor
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000027
Nick Coghlanf088e5e2008-12-14 11:50:48 +000028# NOTE: There are some additional tests relating to interaction with
29# zipimport in the test_zipimport_support test module.
30
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000031modfile = mod.__file__
Thomas Wouters0e3f5912006-08-11 14:57:12 +000032if modfile.endswith(('c', 'o')):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000033 modfile = modfile[:-1]
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000034
Christian Heimesa3538eb2007-11-06 11:44:48 +000035# Normalize file names: on Windows, the case of file names of compiled
36# modules depends on the path used to start the python executable.
37modfile = normcase(modfile)
38
39def revise(filename, *args):
40 return (normcase(filename),) + args
41
Georg Brandl1a3284e2007-12-02 09:40:06 +000042import builtins
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000043
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000044git = mod.StupidGit()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000045
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000046class IsTestBase(unittest.TestCase):
47 predicates = set([inspect.isbuiltin, inspect.isclass, inspect.iscode,
48 inspect.isframe, inspect.isfunction, inspect.ismethod,
Christian Heimes7131fd92008-02-19 14:21:46 +000049 inspect.ismodule, inspect.istraceback,
50 inspect.isgenerator, inspect.isgeneratorfunction])
Tim Peters5a9fb3c2005-01-07 16:01:32 +000051
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000052 def istest(self, predicate, exp):
53 obj = eval(exp)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000054 self.assertTrue(predicate(obj), '%s(%s)' % (predicate.__name__, exp))
Tim Peters5a9fb3c2005-01-07 16:01:32 +000055
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000056 for other in self.predicates - set([predicate]):
Christian Heimes7131fd92008-02-19 14:21:46 +000057 if predicate == inspect.isgeneratorfunction and\
58 other == inspect.isfunction:
59 continue
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000060 self.assertFalse(other(obj), 'not %s(%s)' % (other.__name__, exp))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000061
Christian Heimes7131fd92008-02-19 14:21:46 +000062def generator_function_example(self):
63 for i in range(2):
64 yield i
65
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000066class TestPredicates(IsTestBase):
Christian Heimes227c8002008-03-03 20:34:40 +000067 def test_sixteen(self):
Guido van Rossumc1f779c2007-07-03 08:25:58 +000068 count = len([x for x in dir(inspect) if x.startswith('is')])
Christian Heimes7131fd92008-02-19 14:21:46 +000069 # This test is here for remember you to update Doc/library/inspect.rst
Christian Heimes78644762008-03-04 23:39:23 +000070 # which claims there are 16 such functions
Christian Heimes227c8002008-03-03 20:34:40 +000071 expected = 16
Thomas Wouters0e3f5912006-08-11 14:57:12 +000072 err_msg = "There are %d (not %d) is* functions" % (count, expected)
73 self.assertEqual(count, expected, err_msg)
Tim Peters5a9fb3c2005-01-07 16:01:32 +000074
Christian Heimes7131fd92008-02-19 14:21:46 +000075
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000076 def test_excluding_predicates(self):
Antoine Pitroud5a1a212012-06-17 23:18:07 +020077 global tb
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000078 self.istest(inspect.isbuiltin, 'sys.exit')
79 self.istest(inspect.isbuiltin, '[].append')
Neal Norwitz221085d2007-02-25 20:55:47 +000080 self.istest(inspect.iscode, 'mod.spam.__code__')
Antoine Pitroud5a1a212012-06-17 23:18:07 +020081 try:
82 1/0
83 except:
84 tb = sys.exc_info()[2]
85 self.istest(inspect.isframe, 'tb.tb_frame')
86 self.istest(inspect.istraceback, 'tb')
87 if hasattr(types, 'GetSetDescriptorType'):
88 self.istest(inspect.isgetsetdescriptor,
89 'type(tb.tb_frame).f_locals')
90 else:
91 self.assertFalse(inspect.isgetsetdescriptor(type(tb.tb_frame).f_locals))
92 finally:
93 # Clear traceback and all the frames and local variables hanging to it.
94 tb = None
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000095 self.istest(inspect.isfunction, 'mod.spam')
Christian Heimes4a22b5d2007-11-25 09:39:14 +000096 self.istest(inspect.isfunction, 'mod.StupidGit.abuse')
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000097 self.istest(inspect.ismethod, 'git.argue')
98 self.istest(inspect.ismodule, 'mod')
Guido van Rossum813b0e52007-05-21 18:11:34 +000099 self.istest(inspect.isdatadescriptor, 'collections.defaultdict.default_factory')
Christian Heimes7131fd92008-02-19 14:21:46 +0000100 self.istest(inspect.isgenerator, '(x for x in range(2))')
101 self.istest(inspect.isgeneratorfunction, 'generator_function_example')
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000102 if hasattr(types, 'MemberDescriptorType'):
103 self.istest(inspect.ismemberdescriptor, 'datetime.timedelta.days')
104 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000105 self.assertFalse(inspect.ismemberdescriptor(datetime.timedelta.days))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000106
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000107 def test_isroutine(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000108 self.assertTrue(inspect.isroutine(mod.spam))
109 self.assertTrue(inspect.isroutine([].count))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000110
Benjamin Petersonc4656002009-01-17 22:41:18 +0000111 def test_isclass(self):
112 self.istest(inspect.isclass, 'mod.StupidGit')
113 self.assertTrue(inspect.isclass(list))
114
115 class CustomGetattr(object):
116 def __getattr__(self, attr):
117 return None
118 self.assertFalse(inspect.isclass(CustomGetattr()))
119
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000120 def test_get_slot_members(self):
121 class C(object):
122 __slots__ = ("a", "b")
123
124 x = C()
125 x.a = 42
126 members = dict(inspect.getmembers(x))
Benjamin Peterson577473f2010-01-19 00:09:57 +0000127 self.assertIn('a', members)
128 self.assertNotIn('b', members)
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000129
Benjamin Petersona0dfa822009-11-13 02:25:08 +0000130 def test_isabstract(self):
131 from abc import ABCMeta, abstractmethod
132
133 class AbstractClassExample(metaclass=ABCMeta):
134
135 @abstractmethod
136 def foo(self):
137 pass
138
139 class ClassExample(AbstractClassExample):
140 def foo(self):
141 pass
142
143 a = ClassExample()
144
145 # Test general behaviour.
146 self.assertTrue(inspect.isabstract(AbstractClassExample))
147 self.assertFalse(inspect.isabstract(ClassExample))
148 self.assertFalse(inspect.isabstract(a))
149 self.assertFalse(inspect.isabstract(int))
150 self.assertFalse(inspect.isabstract(5))
151
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000152
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000153class TestInterpreterStack(IsTestBase):
154 def __init__(self, *args, **kwargs):
155 unittest.TestCase.__init__(self, *args, **kwargs)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000156
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000157 git.abuse(7, 8, 9)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000158
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000159 def test_abuse_done(self):
160 self.istest(inspect.istraceback, 'git.ex[2]')
161 self.istest(inspect.isframe, 'mod.fr')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000162
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000163 def test_stack(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000164 self.assertTrue(len(mod.st) >= 5)
Christian Heimesa3538eb2007-11-06 11:44:48 +0000165 self.assertEqual(revise(*mod.st[0][1:]),
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000166 (modfile, 16, 'eggs', [' st = inspect.stack()\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000167 self.assertEqual(revise(*mod.st[1][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000168 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000169 self.assertEqual(revise(*mod.st[2][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000170 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000171 self.assertEqual(revise(*mod.st[3][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000172 (modfile, 39, 'abuse', [' self.argue(a, b, c)\n'], 0))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000173
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000174 def test_trace(self):
175 self.assertEqual(len(git.tr), 3)
Florent Xiclunac8575922010-03-24 17:37:49 +0000176 self.assertEqual(revise(*git.tr[0][1:]),
177 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
178 self.assertEqual(revise(*git.tr[1][1:]),
179 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
180 self.assertEqual(revise(*git.tr[2][1:]),
181 (modfile, 18, 'eggs', [' q = y / 0\n'], 0))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000182
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000183 def test_frame(self):
184 args, varargs, varkw, locals = inspect.getargvalues(mod.fr)
185 self.assertEqual(args, ['x', 'y'])
186 self.assertEqual(varargs, None)
187 self.assertEqual(varkw, None)
188 self.assertEqual(locals, {'x': 11, 'p': 11, 'y': 14})
189 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
190 '(x=11, y=14)')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000191
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000192 def test_previous_frame(self):
193 args, varargs, varkw, locals = inspect.getargvalues(mod.fr.f_back)
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000194 self.assertEqual(args, ['a', 'b', 'c', 'd', 'e', 'f'])
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000195 self.assertEqual(varargs, 'g')
196 self.assertEqual(varkw, 'h')
197 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000198 '(a=7, b=8, c=9, d=3, e=4, f=5, *g=(), **h={})')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000199
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000200class GetSourceBase(unittest.TestCase):
201 # Subclasses must override.
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000202 fodderModule = None
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000203
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000204 def __init__(self, *args, **kwargs):
205 unittest.TestCase.__init__(self, *args, **kwargs)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000206
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000207 with open(inspect.getsourcefile(self.fodderModule)) as fp:
Philip Jenveya27c5bd2009-05-28 06:09:08 +0000208 self.source = fp.read()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000209
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000210 def sourcerange(self, top, bottom):
211 lines = self.source.split("\n")
212 return "\n".join(lines[top-1:bottom]) + "\n"
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000213
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000214 def assertSourceEqual(self, obj, top, bottom):
215 self.assertEqual(inspect.getsource(obj),
216 self.sourcerange(top, bottom))
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000217
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000218class TestRetrievingSourceCode(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000219 fodderModule = mod
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000220
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000221 def test_getclasses(self):
222 classes = inspect.getmembers(mod, inspect.isclass)
223 self.assertEqual(classes,
224 [('FesteringGob', mod.FesteringGob),
225 ('MalodorousPervert', mod.MalodorousPervert),
226 ('ParrotDroppings', mod.ParrotDroppings),
227 ('StupidGit', mod.StupidGit)])
228 tree = inspect.getclasstree([cls[1] for cls in classes], 1)
229 self.assertEqual(tree,
Thomas Wouters725af872006-04-15 09:13:19 +0000230 [(object, ()),
231 [(mod.ParrotDroppings, (object,)),
232 (mod.StupidGit, (object,)),
233 [(mod.MalodorousPervert, (mod.StupidGit,)),
234 [(mod.FesteringGob, (mod.MalodorousPervert,
235 mod.ParrotDroppings))
236 ]
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000237 ]
238 ]
239 ])
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000240
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000241 def test_getfunctions(self):
242 functions = inspect.getmembers(mod, inspect.isfunction)
243 self.assertEqual(functions, [('eggs', mod.eggs),
244 ('spam', mod.spam)])
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000245
R. David Murray378c0cf2010-02-24 01:46:21 +0000246 @unittest.skipIf(sys.flags.optimize >= 2,
247 "Docstrings are omitted with -O2 and above")
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000248 def test_getdoc(self):
249 self.assertEqual(inspect.getdoc(mod), 'A module docstring.')
250 self.assertEqual(inspect.getdoc(mod.StupidGit),
251 'A longer,\n\nindented\n\ndocstring.')
252 self.assertEqual(inspect.getdoc(git.abuse),
253 'Another\n\ndocstring\n\ncontaining\n\ntabs')
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000254
Georg Brandl0c77a822008-06-10 16:37:50 +0000255 def test_cleandoc(self):
256 self.assertEqual(inspect.cleandoc('An\n indented\n docstring.'),
257 'An\nindented\ndocstring.')
258
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000259 def test_getcomments(self):
260 self.assertEqual(inspect.getcomments(mod), '# line 1\n')
261 self.assertEqual(inspect.getcomments(mod.StupidGit), '# line 20\n')
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000262
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000263 def test_getmodule(self):
Thomas Wouters89f507f2006-12-13 04:49:30 +0000264 # Check actual module
265 self.assertEqual(inspect.getmodule(mod), mod)
266 # Check class (uses __module__ attribute)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000267 self.assertEqual(inspect.getmodule(mod.StupidGit), mod)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000268 # Check a method (no __module__ attribute, falls back to filename)
269 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
270 # Do it again (check the caching isn't broken)
271 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
272 # Check a builtin
Georg Brandl1a3284e2007-12-02 09:40:06 +0000273 self.assertEqual(inspect.getmodule(str), sys.modules["builtins"])
Thomas Wouters89f507f2006-12-13 04:49:30 +0000274 # Check filename override
275 self.assertEqual(inspect.getmodule(None, modfile), mod)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000276
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000277 def test_getsource(self):
278 self.assertSourceEqual(git.abuse, 29, 39)
279 self.assertSourceEqual(mod.StupidGit, 21, 46)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000280
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000281 def test_getsourcefile(self):
Christian Heimesa3538eb2007-11-06 11:44:48 +0000282 self.assertEqual(normcase(inspect.getsourcefile(mod.spam)), modfile)
283 self.assertEqual(normcase(inspect.getsourcefile(git.abuse)), modfile)
R. David Murraya1b37402010-06-17 02:04:29 +0000284 fn = "_non_existing_filename_used_for_sourcefile_test.py"
285 co = compile("None", fn, "exec")
R. David Murray4155f972010-06-17 13:23:18 +0000286 self.assertEqual(inspect.getsourcefile(co), None)
R. David Murraya1b37402010-06-17 02:04:29 +0000287 linecache.cache[co.co_filename] = (1, None, "None", co.co_filename)
288 self.assertEqual(normcase(inspect.getsourcefile(co)), fn)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000289
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000290 def test_getfile(self):
291 self.assertEqual(inspect.getfile(mod.StupidGit), mod.__file__)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000292
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000293 def test_getmodule_recursion(self):
Christian Heimes45f9af32007-11-27 21:50:00 +0000294 from types import ModuleType
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000295 name = '__inspect_dummy'
Christian Heimes45f9af32007-11-27 21:50:00 +0000296 m = sys.modules[name] = ModuleType(name)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000297 m.__file__ = "<string>" # hopefully not a real filename...
298 m.__loader__ = "dummy" # pretend the filename is understood by a loader
Georg Brandl7cae87c2006-09-06 06:51:57 +0000299 exec("def x(): pass", m.__dict__)
Neal Norwitz221085d2007-02-25 20:55:47 +0000300 self.assertEqual(inspect.getsourcefile(m.x.__code__), '<string>')
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000301 del sys.modules[name]
302 inspect.getmodule(compile('a=10','','single'))
303
Benjamin Peterson9620cc02011-06-11 15:53:11 -0500304 def test_proceed_with_fake_filename(self):
305 '''doctest monkeypatches linecache to enable inspection'''
306 fn, source = '<test>', 'def x(): pass\n'
307 getlines = linecache.getlines
308 def monkey(filename, module_globals=None):
309 if filename == fn:
Ezio Melottid8b509b2011-09-28 17:37:55 +0300310 return source.splitlines(keepends=True)
Benjamin Peterson9620cc02011-06-11 15:53:11 -0500311 else:
312 return getlines(filename, module_globals)
313 linecache.getlines = monkey
314 try:
315 ns = {}
316 exec(compile(source, fn, 'single'), ns)
317 inspect.getsource(ns["x"])
318 finally:
319 linecache.getlines = getlines
320
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000321class TestDecorators(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000322 fodderModule = mod2
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000323
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000324 def test_wrapped_decorator(self):
Christian Heimes09aaa882008-02-23 15:01:06 +0000325 self.assertSourceEqual(mod2.wrapped, 14, 17)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000326
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000327 def test_replacing_decorator(self):
328 self.assertSourceEqual(mod2.gone, 9, 10)
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000329
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000330class TestOneliners(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000331 fodderModule = mod2
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000332 def test_oneline_lambda(self):
333 # Test inspect.getsource with a one-line lambda function.
334 self.assertSourceEqual(mod2.oll, 25, 25)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000335
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000336 def test_threeline_lambda(self):
337 # Test inspect.getsource with a three-line lambda function,
338 # where the second and third lines are _not_ indented.
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000339 self.assertSourceEqual(mod2.tll, 28, 30)
340
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000341 def test_twoline_indented_lambda(self):
342 # Test inspect.getsource with a two-line lambda function,
343 # where the second line _is_ indented.
344 self.assertSourceEqual(mod2.tlli, 33, 34)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000345
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000346 def test_onelinefunc(self):
347 # Test inspect.getsource with a regular one-line function.
348 self.assertSourceEqual(mod2.onelinefunc, 37, 37)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000349
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000350 def test_manyargs(self):
351 # Test inspect.getsource with a regular function where
352 # the arguments are on two lines and _not_ indented and
353 # the body on the second line with the last arguments.
354 self.assertSourceEqual(mod2.manyargs, 40, 41)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000355
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000356 def test_twolinefunc(self):
357 # Test inspect.getsource with a regular function where
358 # the body is on two lines, following the argument list and
359 # continued on the next line by a \\.
360 self.assertSourceEqual(mod2.twolinefunc, 44, 45)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000361
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000362 def test_lambda_in_list(self):
363 # Test inspect.getsource with a one-line lambda function
364 # defined in a list, indented.
365 self.assertSourceEqual(mod2.a[1], 49, 49)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000366
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000367 def test_anonymous(self):
368 # Test inspect.getsource with a lambda function defined
369 # as argument to another function.
370 self.assertSourceEqual(mod2.anonymous, 55, 55)
371
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000372class TestBuggyCases(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000373 fodderModule = mod2
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000374
375 def test_with_comment(self):
376 self.assertSourceEqual(mod2.with_comment, 58, 59)
377
378 def test_multiline_sig(self):
379 self.assertSourceEqual(mod2.multiline_sig[0], 63, 64)
380
Armin Rigodd5c0232005-09-25 11:45:45 +0000381 def test_nested_class(self):
382 self.assertSourceEqual(mod2.func69().func71, 71, 72)
383
384 def test_one_liner_followed_by_non_name(self):
385 self.assertSourceEqual(mod2.func77, 77, 77)
386
387 def test_one_liner_dedent_non_name(self):
388 self.assertSourceEqual(mod2.cls82.func83, 83, 83)
389
390 def test_with_comment_instead_of_docstring(self):
391 self.assertSourceEqual(mod2.func88, 88, 90)
392
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000393 def test_method_in_dynamic_class(self):
394 self.assertSourceEqual(mod2.method_in_dynamic_class, 95, 97)
395
R. David Murrayb5655772009-05-14 16:17:50 +0000396 @unittest.skipIf(
397 not hasattr(unicodedata, '__file__') or
398 unicodedata.__file__[-4:] in (".pyc", ".pyo"),
399 "unicodedata is not an external binary module")
R. David Murray74b89242009-05-13 17:33:03 +0000400 def test_findsource_binary(self):
R. David Murrayb5655772009-05-14 16:17:50 +0000401 self.assertRaises(IOError, inspect.getsource, unicodedata)
402 self.assertRaises(IOError, inspect.findsource, unicodedata)
R. David Murray74b89242009-05-13 17:33:03 +0000403
R. David Murraya1b37402010-06-17 02:04:29 +0000404 def test_findsource_code_in_linecache(self):
405 lines = ["x=1"]
406 co = compile(lines[0], "_dynamically_created_file", "exec")
407 self.assertRaises(IOError, inspect.findsource, co)
408 self.assertRaises(IOError, inspect.getsource, co)
409 linecache.cache[co.co_filename] = (1, None, lines, co.co_filename)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000410 self.assertEqual(inspect.findsource(co), (lines,0))
411 self.assertEqual(inspect.getsource(co), lines[0])
R. David Murraya1b37402010-06-17 02:04:29 +0000412
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000413class TestNoEOL(GetSourceBase):
414 def __init__(self, *args, **kwargs):
415 self.tempdir = TESTFN + '_dir'
416 os.mkdir(self.tempdir)
417 with open(os.path.join(self.tempdir,
418 'inspect_fodder3%spy' % os.extsep), 'w') as f:
419 f.write("class X:\n pass # No EOL")
420 with DirsOnSysPath(self.tempdir):
421 import inspect_fodder3 as mod3
422 self.fodderModule = mod3
423 GetSourceBase.__init__(self, *args, **kwargs)
424
425 def tearDown(self):
426 shutil.rmtree(self.tempdir)
427
428 def test_class(self):
429 self.assertSourceEqual(self.fodderModule.X, 1, 2)
430
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100431
432class _BrokenDataDescriptor(object):
433 """
434 A broken data descriptor. See bug #1785.
435 """
436 def __get__(*args):
437 raise AssertionError("should not __get__ data descriptors")
438
439 def __set__(*args):
440 raise RuntimeError
441
442 def __getattr__(*args):
443 raise AssertionError("should not __getattr__ data descriptors")
444
445
446class _BrokenMethodDescriptor(object):
447 """
448 A broken method descriptor. See bug #1785.
449 """
450 def __get__(*args):
451 raise AssertionError("should not __get__ method descriptors")
452
453 def __getattr__(*args):
454 raise AssertionError("should not __getattr__ method descriptors")
455
456
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000457# Helper for testing classify_class_attrs.
Tim Peters13b49d32001-09-23 02:00:29 +0000458def attrs_wo_objs(cls):
459 return [t[:3] for t in inspect.classify_class_attrs(cls)]
460
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100461
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000462class TestClassesAndFunctions(unittest.TestCase):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000463 def test_newstyle_mro(self):
464 # The same w/ new-class MRO.
465 class A(object): pass
466 class B(A): pass
467 class C(A): pass
468 class D(B, C): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000469
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000470 expected = (D, B, C, A, object)
471 got = inspect.getmro(D)
472 self.assertEqual(expected, got)
Tim Peters13b49d32001-09-23 02:00:29 +0000473
Christian Heimes3795b532007-11-08 13:48:53 +0000474 def assertArgSpecEquals(self, routine, args_e, varargs_e=None,
475 varkw_e=None, defaults_e=None, formatted=None):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000476 args, varargs, varkw, defaults = inspect.getargspec(routine)
477 self.assertEqual(args, args_e)
478 self.assertEqual(varargs, varargs_e)
479 self.assertEqual(varkw, varkw_e)
480 self.assertEqual(defaults, defaults_e)
481 if formatted is not None:
482 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults),
483 formatted)
Tim Peters13b49d32001-09-23 02:00:29 +0000484
Christian Heimes3795b532007-11-08 13:48:53 +0000485 def assertFullArgSpecEquals(self, routine, args_e, varargs_e=None,
486 varkw_e=None, defaults_e=None,
487 kwonlyargs_e=[], kwonlydefaults_e=None,
488 ann_e={}, formatted=None):
489 args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \
490 inspect.getfullargspec(routine)
491 self.assertEqual(args, args_e)
492 self.assertEqual(varargs, varargs_e)
493 self.assertEqual(varkw, varkw_e)
494 self.assertEqual(defaults, defaults_e)
495 self.assertEqual(kwonlyargs, kwonlyargs_e)
496 self.assertEqual(kwonlydefaults, kwonlydefaults_e)
497 self.assertEqual(ann, ann_e)
498 if formatted is not None:
499 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults,
500 kwonlyargs, kwonlydefaults, ann),
501 formatted)
502
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000503 def test_getargspec(self):
Christian Heimes3795b532007-11-08 13:48:53 +0000504 self.assertArgSpecEquals(mod.eggs, ['x', 'y'], formatted='(x, y)')
Tim Peters13b49d32001-09-23 02:00:29 +0000505
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000506 self.assertArgSpecEquals(mod.spam,
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000507 ['a', 'b', 'c', 'd', 'e', 'f'],
508 'g', 'h', (3, 4, 5),
509 '(a, b, c, d=3, e=4, f=5, *g, **h)')
Tim Peters13b49d32001-09-23 02:00:29 +0000510
Christian Heimes3795b532007-11-08 13:48:53 +0000511 self.assertRaises(ValueError, self.assertArgSpecEquals,
512 mod2.keyworded, [])
513
514 self.assertRaises(ValueError, self.assertArgSpecEquals,
515 mod2.annotated, [])
Benjamin Peterson9953a8d2009-01-17 04:15:01 +0000516 self.assertRaises(ValueError, self.assertArgSpecEquals,
517 mod2.keyword_only_arg, [])
518
Christian Heimes3795b532007-11-08 13:48:53 +0000519
520 def test_getfullargspec(self):
521 self.assertFullArgSpecEquals(mod2.keyworded, [], varargs_e='arg1',
522 kwonlyargs_e=['arg2'],
523 kwonlydefaults_e={'arg2':1},
524 formatted='(*arg1, arg2=1)')
525
526 self.assertFullArgSpecEquals(mod2.annotated, ['arg1'],
Christian Heimesc9543e42007-11-28 08:28:28 +0000527 ann_e={'arg1' : list},
Christian Heimes3795b532007-11-08 13:48:53 +0000528 formatted='(arg1: list)')
Benjamin Peterson9953a8d2009-01-17 04:15:01 +0000529 self.assertFullArgSpecEquals(mod2.keyword_only_arg, [],
530 kwonlyargs_e=['arg'],
531 formatted='(*, arg)')
532
Christian Heimes3795b532007-11-08 13:48:53 +0000533
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000534 def test_getargspec_method(self):
535 class A(object):
536 def m(self):
537 pass
538 self.assertArgSpecEquals(A.m, ['self'])
Tim Peters13b49d32001-09-23 02:00:29 +0000539
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000540 def test_classify_newstyle(self):
541 class A(object):
Tim Peters13b49d32001-09-23 02:00:29 +0000542
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000543 def s(): pass
544 s = staticmethod(s)
Tim Peters13b49d32001-09-23 02:00:29 +0000545
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000546 def c(cls): pass
547 c = classmethod(c)
Tim Peters13b49d32001-09-23 02:00:29 +0000548
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000549 def getp(self): pass
550 p = property(getp)
Tim Peters13b49d32001-09-23 02:00:29 +0000551
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000552 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000553
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000554 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000555
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000556 datablob = '1'
Tim Peters13b49d32001-09-23 02:00:29 +0000557
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100558 dd = _BrokenDataDescriptor()
559 md = _BrokenMethodDescriptor()
560
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000561 attrs = attrs_wo_objs(A)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000562 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
563 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
564 self.assertIn(('p', 'property', A), attrs, 'missing property')
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000565 self.assertIn(('m', 'method', A), attrs,
566 'missing plain method: %r' % attrs)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000567 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
568 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100569 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
570 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000571
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000572 class B(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000573
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000574 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000575
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000576 attrs = attrs_wo_objs(B)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000577 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
578 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
579 self.assertIn(('p', 'property', A), attrs, 'missing property')
580 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
581 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
582 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100583 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
584 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000585
586
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000587 class C(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000588
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000589 def m(self): pass
590 def c(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000591
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000592 attrs = attrs_wo_objs(C)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000593 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
594 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
595 self.assertIn(('p', 'property', A), attrs, 'missing property')
596 self.assertIn(('m', 'method', C), attrs, 'missing plain method')
597 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
598 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100599 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
600 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000601
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000602 class D(B, C):
Tim Peters13b49d32001-09-23 02:00:29 +0000603
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000604 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000605
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000606 attrs = attrs_wo_objs(D)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000607 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
608 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
609 self.assertIn(('p', 'property', A), attrs, 'missing property')
610 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
611 self.assertIn(('m1', 'method', D), attrs, 'missing plain method')
612 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100613 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
614 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
615
616 def test_classify_builtin_types(self):
617 # Simple sanity check that all built-in types can have their
618 # attributes classified.
619 for name in dir(__builtins__):
620 builtin = getattr(__builtins__, name)
621 if isinstance(builtin, type):
622 inspect.classify_class_attrs(builtin)
623
624 def test_getmembers_descriptors(self):
625 class A(object):
626 dd = _BrokenDataDescriptor()
627 md = _BrokenMethodDescriptor()
628
629 def pred_wrapper(pred):
630 # A quick'n'dirty way to discard standard attributes of new-style
631 # classes.
632 class Empty(object):
633 pass
634 def wrapped(x):
635 if '__name__' in dir(x) and hasattr(Empty, x.__name__):
636 return False
637 return pred(x)
638 return wrapped
639
640 ismethoddescriptor = pred_wrapper(inspect.ismethoddescriptor)
641 isdatadescriptor = pred_wrapper(inspect.isdatadescriptor)
642
643 self.assertEqual(inspect.getmembers(A, ismethoddescriptor),
644 [('md', A.__dict__['md'])])
645 self.assertEqual(inspect.getmembers(A, isdatadescriptor),
646 [('dd', A.__dict__['dd'])])
647
648 class B(A):
649 pass
650
651 self.assertEqual(inspect.getmembers(B, ismethoddescriptor),
652 [('md', A.__dict__['md'])])
653 self.assertEqual(inspect.getmembers(B, isdatadescriptor),
654 [('dd', A.__dict__['dd'])])
655
Antoine Pitrou0c603812012-01-18 17:40:18 +0100656 def test_getmembers_method(self):
657 class B:
658 def f(self):
659 pass
660
661 self.assertIn(('f', B.f), inspect.getmembers(B))
662 self.assertNotIn(('f', B.f), inspect.getmembers(B, inspect.ismethod))
663 b = B()
664 self.assertIn(('f', b.f), inspect.getmembers(b))
665 self.assertIn(('f', b.f), inspect.getmembers(b, inspect.ismethod))
666
Jeremy Hyltonc4bf5ed2003-06-27 18:43:12 +0000667
Nick Coghlan2f92e542012-06-23 19:39:55 +1000668_global_ref = object()
669class TestGetClosureVars(unittest.TestCase):
670
671 def test_name_resolution(self):
672 # Basic test of the 4 different resolution mechanisms
673 def f(nonlocal_ref):
674 def g(local_ref):
675 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
676 return g
677 _arg = object()
678 nonlocal_vars = {"nonlocal_ref": _arg}
679 global_vars = {"_global_ref": _global_ref}
680 builtin_vars = {"print": print}
681 unbound_names = {"unbound_ref"}
682 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
683 builtin_vars, unbound_names)
684 self.assertEqual(inspect.getclosurevars(f(_arg)), expected)
685
686 def test_generator_closure(self):
687 def f(nonlocal_ref):
688 def g(local_ref):
689 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
690 yield
691 return g
692 _arg = object()
693 nonlocal_vars = {"nonlocal_ref": _arg}
694 global_vars = {"_global_ref": _global_ref}
695 builtin_vars = {"print": print}
696 unbound_names = {"unbound_ref"}
697 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
698 builtin_vars, unbound_names)
699 self.assertEqual(inspect.getclosurevars(f(_arg)), expected)
700
701 def test_method_closure(self):
702 class C:
703 def f(self, nonlocal_ref):
704 def g(local_ref):
705 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
706 return g
707 _arg = object()
708 nonlocal_vars = {"nonlocal_ref": _arg}
709 global_vars = {"_global_ref": _global_ref}
710 builtin_vars = {"print": print}
711 unbound_names = {"unbound_ref"}
712 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
713 builtin_vars, unbound_names)
714 self.assertEqual(inspect.getclosurevars(C().f(_arg)), expected)
715
716 def test_nonlocal_vars(self):
717 # More complex tests of nonlocal resolution
718 def _nonlocal_vars(f):
719 return inspect.getclosurevars(f).nonlocals
720
721 def make_adder(x):
722 def add(y):
723 return x + y
724 return add
725
726 def curry(func, arg1):
727 return lambda arg2: func(arg1, arg2)
728
729 def less_than(a, b):
730 return a < b
731
732 # The infamous Y combinator.
733 def Y(le):
734 def g(f):
735 return le(lambda x: f(f)(x))
736 Y.g_ref = g
737 return g(g)
738
739 def check_y_combinator(func):
740 self.assertEqual(_nonlocal_vars(func), {'f': Y.g_ref})
741
742 inc = make_adder(1)
743 add_two = make_adder(2)
744 greater_than_five = curry(less_than, 5)
745
746 self.assertEqual(_nonlocal_vars(inc), {'x': 1})
747 self.assertEqual(_nonlocal_vars(add_two), {'x': 2})
748 self.assertEqual(_nonlocal_vars(greater_than_five),
749 {'arg1': 5, 'func': less_than})
750 self.assertEqual(_nonlocal_vars((lambda x: lambda y: x + y)(3)),
751 {'x': 3})
752 Y(check_y_combinator)
753
754 def test_getclosurevars_empty(self):
755 def foo(): pass
756 _empty = inspect.ClosureVars({}, {}, {}, set())
757 self.assertEqual(inspect.getclosurevars(lambda: True), _empty)
758 self.assertEqual(inspect.getclosurevars(foo), _empty)
759
760 def test_getclosurevars_error(self):
761 class T: pass
762 self.assertRaises(TypeError, inspect.getclosurevars, 1)
763 self.assertRaises(TypeError, inspect.getclosurevars, list)
764 self.assertRaises(TypeError, inspect.getclosurevars, {})
765
766
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000767class TestGetcallargsFunctions(unittest.TestCase):
768
769 def assertEqualCallArgs(self, func, call_params_string, locs=None):
770 locs = dict(locs or {}, func=func)
771 r1 = eval('func(%s)' % call_params_string, None, locs)
772 r2 = eval('inspect.getcallargs(func, %s)' % call_params_string, None,
773 locs)
774 self.assertEqual(r1, r2)
775
776 def assertEqualException(self, func, call_param_string, locs=None):
777 locs = dict(locs or {}, func=func)
778 try:
779 eval('func(%s)' % call_param_string, None, locs)
780 except Exception as e:
781 ex1 = e
782 else:
783 self.fail('Exception not raised')
784 try:
785 eval('inspect.getcallargs(func, %s)' % call_param_string, None,
786 locs)
787 except Exception as e:
788 ex2 = e
789 else:
790 self.fail('Exception not raised')
791 self.assertIs(type(ex1), type(ex2))
792 self.assertEqual(str(ex1), str(ex2))
793 del ex1, ex2
794
795 def makeCallable(self, signature):
796 """Create a function that returns its locals()"""
797 code = "lambda %s: locals()"
798 return eval(code % signature)
799
800 def test_plain(self):
801 f = self.makeCallable('a, b=1')
802 self.assertEqualCallArgs(f, '2')
803 self.assertEqualCallArgs(f, '2, 3')
804 self.assertEqualCallArgs(f, 'a=2')
805 self.assertEqualCallArgs(f, 'b=3, a=2')
806 self.assertEqualCallArgs(f, '2, b=3')
807 # expand *iterable / **mapping
808 self.assertEqualCallArgs(f, '*(2,)')
809 self.assertEqualCallArgs(f, '*[2]')
810 self.assertEqualCallArgs(f, '*(2, 3)')
811 self.assertEqualCallArgs(f, '*[2, 3]')
812 self.assertEqualCallArgs(f, '**{"a":2}')
813 self.assertEqualCallArgs(f, 'b=3, **{"a":2}')
814 self.assertEqualCallArgs(f, '2, **{"b":3}')
815 self.assertEqualCallArgs(f, '**{"b":3, "a":2}')
816 # expand UserList / UserDict
817 self.assertEqualCallArgs(f, '*collections.UserList([2])')
818 self.assertEqualCallArgs(f, '*collections.UserList([2, 3])')
819 self.assertEqualCallArgs(f, '**collections.UserDict(a=2)')
820 self.assertEqualCallArgs(f, '2, **collections.UserDict(b=3)')
821 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3)')
822
823 def test_varargs(self):
824 f = self.makeCallable('a, b=1, *c')
825 self.assertEqualCallArgs(f, '2')
826 self.assertEqualCallArgs(f, '2, 3')
827 self.assertEqualCallArgs(f, '2, 3, 4')
828 self.assertEqualCallArgs(f, '*(2,3,4)')
829 self.assertEqualCallArgs(f, '2, *[3,4]')
830 self.assertEqualCallArgs(f, '2, 3, *collections.UserList([4])')
831
832 def test_varkw(self):
833 f = self.makeCallable('a, b=1, **c')
834 self.assertEqualCallArgs(f, 'a=2')
835 self.assertEqualCallArgs(f, '2, b=3, c=4')
836 self.assertEqualCallArgs(f, 'b=3, a=2, c=4')
837 self.assertEqualCallArgs(f, 'c=4, **{"a":2, "b":3}')
838 self.assertEqualCallArgs(f, '2, c=4, **{"b":3}')
839 self.assertEqualCallArgs(f, 'b=2, **{"a":3, "c":4}')
840 self.assertEqualCallArgs(f, '**collections.UserDict(a=2, b=3, c=4)')
841 self.assertEqualCallArgs(f, '2, c=4, **collections.UserDict(b=3)')
842 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3, c=4)')
843
Benjamin Peterson6a2638b2011-03-28 17:32:31 -0500844 def test_varkw_only(self):
845 # issue11256:
846 f = self.makeCallable('**c')
847 self.assertEqualCallArgs(f, '')
848 self.assertEqualCallArgs(f, 'a=1')
849 self.assertEqualCallArgs(f, 'a=1, b=2')
850 self.assertEqualCallArgs(f, 'c=3, **{"a": 1, "b": 2}')
851 self.assertEqualCallArgs(f, '**collections.UserDict(a=1, b=2)')
852 self.assertEqualCallArgs(f, 'c=3, **collections.UserDict(a=1, b=2)')
853
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000854 def test_keyword_only(self):
855 f = self.makeCallable('a=3, *, c, d=2')
856 self.assertEqualCallArgs(f, 'c=3')
857 self.assertEqualCallArgs(f, 'c=3, a=3')
858 self.assertEqualCallArgs(f, 'a=2, c=4')
859 self.assertEqualCallArgs(f, '4, c=4')
860 self.assertEqualException(f, '')
861 self.assertEqualException(f, '3')
862 self.assertEqualException(f, 'a=3')
863 self.assertEqualException(f, 'd=4')
864
Benjamin Peterson6a2638b2011-03-28 17:32:31 -0500865 f = self.makeCallable('*, c, d=2')
866 self.assertEqualCallArgs(f, 'c=3')
867 self.assertEqualCallArgs(f, 'c=3, d=4')
868 self.assertEqualCallArgs(f, 'd=4, c=3')
869
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000870 def test_multiple_features(self):
871 f = self.makeCallable('a, b=2, *f, **g')
872 self.assertEqualCallArgs(f, '2, 3, 7')
873 self.assertEqualCallArgs(f, '2, 3, x=8')
874 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
875 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9')
876 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9')
877 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
878 '[2, 3, (4,[5,6])]), **{"y":9, "z":10}')
879 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
880 '(4,[5,6])]), **collections.UserDict('
881 'y=9, z=10)')
882
Benjamin Peterson6a2638b2011-03-28 17:32:31 -0500883 f = self.makeCallable('a, b=2, *f, x, y=99, **g')
884 self.assertEqualCallArgs(f, '2, 3, x=8')
885 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
886 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9, z=10')
887 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9, z=10')
888 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
889 '[2, 3, (4,[5,6])]), q=0, **{"y":9, "z":10}')
890 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
891 '(4,[5,6])]), q=0, **collections.UserDict('
892 'y=9, z=10)')
893
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000894 def test_errors(self):
895 f0 = self.makeCallable('')
896 f1 = self.makeCallable('a, b')
897 f2 = self.makeCallable('a, b=1')
898 # f0 takes no arguments
899 self.assertEqualException(f0, '1')
900 self.assertEqualException(f0, 'x=1')
901 self.assertEqualException(f0, '1,x=1')
902 # f1 takes exactly 2 arguments
903 self.assertEqualException(f1, '')
904 self.assertEqualException(f1, '1')
905 self.assertEqualException(f1, 'a=2')
906 self.assertEqualException(f1, 'b=3')
907 # f2 takes at least 1 argument
908 self.assertEqualException(f2, '')
909 self.assertEqualException(f2, 'b=3')
910 for f in f1, f2:
911 # f1/f2 takes exactly/at most 2 arguments
912 self.assertEqualException(f, '2, 3, 4')
913 self.assertEqualException(f, '1, 2, 3, a=1')
914 self.assertEqualException(f, '2, 3, 4, c=5')
Georg Brandl178e5ea2012-02-21 00:32:36 +0100915 # XXX: success of this one depends on dict order
916 ## self.assertEqualException(f, '2, 3, 4, a=1, c=5')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000917 # f got an unexpected keyword argument
918 self.assertEqualException(f, 'c=2')
919 self.assertEqualException(f, '2, c=3')
920 self.assertEqualException(f, '2, 3, c=4')
921 self.assertEqualException(f, '2, c=4, b=3')
922 self.assertEqualException(f, '**{u"\u03c0\u03b9": 4}')
923 # f got multiple values for keyword argument
924 self.assertEqualException(f, '1, a=2')
925 self.assertEqualException(f, '1, **{"a":2}')
926 self.assertEqualException(f, '1, 2, b=3')
927 # XXX: Python inconsistency
928 # - for functions and bound methods: unexpected keyword 'c'
929 # - for unbound methods: multiple values for keyword 'a'
930 #self.assertEqualException(f, '1, c=3, a=2')
Benjamin Peterson6a2638b2011-03-28 17:32:31 -0500931 # issue11256:
932 f3 = self.makeCallable('**c')
933 self.assertEqualException(f3, '1, 2')
934 self.assertEqualException(f3, '1, 2, a=1, b=2')
935 f4 = self.makeCallable('*, a, b=0')
936 self.assertEqualException(f3, '1, 2')
937 self.assertEqualException(f3, '1, 2, a=1, b=2')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000938
939class TestGetcallargsMethods(TestGetcallargsFunctions):
940
941 def setUp(self):
942 class Foo(object):
943 pass
944 self.cls = Foo
945 self.inst = Foo()
946
947 def makeCallable(self, signature):
948 assert 'self' not in signature
949 mk = super(TestGetcallargsMethods, self).makeCallable
950 self.cls.method = mk('self, ' + signature)
951 return self.inst.method
952
953class TestGetcallargsUnboundMethods(TestGetcallargsMethods):
954
955 def makeCallable(self, signature):
956 super(TestGetcallargsUnboundMethods, self).makeCallable(signature)
957 return self.cls.method
958
959 def assertEqualCallArgs(self, func, call_params_string, locs=None):
960 return super(TestGetcallargsUnboundMethods, self).assertEqualCallArgs(
961 *self._getAssertEqualParams(func, call_params_string, locs))
962
963 def assertEqualException(self, func, call_params_string, locs=None):
964 return super(TestGetcallargsUnboundMethods, self).assertEqualException(
965 *self._getAssertEqualParams(func, call_params_string, locs))
966
967 def _getAssertEqualParams(self, func, call_params_string, locs=None):
968 assert 'inst' not in call_params_string
969 locs = dict(locs or {}, inst=self.inst)
970 return (func, 'inst,' + call_params_string, locs)
971
Michael Foord95fc51d2010-11-20 15:07:30 +0000972
973class TestGetattrStatic(unittest.TestCase):
974
975 def test_basic(self):
976 class Thing(object):
977 x = object()
978
979 thing = Thing()
980 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
981 self.assertEqual(inspect.getattr_static(thing, 'x', None), Thing.x)
982 with self.assertRaises(AttributeError):
983 inspect.getattr_static(thing, 'y')
984
985 self.assertEqual(inspect.getattr_static(thing, 'y', 3), 3)
986
987 def test_inherited(self):
988 class Thing(object):
989 x = object()
990 class OtherThing(Thing):
991 pass
992
993 something = OtherThing()
994 self.assertEqual(inspect.getattr_static(something, 'x'), Thing.x)
995
996 def test_instance_attr(self):
997 class Thing(object):
998 x = 2
999 def __init__(self, x):
1000 self.x = x
1001 thing = Thing(3)
1002 self.assertEqual(inspect.getattr_static(thing, 'x'), 3)
1003 del thing.x
1004 self.assertEqual(inspect.getattr_static(thing, 'x'), 2)
1005
1006 def test_property(self):
1007 class Thing(object):
1008 @property
1009 def x(self):
1010 raise AttributeError("I'm pretending not to exist")
1011 thing = Thing()
1012 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1013
Ezio Melotti75cbd732011-04-28 00:59:29 +03001014 def test_descriptor_raises_AttributeError(self):
Michael Foord95fc51d2010-11-20 15:07:30 +00001015 class descriptor(object):
1016 def __get__(*_):
1017 raise AttributeError("I'm pretending not to exist")
1018 desc = descriptor()
1019 class Thing(object):
1020 x = desc
1021 thing = Thing()
1022 self.assertEqual(inspect.getattr_static(thing, 'x'), desc)
1023
1024 def test_classAttribute(self):
1025 class Thing(object):
1026 x = object()
1027
1028 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.x)
1029
1030 def test_inherited_classattribute(self):
1031 class Thing(object):
1032 x = object()
1033 class OtherThing(Thing):
1034 pass
1035
1036 self.assertEqual(inspect.getattr_static(OtherThing, 'x'), Thing.x)
1037
1038 def test_slots(self):
1039 class Thing(object):
1040 y = 'bar'
1041 __slots__ = ['x']
1042 def __init__(self):
1043 self.x = 'foo'
1044 thing = Thing()
1045 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1046 self.assertEqual(inspect.getattr_static(thing, 'y'), 'bar')
1047
1048 del thing.x
1049 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1050
1051 def test_metaclass(self):
1052 class meta(type):
1053 attr = 'foo'
1054 class Thing(object, metaclass=meta):
1055 pass
1056 self.assertEqual(inspect.getattr_static(Thing, 'attr'), 'foo')
1057
1058 class sub(meta):
1059 pass
1060 class OtherThing(object, metaclass=sub):
1061 x = 3
1062 self.assertEqual(inspect.getattr_static(OtherThing, 'attr'), 'foo')
1063
1064 class OtherOtherThing(OtherThing):
1065 pass
1066 # this test is odd, but it was added as it exposed a bug
1067 self.assertEqual(inspect.getattr_static(OtherOtherThing, 'x'), 3)
1068
1069 def test_no_dict_no_slots(self):
1070 self.assertEqual(inspect.getattr_static(1, 'foo', None), None)
1071 self.assertNotEqual(inspect.getattr_static('foo', 'lower'), None)
1072
1073 def test_no_dict_no_slots_instance_member(self):
1074 # returns descriptor
1075 with open(__file__) as handle:
1076 self.assertEqual(inspect.getattr_static(handle, 'name'), type(handle).name)
1077
1078 def test_inherited_slots(self):
1079 # returns descriptor
1080 class Thing(object):
1081 __slots__ = ['x']
1082 def __init__(self):
1083 self.x = 'foo'
1084
1085 class OtherThing(Thing):
1086 pass
1087 # it would be nice if this worked...
1088 # we get the descriptor instead of the instance attribute
1089 self.assertEqual(inspect.getattr_static(OtherThing(), 'x'), Thing.x)
1090
1091 def test_descriptor(self):
1092 class descriptor(object):
1093 def __get__(self, instance, owner):
1094 return 3
1095 class Foo(object):
1096 d = descriptor()
1097
1098 foo = Foo()
1099
1100 # for a non data descriptor we return the instance attribute
1101 foo.__dict__['d'] = 1
1102 self.assertEqual(inspect.getattr_static(foo, 'd'), 1)
1103
1104 # if the descriptor is a data-desciptor we should return the
1105 # descriptor
1106 descriptor.__set__ = lambda s, i, v: None
1107 self.assertEqual(inspect.getattr_static(foo, 'd'), Foo.__dict__['d'])
1108
1109
1110 def test_metaclass_with_descriptor(self):
1111 class descriptor(object):
1112 def __get__(self, instance, owner):
1113 return 3
1114 class meta(type):
1115 d = descriptor()
1116 class Thing(object, metaclass=meta):
1117 pass
1118 self.assertEqual(inspect.getattr_static(Thing, 'd'), meta.__dict__['d'])
1119
1120
Michael Foordcc7ebb82010-11-20 16:20:16 +00001121 def test_class_as_property(self):
1122 class Base(object):
1123 foo = 3
1124
1125 class Something(Base):
Michael Foord35184ed2010-11-20 16:58:30 +00001126 executed = False
Michael Foordcc7ebb82010-11-20 16:20:16 +00001127 @property
1128 def __class__(self):
Michael Foord35184ed2010-11-20 16:58:30 +00001129 self.executed = True
Michael Foordcc7ebb82010-11-20 16:20:16 +00001130 return object
1131
Michael Foord35184ed2010-11-20 16:58:30 +00001132 instance = Something()
1133 self.assertEqual(inspect.getattr_static(instance, 'foo'), 3)
1134 self.assertFalse(instance.executed)
Michael Foordcc7ebb82010-11-20 16:20:16 +00001135 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1136
Michael Foorde5162652010-11-20 16:40:44 +00001137 def test_mro_as_property(self):
1138 class Meta(type):
1139 @property
1140 def __mro__(self):
1141 return (object,)
1142
1143 class Base(object):
1144 foo = 3
1145
1146 class Something(Base, metaclass=Meta):
1147 pass
1148
1149 self.assertEqual(inspect.getattr_static(Something(), 'foo'), 3)
1150 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1151
Michael Foorddcebe0f2011-03-15 19:20:44 -04001152 def test_dict_as_property(self):
1153 test = self
1154 test.called = False
1155
1156 class Foo(dict):
1157 a = 3
1158 @property
1159 def __dict__(self):
1160 test.called = True
1161 return {}
1162
1163 foo = Foo()
1164 foo.a = 4
1165 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1166 self.assertFalse(test.called)
1167
1168 def test_custom_object_dict(self):
1169 test = self
1170 test.called = False
1171
1172 class Custom(dict):
1173 def get(self, key, default=None):
1174 test.called = True
1175 super().get(key, default)
1176
1177 class Foo(object):
1178 a = 3
1179 foo = Foo()
1180 foo.__dict__ = Custom()
1181 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1182 self.assertFalse(test.called)
1183
1184 def test_metaclass_dict_as_property(self):
1185 class Meta(type):
1186 @property
1187 def __dict__(self):
1188 self.executed = True
1189
1190 class Thing(metaclass=Meta):
1191 executed = False
1192
1193 def __init__(self):
1194 self.spam = 42
1195
1196 instance = Thing()
1197 self.assertEqual(inspect.getattr_static(instance, "spam"), 42)
1198 self.assertFalse(Thing.executed)
Michael Foorde5162652010-11-20 16:40:44 +00001199
Michael Foorda51623b2011-12-18 22:01:40 +00001200 def test_module(self):
1201 sentinel = object()
1202 self.assertIsNot(inspect.getattr_static(sys, "version", sentinel),
1203 sentinel)
1204
Michael Foord3ba95f82011-12-22 01:13:37 +00001205 def test_metaclass_with_metaclass_with_dict_as_property(self):
1206 class MetaMeta(type):
1207 @property
1208 def __dict__(self):
1209 self.executed = True
1210 return dict(spam=42)
1211
1212 class Meta(type, metaclass=MetaMeta):
1213 executed = False
1214
1215 class Thing(metaclass=Meta):
1216 pass
1217
1218 with self.assertRaises(AttributeError):
1219 inspect.getattr_static(Thing, "spam")
1220 self.assertFalse(Thing.executed)
1221
Nick Coghlane0f04652010-11-21 03:44:04 +00001222class TestGetGeneratorState(unittest.TestCase):
1223
1224 def setUp(self):
1225 def number_generator():
1226 for number in range(5):
1227 yield number
1228 self.generator = number_generator()
1229
1230 def _generatorstate(self):
1231 return inspect.getgeneratorstate(self.generator)
1232
1233 def test_created(self):
1234 self.assertEqual(self._generatorstate(), inspect.GEN_CREATED)
1235
1236 def test_suspended(self):
1237 next(self.generator)
1238 self.assertEqual(self._generatorstate(), inspect.GEN_SUSPENDED)
1239
1240 def test_closed_after_exhaustion(self):
1241 for i in self.generator:
1242 pass
1243 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1244
1245 def test_closed_after_immediate_exception(self):
1246 with self.assertRaises(RuntimeError):
1247 self.generator.throw(RuntimeError)
1248 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1249
1250 def test_running(self):
1251 # As mentioned on issue #10220, checking for the RUNNING state only
1252 # makes sense inside the generator itself.
1253 # The following generator checks for this by using the closure's
1254 # reference to self and the generator state checking helper method
1255 def running_check_generator():
1256 for number in range(5):
1257 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1258 yield number
1259 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1260 self.generator = running_check_generator()
1261 # Running up to the first yield
1262 next(self.generator)
1263 # Running after the first yield
1264 next(self.generator)
1265
Nick Coghlan7921b9f2010-11-30 06:36:04 +00001266 def test_easy_debugging(self):
1267 # repr() and str() of a generator state should contain the state name
1268 names = 'GEN_CREATED GEN_RUNNING GEN_SUSPENDED GEN_CLOSED'.split()
1269 for name in names:
1270 state = getattr(inspect, name)
1271 self.assertIn(name, repr(state))
1272 self.assertIn(name, str(state))
1273
Nick Coghlane0f04652010-11-21 03:44:04 +00001274
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001275class TestSignatureObject(unittest.TestCase):
1276 @staticmethod
1277 def signature(func):
1278 sig = inspect.signature(func)
1279 return (tuple((param.name,
1280 (... if param.default is param.empty else param.default),
1281 (... if param.annotation is param.empty
1282 else param.annotation),
1283 str(param.kind).lower())
1284 for param in sig.parameters.values()),
1285 (... if sig.return_annotation is sig.empty
1286 else sig.return_annotation))
1287
1288 def test_signature_object(self):
1289 S = inspect.Signature
1290 P = inspect.Parameter
1291
1292 self.assertEqual(str(S()), '()')
1293
1294 def test(po, pk, *args, ko, **kwargs):
1295 pass
1296 sig = inspect.signature(test)
1297 po = sig.parameters['po'].replace(kind=P.POSITIONAL_ONLY)
1298 pk = sig.parameters['pk']
1299 args = sig.parameters['args']
1300 ko = sig.parameters['ko']
1301 kwargs = sig.parameters['kwargs']
1302
1303 S((po, pk, args, ko, kwargs))
1304
1305 with self.assertRaisesRegexp(ValueError, 'wrong parameter order'):
1306 S((pk, po, args, ko, kwargs))
1307
1308 with self.assertRaisesRegexp(ValueError, 'wrong parameter order'):
1309 S((po, args, pk, ko, kwargs))
1310
1311 with self.assertRaisesRegexp(ValueError, 'wrong parameter order'):
1312 S((args, po, pk, ko, kwargs))
1313
1314 with self.assertRaisesRegexp(ValueError, 'wrong parameter order'):
1315 S((po, pk, args, kwargs, ko))
1316
1317 kwargs2 = kwargs.replace(name='args')
1318 with self.assertRaisesRegexp(ValueError, 'duplicate parameter name'):
1319 S((po, pk, args, kwargs2, ko))
1320
1321 def test_signature_immutability(self):
1322 def test(a):
1323 pass
1324 sig = inspect.signature(test)
1325
1326 with self.assertRaises(AttributeError):
1327 sig.foo = 'bar'
1328
1329 with self.assertRaises(TypeError):
1330 sig.parameters['a'] = None
1331
1332 def test_signature_on_noarg(self):
1333 def test():
1334 pass
1335 self.assertEqual(self.signature(test), ((), ...))
1336
1337 def test_signature_on_wargs(self):
1338 def test(a, b:'foo') -> 123:
1339 pass
1340 self.assertEqual(self.signature(test),
1341 ((('a', ..., ..., "positional_or_keyword"),
1342 ('b', ..., 'foo', "positional_or_keyword")),
1343 123))
1344
1345 def test_signature_on_wkwonly(self):
1346 def test(*, a:float, b:str) -> int:
1347 pass
1348 self.assertEqual(self.signature(test),
1349 ((('a', ..., float, "keyword_only"),
1350 ('b', ..., str, "keyword_only")),
1351 int))
1352
1353 def test_signature_on_complex_args(self):
1354 def test(a, b:'foo'=10, *args:'bar', spam:'baz', ham=123, **kwargs:int):
1355 pass
1356 self.assertEqual(self.signature(test),
1357 ((('a', ..., ..., "positional_or_keyword"),
1358 ('b', 10, 'foo', "positional_or_keyword"),
1359 ('args', ..., 'bar', "var_positional"),
1360 ('spam', ..., 'baz', "keyword_only"),
1361 ('ham', 123, ..., "keyword_only"),
1362 ('kwargs', ..., int, "var_keyword")),
1363 ...))
1364
1365 def test_signature_on_builtin_function(self):
1366 with self.assertRaisesRegexp(ValueError, 'not supported by signature'):
1367 inspect.signature(type)
1368 with self.assertRaisesRegexp(ValueError, 'not supported by signature'):
1369 # support for 'wrapper_descriptor'
1370 inspect.signature(type.__call__)
1371 with self.assertRaisesRegexp(ValueError, 'not supported by signature'):
1372 # support for 'method-wrapper'
1373 inspect.signature(min.__call__)
1374 with self.assertRaisesRegexp(ValueError,
1375 'no signature found for builtin function'):
1376 # support for 'method-wrapper'
1377 inspect.signature(min)
1378
1379 def test_signature_on_non_function(self):
1380 with self.assertRaisesRegexp(TypeError, 'is not a callable object'):
1381 inspect.signature(42)
1382
1383 with self.assertRaisesRegexp(TypeError, 'is not a Python function'):
1384 inspect.Signature.from_function(42)
1385
1386 def test_signature_on_method(self):
1387 class Test:
1388 def foo(self, arg1, arg2=1) -> int:
1389 pass
1390
1391 meth = Test().foo
1392
1393 self.assertEqual(self.signature(meth),
1394 ((('arg1', ..., ..., "positional_or_keyword"),
1395 ('arg2', 1, ..., "positional_or_keyword")),
1396 int))
1397
1398 def test_signature_on_classmethod(self):
1399 class Test:
1400 @classmethod
1401 def foo(cls, arg1, *, arg2=1):
1402 pass
1403
1404 meth = Test().foo
1405 self.assertEqual(self.signature(meth),
1406 ((('arg1', ..., ..., "positional_or_keyword"),
1407 ('arg2', 1, ..., "keyword_only")),
1408 ...))
1409
1410 meth = Test.foo
1411 self.assertEqual(self.signature(meth),
1412 ((('arg1', ..., ..., "positional_or_keyword"),
1413 ('arg2', 1, ..., "keyword_only")),
1414 ...))
1415
1416 def test_signature_on_staticmethod(self):
1417 class Test:
1418 @staticmethod
1419 def foo(cls, *, arg):
1420 pass
1421
1422 meth = Test().foo
1423 self.assertEqual(self.signature(meth),
1424 ((('cls', ..., ..., "positional_or_keyword"),
1425 ('arg', ..., ..., "keyword_only")),
1426 ...))
1427
1428 meth = Test.foo
1429 self.assertEqual(self.signature(meth),
1430 ((('cls', ..., ..., "positional_or_keyword"),
1431 ('arg', ..., ..., "keyword_only")),
1432 ...))
1433
1434 def test_signature_on_partial(self):
1435 from functools import partial
1436
1437 def test():
1438 pass
1439
1440 self.assertEqual(self.signature(partial(test)), ((), ...))
1441
1442 with self.assertRaisesRegexp(ValueError, "has incorrect arguments"):
1443 inspect.signature(partial(test, 1))
1444
1445 with self.assertRaisesRegexp(ValueError, "has incorrect arguments"):
1446 inspect.signature(partial(test, a=1))
1447
1448 def test(a, b, *, c, d):
1449 pass
1450
1451 self.assertEqual(self.signature(partial(test)),
1452 ((('a', ..., ..., "positional_or_keyword"),
1453 ('b', ..., ..., "positional_or_keyword"),
1454 ('c', ..., ..., "keyword_only"),
1455 ('d', ..., ..., "keyword_only")),
1456 ...))
1457
1458 self.assertEqual(self.signature(partial(test, 1)),
1459 ((('b', ..., ..., "positional_or_keyword"),
1460 ('c', ..., ..., "keyword_only"),
1461 ('d', ..., ..., "keyword_only")),
1462 ...))
1463
1464 self.assertEqual(self.signature(partial(test, 1, c=2)),
1465 ((('b', ..., ..., "positional_or_keyword"),
1466 ('c', 2, ..., "keyword_only"),
1467 ('d', ..., ..., "keyword_only")),
1468 ...))
1469
1470 self.assertEqual(self.signature(partial(test, b=1, c=2)),
1471 ((('a', ..., ..., "positional_or_keyword"),
1472 ('b', 1, ..., "positional_or_keyword"),
1473 ('c', 2, ..., "keyword_only"),
1474 ('d', ..., ..., "keyword_only")),
1475 ...))
1476
1477 self.assertEqual(self.signature(partial(test, 0, b=1, c=2)),
1478 ((('b', 1, ..., "positional_or_keyword"),
1479 ('c', 2, ..., "keyword_only"),
1480 ('d', ..., ..., "keyword_only"),),
1481 ...))
1482
1483 def test(a, *args, b, **kwargs):
1484 pass
1485
1486 self.assertEqual(self.signature(partial(test, 1)),
1487 ((('args', ..., ..., "var_positional"),
1488 ('b', ..., ..., "keyword_only"),
1489 ('kwargs', ..., ..., "var_keyword")),
1490 ...))
1491
1492 self.assertEqual(self.signature(partial(test, 1, 2, 3)),
1493 ((('args', ..., ..., "var_positional"),
1494 ('b', ..., ..., "keyword_only"),
1495 ('kwargs', ..., ..., "var_keyword")),
1496 ...))
1497
1498
1499 self.assertEqual(self.signature(partial(test, 1, 2, 3, test=True)),
1500 ((('args', ..., ..., "var_positional"),
1501 ('b', ..., ..., "keyword_only"),
1502 ('kwargs', ..., ..., "var_keyword")),
1503 ...))
1504
1505 self.assertEqual(self.signature(partial(test, 1, 2, 3, test=1, b=0)),
1506 ((('args', ..., ..., "var_positional"),
1507 ('b', 0, ..., "keyword_only"),
1508 ('kwargs', ..., ..., "var_keyword")),
1509 ...))
1510
1511 self.assertEqual(self.signature(partial(test, b=0)),
1512 ((('a', ..., ..., "positional_or_keyword"),
1513 ('args', ..., ..., "var_positional"),
1514 ('b', 0, ..., "keyword_only"),
1515 ('kwargs', ..., ..., "var_keyword")),
1516 ...))
1517
1518 self.assertEqual(self.signature(partial(test, b=0, test=1)),
1519 ((('a', ..., ..., "positional_or_keyword"),
1520 ('args', ..., ..., "var_positional"),
1521 ('b', 0, ..., "keyword_only"),
1522 ('kwargs', ..., ..., "var_keyword")),
1523 ...))
1524
1525 def test(a, b, c:int) -> 42:
1526 pass
1527
1528 sig = test.__signature__ = inspect.signature(test)
1529
1530 self.assertEqual(self.signature(partial(partial(test, 1))),
1531 ((('b', ..., ..., "positional_or_keyword"),
1532 ('c', ..., int, "positional_or_keyword")),
1533 42))
1534
1535 self.assertEqual(self.signature(partial(partial(test, 1), 2)),
1536 ((('c', ..., int, "positional_or_keyword"),),
1537 42))
1538
1539 psig = inspect.signature(partial(partial(test, 1), 2))
1540
1541 def foo(a):
1542 return a
1543 _foo = partial(partial(foo, a=10), a=20)
1544 self.assertEqual(self.signature(_foo),
1545 ((('a', 20, ..., "positional_or_keyword"),),
1546 ...))
1547 # check that we don't have any side-effects in signature(),
1548 # and the partial object is still functioning
1549 self.assertEqual(_foo(), 20)
1550
1551 def foo(a, b, c):
1552 return a, b, c
1553 _foo = partial(partial(foo, 1, b=20), b=30)
1554 self.assertEqual(self.signature(_foo),
1555 ((('b', 30, ..., "positional_or_keyword"),
1556 ('c', ..., ..., "positional_or_keyword")),
1557 ...))
1558 self.assertEqual(_foo(c=10), (1, 30, 10))
1559 _foo = partial(_foo, 2) # now 'b' has two values -
1560 # positional and keyword
1561 with self.assertRaisesRegexp(ValueError, "has incorrect arguments"):
1562 inspect.signature(_foo)
1563
1564 def foo(a, b, c, *, d):
1565 return a, b, c, d
1566 _foo = partial(partial(foo, d=20, c=20), b=10, d=30)
1567 self.assertEqual(self.signature(_foo),
1568 ((('a', ..., ..., "positional_or_keyword"),
1569 ('b', 10, ..., "positional_or_keyword"),
1570 ('c', 20, ..., "positional_or_keyword"),
1571 ('d', 30, ..., "keyword_only")),
1572 ...))
1573 ba = inspect.signature(_foo).bind(a=200, b=11)
1574 self.assertEqual(_foo(*ba.args, **ba.kwargs), (200, 11, 20, 30))
1575
1576 def foo(a=1, b=2, c=3):
1577 return a, b, c
1578 _foo = partial(foo, a=10, c=13)
1579 ba = inspect.signature(_foo).bind(11)
1580 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 2, 13))
1581 ba = inspect.signature(_foo).bind(11, 12)
1582 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
1583 ba = inspect.signature(_foo).bind(11, b=12)
1584 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
1585 ba = inspect.signature(_foo).bind(b=12)
1586 self.assertEqual(_foo(*ba.args, **ba.kwargs), (10, 12, 13))
1587 _foo = partial(_foo, b=10)
1588 ba = inspect.signature(_foo).bind(12, 14)
1589 self.assertEqual(_foo(*ba.args, **ba.kwargs), (12, 14, 13))
1590
1591 def test_signature_on_decorated(self):
1592 import functools
1593
1594 def decorator(func):
1595 @functools.wraps(func)
1596 def wrapper(*args, **kwargs) -> int:
1597 return func(*args, **kwargs)
1598 return wrapper
1599
1600 class Foo:
1601 @decorator
1602 def bar(self, a, b):
1603 pass
1604
1605 self.assertEqual(self.signature(Foo.bar),
1606 ((('self', ..., ..., "positional_or_keyword"),
1607 ('a', ..., ..., "positional_or_keyword"),
1608 ('b', ..., ..., "positional_or_keyword")),
1609 ...))
1610
1611 self.assertEqual(self.signature(Foo().bar),
1612 ((('a', ..., ..., "positional_or_keyword"),
1613 ('b', ..., ..., "positional_or_keyword")),
1614 ...))
1615
1616 # Test that we handle method wrappers correctly
1617 def decorator(func):
1618 @functools.wraps(func)
1619 def wrapper(*args, **kwargs) -> int:
1620 return func(42, *args, **kwargs)
1621 sig = inspect.signature(func)
1622 new_params = tuple(sig.parameters.values())[1:]
1623 wrapper.__signature__ = sig.replace(parameters=new_params)
1624 return wrapper
1625
1626 class Foo:
1627 @decorator
1628 def __call__(self, a, b):
1629 pass
1630
1631 self.assertEqual(self.signature(Foo.__call__),
1632 ((('a', ..., ..., "positional_or_keyword"),
1633 ('b', ..., ..., "positional_or_keyword")),
1634 ...))
1635
1636 self.assertEqual(self.signature(Foo().__call__),
1637 ((('b', ..., ..., "positional_or_keyword"),),
1638 ...))
1639
1640 def test_signature_on_class(self):
1641 class C:
1642 def __init__(self, a):
1643 pass
1644
1645 self.assertEqual(self.signature(C),
1646 ((('a', ..., ..., "positional_or_keyword"),),
1647 ...))
1648
1649 class CM(type):
1650 def __call__(cls, a):
1651 pass
1652 class C(metaclass=CM):
1653 def __init__(self, b):
1654 pass
1655
1656 self.assertEqual(self.signature(C),
1657 ((('a', ..., ..., "positional_or_keyword"),),
1658 ...))
1659
1660 class CM(type):
1661 def __new__(mcls, name, bases, dct, *, foo=1):
1662 return super().__new__(mcls, name, bases, dct)
1663 class C(metaclass=CM):
1664 def __init__(self, b):
1665 pass
1666
1667 self.assertEqual(self.signature(C),
1668 ((('b', ..., ..., "positional_or_keyword"),),
1669 ...))
1670
1671 self.assertEqual(self.signature(CM),
1672 ((('name', ..., ..., "positional_or_keyword"),
1673 ('bases', ..., ..., "positional_or_keyword"),
1674 ('dct', ..., ..., "positional_or_keyword"),
1675 ('foo', 1, ..., "keyword_only")),
1676 ...))
1677
1678 class CMM(type):
1679 def __new__(mcls, name, bases, dct, *, foo=1):
1680 return super().__new__(mcls, name, bases, dct)
1681 def __call__(cls, nm, bs, dt):
1682 return type(nm, bs, dt)
1683 class CM(type, metaclass=CMM):
1684 def __new__(mcls, name, bases, dct, *, bar=2):
1685 return super().__new__(mcls, name, bases, dct)
1686 class C(metaclass=CM):
1687 def __init__(self, b):
1688 pass
1689
1690 self.assertEqual(self.signature(CMM),
1691 ((('name', ..., ..., "positional_or_keyword"),
1692 ('bases', ..., ..., "positional_or_keyword"),
1693 ('dct', ..., ..., "positional_or_keyword"),
1694 ('foo', 1, ..., "keyword_only")),
1695 ...))
1696
1697 self.assertEqual(self.signature(CM),
1698 ((('nm', ..., ..., "positional_or_keyword"),
1699 ('bs', ..., ..., "positional_or_keyword"),
1700 ('dt', ..., ..., "positional_or_keyword")),
1701 ...))
1702
1703 self.assertEqual(self.signature(C),
1704 ((('b', ..., ..., "positional_or_keyword"),),
1705 ...))
1706
1707 class CM(type):
1708 def __init__(cls, name, bases, dct, *, bar=2):
1709 return super().__init__(name, bases, dct)
1710 class C(metaclass=CM):
1711 def __init__(self, b):
1712 pass
1713
1714 self.assertEqual(self.signature(CM),
1715 ((('name', ..., ..., "positional_or_keyword"),
1716 ('bases', ..., ..., "positional_or_keyword"),
1717 ('dct', ..., ..., "positional_or_keyword"),
1718 ('bar', 2, ..., "keyword_only")),
1719 ...))
1720
1721 def test_signature_on_callable_objects(self):
1722 class Foo:
1723 def __call__(self, a):
1724 pass
1725
1726 self.assertEqual(self.signature(Foo()),
1727 ((('a', ..., ..., "positional_or_keyword"),),
1728 ...))
1729
1730 class Spam:
1731 pass
1732 with self.assertRaisesRegexp(TypeError, "is not a callable object"):
1733 inspect.signature(Spam())
1734
1735 class Bar(Spam, Foo):
1736 pass
1737
1738 self.assertEqual(self.signature(Bar()),
1739 ((('a', ..., ..., "positional_or_keyword"),),
1740 ...))
1741
1742 class ToFail:
1743 __call__ = type
1744 with self.assertRaisesRegexp(ValueError, "not supported by signature"):
1745 inspect.signature(ToFail())
1746
1747
1748 class Wrapped:
1749 pass
1750 Wrapped.__wrapped__ = lambda a: None
1751 self.assertEqual(self.signature(Wrapped),
1752 ((('a', ..., ..., "positional_or_keyword"),),
1753 ...))
1754
1755 def test_signature_on_lambdas(self):
1756 self.assertEqual(self.signature((lambda a=10: a)),
1757 ((('a', 10, ..., "positional_or_keyword"),),
1758 ...))
1759
1760 def test_signature_equality(self):
1761 def foo(a, *, b:int) -> float: pass
1762 self.assertNotEqual(inspect.signature(foo), 42)
1763
1764 def bar(a, *, b:int) -> float: pass
1765 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
1766
1767 def bar(a, *, b:int) -> int: pass
1768 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
1769
1770 def bar(a, *, b:int): pass
1771 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
1772
1773 def bar(a, *, b:int=42) -> float: pass
1774 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
1775
1776 def bar(a, *, c) -> float: pass
1777 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
1778
1779 def bar(a, b:int) -> float: pass
1780 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
1781 def spam(b:int, a) -> float: pass
1782 self.assertNotEqual(inspect.signature(spam), inspect.signature(bar))
1783
1784 def foo(*, a, b, c): pass
1785 def bar(*, c, b, a): pass
1786 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
1787
1788 def foo(*, a=1, b, c): pass
1789 def bar(*, c, b, a=1): pass
1790 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
1791
1792 def foo(pos, *, a=1, b, c): pass
1793 def bar(pos, *, c, b, a=1): pass
1794 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
1795
1796 def foo(pos, *, a, b, c): pass
1797 def bar(pos, *, c, b, a=1): pass
1798 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
1799
1800 def foo(pos, *args, a=42, b, c, **kwargs:int): pass
1801 def bar(pos, *args, c, b, a=42, **kwargs:int): pass
1802 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
1803
1804 def test_signature_unhashable(self):
1805 def foo(a): pass
1806 sig = inspect.signature(foo)
1807 with self.assertRaisesRegexp(TypeError, 'unhashable type'):
1808 hash(sig)
1809
1810 def test_signature_str(self):
1811 def foo(a:int=1, *, b, c=None, **kwargs) -> 42:
1812 pass
1813 self.assertEqual(str(inspect.signature(foo)),
1814 '(a:int=1, *, b, c=None, **kwargs) -> 42')
1815
1816 def foo(a:int=1, *args, b, c=None, **kwargs) -> 42:
1817 pass
1818 self.assertEqual(str(inspect.signature(foo)),
1819 '(a:int=1, *args, b, c=None, **kwargs) -> 42')
1820
1821 def foo():
1822 pass
1823 self.assertEqual(str(inspect.signature(foo)), '()')
1824
1825 def test_signature_str_positional_only(self):
1826 P = inspect.Parameter
1827
1828 def test(a_po, *, b, **kwargs):
1829 return a_po, kwargs
1830
1831 sig = inspect.signature(test)
1832 new_params = list(sig.parameters.values())
1833 new_params[0] = new_params[0].replace(kind=P.POSITIONAL_ONLY)
1834 test.__signature__ = sig.replace(parameters=new_params)
1835
1836 self.assertEqual(str(inspect.signature(test)),
1837 '(<a_po>, *, b, **kwargs)')
1838
1839 sig = inspect.signature(test)
1840 new_params = list(sig.parameters.values())
1841 new_params[0] = new_params[0].replace(name=None)
1842 test.__signature__ = sig.replace(parameters=new_params)
1843 self.assertEqual(str(inspect.signature(test)),
1844 '(<0>, *, b, **kwargs)')
1845
1846 def test_signature_replace_anno(self):
1847 def test() -> 42:
1848 pass
1849
1850 sig = inspect.signature(test)
1851 sig = sig.replace(return_annotation=None)
1852 self.assertIs(sig.return_annotation, None)
1853 sig = sig.replace(return_annotation=sig.empty)
1854 self.assertIs(sig.return_annotation, sig.empty)
1855 sig = sig.replace(return_annotation=42)
1856 self.assertEqual(sig.return_annotation, 42)
1857 self.assertEqual(sig, inspect.signature(test))
1858
1859
1860class TestParameterObject(unittest.TestCase):
1861 def test_signature_parameter_kinds(self):
1862 P = inspect.Parameter
1863 self.assertTrue(P.POSITIONAL_ONLY < P.POSITIONAL_OR_KEYWORD < \
1864 P.VAR_POSITIONAL < P.KEYWORD_ONLY < P.VAR_KEYWORD)
1865
1866 self.assertEqual(str(P.POSITIONAL_ONLY), 'POSITIONAL_ONLY')
1867 self.assertTrue('POSITIONAL_ONLY' in repr(P.POSITIONAL_ONLY))
1868
1869 def test_signature_parameter_object(self):
1870 p = inspect.Parameter('foo', default=10,
1871 kind=inspect.Parameter.POSITIONAL_ONLY)
1872 self.assertEqual(p.name, 'foo')
1873 self.assertEqual(p.default, 10)
1874 self.assertIs(p.annotation, p.empty)
1875 self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY)
1876
1877 with self.assertRaisesRegexp(ValueError, 'invalid value'):
1878 inspect.Parameter('foo', default=10, kind='123')
1879
1880 with self.assertRaisesRegexp(ValueError, 'not a valid parameter name'):
1881 inspect.Parameter('1', kind=inspect.Parameter.VAR_KEYWORD)
1882
1883 with self.assertRaisesRegexp(ValueError,
1884 'non-positional-only parameter'):
1885 inspect.Parameter(None, kind=inspect.Parameter.VAR_KEYWORD)
1886
1887 with self.assertRaisesRegexp(ValueError, 'cannot have default values'):
1888 inspect.Parameter('a', default=42,
1889 kind=inspect.Parameter.VAR_KEYWORD)
1890
1891 with self.assertRaisesRegexp(ValueError, 'cannot have default values'):
1892 inspect.Parameter('a', default=42,
1893 kind=inspect.Parameter.VAR_POSITIONAL)
1894
1895 p = inspect.Parameter('a', default=42,
1896 kind=inspect.Parameter.POSITIONAL_OR_KEYWORD)
1897 with self.assertRaisesRegexp(ValueError, 'cannot have default values'):
1898 p.replace(kind=inspect.Parameter.VAR_POSITIONAL)
1899
1900 self.assertTrue(repr(p).startswith('<Parameter'))
1901
1902 def test_signature_parameter_equality(self):
1903 P = inspect.Parameter
1904 p = P('foo', default=42, kind=inspect.Parameter.KEYWORD_ONLY)
1905
1906 self.assertEqual(p, p)
1907 self.assertNotEqual(p, 42)
1908
1909 self.assertEqual(p, P('foo', default=42,
1910 kind=inspect.Parameter.KEYWORD_ONLY))
1911
1912 def test_signature_parameter_unhashable(self):
1913 p = inspect.Parameter('foo', default=42,
1914 kind=inspect.Parameter.KEYWORD_ONLY)
1915
1916 with self.assertRaisesRegexp(TypeError, 'unhashable type'):
1917 hash(p)
1918
1919 def test_signature_parameter_replace(self):
1920 p = inspect.Parameter('foo', default=42,
1921 kind=inspect.Parameter.KEYWORD_ONLY)
1922
1923 self.assertIsNot(p, p.replace())
1924 self.assertEqual(p, p.replace())
1925
1926 p2 = p.replace(annotation=1)
1927 self.assertEqual(p2.annotation, 1)
1928 p2 = p2.replace(annotation=p2.empty)
1929 self.assertEqual(p, p2)
1930
1931 p2 = p2.replace(name='bar')
1932 self.assertEqual(p2.name, 'bar')
1933 self.assertNotEqual(p2, p)
1934
1935 with self.assertRaisesRegexp(ValueError, 'not a valid parameter name'):
1936 p2 = p2.replace(name=p2.empty)
1937
1938 p2 = p2.replace(name='foo', default=None)
1939 self.assertIs(p2.default, None)
1940 self.assertNotEqual(p2, p)
1941
1942 p2 = p2.replace(name='foo', default=p2.empty)
1943 self.assertIs(p2.default, p2.empty)
1944
1945
1946 p2 = p2.replace(default=42, kind=p2.POSITIONAL_OR_KEYWORD)
1947 self.assertEqual(p2.kind, p2.POSITIONAL_OR_KEYWORD)
1948 self.assertNotEqual(p2, p)
1949
1950 with self.assertRaisesRegexp(ValueError, 'invalid value for'):
1951 p2 = p2.replace(kind=p2.empty)
1952
1953 p2 = p2.replace(kind=p2.KEYWORD_ONLY)
1954 self.assertEqual(p2, p)
1955
1956 def test_signature_parameter_positional_only(self):
1957 p = inspect.Parameter(None, kind=inspect.Parameter.POSITIONAL_ONLY)
1958 self.assertEqual(str(p), '<>')
1959
1960 p = p.replace(name='1')
1961 self.assertEqual(str(p), '<1>')
1962
1963 def test_signature_parameter_immutability(self):
1964 p = inspect.Parameter(None, kind=inspect.Parameter.POSITIONAL_ONLY)
1965
1966 with self.assertRaises(AttributeError):
1967 p.foo = 'bar'
1968
1969 with self.assertRaises(AttributeError):
1970 p.kind = 123
1971
1972
1973class TestSignatureBind(unittest.TestCase):
1974 @staticmethod
1975 def call(func, *args, **kwargs):
1976 sig = inspect.signature(func)
1977 ba = sig.bind(*args, **kwargs)
1978 return func(*ba.args, **ba.kwargs)
1979
1980 def test_signature_bind_empty(self):
1981 def test():
1982 return 42
1983
1984 self.assertEqual(self.call(test), 42)
1985 with self.assertRaisesRegexp(TypeError, 'too many positional arguments'):
1986 self.call(test, 1)
1987 with self.assertRaisesRegexp(TypeError, 'too many positional arguments'):
1988 self.call(test, 1, spam=10)
1989 with self.assertRaisesRegexp(TypeError, 'too many keyword arguments'):
1990 self.call(test, spam=1)
1991
1992 def test_signature_bind_var(self):
1993 def test(*args, **kwargs):
1994 return args, kwargs
1995
1996 self.assertEqual(self.call(test), ((), {}))
1997 self.assertEqual(self.call(test, 1), ((1,), {}))
1998 self.assertEqual(self.call(test, 1, 2), ((1, 2), {}))
1999 self.assertEqual(self.call(test, foo='bar'), ((), {'foo': 'bar'}))
2000 self.assertEqual(self.call(test, 1, foo='bar'), ((1,), {'foo': 'bar'}))
2001 self.assertEqual(self.call(test, args=10), ((), {'args': 10}))
2002 self.assertEqual(self.call(test, 1, 2, foo='bar'),
2003 ((1, 2), {'foo': 'bar'}))
2004
2005 def test_signature_bind_just_args(self):
2006 def test(a, b, c):
2007 return a, b, c
2008
2009 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
2010
2011 with self.assertRaisesRegexp(TypeError, 'too many positional arguments'):
2012 self.call(test, 1, 2, 3, 4)
2013
2014 with self.assertRaisesRegexp(TypeError, "'b' parameter lacking default"):
2015 self.call(test, 1)
2016
2017 with self.assertRaisesRegexp(TypeError, "'a' parameter lacking default"):
2018 self.call(test)
2019
2020 def test(a, b, c=10):
2021 return a, b, c
2022 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
2023 self.assertEqual(self.call(test, 1, 2), (1, 2, 10))
2024
2025 def test(a=1, b=2, c=3):
2026 return a, b, c
2027 self.assertEqual(self.call(test, a=10, c=13), (10, 2, 13))
2028 self.assertEqual(self.call(test, a=10), (10, 2, 3))
2029 self.assertEqual(self.call(test, b=10), (1, 10, 3))
2030
2031 def test_signature_bind_varargs_order(self):
2032 def test(*args):
2033 return args
2034
2035 self.assertEqual(self.call(test), ())
2036 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
2037
2038 def test_signature_bind_args_and_varargs(self):
2039 def test(a, b, c=3, *args):
2040 return a, b, c, args
2041
2042 self.assertEqual(self.call(test, 1, 2, 3, 4, 5), (1, 2, 3, (4, 5)))
2043 self.assertEqual(self.call(test, 1, 2), (1, 2, 3, ()))
2044 self.assertEqual(self.call(test, b=1, a=2), (2, 1, 3, ()))
2045 self.assertEqual(self.call(test, 1, b=2), (1, 2, 3, ()))
2046
2047 with self.assertRaisesRegexp(TypeError,
2048 "multiple values for argument 'c'"):
2049 self.call(test, 1, 2, 3, c=4)
2050
2051 def test_signature_bind_just_kwargs(self):
2052 def test(**kwargs):
2053 return kwargs
2054
2055 self.assertEqual(self.call(test), {})
2056 self.assertEqual(self.call(test, foo='bar', spam='ham'),
2057 {'foo': 'bar', 'spam': 'ham'})
2058
2059 def test_signature_bind_args_and_kwargs(self):
2060 def test(a, b, c=3, **kwargs):
2061 return a, b, c, kwargs
2062
2063 self.assertEqual(self.call(test, 1, 2), (1, 2, 3, {}))
2064 self.assertEqual(self.call(test, 1, 2, foo='bar', spam='ham'),
2065 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
2066 self.assertEqual(self.call(test, b=2, a=1, foo='bar', spam='ham'),
2067 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
2068 self.assertEqual(self.call(test, a=1, b=2, foo='bar', spam='ham'),
2069 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
2070 self.assertEqual(self.call(test, 1, b=2, foo='bar', spam='ham'),
2071 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
2072 self.assertEqual(self.call(test, 1, b=2, c=4, foo='bar', spam='ham'),
2073 (1, 2, 4, {'foo': 'bar', 'spam': 'ham'}))
2074 self.assertEqual(self.call(test, 1, 2, 4, foo='bar'),
2075 (1, 2, 4, {'foo': 'bar'}))
2076 self.assertEqual(self.call(test, c=5, a=4, b=3),
2077 (4, 3, 5, {}))
2078
2079 def test_signature_bind_kwonly(self):
2080 def test(*, foo):
2081 return foo
2082 with self.assertRaisesRegexp(TypeError,
2083 'too many positional arguments'):
2084 self.call(test, 1)
2085 self.assertEqual(self.call(test, foo=1), 1)
2086
2087 def test(a, *, foo=1, bar):
2088 return foo
2089 with self.assertRaisesRegexp(TypeError,
2090 "'bar' parameter lacking default value"):
2091 self.call(test, 1)
2092
2093 def test(foo, *, bar):
2094 return foo, bar
2095 self.assertEqual(self.call(test, 1, bar=2), (1, 2))
2096 self.assertEqual(self.call(test, bar=2, foo=1), (1, 2))
2097
2098 with self.assertRaisesRegexp(TypeError,
2099 'too many keyword arguments'):
2100 self.call(test, bar=2, foo=1, spam=10)
2101
2102 with self.assertRaisesRegexp(TypeError,
2103 'too many positional arguments'):
2104 self.call(test, 1, 2)
2105
2106 with self.assertRaisesRegexp(TypeError,
2107 'too many positional arguments'):
2108 self.call(test, 1, 2, bar=2)
2109
2110 with self.assertRaisesRegexp(TypeError,
2111 'too many keyword arguments'):
2112 self.call(test, 1, bar=2, spam='ham')
2113
2114 with self.assertRaisesRegexp(TypeError,
2115 "'bar' parameter lacking default value"):
2116 self.call(test, 1)
2117
2118 def test(foo, *, bar, **bin):
2119 return foo, bar, bin
2120 self.assertEqual(self.call(test, 1, bar=2), (1, 2, {}))
2121 self.assertEqual(self.call(test, foo=1, bar=2), (1, 2, {}))
2122 self.assertEqual(self.call(test, 1, bar=2, spam='ham'),
2123 (1, 2, {'spam': 'ham'}))
2124 self.assertEqual(self.call(test, spam='ham', foo=1, bar=2),
2125 (1, 2, {'spam': 'ham'}))
2126 with self.assertRaisesRegexp(TypeError,
2127 "'foo' parameter lacking default value"):
2128 self.call(test, spam='ham', bar=2)
2129 self.assertEqual(self.call(test, 1, bar=2, bin=1, spam=10),
2130 (1, 2, {'bin': 1, 'spam': 10}))
2131
2132 def test_signature_bind_arguments(self):
2133 def test(a, *args, b, z=100, **kwargs):
2134 pass
2135 sig = inspect.signature(test)
2136 ba = sig.bind(10, 20, b=30, c=40, args=50, kwargs=60)
2137 # we won't have 'z' argument in the bound arguments object, as we didn't
2138 # pass it to the 'bind'
2139 self.assertEqual(tuple(ba.arguments.items()),
2140 (('a', 10), ('args', (20,)), ('b', 30),
2141 ('kwargs', {'c': 40, 'args': 50, 'kwargs': 60})))
2142 self.assertEqual(ba.kwargs,
2143 {'b': 30, 'c': 40, 'args': 50, 'kwargs': 60})
2144 self.assertEqual(ba.args, (10, 20))
2145
2146 def test_signature_bind_positional_only(self):
2147 P = inspect.Parameter
2148
2149 def test(a_po, b_po, c_po=3, foo=42, *, bar=50, **kwargs):
2150 return a_po, b_po, c_po, foo, bar, kwargs
2151
2152 sig = inspect.signature(test)
2153 new_params = collections.OrderedDict(tuple(sig.parameters.items()))
2154 for name in ('a_po', 'b_po', 'c_po'):
2155 new_params[name] = new_params[name].replace(kind=P.POSITIONAL_ONLY)
2156 new_sig = sig.replace(parameters=new_params.values())
2157 test.__signature__ = new_sig
2158
2159 self.assertEqual(self.call(test, 1, 2, 4, 5, bar=6),
2160 (1, 2, 4, 5, 6, {}))
2161
2162 with self.assertRaisesRegexp(TypeError, "parameter is positional only"):
2163 self.call(test, 1, 2, c_po=4)
2164
2165 with self.assertRaisesRegexp(TypeError, "parameter is positional only"):
2166 self.call(test, a_po=1, b_po=2)
2167
2168
2169class TestBoundArguments(unittest.TestCase):
2170 def test_signature_bound_arguments_unhashable(self):
2171 def foo(a): pass
2172 ba = inspect.signature(foo).bind(1)
2173
2174 with self.assertRaisesRegexp(TypeError, 'unhashable type'):
2175 hash(ba)
2176
2177 def test_signature_bound_arguments_equality(self):
2178 def foo(a): pass
2179 ba = inspect.signature(foo).bind(1)
2180 self.assertEqual(ba, ba)
2181
2182 ba2 = inspect.signature(foo).bind(1)
2183 self.assertEqual(ba, ba2)
2184
2185 ba3 = inspect.signature(foo).bind(2)
2186 self.assertNotEqual(ba, ba3)
2187 ba3.arguments['a'] = 1
2188 self.assertEqual(ba, ba3)
2189
2190 def bar(b): pass
2191 ba4 = inspect.signature(bar).bind(1)
2192 self.assertNotEqual(ba, ba4)
2193
2194
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00002195def test_main():
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00002196 run_unittest(
2197 TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBuggyCases,
2198 TestInterpreterStack, TestClassesAndFunctions, TestPredicates,
2199 TestGetcallargsFunctions, TestGetcallargsMethods,
Alexander Belopolskyf546e702010-12-02 00:10:11 +00002200 TestGetcallargsUnboundMethods, TestGetattrStatic, TestGetGeneratorState,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002201 TestNoEOL, TestSignatureObject, TestSignatureBind, TestParameterObject,
Nick Coghlan2f92e542012-06-23 19:39:55 +10002202 TestBoundArguments, TestGetClosureVars
Michael Foord95fc51d2010-11-20 15:07:30 +00002203 )
Martin v. Löwis893ffa42003-10-31 15:35:53 +00002204
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00002205if __name__ == "__main__":
2206 test_main()