blob: 53c947fc9de2d2a0d276366f279f90d6ee7e4140 [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
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000668class TestGetcallargsFunctions(unittest.TestCase):
669
670 def assertEqualCallArgs(self, func, call_params_string, locs=None):
671 locs = dict(locs or {}, func=func)
672 r1 = eval('func(%s)' % call_params_string, None, locs)
673 r2 = eval('inspect.getcallargs(func, %s)' % call_params_string, None,
674 locs)
675 self.assertEqual(r1, r2)
676
677 def assertEqualException(self, func, call_param_string, locs=None):
678 locs = dict(locs or {}, func=func)
679 try:
680 eval('func(%s)' % call_param_string, None, locs)
681 except Exception as e:
682 ex1 = e
683 else:
684 self.fail('Exception not raised')
685 try:
686 eval('inspect.getcallargs(func, %s)' % call_param_string, None,
687 locs)
688 except Exception as e:
689 ex2 = e
690 else:
691 self.fail('Exception not raised')
692 self.assertIs(type(ex1), type(ex2))
693 self.assertEqual(str(ex1), str(ex2))
694 del ex1, ex2
695
696 def makeCallable(self, signature):
697 """Create a function that returns its locals()"""
698 code = "lambda %s: locals()"
699 return eval(code % signature)
700
701 def test_plain(self):
702 f = self.makeCallable('a, b=1')
703 self.assertEqualCallArgs(f, '2')
704 self.assertEqualCallArgs(f, '2, 3')
705 self.assertEqualCallArgs(f, 'a=2')
706 self.assertEqualCallArgs(f, 'b=3, a=2')
707 self.assertEqualCallArgs(f, '2, b=3')
708 # expand *iterable / **mapping
709 self.assertEqualCallArgs(f, '*(2,)')
710 self.assertEqualCallArgs(f, '*[2]')
711 self.assertEqualCallArgs(f, '*(2, 3)')
712 self.assertEqualCallArgs(f, '*[2, 3]')
713 self.assertEqualCallArgs(f, '**{"a":2}')
714 self.assertEqualCallArgs(f, 'b=3, **{"a":2}')
715 self.assertEqualCallArgs(f, '2, **{"b":3}')
716 self.assertEqualCallArgs(f, '**{"b":3, "a":2}')
717 # expand UserList / UserDict
718 self.assertEqualCallArgs(f, '*collections.UserList([2])')
719 self.assertEqualCallArgs(f, '*collections.UserList([2, 3])')
720 self.assertEqualCallArgs(f, '**collections.UserDict(a=2)')
721 self.assertEqualCallArgs(f, '2, **collections.UserDict(b=3)')
722 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3)')
723
724 def test_varargs(self):
725 f = self.makeCallable('a, b=1, *c')
726 self.assertEqualCallArgs(f, '2')
727 self.assertEqualCallArgs(f, '2, 3')
728 self.assertEqualCallArgs(f, '2, 3, 4')
729 self.assertEqualCallArgs(f, '*(2,3,4)')
730 self.assertEqualCallArgs(f, '2, *[3,4]')
731 self.assertEqualCallArgs(f, '2, 3, *collections.UserList([4])')
732
733 def test_varkw(self):
734 f = self.makeCallable('a, b=1, **c')
735 self.assertEqualCallArgs(f, 'a=2')
736 self.assertEqualCallArgs(f, '2, b=3, c=4')
737 self.assertEqualCallArgs(f, 'b=3, a=2, c=4')
738 self.assertEqualCallArgs(f, 'c=4, **{"a":2, "b":3}')
739 self.assertEqualCallArgs(f, '2, c=4, **{"b":3}')
740 self.assertEqualCallArgs(f, 'b=2, **{"a":3, "c":4}')
741 self.assertEqualCallArgs(f, '**collections.UserDict(a=2, b=3, c=4)')
742 self.assertEqualCallArgs(f, '2, c=4, **collections.UserDict(b=3)')
743 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3, c=4)')
744
Benjamin Peterson6a2638b2011-03-28 17:32:31 -0500745 def test_varkw_only(self):
746 # issue11256:
747 f = self.makeCallable('**c')
748 self.assertEqualCallArgs(f, '')
749 self.assertEqualCallArgs(f, 'a=1')
750 self.assertEqualCallArgs(f, 'a=1, b=2')
751 self.assertEqualCallArgs(f, 'c=3, **{"a": 1, "b": 2}')
752 self.assertEqualCallArgs(f, '**collections.UserDict(a=1, b=2)')
753 self.assertEqualCallArgs(f, 'c=3, **collections.UserDict(a=1, b=2)')
754
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000755 def test_keyword_only(self):
756 f = self.makeCallable('a=3, *, c, d=2')
757 self.assertEqualCallArgs(f, 'c=3')
758 self.assertEqualCallArgs(f, 'c=3, a=3')
759 self.assertEqualCallArgs(f, 'a=2, c=4')
760 self.assertEqualCallArgs(f, '4, c=4')
761 self.assertEqualException(f, '')
762 self.assertEqualException(f, '3')
763 self.assertEqualException(f, 'a=3')
764 self.assertEqualException(f, 'd=4')
765
Benjamin Peterson6a2638b2011-03-28 17:32:31 -0500766 f = self.makeCallable('*, c, d=2')
767 self.assertEqualCallArgs(f, 'c=3')
768 self.assertEqualCallArgs(f, 'c=3, d=4')
769 self.assertEqualCallArgs(f, 'd=4, c=3')
770
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000771 def test_multiple_features(self):
772 f = self.makeCallable('a, b=2, *f, **g')
773 self.assertEqualCallArgs(f, '2, 3, 7')
774 self.assertEqualCallArgs(f, '2, 3, x=8')
775 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
776 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9')
777 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9')
778 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
779 '[2, 3, (4,[5,6])]), **{"y":9, "z":10}')
780 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
781 '(4,[5,6])]), **collections.UserDict('
782 'y=9, z=10)')
783
Benjamin Peterson6a2638b2011-03-28 17:32:31 -0500784 f = self.makeCallable('a, b=2, *f, x, y=99, **g')
785 self.assertEqualCallArgs(f, '2, 3, x=8')
786 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
787 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9, z=10')
788 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9, z=10')
789 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
790 '[2, 3, (4,[5,6])]), q=0, **{"y":9, "z":10}')
791 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
792 '(4,[5,6])]), q=0, **collections.UserDict('
793 'y=9, z=10)')
794
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000795 def test_errors(self):
796 f0 = self.makeCallable('')
797 f1 = self.makeCallable('a, b')
798 f2 = self.makeCallable('a, b=1')
799 # f0 takes no arguments
800 self.assertEqualException(f0, '1')
801 self.assertEqualException(f0, 'x=1')
802 self.assertEqualException(f0, '1,x=1')
803 # f1 takes exactly 2 arguments
804 self.assertEqualException(f1, '')
805 self.assertEqualException(f1, '1')
806 self.assertEqualException(f1, 'a=2')
807 self.assertEqualException(f1, 'b=3')
808 # f2 takes at least 1 argument
809 self.assertEqualException(f2, '')
810 self.assertEqualException(f2, 'b=3')
811 for f in f1, f2:
812 # f1/f2 takes exactly/at most 2 arguments
813 self.assertEqualException(f, '2, 3, 4')
814 self.assertEqualException(f, '1, 2, 3, a=1')
815 self.assertEqualException(f, '2, 3, 4, c=5')
Georg Brandl178e5ea2012-02-21 00:32:36 +0100816 # XXX: success of this one depends on dict order
817 ## self.assertEqualException(f, '2, 3, 4, a=1, c=5')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000818 # f got an unexpected keyword argument
819 self.assertEqualException(f, 'c=2')
820 self.assertEqualException(f, '2, c=3')
821 self.assertEqualException(f, '2, 3, c=4')
822 self.assertEqualException(f, '2, c=4, b=3')
823 self.assertEqualException(f, '**{u"\u03c0\u03b9": 4}')
824 # f got multiple values for keyword argument
825 self.assertEqualException(f, '1, a=2')
826 self.assertEqualException(f, '1, **{"a":2}')
827 self.assertEqualException(f, '1, 2, b=3')
828 # XXX: Python inconsistency
829 # - for functions and bound methods: unexpected keyword 'c'
830 # - for unbound methods: multiple values for keyword 'a'
831 #self.assertEqualException(f, '1, c=3, a=2')
Benjamin Peterson6a2638b2011-03-28 17:32:31 -0500832 # issue11256:
833 f3 = self.makeCallable('**c')
834 self.assertEqualException(f3, '1, 2')
835 self.assertEqualException(f3, '1, 2, a=1, b=2')
836 f4 = self.makeCallable('*, a, b=0')
837 self.assertEqualException(f3, '1, 2')
838 self.assertEqualException(f3, '1, 2, a=1, b=2')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000839
840class TestGetcallargsMethods(TestGetcallargsFunctions):
841
842 def setUp(self):
843 class Foo(object):
844 pass
845 self.cls = Foo
846 self.inst = Foo()
847
848 def makeCallable(self, signature):
849 assert 'self' not in signature
850 mk = super(TestGetcallargsMethods, self).makeCallable
851 self.cls.method = mk('self, ' + signature)
852 return self.inst.method
853
854class TestGetcallargsUnboundMethods(TestGetcallargsMethods):
855
856 def makeCallable(self, signature):
857 super(TestGetcallargsUnboundMethods, self).makeCallable(signature)
858 return self.cls.method
859
860 def assertEqualCallArgs(self, func, call_params_string, locs=None):
861 return super(TestGetcallargsUnboundMethods, self).assertEqualCallArgs(
862 *self._getAssertEqualParams(func, call_params_string, locs))
863
864 def assertEqualException(self, func, call_params_string, locs=None):
865 return super(TestGetcallargsUnboundMethods, self).assertEqualException(
866 *self._getAssertEqualParams(func, call_params_string, locs))
867
868 def _getAssertEqualParams(self, func, call_params_string, locs=None):
869 assert 'inst' not in call_params_string
870 locs = dict(locs or {}, inst=self.inst)
871 return (func, 'inst,' + call_params_string, locs)
872
Michael Foord95fc51d2010-11-20 15:07:30 +0000873
874class TestGetattrStatic(unittest.TestCase):
875
876 def test_basic(self):
877 class Thing(object):
878 x = object()
879
880 thing = Thing()
881 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
882 self.assertEqual(inspect.getattr_static(thing, 'x', None), Thing.x)
883 with self.assertRaises(AttributeError):
884 inspect.getattr_static(thing, 'y')
885
886 self.assertEqual(inspect.getattr_static(thing, 'y', 3), 3)
887
888 def test_inherited(self):
889 class Thing(object):
890 x = object()
891 class OtherThing(Thing):
892 pass
893
894 something = OtherThing()
895 self.assertEqual(inspect.getattr_static(something, 'x'), Thing.x)
896
897 def test_instance_attr(self):
898 class Thing(object):
899 x = 2
900 def __init__(self, x):
901 self.x = x
902 thing = Thing(3)
903 self.assertEqual(inspect.getattr_static(thing, 'x'), 3)
904 del thing.x
905 self.assertEqual(inspect.getattr_static(thing, 'x'), 2)
906
907 def test_property(self):
908 class Thing(object):
909 @property
910 def x(self):
911 raise AttributeError("I'm pretending not to exist")
912 thing = Thing()
913 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
914
Ezio Melotti75cbd732011-04-28 00:59:29 +0300915 def test_descriptor_raises_AttributeError(self):
Michael Foord95fc51d2010-11-20 15:07:30 +0000916 class descriptor(object):
917 def __get__(*_):
918 raise AttributeError("I'm pretending not to exist")
919 desc = descriptor()
920 class Thing(object):
921 x = desc
922 thing = Thing()
923 self.assertEqual(inspect.getattr_static(thing, 'x'), desc)
924
925 def test_classAttribute(self):
926 class Thing(object):
927 x = object()
928
929 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.x)
930
931 def test_inherited_classattribute(self):
932 class Thing(object):
933 x = object()
934 class OtherThing(Thing):
935 pass
936
937 self.assertEqual(inspect.getattr_static(OtherThing, 'x'), Thing.x)
938
939 def test_slots(self):
940 class Thing(object):
941 y = 'bar'
942 __slots__ = ['x']
943 def __init__(self):
944 self.x = 'foo'
945 thing = Thing()
946 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
947 self.assertEqual(inspect.getattr_static(thing, 'y'), 'bar')
948
949 del thing.x
950 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
951
952 def test_metaclass(self):
953 class meta(type):
954 attr = 'foo'
955 class Thing(object, metaclass=meta):
956 pass
957 self.assertEqual(inspect.getattr_static(Thing, 'attr'), 'foo')
958
959 class sub(meta):
960 pass
961 class OtherThing(object, metaclass=sub):
962 x = 3
963 self.assertEqual(inspect.getattr_static(OtherThing, 'attr'), 'foo')
964
965 class OtherOtherThing(OtherThing):
966 pass
967 # this test is odd, but it was added as it exposed a bug
968 self.assertEqual(inspect.getattr_static(OtherOtherThing, 'x'), 3)
969
970 def test_no_dict_no_slots(self):
971 self.assertEqual(inspect.getattr_static(1, 'foo', None), None)
972 self.assertNotEqual(inspect.getattr_static('foo', 'lower'), None)
973
974 def test_no_dict_no_slots_instance_member(self):
975 # returns descriptor
976 with open(__file__) as handle:
977 self.assertEqual(inspect.getattr_static(handle, 'name'), type(handle).name)
978
979 def test_inherited_slots(self):
980 # returns descriptor
981 class Thing(object):
982 __slots__ = ['x']
983 def __init__(self):
984 self.x = 'foo'
985
986 class OtherThing(Thing):
987 pass
988 # it would be nice if this worked...
989 # we get the descriptor instead of the instance attribute
990 self.assertEqual(inspect.getattr_static(OtherThing(), 'x'), Thing.x)
991
992 def test_descriptor(self):
993 class descriptor(object):
994 def __get__(self, instance, owner):
995 return 3
996 class Foo(object):
997 d = descriptor()
998
999 foo = Foo()
1000
1001 # for a non data descriptor we return the instance attribute
1002 foo.__dict__['d'] = 1
1003 self.assertEqual(inspect.getattr_static(foo, 'd'), 1)
1004
1005 # if the descriptor is a data-desciptor we should return the
1006 # descriptor
1007 descriptor.__set__ = lambda s, i, v: None
1008 self.assertEqual(inspect.getattr_static(foo, 'd'), Foo.__dict__['d'])
1009
1010
1011 def test_metaclass_with_descriptor(self):
1012 class descriptor(object):
1013 def __get__(self, instance, owner):
1014 return 3
1015 class meta(type):
1016 d = descriptor()
1017 class Thing(object, metaclass=meta):
1018 pass
1019 self.assertEqual(inspect.getattr_static(Thing, 'd'), meta.__dict__['d'])
1020
1021
Michael Foordcc7ebb82010-11-20 16:20:16 +00001022 def test_class_as_property(self):
1023 class Base(object):
1024 foo = 3
1025
1026 class Something(Base):
Michael Foord35184ed2010-11-20 16:58:30 +00001027 executed = False
Michael Foordcc7ebb82010-11-20 16:20:16 +00001028 @property
1029 def __class__(self):
Michael Foord35184ed2010-11-20 16:58:30 +00001030 self.executed = True
Michael Foordcc7ebb82010-11-20 16:20:16 +00001031 return object
1032
Michael Foord35184ed2010-11-20 16:58:30 +00001033 instance = Something()
1034 self.assertEqual(inspect.getattr_static(instance, 'foo'), 3)
1035 self.assertFalse(instance.executed)
Michael Foordcc7ebb82010-11-20 16:20:16 +00001036 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1037
Michael Foorde5162652010-11-20 16:40:44 +00001038 def test_mro_as_property(self):
1039 class Meta(type):
1040 @property
1041 def __mro__(self):
1042 return (object,)
1043
1044 class Base(object):
1045 foo = 3
1046
1047 class Something(Base, metaclass=Meta):
1048 pass
1049
1050 self.assertEqual(inspect.getattr_static(Something(), 'foo'), 3)
1051 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1052
Michael Foorddcebe0f2011-03-15 19:20:44 -04001053 def test_dict_as_property(self):
1054 test = self
1055 test.called = False
1056
1057 class Foo(dict):
1058 a = 3
1059 @property
1060 def __dict__(self):
1061 test.called = True
1062 return {}
1063
1064 foo = Foo()
1065 foo.a = 4
1066 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1067 self.assertFalse(test.called)
1068
1069 def test_custom_object_dict(self):
1070 test = self
1071 test.called = False
1072
1073 class Custom(dict):
1074 def get(self, key, default=None):
1075 test.called = True
1076 super().get(key, default)
1077
1078 class Foo(object):
1079 a = 3
1080 foo = Foo()
1081 foo.__dict__ = Custom()
1082 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1083 self.assertFalse(test.called)
1084
1085 def test_metaclass_dict_as_property(self):
1086 class Meta(type):
1087 @property
1088 def __dict__(self):
1089 self.executed = True
1090
1091 class Thing(metaclass=Meta):
1092 executed = False
1093
1094 def __init__(self):
1095 self.spam = 42
1096
1097 instance = Thing()
1098 self.assertEqual(inspect.getattr_static(instance, "spam"), 42)
1099 self.assertFalse(Thing.executed)
Michael Foorde5162652010-11-20 16:40:44 +00001100
Michael Foorda51623b2011-12-18 22:01:40 +00001101 def test_module(self):
1102 sentinel = object()
1103 self.assertIsNot(inspect.getattr_static(sys, "version", sentinel),
1104 sentinel)
1105
Michael Foord3ba95f82011-12-22 01:13:37 +00001106 def test_metaclass_with_metaclass_with_dict_as_property(self):
1107 class MetaMeta(type):
1108 @property
1109 def __dict__(self):
1110 self.executed = True
1111 return dict(spam=42)
1112
1113 class Meta(type, metaclass=MetaMeta):
1114 executed = False
1115
1116 class Thing(metaclass=Meta):
1117 pass
1118
1119 with self.assertRaises(AttributeError):
1120 inspect.getattr_static(Thing, "spam")
1121 self.assertFalse(Thing.executed)
1122
Nick Coghlane0f04652010-11-21 03:44:04 +00001123class TestGetGeneratorState(unittest.TestCase):
1124
1125 def setUp(self):
1126 def number_generator():
1127 for number in range(5):
1128 yield number
1129 self.generator = number_generator()
1130
1131 def _generatorstate(self):
1132 return inspect.getgeneratorstate(self.generator)
1133
1134 def test_created(self):
1135 self.assertEqual(self._generatorstate(), inspect.GEN_CREATED)
1136
1137 def test_suspended(self):
1138 next(self.generator)
1139 self.assertEqual(self._generatorstate(), inspect.GEN_SUSPENDED)
1140
1141 def test_closed_after_exhaustion(self):
1142 for i in self.generator:
1143 pass
1144 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1145
1146 def test_closed_after_immediate_exception(self):
1147 with self.assertRaises(RuntimeError):
1148 self.generator.throw(RuntimeError)
1149 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1150
1151 def test_running(self):
1152 # As mentioned on issue #10220, checking for the RUNNING state only
1153 # makes sense inside the generator itself.
1154 # The following generator checks for this by using the closure's
1155 # reference to self and the generator state checking helper method
1156 def running_check_generator():
1157 for number in range(5):
1158 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1159 yield number
1160 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1161 self.generator = running_check_generator()
1162 # Running up to the first yield
1163 next(self.generator)
1164 # Running after the first yield
1165 next(self.generator)
1166
Nick Coghlan7921b9f2010-11-30 06:36:04 +00001167 def test_easy_debugging(self):
1168 # repr() and str() of a generator state should contain the state name
1169 names = 'GEN_CREATED GEN_RUNNING GEN_SUSPENDED GEN_CLOSED'.split()
1170 for name in names:
1171 state = getattr(inspect, name)
1172 self.assertIn(name, repr(state))
1173 self.assertIn(name, str(state))
1174
Nick Coghlane0f04652010-11-21 03:44:04 +00001175
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001176class TestSignatureObject(unittest.TestCase):
1177 @staticmethod
1178 def signature(func):
1179 sig = inspect.signature(func)
1180 return (tuple((param.name,
1181 (... if param.default is param.empty else param.default),
1182 (... if param.annotation is param.empty
1183 else param.annotation),
1184 str(param.kind).lower())
1185 for param in sig.parameters.values()),
1186 (... if sig.return_annotation is sig.empty
1187 else sig.return_annotation))
1188
1189 def test_signature_object(self):
1190 S = inspect.Signature
1191 P = inspect.Parameter
1192
1193 self.assertEqual(str(S()), '()')
1194
1195 def test(po, pk, *args, ko, **kwargs):
1196 pass
1197 sig = inspect.signature(test)
1198 po = sig.parameters['po'].replace(kind=P.POSITIONAL_ONLY)
1199 pk = sig.parameters['pk']
1200 args = sig.parameters['args']
1201 ko = sig.parameters['ko']
1202 kwargs = sig.parameters['kwargs']
1203
1204 S((po, pk, args, ko, kwargs))
1205
1206 with self.assertRaisesRegexp(ValueError, 'wrong parameter order'):
1207 S((pk, po, args, ko, kwargs))
1208
1209 with self.assertRaisesRegexp(ValueError, 'wrong parameter order'):
1210 S((po, args, pk, ko, kwargs))
1211
1212 with self.assertRaisesRegexp(ValueError, 'wrong parameter order'):
1213 S((args, po, pk, ko, kwargs))
1214
1215 with self.assertRaisesRegexp(ValueError, 'wrong parameter order'):
1216 S((po, pk, args, kwargs, ko))
1217
1218 kwargs2 = kwargs.replace(name='args')
1219 with self.assertRaisesRegexp(ValueError, 'duplicate parameter name'):
1220 S((po, pk, args, kwargs2, ko))
1221
1222 def test_signature_immutability(self):
1223 def test(a):
1224 pass
1225 sig = inspect.signature(test)
1226
1227 with self.assertRaises(AttributeError):
1228 sig.foo = 'bar'
1229
1230 with self.assertRaises(TypeError):
1231 sig.parameters['a'] = None
1232
1233 def test_signature_on_noarg(self):
1234 def test():
1235 pass
1236 self.assertEqual(self.signature(test), ((), ...))
1237
1238 def test_signature_on_wargs(self):
1239 def test(a, b:'foo') -> 123:
1240 pass
1241 self.assertEqual(self.signature(test),
1242 ((('a', ..., ..., "positional_or_keyword"),
1243 ('b', ..., 'foo', "positional_or_keyword")),
1244 123))
1245
1246 def test_signature_on_wkwonly(self):
1247 def test(*, a:float, b:str) -> int:
1248 pass
1249 self.assertEqual(self.signature(test),
1250 ((('a', ..., float, "keyword_only"),
1251 ('b', ..., str, "keyword_only")),
1252 int))
1253
1254 def test_signature_on_complex_args(self):
1255 def test(a, b:'foo'=10, *args:'bar', spam:'baz', ham=123, **kwargs:int):
1256 pass
1257 self.assertEqual(self.signature(test),
1258 ((('a', ..., ..., "positional_or_keyword"),
1259 ('b', 10, 'foo', "positional_or_keyword"),
1260 ('args', ..., 'bar', "var_positional"),
1261 ('spam', ..., 'baz', "keyword_only"),
1262 ('ham', 123, ..., "keyword_only"),
1263 ('kwargs', ..., int, "var_keyword")),
1264 ...))
1265
1266 def test_signature_on_builtin_function(self):
1267 with self.assertRaisesRegexp(ValueError, 'not supported by signature'):
1268 inspect.signature(type)
1269 with self.assertRaisesRegexp(ValueError, 'not supported by signature'):
1270 # support for 'wrapper_descriptor'
1271 inspect.signature(type.__call__)
1272 with self.assertRaisesRegexp(ValueError, 'not supported by signature'):
1273 # support for 'method-wrapper'
1274 inspect.signature(min.__call__)
1275 with self.assertRaisesRegexp(ValueError,
1276 'no signature found for builtin function'):
1277 # support for 'method-wrapper'
1278 inspect.signature(min)
1279
1280 def test_signature_on_non_function(self):
1281 with self.assertRaisesRegexp(TypeError, 'is not a callable object'):
1282 inspect.signature(42)
1283
1284 with self.assertRaisesRegexp(TypeError, 'is not a Python function'):
1285 inspect.Signature.from_function(42)
1286
1287 def test_signature_on_method(self):
1288 class Test:
1289 def foo(self, arg1, arg2=1) -> int:
1290 pass
1291
1292 meth = Test().foo
1293
1294 self.assertEqual(self.signature(meth),
1295 ((('arg1', ..., ..., "positional_or_keyword"),
1296 ('arg2', 1, ..., "positional_or_keyword")),
1297 int))
1298
1299 def test_signature_on_classmethod(self):
1300 class Test:
1301 @classmethod
1302 def foo(cls, arg1, *, arg2=1):
1303 pass
1304
1305 meth = Test().foo
1306 self.assertEqual(self.signature(meth),
1307 ((('arg1', ..., ..., "positional_or_keyword"),
1308 ('arg2', 1, ..., "keyword_only")),
1309 ...))
1310
1311 meth = Test.foo
1312 self.assertEqual(self.signature(meth),
1313 ((('arg1', ..., ..., "positional_or_keyword"),
1314 ('arg2', 1, ..., "keyword_only")),
1315 ...))
1316
1317 def test_signature_on_staticmethod(self):
1318 class Test:
1319 @staticmethod
1320 def foo(cls, *, arg):
1321 pass
1322
1323 meth = Test().foo
1324 self.assertEqual(self.signature(meth),
1325 ((('cls', ..., ..., "positional_or_keyword"),
1326 ('arg', ..., ..., "keyword_only")),
1327 ...))
1328
1329 meth = Test.foo
1330 self.assertEqual(self.signature(meth),
1331 ((('cls', ..., ..., "positional_or_keyword"),
1332 ('arg', ..., ..., "keyword_only")),
1333 ...))
1334
1335 def test_signature_on_partial(self):
1336 from functools import partial
1337
1338 def test():
1339 pass
1340
1341 self.assertEqual(self.signature(partial(test)), ((), ...))
1342
1343 with self.assertRaisesRegexp(ValueError, "has incorrect arguments"):
1344 inspect.signature(partial(test, 1))
1345
1346 with self.assertRaisesRegexp(ValueError, "has incorrect arguments"):
1347 inspect.signature(partial(test, a=1))
1348
1349 def test(a, b, *, c, d):
1350 pass
1351
1352 self.assertEqual(self.signature(partial(test)),
1353 ((('a', ..., ..., "positional_or_keyword"),
1354 ('b', ..., ..., "positional_or_keyword"),
1355 ('c', ..., ..., "keyword_only"),
1356 ('d', ..., ..., "keyword_only")),
1357 ...))
1358
1359 self.assertEqual(self.signature(partial(test, 1)),
1360 ((('b', ..., ..., "positional_or_keyword"),
1361 ('c', ..., ..., "keyword_only"),
1362 ('d', ..., ..., "keyword_only")),
1363 ...))
1364
1365 self.assertEqual(self.signature(partial(test, 1, c=2)),
1366 ((('b', ..., ..., "positional_or_keyword"),
1367 ('c', 2, ..., "keyword_only"),
1368 ('d', ..., ..., "keyword_only")),
1369 ...))
1370
1371 self.assertEqual(self.signature(partial(test, b=1, c=2)),
1372 ((('a', ..., ..., "positional_or_keyword"),
1373 ('b', 1, ..., "positional_or_keyword"),
1374 ('c', 2, ..., "keyword_only"),
1375 ('d', ..., ..., "keyword_only")),
1376 ...))
1377
1378 self.assertEqual(self.signature(partial(test, 0, b=1, c=2)),
1379 ((('b', 1, ..., "positional_or_keyword"),
1380 ('c', 2, ..., "keyword_only"),
1381 ('d', ..., ..., "keyword_only"),),
1382 ...))
1383
1384 def test(a, *args, b, **kwargs):
1385 pass
1386
1387 self.assertEqual(self.signature(partial(test, 1)),
1388 ((('args', ..., ..., "var_positional"),
1389 ('b', ..., ..., "keyword_only"),
1390 ('kwargs', ..., ..., "var_keyword")),
1391 ...))
1392
1393 self.assertEqual(self.signature(partial(test, 1, 2, 3)),
1394 ((('args', ..., ..., "var_positional"),
1395 ('b', ..., ..., "keyword_only"),
1396 ('kwargs', ..., ..., "var_keyword")),
1397 ...))
1398
1399
1400 self.assertEqual(self.signature(partial(test, 1, 2, 3, test=True)),
1401 ((('args', ..., ..., "var_positional"),
1402 ('b', ..., ..., "keyword_only"),
1403 ('kwargs', ..., ..., "var_keyword")),
1404 ...))
1405
1406 self.assertEqual(self.signature(partial(test, 1, 2, 3, test=1, b=0)),
1407 ((('args', ..., ..., "var_positional"),
1408 ('b', 0, ..., "keyword_only"),
1409 ('kwargs', ..., ..., "var_keyword")),
1410 ...))
1411
1412 self.assertEqual(self.signature(partial(test, b=0)),
1413 ((('a', ..., ..., "positional_or_keyword"),
1414 ('args', ..., ..., "var_positional"),
1415 ('b', 0, ..., "keyword_only"),
1416 ('kwargs', ..., ..., "var_keyword")),
1417 ...))
1418
1419 self.assertEqual(self.signature(partial(test, b=0, test=1)),
1420 ((('a', ..., ..., "positional_or_keyword"),
1421 ('args', ..., ..., "var_positional"),
1422 ('b', 0, ..., "keyword_only"),
1423 ('kwargs', ..., ..., "var_keyword")),
1424 ...))
1425
1426 def test(a, b, c:int) -> 42:
1427 pass
1428
1429 sig = test.__signature__ = inspect.signature(test)
1430
1431 self.assertEqual(self.signature(partial(partial(test, 1))),
1432 ((('b', ..., ..., "positional_or_keyword"),
1433 ('c', ..., int, "positional_or_keyword")),
1434 42))
1435
1436 self.assertEqual(self.signature(partial(partial(test, 1), 2)),
1437 ((('c', ..., int, "positional_or_keyword"),),
1438 42))
1439
1440 psig = inspect.signature(partial(partial(test, 1), 2))
1441
1442 def foo(a):
1443 return a
1444 _foo = partial(partial(foo, a=10), a=20)
1445 self.assertEqual(self.signature(_foo),
1446 ((('a', 20, ..., "positional_or_keyword"),),
1447 ...))
1448 # check that we don't have any side-effects in signature(),
1449 # and the partial object is still functioning
1450 self.assertEqual(_foo(), 20)
1451
1452 def foo(a, b, c):
1453 return a, b, c
1454 _foo = partial(partial(foo, 1, b=20), b=30)
1455 self.assertEqual(self.signature(_foo),
1456 ((('b', 30, ..., "positional_or_keyword"),
1457 ('c', ..., ..., "positional_or_keyword")),
1458 ...))
1459 self.assertEqual(_foo(c=10), (1, 30, 10))
1460 _foo = partial(_foo, 2) # now 'b' has two values -
1461 # positional and keyword
1462 with self.assertRaisesRegexp(ValueError, "has incorrect arguments"):
1463 inspect.signature(_foo)
1464
1465 def foo(a, b, c, *, d):
1466 return a, b, c, d
1467 _foo = partial(partial(foo, d=20, c=20), b=10, d=30)
1468 self.assertEqual(self.signature(_foo),
1469 ((('a', ..., ..., "positional_or_keyword"),
1470 ('b', 10, ..., "positional_or_keyword"),
1471 ('c', 20, ..., "positional_or_keyword"),
1472 ('d', 30, ..., "keyword_only")),
1473 ...))
1474 ba = inspect.signature(_foo).bind(a=200, b=11)
1475 self.assertEqual(_foo(*ba.args, **ba.kwargs), (200, 11, 20, 30))
1476
1477 def foo(a=1, b=2, c=3):
1478 return a, b, c
1479 _foo = partial(foo, a=10, c=13)
1480 ba = inspect.signature(_foo).bind(11)
1481 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 2, 13))
1482 ba = inspect.signature(_foo).bind(11, 12)
1483 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
1484 ba = inspect.signature(_foo).bind(11, b=12)
1485 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
1486 ba = inspect.signature(_foo).bind(b=12)
1487 self.assertEqual(_foo(*ba.args, **ba.kwargs), (10, 12, 13))
1488 _foo = partial(_foo, b=10)
1489 ba = inspect.signature(_foo).bind(12, 14)
1490 self.assertEqual(_foo(*ba.args, **ba.kwargs), (12, 14, 13))
1491
1492 def test_signature_on_decorated(self):
1493 import functools
1494
1495 def decorator(func):
1496 @functools.wraps(func)
1497 def wrapper(*args, **kwargs) -> int:
1498 return func(*args, **kwargs)
1499 return wrapper
1500
1501 class Foo:
1502 @decorator
1503 def bar(self, a, b):
1504 pass
1505
1506 self.assertEqual(self.signature(Foo.bar),
1507 ((('self', ..., ..., "positional_or_keyword"),
1508 ('a', ..., ..., "positional_or_keyword"),
1509 ('b', ..., ..., "positional_or_keyword")),
1510 ...))
1511
1512 self.assertEqual(self.signature(Foo().bar),
1513 ((('a', ..., ..., "positional_or_keyword"),
1514 ('b', ..., ..., "positional_or_keyword")),
1515 ...))
1516
1517 # Test that we handle method wrappers correctly
1518 def decorator(func):
1519 @functools.wraps(func)
1520 def wrapper(*args, **kwargs) -> int:
1521 return func(42, *args, **kwargs)
1522 sig = inspect.signature(func)
1523 new_params = tuple(sig.parameters.values())[1:]
1524 wrapper.__signature__ = sig.replace(parameters=new_params)
1525 return wrapper
1526
1527 class Foo:
1528 @decorator
1529 def __call__(self, a, b):
1530 pass
1531
1532 self.assertEqual(self.signature(Foo.__call__),
1533 ((('a', ..., ..., "positional_or_keyword"),
1534 ('b', ..., ..., "positional_or_keyword")),
1535 ...))
1536
1537 self.assertEqual(self.signature(Foo().__call__),
1538 ((('b', ..., ..., "positional_or_keyword"),),
1539 ...))
1540
1541 def test_signature_on_class(self):
1542 class C:
1543 def __init__(self, a):
1544 pass
1545
1546 self.assertEqual(self.signature(C),
1547 ((('a', ..., ..., "positional_or_keyword"),),
1548 ...))
1549
1550 class CM(type):
1551 def __call__(cls, a):
1552 pass
1553 class C(metaclass=CM):
1554 def __init__(self, b):
1555 pass
1556
1557 self.assertEqual(self.signature(C),
1558 ((('a', ..., ..., "positional_or_keyword"),),
1559 ...))
1560
1561 class CM(type):
1562 def __new__(mcls, name, bases, dct, *, foo=1):
1563 return super().__new__(mcls, name, bases, dct)
1564 class C(metaclass=CM):
1565 def __init__(self, b):
1566 pass
1567
1568 self.assertEqual(self.signature(C),
1569 ((('b', ..., ..., "positional_or_keyword"),),
1570 ...))
1571
1572 self.assertEqual(self.signature(CM),
1573 ((('name', ..., ..., "positional_or_keyword"),
1574 ('bases', ..., ..., "positional_or_keyword"),
1575 ('dct', ..., ..., "positional_or_keyword"),
1576 ('foo', 1, ..., "keyword_only")),
1577 ...))
1578
1579 class CMM(type):
1580 def __new__(mcls, name, bases, dct, *, foo=1):
1581 return super().__new__(mcls, name, bases, dct)
1582 def __call__(cls, nm, bs, dt):
1583 return type(nm, bs, dt)
1584 class CM(type, metaclass=CMM):
1585 def __new__(mcls, name, bases, dct, *, bar=2):
1586 return super().__new__(mcls, name, bases, dct)
1587 class C(metaclass=CM):
1588 def __init__(self, b):
1589 pass
1590
1591 self.assertEqual(self.signature(CMM),
1592 ((('name', ..., ..., "positional_or_keyword"),
1593 ('bases', ..., ..., "positional_or_keyword"),
1594 ('dct', ..., ..., "positional_or_keyword"),
1595 ('foo', 1, ..., "keyword_only")),
1596 ...))
1597
1598 self.assertEqual(self.signature(CM),
1599 ((('nm', ..., ..., "positional_or_keyword"),
1600 ('bs', ..., ..., "positional_or_keyword"),
1601 ('dt', ..., ..., "positional_or_keyword")),
1602 ...))
1603
1604 self.assertEqual(self.signature(C),
1605 ((('b', ..., ..., "positional_or_keyword"),),
1606 ...))
1607
1608 class CM(type):
1609 def __init__(cls, name, bases, dct, *, bar=2):
1610 return super().__init__(name, bases, dct)
1611 class C(metaclass=CM):
1612 def __init__(self, b):
1613 pass
1614
1615 self.assertEqual(self.signature(CM),
1616 ((('name', ..., ..., "positional_or_keyword"),
1617 ('bases', ..., ..., "positional_or_keyword"),
1618 ('dct', ..., ..., "positional_or_keyword"),
1619 ('bar', 2, ..., "keyword_only")),
1620 ...))
1621
1622 def test_signature_on_callable_objects(self):
1623 class Foo:
1624 def __call__(self, a):
1625 pass
1626
1627 self.assertEqual(self.signature(Foo()),
1628 ((('a', ..., ..., "positional_or_keyword"),),
1629 ...))
1630
1631 class Spam:
1632 pass
1633 with self.assertRaisesRegexp(TypeError, "is not a callable object"):
1634 inspect.signature(Spam())
1635
1636 class Bar(Spam, Foo):
1637 pass
1638
1639 self.assertEqual(self.signature(Bar()),
1640 ((('a', ..., ..., "positional_or_keyword"),),
1641 ...))
1642
1643 class ToFail:
1644 __call__ = type
1645 with self.assertRaisesRegexp(ValueError, "not supported by signature"):
1646 inspect.signature(ToFail())
1647
1648
1649 class Wrapped:
1650 pass
1651 Wrapped.__wrapped__ = lambda a: None
1652 self.assertEqual(self.signature(Wrapped),
1653 ((('a', ..., ..., "positional_or_keyword"),),
1654 ...))
1655
1656 def test_signature_on_lambdas(self):
1657 self.assertEqual(self.signature((lambda a=10: a)),
1658 ((('a', 10, ..., "positional_or_keyword"),),
1659 ...))
1660
1661 def test_signature_equality(self):
1662 def foo(a, *, b:int) -> float: pass
1663 self.assertNotEqual(inspect.signature(foo), 42)
1664
1665 def bar(a, *, b:int) -> float: pass
1666 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
1667
1668 def bar(a, *, b:int) -> int: pass
1669 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
1670
1671 def bar(a, *, b:int): pass
1672 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
1673
1674 def bar(a, *, b:int=42) -> float: pass
1675 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
1676
1677 def bar(a, *, c) -> float: pass
1678 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
1679
1680 def bar(a, b:int) -> float: pass
1681 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
1682 def spam(b:int, a) -> float: pass
1683 self.assertNotEqual(inspect.signature(spam), inspect.signature(bar))
1684
1685 def foo(*, a, b, c): pass
1686 def bar(*, c, b, a): pass
1687 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
1688
1689 def foo(*, a=1, b, c): pass
1690 def bar(*, c, b, a=1): pass
1691 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
1692
1693 def foo(pos, *, a=1, b, c): pass
1694 def bar(pos, *, c, b, a=1): pass
1695 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
1696
1697 def foo(pos, *, a, b, c): pass
1698 def bar(pos, *, c, b, a=1): pass
1699 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
1700
1701 def foo(pos, *args, a=42, b, c, **kwargs:int): pass
1702 def bar(pos, *args, c, b, a=42, **kwargs:int): pass
1703 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
1704
1705 def test_signature_unhashable(self):
1706 def foo(a): pass
1707 sig = inspect.signature(foo)
1708 with self.assertRaisesRegexp(TypeError, 'unhashable type'):
1709 hash(sig)
1710
1711 def test_signature_str(self):
1712 def foo(a:int=1, *, b, c=None, **kwargs) -> 42:
1713 pass
1714 self.assertEqual(str(inspect.signature(foo)),
1715 '(a:int=1, *, b, c=None, **kwargs) -> 42')
1716
1717 def foo(a:int=1, *args, b, c=None, **kwargs) -> 42:
1718 pass
1719 self.assertEqual(str(inspect.signature(foo)),
1720 '(a:int=1, *args, b, c=None, **kwargs) -> 42')
1721
1722 def foo():
1723 pass
1724 self.assertEqual(str(inspect.signature(foo)), '()')
1725
1726 def test_signature_str_positional_only(self):
1727 P = inspect.Parameter
1728
1729 def test(a_po, *, b, **kwargs):
1730 return a_po, kwargs
1731
1732 sig = inspect.signature(test)
1733 new_params = list(sig.parameters.values())
1734 new_params[0] = new_params[0].replace(kind=P.POSITIONAL_ONLY)
1735 test.__signature__ = sig.replace(parameters=new_params)
1736
1737 self.assertEqual(str(inspect.signature(test)),
1738 '(<a_po>, *, b, **kwargs)')
1739
1740 sig = inspect.signature(test)
1741 new_params = list(sig.parameters.values())
1742 new_params[0] = new_params[0].replace(name=None)
1743 test.__signature__ = sig.replace(parameters=new_params)
1744 self.assertEqual(str(inspect.signature(test)),
1745 '(<0>, *, b, **kwargs)')
1746
1747 def test_signature_replace_anno(self):
1748 def test() -> 42:
1749 pass
1750
1751 sig = inspect.signature(test)
1752 sig = sig.replace(return_annotation=None)
1753 self.assertIs(sig.return_annotation, None)
1754 sig = sig.replace(return_annotation=sig.empty)
1755 self.assertIs(sig.return_annotation, sig.empty)
1756 sig = sig.replace(return_annotation=42)
1757 self.assertEqual(sig.return_annotation, 42)
1758 self.assertEqual(sig, inspect.signature(test))
1759
1760
1761class TestParameterObject(unittest.TestCase):
1762 def test_signature_parameter_kinds(self):
1763 P = inspect.Parameter
1764 self.assertTrue(P.POSITIONAL_ONLY < P.POSITIONAL_OR_KEYWORD < \
1765 P.VAR_POSITIONAL < P.KEYWORD_ONLY < P.VAR_KEYWORD)
1766
1767 self.assertEqual(str(P.POSITIONAL_ONLY), 'POSITIONAL_ONLY')
1768 self.assertTrue('POSITIONAL_ONLY' in repr(P.POSITIONAL_ONLY))
1769
1770 def test_signature_parameter_object(self):
1771 p = inspect.Parameter('foo', default=10,
1772 kind=inspect.Parameter.POSITIONAL_ONLY)
1773 self.assertEqual(p.name, 'foo')
1774 self.assertEqual(p.default, 10)
1775 self.assertIs(p.annotation, p.empty)
1776 self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY)
1777
1778 with self.assertRaisesRegexp(ValueError, 'invalid value'):
1779 inspect.Parameter('foo', default=10, kind='123')
1780
1781 with self.assertRaisesRegexp(ValueError, 'not a valid parameter name'):
1782 inspect.Parameter('1', kind=inspect.Parameter.VAR_KEYWORD)
1783
1784 with self.assertRaisesRegexp(ValueError,
1785 'non-positional-only parameter'):
1786 inspect.Parameter(None, kind=inspect.Parameter.VAR_KEYWORD)
1787
1788 with self.assertRaisesRegexp(ValueError, 'cannot have default values'):
1789 inspect.Parameter('a', default=42,
1790 kind=inspect.Parameter.VAR_KEYWORD)
1791
1792 with self.assertRaisesRegexp(ValueError, 'cannot have default values'):
1793 inspect.Parameter('a', default=42,
1794 kind=inspect.Parameter.VAR_POSITIONAL)
1795
1796 p = inspect.Parameter('a', default=42,
1797 kind=inspect.Parameter.POSITIONAL_OR_KEYWORD)
1798 with self.assertRaisesRegexp(ValueError, 'cannot have default values'):
1799 p.replace(kind=inspect.Parameter.VAR_POSITIONAL)
1800
1801 self.assertTrue(repr(p).startswith('<Parameter'))
1802
1803 def test_signature_parameter_equality(self):
1804 P = inspect.Parameter
1805 p = P('foo', default=42, kind=inspect.Parameter.KEYWORD_ONLY)
1806
1807 self.assertEqual(p, p)
1808 self.assertNotEqual(p, 42)
1809
1810 self.assertEqual(p, P('foo', default=42,
1811 kind=inspect.Parameter.KEYWORD_ONLY))
1812
1813 def test_signature_parameter_unhashable(self):
1814 p = inspect.Parameter('foo', default=42,
1815 kind=inspect.Parameter.KEYWORD_ONLY)
1816
1817 with self.assertRaisesRegexp(TypeError, 'unhashable type'):
1818 hash(p)
1819
1820 def test_signature_parameter_replace(self):
1821 p = inspect.Parameter('foo', default=42,
1822 kind=inspect.Parameter.KEYWORD_ONLY)
1823
1824 self.assertIsNot(p, p.replace())
1825 self.assertEqual(p, p.replace())
1826
1827 p2 = p.replace(annotation=1)
1828 self.assertEqual(p2.annotation, 1)
1829 p2 = p2.replace(annotation=p2.empty)
1830 self.assertEqual(p, p2)
1831
1832 p2 = p2.replace(name='bar')
1833 self.assertEqual(p2.name, 'bar')
1834 self.assertNotEqual(p2, p)
1835
1836 with self.assertRaisesRegexp(ValueError, 'not a valid parameter name'):
1837 p2 = p2.replace(name=p2.empty)
1838
1839 p2 = p2.replace(name='foo', default=None)
1840 self.assertIs(p2.default, None)
1841 self.assertNotEqual(p2, p)
1842
1843 p2 = p2.replace(name='foo', default=p2.empty)
1844 self.assertIs(p2.default, p2.empty)
1845
1846
1847 p2 = p2.replace(default=42, kind=p2.POSITIONAL_OR_KEYWORD)
1848 self.assertEqual(p2.kind, p2.POSITIONAL_OR_KEYWORD)
1849 self.assertNotEqual(p2, p)
1850
1851 with self.assertRaisesRegexp(ValueError, 'invalid value for'):
1852 p2 = p2.replace(kind=p2.empty)
1853
1854 p2 = p2.replace(kind=p2.KEYWORD_ONLY)
1855 self.assertEqual(p2, p)
1856
1857 def test_signature_parameter_positional_only(self):
1858 p = inspect.Parameter(None, kind=inspect.Parameter.POSITIONAL_ONLY)
1859 self.assertEqual(str(p), '<>')
1860
1861 p = p.replace(name='1')
1862 self.assertEqual(str(p), '<1>')
1863
1864 def test_signature_parameter_immutability(self):
1865 p = inspect.Parameter(None, kind=inspect.Parameter.POSITIONAL_ONLY)
1866
1867 with self.assertRaises(AttributeError):
1868 p.foo = 'bar'
1869
1870 with self.assertRaises(AttributeError):
1871 p.kind = 123
1872
1873
1874class TestSignatureBind(unittest.TestCase):
1875 @staticmethod
1876 def call(func, *args, **kwargs):
1877 sig = inspect.signature(func)
1878 ba = sig.bind(*args, **kwargs)
1879 return func(*ba.args, **ba.kwargs)
1880
1881 def test_signature_bind_empty(self):
1882 def test():
1883 return 42
1884
1885 self.assertEqual(self.call(test), 42)
1886 with self.assertRaisesRegexp(TypeError, 'too many positional arguments'):
1887 self.call(test, 1)
1888 with self.assertRaisesRegexp(TypeError, 'too many positional arguments'):
1889 self.call(test, 1, spam=10)
1890 with self.assertRaisesRegexp(TypeError, 'too many keyword arguments'):
1891 self.call(test, spam=1)
1892
1893 def test_signature_bind_var(self):
1894 def test(*args, **kwargs):
1895 return args, kwargs
1896
1897 self.assertEqual(self.call(test), ((), {}))
1898 self.assertEqual(self.call(test, 1), ((1,), {}))
1899 self.assertEqual(self.call(test, 1, 2), ((1, 2), {}))
1900 self.assertEqual(self.call(test, foo='bar'), ((), {'foo': 'bar'}))
1901 self.assertEqual(self.call(test, 1, foo='bar'), ((1,), {'foo': 'bar'}))
1902 self.assertEqual(self.call(test, args=10), ((), {'args': 10}))
1903 self.assertEqual(self.call(test, 1, 2, foo='bar'),
1904 ((1, 2), {'foo': 'bar'}))
1905
1906 def test_signature_bind_just_args(self):
1907 def test(a, b, c):
1908 return a, b, c
1909
1910 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
1911
1912 with self.assertRaisesRegexp(TypeError, 'too many positional arguments'):
1913 self.call(test, 1, 2, 3, 4)
1914
1915 with self.assertRaisesRegexp(TypeError, "'b' parameter lacking default"):
1916 self.call(test, 1)
1917
1918 with self.assertRaisesRegexp(TypeError, "'a' parameter lacking default"):
1919 self.call(test)
1920
1921 def test(a, b, c=10):
1922 return a, b, c
1923 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
1924 self.assertEqual(self.call(test, 1, 2), (1, 2, 10))
1925
1926 def test(a=1, b=2, c=3):
1927 return a, b, c
1928 self.assertEqual(self.call(test, a=10, c=13), (10, 2, 13))
1929 self.assertEqual(self.call(test, a=10), (10, 2, 3))
1930 self.assertEqual(self.call(test, b=10), (1, 10, 3))
1931
1932 def test_signature_bind_varargs_order(self):
1933 def test(*args):
1934 return args
1935
1936 self.assertEqual(self.call(test), ())
1937 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
1938
1939 def test_signature_bind_args_and_varargs(self):
1940 def test(a, b, c=3, *args):
1941 return a, b, c, args
1942
1943 self.assertEqual(self.call(test, 1, 2, 3, 4, 5), (1, 2, 3, (4, 5)))
1944 self.assertEqual(self.call(test, 1, 2), (1, 2, 3, ()))
1945 self.assertEqual(self.call(test, b=1, a=2), (2, 1, 3, ()))
1946 self.assertEqual(self.call(test, 1, b=2), (1, 2, 3, ()))
1947
1948 with self.assertRaisesRegexp(TypeError,
1949 "multiple values for argument 'c'"):
1950 self.call(test, 1, 2, 3, c=4)
1951
1952 def test_signature_bind_just_kwargs(self):
1953 def test(**kwargs):
1954 return kwargs
1955
1956 self.assertEqual(self.call(test), {})
1957 self.assertEqual(self.call(test, foo='bar', spam='ham'),
1958 {'foo': 'bar', 'spam': 'ham'})
1959
1960 def test_signature_bind_args_and_kwargs(self):
1961 def test(a, b, c=3, **kwargs):
1962 return a, b, c, kwargs
1963
1964 self.assertEqual(self.call(test, 1, 2), (1, 2, 3, {}))
1965 self.assertEqual(self.call(test, 1, 2, foo='bar', spam='ham'),
1966 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
1967 self.assertEqual(self.call(test, b=2, a=1, foo='bar', spam='ham'),
1968 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
1969 self.assertEqual(self.call(test, a=1, b=2, foo='bar', spam='ham'),
1970 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
1971 self.assertEqual(self.call(test, 1, b=2, foo='bar', spam='ham'),
1972 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
1973 self.assertEqual(self.call(test, 1, b=2, c=4, foo='bar', spam='ham'),
1974 (1, 2, 4, {'foo': 'bar', 'spam': 'ham'}))
1975 self.assertEqual(self.call(test, 1, 2, 4, foo='bar'),
1976 (1, 2, 4, {'foo': 'bar'}))
1977 self.assertEqual(self.call(test, c=5, a=4, b=3),
1978 (4, 3, 5, {}))
1979
1980 def test_signature_bind_kwonly(self):
1981 def test(*, foo):
1982 return foo
1983 with self.assertRaisesRegexp(TypeError,
1984 'too many positional arguments'):
1985 self.call(test, 1)
1986 self.assertEqual(self.call(test, foo=1), 1)
1987
1988 def test(a, *, foo=1, bar):
1989 return foo
1990 with self.assertRaisesRegexp(TypeError,
1991 "'bar' parameter lacking default value"):
1992 self.call(test, 1)
1993
1994 def test(foo, *, bar):
1995 return foo, bar
1996 self.assertEqual(self.call(test, 1, bar=2), (1, 2))
1997 self.assertEqual(self.call(test, bar=2, foo=1), (1, 2))
1998
1999 with self.assertRaisesRegexp(TypeError,
2000 'too many keyword arguments'):
2001 self.call(test, bar=2, foo=1, spam=10)
2002
2003 with self.assertRaisesRegexp(TypeError,
2004 'too many positional arguments'):
2005 self.call(test, 1, 2)
2006
2007 with self.assertRaisesRegexp(TypeError,
2008 'too many positional arguments'):
2009 self.call(test, 1, 2, bar=2)
2010
2011 with self.assertRaisesRegexp(TypeError,
2012 'too many keyword arguments'):
2013 self.call(test, 1, bar=2, spam='ham')
2014
2015 with self.assertRaisesRegexp(TypeError,
2016 "'bar' parameter lacking default value"):
2017 self.call(test, 1)
2018
2019 def test(foo, *, bar, **bin):
2020 return foo, bar, bin
2021 self.assertEqual(self.call(test, 1, bar=2), (1, 2, {}))
2022 self.assertEqual(self.call(test, foo=1, bar=2), (1, 2, {}))
2023 self.assertEqual(self.call(test, 1, bar=2, spam='ham'),
2024 (1, 2, {'spam': 'ham'}))
2025 self.assertEqual(self.call(test, spam='ham', foo=1, bar=2),
2026 (1, 2, {'spam': 'ham'}))
2027 with self.assertRaisesRegexp(TypeError,
2028 "'foo' parameter lacking default value"):
2029 self.call(test, spam='ham', bar=2)
2030 self.assertEqual(self.call(test, 1, bar=2, bin=1, spam=10),
2031 (1, 2, {'bin': 1, 'spam': 10}))
2032
2033 def test_signature_bind_arguments(self):
2034 def test(a, *args, b, z=100, **kwargs):
2035 pass
2036 sig = inspect.signature(test)
2037 ba = sig.bind(10, 20, b=30, c=40, args=50, kwargs=60)
2038 # we won't have 'z' argument in the bound arguments object, as we didn't
2039 # pass it to the 'bind'
2040 self.assertEqual(tuple(ba.arguments.items()),
2041 (('a', 10), ('args', (20,)), ('b', 30),
2042 ('kwargs', {'c': 40, 'args': 50, 'kwargs': 60})))
2043 self.assertEqual(ba.kwargs,
2044 {'b': 30, 'c': 40, 'args': 50, 'kwargs': 60})
2045 self.assertEqual(ba.args, (10, 20))
2046
2047 def test_signature_bind_positional_only(self):
2048 P = inspect.Parameter
2049
2050 def test(a_po, b_po, c_po=3, foo=42, *, bar=50, **kwargs):
2051 return a_po, b_po, c_po, foo, bar, kwargs
2052
2053 sig = inspect.signature(test)
2054 new_params = collections.OrderedDict(tuple(sig.parameters.items()))
2055 for name in ('a_po', 'b_po', 'c_po'):
2056 new_params[name] = new_params[name].replace(kind=P.POSITIONAL_ONLY)
2057 new_sig = sig.replace(parameters=new_params.values())
2058 test.__signature__ = new_sig
2059
2060 self.assertEqual(self.call(test, 1, 2, 4, 5, bar=6),
2061 (1, 2, 4, 5, 6, {}))
2062
2063 with self.assertRaisesRegexp(TypeError, "parameter is positional only"):
2064 self.call(test, 1, 2, c_po=4)
2065
2066 with self.assertRaisesRegexp(TypeError, "parameter is positional only"):
2067 self.call(test, a_po=1, b_po=2)
2068
2069
2070class TestBoundArguments(unittest.TestCase):
2071 def test_signature_bound_arguments_unhashable(self):
2072 def foo(a): pass
2073 ba = inspect.signature(foo).bind(1)
2074
2075 with self.assertRaisesRegexp(TypeError, 'unhashable type'):
2076 hash(ba)
2077
2078 def test_signature_bound_arguments_equality(self):
2079 def foo(a): pass
2080 ba = inspect.signature(foo).bind(1)
2081 self.assertEqual(ba, ba)
2082
2083 ba2 = inspect.signature(foo).bind(1)
2084 self.assertEqual(ba, ba2)
2085
2086 ba3 = inspect.signature(foo).bind(2)
2087 self.assertNotEqual(ba, ba3)
2088 ba3.arguments['a'] = 1
2089 self.assertEqual(ba, ba3)
2090
2091 def bar(b): pass
2092 ba4 = inspect.signature(bar).bind(1)
2093 self.assertNotEqual(ba, ba4)
2094
2095
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00002096def test_main():
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00002097 run_unittest(
2098 TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBuggyCases,
2099 TestInterpreterStack, TestClassesAndFunctions, TestPredicates,
2100 TestGetcallargsFunctions, TestGetcallargsMethods,
Alexander Belopolskyf546e702010-12-02 00:10:11 +00002101 TestGetcallargsUnboundMethods, TestGetattrStatic, TestGetGeneratorState,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002102 TestNoEOL, TestSignatureObject, TestSignatureBind, TestParameterObject,
2103 TestBoundArguments
Michael Foord95fc51d2010-11-20 15:07:30 +00002104 )
Martin v. Löwis893ffa42003-10-31 15:35:53 +00002105
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00002106if __name__ == "__main__":
2107 test_main()