blob: 7ed4ffef8c6430bde3e80bd9da3c1d52f8b95db8 [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
Nick Coghlan6c6e2542012-06-23 20:07:39 +1000766 def _private_globals(self):
767 code = """def f(): print(path)"""
768 ns = {}
769 exec(code, ns)
770 return ns["f"], ns
771
772 def test_builtins_fallback(self):
773 f, ns = self._private_globals()
774 ns.pop("__builtins__", None)
775 expected = inspect.ClosureVars({}, {}, {"print":print}, {"path"})
776 self.assertEqual(inspect.getclosurevars(f), expected)
777
778 def test_builtins_as_dict(self):
779 f, ns = self._private_globals()
780 ns["__builtins__"] = {"path":1}
781 expected = inspect.ClosureVars({}, {}, {"path":1}, {"print"})
782 self.assertEqual(inspect.getclosurevars(f), expected)
783
784 def test_builtins_as_module(self):
785 f, ns = self._private_globals()
786 ns["__builtins__"] = os
787 expected = inspect.ClosureVars({}, {}, {"path":os.path}, {"print"})
788 self.assertEqual(inspect.getclosurevars(f), expected)
789
Nick Coghlan2f92e542012-06-23 19:39:55 +1000790
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000791class TestGetcallargsFunctions(unittest.TestCase):
792
793 def assertEqualCallArgs(self, func, call_params_string, locs=None):
794 locs = dict(locs or {}, func=func)
795 r1 = eval('func(%s)' % call_params_string, None, locs)
796 r2 = eval('inspect.getcallargs(func, %s)' % call_params_string, None,
797 locs)
798 self.assertEqual(r1, r2)
799
800 def assertEqualException(self, func, call_param_string, locs=None):
801 locs = dict(locs or {}, func=func)
802 try:
803 eval('func(%s)' % call_param_string, None, locs)
804 except Exception as e:
805 ex1 = e
806 else:
807 self.fail('Exception not raised')
808 try:
809 eval('inspect.getcallargs(func, %s)' % call_param_string, None,
810 locs)
811 except Exception as e:
812 ex2 = e
813 else:
814 self.fail('Exception not raised')
815 self.assertIs(type(ex1), type(ex2))
816 self.assertEqual(str(ex1), str(ex2))
817 del ex1, ex2
818
819 def makeCallable(self, signature):
820 """Create a function that returns its locals()"""
821 code = "lambda %s: locals()"
822 return eval(code % signature)
823
824 def test_plain(self):
825 f = self.makeCallable('a, b=1')
826 self.assertEqualCallArgs(f, '2')
827 self.assertEqualCallArgs(f, '2, 3')
828 self.assertEqualCallArgs(f, 'a=2')
829 self.assertEqualCallArgs(f, 'b=3, a=2')
830 self.assertEqualCallArgs(f, '2, b=3')
831 # expand *iterable / **mapping
832 self.assertEqualCallArgs(f, '*(2,)')
833 self.assertEqualCallArgs(f, '*[2]')
834 self.assertEqualCallArgs(f, '*(2, 3)')
835 self.assertEqualCallArgs(f, '*[2, 3]')
836 self.assertEqualCallArgs(f, '**{"a":2}')
837 self.assertEqualCallArgs(f, 'b=3, **{"a":2}')
838 self.assertEqualCallArgs(f, '2, **{"b":3}')
839 self.assertEqualCallArgs(f, '**{"b":3, "a":2}')
840 # expand UserList / UserDict
841 self.assertEqualCallArgs(f, '*collections.UserList([2])')
842 self.assertEqualCallArgs(f, '*collections.UserList([2, 3])')
843 self.assertEqualCallArgs(f, '**collections.UserDict(a=2)')
844 self.assertEqualCallArgs(f, '2, **collections.UserDict(b=3)')
845 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3)')
846
847 def test_varargs(self):
848 f = self.makeCallable('a, b=1, *c')
849 self.assertEqualCallArgs(f, '2')
850 self.assertEqualCallArgs(f, '2, 3')
851 self.assertEqualCallArgs(f, '2, 3, 4')
852 self.assertEqualCallArgs(f, '*(2,3,4)')
853 self.assertEqualCallArgs(f, '2, *[3,4]')
854 self.assertEqualCallArgs(f, '2, 3, *collections.UserList([4])')
855
856 def test_varkw(self):
857 f = self.makeCallable('a, b=1, **c')
858 self.assertEqualCallArgs(f, 'a=2')
859 self.assertEqualCallArgs(f, '2, b=3, c=4')
860 self.assertEqualCallArgs(f, 'b=3, a=2, c=4')
861 self.assertEqualCallArgs(f, 'c=4, **{"a":2, "b":3}')
862 self.assertEqualCallArgs(f, '2, c=4, **{"b":3}')
863 self.assertEqualCallArgs(f, 'b=2, **{"a":3, "c":4}')
864 self.assertEqualCallArgs(f, '**collections.UserDict(a=2, b=3, c=4)')
865 self.assertEqualCallArgs(f, '2, c=4, **collections.UserDict(b=3)')
866 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3, c=4)')
867
Benjamin Peterson6a2638b2011-03-28 17:32:31 -0500868 def test_varkw_only(self):
869 # issue11256:
870 f = self.makeCallable('**c')
871 self.assertEqualCallArgs(f, '')
872 self.assertEqualCallArgs(f, 'a=1')
873 self.assertEqualCallArgs(f, 'a=1, b=2')
874 self.assertEqualCallArgs(f, 'c=3, **{"a": 1, "b": 2}')
875 self.assertEqualCallArgs(f, '**collections.UserDict(a=1, b=2)')
876 self.assertEqualCallArgs(f, 'c=3, **collections.UserDict(a=1, b=2)')
877
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000878 def test_keyword_only(self):
879 f = self.makeCallable('a=3, *, c, d=2')
880 self.assertEqualCallArgs(f, 'c=3')
881 self.assertEqualCallArgs(f, 'c=3, a=3')
882 self.assertEqualCallArgs(f, 'a=2, c=4')
883 self.assertEqualCallArgs(f, '4, c=4')
884 self.assertEqualException(f, '')
885 self.assertEqualException(f, '3')
886 self.assertEqualException(f, 'a=3')
887 self.assertEqualException(f, 'd=4')
888
Benjamin Peterson6a2638b2011-03-28 17:32:31 -0500889 f = self.makeCallable('*, c, d=2')
890 self.assertEqualCallArgs(f, 'c=3')
891 self.assertEqualCallArgs(f, 'c=3, d=4')
892 self.assertEqualCallArgs(f, 'd=4, c=3')
893
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000894 def test_multiple_features(self):
895 f = self.makeCallable('a, b=2, *f, **g')
896 self.assertEqualCallArgs(f, '2, 3, 7')
897 self.assertEqualCallArgs(f, '2, 3, x=8')
898 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
899 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9')
900 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9')
901 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
902 '[2, 3, (4,[5,6])]), **{"y":9, "z":10}')
903 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
904 '(4,[5,6])]), **collections.UserDict('
905 'y=9, z=10)')
906
Benjamin Peterson6a2638b2011-03-28 17:32:31 -0500907 f = self.makeCallable('a, b=2, *f, x, y=99, **g')
908 self.assertEqualCallArgs(f, '2, 3, x=8')
909 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
910 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9, z=10')
911 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9, z=10')
912 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
913 '[2, 3, (4,[5,6])]), q=0, **{"y":9, "z":10}')
914 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
915 '(4,[5,6])]), q=0, **collections.UserDict('
916 'y=9, z=10)')
917
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000918 def test_errors(self):
919 f0 = self.makeCallable('')
920 f1 = self.makeCallable('a, b')
921 f2 = self.makeCallable('a, b=1')
922 # f0 takes no arguments
923 self.assertEqualException(f0, '1')
924 self.assertEqualException(f0, 'x=1')
925 self.assertEqualException(f0, '1,x=1')
926 # f1 takes exactly 2 arguments
927 self.assertEqualException(f1, '')
928 self.assertEqualException(f1, '1')
929 self.assertEqualException(f1, 'a=2')
930 self.assertEqualException(f1, 'b=3')
931 # f2 takes at least 1 argument
932 self.assertEqualException(f2, '')
933 self.assertEqualException(f2, 'b=3')
934 for f in f1, f2:
935 # f1/f2 takes exactly/at most 2 arguments
936 self.assertEqualException(f, '2, 3, 4')
937 self.assertEqualException(f, '1, 2, 3, a=1')
938 self.assertEqualException(f, '2, 3, 4, c=5')
Georg Brandl178e5ea2012-02-21 00:32:36 +0100939 # XXX: success of this one depends on dict order
940 ## self.assertEqualException(f, '2, 3, 4, a=1, c=5')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000941 # f got an unexpected keyword argument
942 self.assertEqualException(f, 'c=2')
943 self.assertEqualException(f, '2, c=3')
944 self.assertEqualException(f, '2, 3, c=4')
945 self.assertEqualException(f, '2, c=4, b=3')
946 self.assertEqualException(f, '**{u"\u03c0\u03b9": 4}')
947 # f got multiple values for keyword argument
948 self.assertEqualException(f, '1, a=2')
949 self.assertEqualException(f, '1, **{"a":2}')
950 self.assertEqualException(f, '1, 2, b=3')
951 # XXX: Python inconsistency
952 # - for functions and bound methods: unexpected keyword 'c'
953 # - for unbound methods: multiple values for keyword 'a'
954 #self.assertEqualException(f, '1, c=3, a=2')
Benjamin Peterson6a2638b2011-03-28 17:32:31 -0500955 # issue11256:
956 f3 = self.makeCallable('**c')
957 self.assertEqualException(f3, '1, 2')
958 self.assertEqualException(f3, '1, 2, a=1, b=2')
959 f4 = self.makeCallable('*, a, b=0')
960 self.assertEqualException(f3, '1, 2')
961 self.assertEqualException(f3, '1, 2, a=1, b=2')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000962
963class TestGetcallargsMethods(TestGetcallargsFunctions):
964
965 def setUp(self):
966 class Foo(object):
967 pass
968 self.cls = Foo
969 self.inst = Foo()
970
971 def makeCallable(self, signature):
972 assert 'self' not in signature
973 mk = super(TestGetcallargsMethods, self).makeCallable
974 self.cls.method = mk('self, ' + signature)
975 return self.inst.method
976
977class TestGetcallargsUnboundMethods(TestGetcallargsMethods):
978
979 def makeCallable(self, signature):
980 super(TestGetcallargsUnboundMethods, self).makeCallable(signature)
981 return self.cls.method
982
983 def assertEqualCallArgs(self, func, call_params_string, locs=None):
984 return super(TestGetcallargsUnboundMethods, self).assertEqualCallArgs(
985 *self._getAssertEqualParams(func, call_params_string, locs))
986
987 def assertEqualException(self, func, call_params_string, locs=None):
988 return super(TestGetcallargsUnboundMethods, self).assertEqualException(
989 *self._getAssertEqualParams(func, call_params_string, locs))
990
991 def _getAssertEqualParams(self, func, call_params_string, locs=None):
992 assert 'inst' not in call_params_string
993 locs = dict(locs or {}, inst=self.inst)
994 return (func, 'inst,' + call_params_string, locs)
995
Michael Foord95fc51d2010-11-20 15:07:30 +0000996
997class TestGetattrStatic(unittest.TestCase):
998
999 def test_basic(self):
1000 class Thing(object):
1001 x = object()
1002
1003 thing = Thing()
1004 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1005 self.assertEqual(inspect.getattr_static(thing, 'x', None), Thing.x)
1006 with self.assertRaises(AttributeError):
1007 inspect.getattr_static(thing, 'y')
1008
1009 self.assertEqual(inspect.getattr_static(thing, 'y', 3), 3)
1010
1011 def test_inherited(self):
1012 class Thing(object):
1013 x = object()
1014 class OtherThing(Thing):
1015 pass
1016
1017 something = OtherThing()
1018 self.assertEqual(inspect.getattr_static(something, 'x'), Thing.x)
1019
1020 def test_instance_attr(self):
1021 class Thing(object):
1022 x = 2
1023 def __init__(self, x):
1024 self.x = x
1025 thing = Thing(3)
1026 self.assertEqual(inspect.getattr_static(thing, 'x'), 3)
1027 del thing.x
1028 self.assertEqual(inspect.getattr_static(thing, 'x'), 2)
1029
1030 def test_property(self):
1031 class Thing(object):
1032 @property
1033 def x(self):
1034 raise AttributeError("I'm pretending not to exist")
1035 thing = Thing()
1036 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1037
Ezio Melotti75cbd732011-04-28 00:59:29 +03001038 def test_descriptor_raises_AttributeError(self):
Michael Foord95fc51d2010-11-20 15:07:30 +00001039 class descriptor(object):
1040 def __get__(*_):
1041 raise AttributeError("I'm pretending not to exist")
1042 desc = descriptor()
1043 class Thing(object):
1044 x = desc
1045 thing = Thing()
1046 self.assertEqual(inspect.getattr_static(thing, 'x'), desc)
1047
1048 def test_classAttribute(self):
1049 class Thing(object):
1050 x = object()
1051
1052 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.x)
1053
1054 def test_inherited_classattribute(self):
1055 class Thing(object):
1056 x = object()
1057 class OtherThing(Thing):
1058 pass
1059
1060 self.assertEqual(inspect.getattr_static(OtherThing, 'x'), Thing.x)
1061
1062 def test_slots(self):
1063 class Thing(object):
1064 y = 'bar'
1065 __slots__ = ['x']
1066 def __init__(self):
1067 self.x = 'foo'
1068 thing = Thing()
1069 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1070 self.assertEqual(inspect.getattr_static(thing, 'y'), 'bar')
1071
1072 del thing.x
1073 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1074
1075 def test_metaclass(self):
1076 class meta(type):
1077 attr = 'foo'
1078 class Thing(object, metaclass=meta):
1079 pass
1080 self.assertEqual(inspect.getattr_static(Thing, 'attr'), 'foo')
1081
1082 class sub(meta):
1083 pass
1084 class OtherThing(object, metaclass=sub):
1085 x = 3
1086 self.assertEqual(inspect.getattr_static(OtherThing, 'attr'), 'foo')
1087
1088 class OtherOtherThing(OtherThing):
1089 pass
1090 # this test is odd, but it was added as it exposed a bug
1091 self.assertEqual(inspect.getattr_static(OtherOtherThing, 'x'), 3)
1092
1093 def test_no_dict_no_slots(self):
1094 self.assertEqual(inspect.getattr_static(1, 'foo', None), None)
1095 self.assertNotEqual(inspect.getattr_static('foo', 'lower'), None)
1096
1097 def test_no_dict_no_slots_instance_member(self):
1098 # returns descriptor
1099 with open(__file__) as handle:
1100 self.assertEqual(inspect.getattr_static(handle, 'name'), type(handle).name)
1101
1102 def test_inherited_slots(self):
1103 # returns descriptor
1104 class Thing(object):
1105 __slots__ = ['x']
1106 def __init__(self):
1107 self.x = 'foo'
1108
1109 class OtherThing(Thing):
1110 pass
1111 # it would be nice if this worked...
1112 # we get the descriptor instead of the instance attribute
1113 self.assertEqual(inspect.getattr_static(OtherThing(), 'x'), Thing.x)
1114
1115 def test_descriptor(self):
1116 class descriptor(object):
1117 def __get__(self, instance, owner):
1118 return 3
1119 class Foo(object):
1120 d = descriptor()
1121
1122 foo = Foo()
1123
1124 # for a non data descriptor we return the instance attribute
1125 foo.__dict__['d'] = 1
1126 self.assertEqual(inspect.getattr_static(foo, 'd'), 1)
1127
1128 # if the descriptor is a data-desciptor we should return the
1129 # descriptor
1130 descriptor.__set__ = lambda s, i, v: None
1131 self.assertEqual(inspect.getattr_static(foo, 'd'), Foo.__dict__['d'])
1132
1133
1134 def test_metaclass_with_descriptor(self):
1135 class descriptor(object):
1136 def __get__(self, instance, owner):
1137 return 3
1138 class meta(type):
1139 d = descriptor()
1140 class Thing(object, metaclass=meta):
1141 pass
1142 self.assertEqual(inspect.getattr_static(Thing, 'd'), meta.__dict__['d'])
1143
1144
Michael Foordcc7ebb82010-11-20 16:20:16 +00001145 def test_class_as_property(self):
1146 class Base(object):
1147 foo = 3
1148
1149 class Something(Base):
Michael Foord35184ed2010-11-20 16:58:30 +00001150 executed = False
Michael Foordcc7ebb82010-11-20 16:20:16 +00001151 @property
1152 def __class__(self):
Michael Foord35184ed2010-11-20 16:58:30 +00001153 self.executed = True
Michael Foordcc7ebb82010-11-20 16:20:16 +00001154 return object
1155
Michael Foord35184ed2010-11-20 16:58:30 +00001156 instance = Something()
1157 self.assertEqual(inspect.getattr_static(instance, 'foo'), 3)
1158 self.assertFalse(instance.executed)
Michael Foordcc7ebb82010-11-20 16:20:16 +00001159 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1160
Michael Foorde5162652010-11-20 16:40:44 +00001161 def test_mro_as_property(self):
1162 class Meta(type):
1163 @property
1164 def __mro__(self):
1165 return (object,)
1166
1167 class Base(object):
1168 foo = 3
1169
1170 class Something(Base, metaclass=Meta):
1171 pass
1172
1173 self.assertEqual(inspect.getattr_static(Something(), 'foo'), 3)
1174 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1175
Michael Foorddcebe0f2011-03-15 19:20:44 -04001176 def test_dict_as_property(self):
1177 test = self
1178 test.called = False
1179
1180 class Foo(dict):
1181 a = 3
1182 @property
1183 def __dict__(self):
1184 test.called = True
1185 return {}
1186
1187 foo = Foo()
1188 foo.a = 4
1189 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1190 self.assertFalse(test.called)
1191
1192 def test_custom_object_dict(self):
1193 test = self
1194 test.called = False
1195
1196 class Custom(dict):
1197 def get(self, key, default=None):
1198 test.called = True
1199 super().get(key, default)
1200
1201 class Foo(object):
1202 a = 3
1203 foo = Foo()
1204 foo.__dict__ = Custom()
1205 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1206 self.assertFalse(test.called)
1207
1208 def test_metaclass_dict_as_property(self):
1209 class Meta(type):
1210 @property
1211 def __dict__(self):
1212 self.executed = True
1213
1214 class Thing(metaclass=Meta):
1215 executed = False
1216
1217 def __init__(self):
1218 self.spam = 42
1219
1220 instance = Thing()
1221 self.assertEqual(inspect.getattr_static(instance, "spam"), 42)
1222 self.assertFalse(Thing.executed)
Michael Foorde5162652010-11-20 16:40:44 +00001223
Michael Foorda51623b2011-12-18 22:01:40 +00001224 def test_module(self):
1225 sentinel = object()
1226 self.assertIsNot(inspect.getattr_static(sys, "version", sentinel),
1227 sentinel)
1228
Michael Foord3ba95f82011-12-22 01:13:37 +00001229 def test_metaclass_with_metaclass_with_dict_as_property(self):
1230 class MetaMeta(type):
1231 @property
1232 def __dict__(self):
1233 self.executed = True
1234 return dict(spam=42)
1235
1236 class Meta(type, metaclass=MetaMeta):
1237 executed = False
1238
1239 class Thing(metaclass=Meta):
1240 pass
1241
1242 with self.assertRaises(AttributeError):
1243 inspect.getattr_static(Thing, "spam")
1244 self.assertFalse(Thing.executed)
1245
Nick Coghlane0f04652010-11-21 03:44:04 +00001246class TestGetGeneratorState(unittest.TestCase):
1247
1248 def setUp(self):
1249 def number_generator():
1250 for number in range(5):
1251 yield number
1252 self.generator = number_generator()
1253
1254 def _generatorstate(self):
1255 return inspect.getgeneratorstate(self.generator)
1256
1257 def test_created(self):
1258 self.assertEqual(self._generatorstate(), inspect.GEN_CREATED)
1259
1260 def test_suspended(self):
1261 next(self.generator)
1262 self.assertEqual(self._generatorstate(), inspect.GEN_SUSPENDED)
1263
1264 def test_closed_after_exhaustion(self):
1265 for i in self.generator:
1266 pass
1267 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1268
1269 def test_closed_after_immediate_exception(self):
1270 with self.assertRaises(RuntimeError):
1271 self.generator.throw(RuntimeError)
1272 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1273
1274 def test_running(self):
1275 # As mentioned on issue #10220, checking for the RUNNING state only
1276 # makes sense inside the generator itself.
1277 # The following generator checks for this by using the closure's
1278 # reference to self and the generator state checking helper method
1279 def running_check_generator():
1280 for number in range(5):
1281 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1282 yield number
1283 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1284 self.generator = running_check_generator()
1285 # Running up to the first yield
1286 next(self.generator)
1287 # Running after the first yield
1288 next(self.generator)
1289
Nick Coghlan7921b9f2010-11-30 06:36:04 +00001290 def test_easy_debugging(self):
1291 # repr() and str() of a generator state should contain the state name
1292 names = 'GEN_CREATED GEN_RUNNING GEN_SUSPENDED GEN_CLOSED'.split()
1293 for name in names:
1294 state = getattr(inspect, name)
1295 self.assertIn(name, repr(state))
1296 self.assertIn(name, str(state))
1297
Nick Coghlan04e2e3f2012-06-23 19:52:05 +10001298 def test_getgeneratorlocals(self):
1299 def each(lst, a=None):
1300 b=(1, 2, 3)
1301 for v in lst:
1302 if v == 3:
1303 c = 12
1304 yield v
1305
1306 numbers = each([1, 2, 3])
1307 self.assertEqual(inspect.getgeneratorlocals(numbers),
1308 {'a': None, 'lst': [1, 2, 3]})
1309 next(numbers)
1310 self.assertEqual(inspect.getgeneratorlocals(numbers),
1311 {'a': None, 'lst': [1, 2, 3], 'v': 1,
1312 'b': (1, 2, 3)})
1313 next(numbers)
1314 self.assertEqual(inspect.getgeneratorlocals(numbers),
1315 {'a': None, 'lst': [1, 2, 3], 'v': 2,
1316 'b': (1, 2, 3)})
1317 next(numbers)
1318 self.assertEqual(inspect.getgeneratorlocals(numbers),
1319 {'a': None, 'lst': [1, 2, 3], 'v': 3,
1320 'b': (1, 2, 3), 'c': 12})
1321 try:
1322 next(numbers)
1323 except StopIteration:
1324 pass
1325 self.assertEqual(inspect.getgeneratorlocals(numbers), {})
1326
1327 def test_getgeneratorlocals_empty(self):
1328 def yield_one():
1329 yield 1
1330 one = yield_one()
1331 self.assertEqual(inspect.getgeneratorlocals(one), {})
1332 try:
1333 next(one)
1334 except StopIteration:
1335 pass
1336 self.assertEqual(inspect.getgeneratorlocals(one), {})
1337
1338 def test_getgeneratorlocals_error(self):
1339 self.assertRaises(TypeError, inspect.getgeneratorlocals, 1)
1340 self.assertRaises(TypeError, inspect.getgeneratorlocals, lambda x: True)
1341 self.assertRaises(TypeError, inspect.getgeneratorlocals, set)
1342 self.assertRaises(TypeError, inspect.getgeneratorlocals, (2,3))
1343
Nick Coghlane0f04652010-11-21 03:44:04 +00001344
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001345class TestSignatureObject(unittest.TestCase):
1346 @staticmethod
1347 def signature(func):
1348 sig = inspect.signature(func)
1349 return (tuple((param.name,
1350 (... if param.default is param.empty else param.default),
1351 (... if param.annotation is param.empty
1352 else param.annotation),
1353 str(param.kind).lower())
1354 for param in sig.parameters.values()),
1355 (... if sig.return_annotation is sig.empty
1356 else sig.return_annotation))
1357
1358 def test_signature_object(self):
1359 S = inspect.Signature
1360 P = inspect.Parameter
1361
1362 self.assertEqual(str(S()), '()')
1363
1364 def test(po, pk, *args, ko, **kwargs):
1365 pass
1366 sig = inspect.signature(test)
1367 po = sig.parameters['po'].replace(kind=P.POSITIONAL_ONLY)
1368 pk = sig.parameters['pk']
1369 args = sig.parameters['args']
1370 ko = sig.parameters['ko']
1371 kwargs = sig.parameters['kwargs']
1372
1373 S((po, pk, args, ko, kwargs))
1374
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001375 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001376 S((pk, po, args, ko, kwargs))
1377
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001378 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001379 S((po, args, pk, ko, kwargs))
1380
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001381 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001382 S((args, po, pk, ko, kwargs))
1383
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001384 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001385 S((po, pk, args, kwargs, ko))
1386
1387 kwargs2 = kwargs.replace(name='args')
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001388 with self.assertRaisesRegex(ValueError, 'duplicate parameter name'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001389 S((po, pk, args, kwargs2, ko))
1390
1391 def test_signature_immutability(self):
1392 def test(a):
1393 pass
1394 sig = inspect.signature(test)
1395
1396 with self.assertRaises(AttributeError):
1397 sig.foo = 'bar'
1398
1399 with self.assertRaises(TypeError):
1400 sig.parameters['a'] = None
1401
1402 def test_signature_on_noarg(self):
1403 def test():
1404 pass
1405 self.assertEqual(self.signature(test), ((), ...))
1406
1407 def test_signature_on_wargs(self):
1408 def test(a, b:'foo') -> 123:
1409 pass
1410 self.assertEqual(self.signature(test),
1411 ((('a', ..., ..., "positional_or_keyword"),
1412 ('b', ..., 'foo', "positional_or_keyword")),
1413 123))
1414
1415 def test_signature_on_wkwonly(self):
1416 def test(*, a:float, b:str) -> int:
1417 pass
1418 self.assertEqual(self.signature(test),
1419 ((('a', ..., float, "keyword_only"),
1420 ('b', ..., str, "keyword_only")),
1421 int))
1422
1423 def test_signature_on_complex_args(self):
1424 def test(a, b:'foo'=10, *args:'bar', spam:'baz', ham=123, **kwargs:int):
1425 pass
1426 self.assertEqual(self.signature(test),
1427 ((('a', ..., ..., "positional_or_keyword"),
1428 ('b', 10, 'foo', "positional_or_keyword"),
1429 ('args', ..., 'bar', "var_positional"),
1430 ('spam', ..., 'baz', "keyword_only"),
1431 ('ham', 123, ..., "keyword_only"),
1432 ('kwargs', ..., int, "var_keyword")),
1433 ...))
1434
1435 def test_signature_on_builtin_function(self):
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001436 with self.assertRaisesRegex(ValueError, 'not supported by signature'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001437 inspect.signature(type)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001438 with self.assertRaisesRegex(ValueError, 'not supported by signature'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001439 # support for 'wrapper_descriptor'
1440 inspect.signature(type.__call__)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001441 with self.assertRaisesRegex(ValueError, 'not supported by signature'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001442 # support for 'method-wrapper'
1443 inspect.signature(min.__call__)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001444 with self.assertRaisesRegex(ValueError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001445 'no signature found for builtin function'):
1446 # support for 'method-wrapper'
1447 inspect.signature(min)
1448
1449 def test_signature_on_non_function(self):
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001450 with self.assertRaisesRegex(TypeError, 'is not a callable object'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001451 inspect.signature(42)
1452
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001453 with self.assertRaisesRegex(TypeError, 'is not a Python function'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001454 inspect.Signature.from_function(42)
1455
1456 def test_signature_on_method(self):
1457 class Test:
1458 def foo(self, arg1, arg2=1) -> int:
1459 pass
1460
1461 meth = Test().foo
1462
1463 self.assertEqual(self.signature(meth),
1464 ((('arg1', ..., ..., "positional_or_keyword"),
1465 ('arg2', 1, ..., "positional_or_keyword")),
1466 int))
1467
1468 def test_signature_on_classmethod(self):
1469 class Test:
1470 @classmethod
1471 def foo(cls, arg1, *, arg2=1):
1472 pass
1473
1474 meth = Test().foo
1475 self.assertEqual(self.signature(meth),
1476 ((('arg1', ..., ..., "positional_or_keyword"),
1477 ('arg2', 1, ..., "keyword_only")),
1478 ...))
1479
1480 meth = Test.foo
1481 self.assertEqual(self.signature(meth),
1482 ((('arg1', ..., ..., "positional_or_keyword"),
1483 ('arg2', 1, ..., "keyword_only")),
1484 ...))
1485
1486 def test_signature_on_staticmethod(self):
1487 class Test:
1488 @staticmethod
1489 def foo(cls, *, arg):
1490 pass
1491
1492 meth = Test().foo
1493 self.assertEqual(self.signature(meth),
1494 ((('cls', ..., ..., "positional_or_keyword"),
1495 ('arg', ..., ..., "keyword_only")),
1496 ...))
1497
1498 meth = Test.foo
1499 self.assertEqual(self.signature(meth),
1500 ((('cls', ..., ..., "positional_or_keyword"),
1501 ('arg', ..., ..., "keyword_only")),
1502 ...))
1503
1504 def test_signature_on_partial(self):
1505 from functools import partial
1506
1507 def test():
1508 pass
1509
1510 self.assertEqual(self.signature(partial(test)), ((), ...))
1511
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001512 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001513 inspect.signature(partial(test, 1))
1514
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001515 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001516 inspect.signature(partial(test, a=1))
1517
1518 def test(a, b, *, c, d):
1519 pass
1520
1521 self.assertEqual(self.signature(partial(test)),
1522 ((('a', ..., ..., "positional_or_keyword"),
1523 ('b', ..., ..., "positional_or_keyword"),
1524 ('c', ..., ..., "keyword_only"),
1525 ('d', ..., ..., "keyword_only")),
1526 ...))
1527
1528 self.assertEqual(self.signature(partial(test, 1)),
1529 ((('b', ..., ..., "positional_or_keyword"),
1530 ('c', ..., ..., "keyword_only"),
1531 ('d', ..., ..., "keyword_only")),
1532 ...))
1533
1534 self.assertEqual(self.signature(partial(test, 1, c=2)),
1535 ((('b', ..., ..., "positional_or_keyword"),
1536 ('c', 2, ..., "keyword_only"),
1537 ('d', ..., ..., "keyword_only")),
1538 ...))
1539
1540 self.assertEqual(self.signature(partial(test, b=1, c=2)),
1541 ((('a', ..., ..., "positional_or_keyword"),
1542 ('b', 1, ..., "positional_or_keyword"),
1543 ('c', 2, ..., "keyword_only"),
1544 ('d', ..., ..., "keyword_only")),
1545 ...))
1546
1547 self.assertEqual(self.signature(partial(test, 0, b=1, c=2)),
1548 ((('b', 1, ..., "positional_or_keyword"),
1549 ('c', 2, ..., "keyword_only"),
1550 ('d', ..., ..., "keyword_only"),),
1551 ...))
1552
1553 def test(a, *args, b, **kwargs):
1554 pass
1555
1556 self.assertEqual(self.signature(partial(test, 1)),
1557 ((('args', ..., ..., "var_positional"),
1558 ('b', ..., ..., "keyword_only"),
1559 ('kwargs', ..., ..., "var_keyword")),
1560 ...))
1561
1562 self.assertEqual(self.signature(partial(test, 1, 2, 3)),
1563 ((('args', ..., ..., "var_positional"),
1564 ('b', ..., ..., "keyword_only"),
1565 ('kwargs', ..., ..., "var_keyword")),
1566 ...))
1567
1568
1569 self.assertEqual(self.signature(partial(test, 1, 2, 3, test=True)),
1570 ((('args', ..., ..., "var_positional"),
1571 ('b', ..., ..., "keyword_only"),
1572 ('kwargs', ..., ..., "var_keyword")),
1573 ...))
1574
1575 self.assertEqual(self.signature(partial(test, 1, 2, 3, test=1, b=0)),
1576 ((('args', ..., ..., "var_positional"),
1577 ('b', 0, ..., "keyword_only"),
1578 ('kwargs', ..., ..., "var_keyword")),
1579 ...))
1580
1581 self.assertEqual(self.signature(partial(test, b=0)),
1582 ((('a', ..., ..., "positional_or_keyword"),
1583 ('args', ..., ..., "var_positional"),
1584 ('b', 0, ..., "keyword_only"),
1585 ('kwargs', ..., ..., "var_keyword")),
1586 ...))
1587
1588 self.assertEqual(self.signature(partial(test, b=0, test=1)),
1589 ((('a', ..., ..., "positional_or_keyword"),
1590 ('args', ..., ..., "var_positional"),
1591 ('b', 0, ..., "keyword_only"),
1592 ('kwargs', ..., ..., "var_keyword")),
1593 ...))
1594
1595 def test(a, b, c:int) -> 42:
1596 pass
1597
1598 sig = test.__signature__ = inspect.signature(test)
1599
1600 self.assertEqual(self.signature(partial(partial(test, 1))),
1601 ((('b', ..., ..., "positional_or_keyword"),
1602 ('c', ..., int, "positional_or_keyword")),
1603 42))
1604
1605 self.assertEqual(self.signature(partial(partial(test, 1), 2)),
1606 ((('c', ..., int, "positional_or_keyword"),),
1607 42))
1608
1609 psig = inspect.signature(partial(partial(test, 1), 2))
1610
1611 def foo(a):
1612 return a
1613 _foo = partial(partial(foo, a=10), a=20)
1614 self.assertEqual(self.signature(_foo),
1615 ((('a', 20, ..., "positional_or_keyword"),),
1616 ...))
1617 # check that we don't have any side-effects in signature(),
1618 # and the partial object is still functioning
1619 self.assertEqual(_foo(), 20)
1620
1621 def foo(a, b, c):
1622 return a, b, c
1623 _foo = partial(partial(foo, 1, b=20), b=30)
1624 self.assertEqual(self.signature(_foo),
1625 ((('b', 30, ..., "positional_or_keyword"),
1626 ('c', ..., ..., "positional_or_keyword")),
1627 ...))
1628 self.assertEqual(_foo(c=10), (1, 30, 10))
1629 _foo = partial(_foo, 2) # now 'b' has two values -
1630 # positional and keyword
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001631 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001632 inspect.signature(_foo)
1633
1634 def foo(a, b, c, *, d):
1635 return a, b, c, d
1636 _foo = partial(partial(foo, d=20, c=20), b=10, d=30)
1637 self.assertEqual(self.signature(_foo),
1638 ((('a', ..., ..., "positional_or_keyword"),
1639 ('b', 10, ..., "positional_or_keyword"),
1640 ('c', 20, ..., "positional_or_keyword"),
1641 ('d', 30, ..., "keyword_only")),
1642 ...))
1643 ba = inspect.signature(_foo).bind(a=200, b=11)
1644 self.assertEqual(_foo(*ba.args, **ba.kwargs), (200, 11, 20, 30))
1645
1646 def foo(a=1, b=2, c=3):
1647 return a, b, c
1648 _foo = partial(foo, a=10, c=13)
1649 ba = inspect.signature(_foo).bind(11)
1650 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 2, 13))
1651 ba = inspect.signature(_foo).bind(11, 12)
1652 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
1653 ba = inspect.signature(_foo).bind(11, b=12)
1654 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
1655 ba = inspect.signature(_foo).bind(b=12)
1656 self.assertEqual(_foo(*ba.args, **ba.kwargs), (10, 12, 13))
1657 _foo = partial(_foo, b=10)
1658 ba = inspect.signature(_foo).bind(12, 14)
1659 self.assertEqual(_foo(*ba.args, **ba.kwargs), (12, 14, 13))
1660
1661 def test_signature_on_decorated(self):
1662 import functools
1663
1664 def decorator(func):
1665 @functools.wraps(func)
1666 def wrapper(*args, **kwargs) -> int:
1667 return func(*args, **kwargs)
1668 return wrapper
1669
1670 class Foo:
1671 @decorator
1672 def bar(self, a, b):
1673 pass
1674
1675 self.assertEqual(self.signature(Foo.bar),
1676 ((('self', ..., ..., "positional_or_keyword"),
1677 ('a', ..., ..., "positional_or_keyword"),
1678 ('b', ..., ..., "positional_or_keyword")),
1679 ...))
1680
1681 self.assertEqual(self.signature(Foo().bar),
1682 ((('a', ..., ..., "positional_or_keyword"),
1683 ('b', ..., ..., "positional_or_keyword")),
1684 ...))
1685
1686 # Test that we handle method wrappers correctly
1687 def decorator(func):
1688 @functools.wraps(func)
1689 def wrapper(*args, **kwargs) -> int:
1690 return func(42, *args, **kwargs)
1691 sig = inspect.signature(func)
1692 new_params = tuple(sig.parameters.values())[1:]
1693 wrapper.__signature__ = sig.replace(parameters=new_params)
1694 return wrapper
1695
1696 class Foo:
1697 @decorator
1698 def __call__(self, a, b):
1699 pass
1700
1701 self.assertEqual(self.signature(Foo.__call__),
1702 ((('a', ..., ..., "positional_or_keyword"),
1703 ('b', ..., ..., "positional_or_keyword")),
1704 ...))
1705
1706 self.assertEqual(self.signature(Foo().__call__),
1707 ((('b', ..., ..., "positional_or_keyword"),),
1708 ...))
1709
1710 def test_signature_on_class(self):
1711 class C:
1712 def __init__(self, a):
1713 pass
1714
1715 self.assertEqual(self.signature(C),
1716 ((('a', ..., ..., "positional_or_keyword"),),
1717 ...))
1718
1719 class CM(type):
1720 def __call__(cls, a):
1721 pass
1722 class C(metaclass=CM):
1723 def __init__(self, b):
1724 pass
1725
1726 self.assertEqual(self.signature(C),
1727 ((('a', ..., ..., "positional_or_keyword"),),
1728 ...))
1729
1730 class CM(type):
1731 def __new__(mcls, name, bases, dct, *, foo=1):
1732 return super().__new__(mcls, name, bases, dct)
1733 class C(metaclass=CM):
1734 def __init__(self, b):
1735 pass
1736
1737 self.assertEqual(self.signature(C),
1738 ((('b', ..., ..., "positional_or_keyword"),),
1739 ...))
1740
1741 self.assertEqual(self.signature(CM),
1742 ((('name', ..., ..., "positional_or_keyword"),
1743 ('bases', ..., ..., "positional_or_keyword"),
1744 ('dct', ..., ..., "positional_or_keyword"),
1745 ('foo', 1, ..., "keyword_only")),
1746 ...))
1747
1748 class CMM(type):
1749 def __new__(mcls, name, bases, dct, *, foo=1):
1750 return super().__new__(mcls, name, bases, dct)
1751 def __call__(cls, nm, bs, dt):
1752 return type(nm, bs, dt)
1753 class CM(type, metaclass=CMM):
1754 def __new__(mcls, name, bases, dct, *, bar=2):
1755 return super().__new__(mcls, name, bases, dct)
1756 class C(metaclass=CM):
1757 def __init__(self, b):
1758 pass
1759
1760 self.assertEqual(self.signature(CMM),
1761 ((('name', ..., ..., "positional_or_keyword"),
1762 ('bases', ..., ..., "positional_or_keyword"),
1763 ('dct', ..., ..., "positional_or_keyword"),
1764 ('foo', 1, ..., "keyword_only")),
1765 ...))
1766
1767 self.assertEqual(self.signature(CM),
1768 ((('nm', ..., ..., "positional_or_keyword"),
1769 ('bs', ..., ..., "positional_or_keyword"),
1770 ('dt', ..., ..., "positional_or_keyword")),
1771 ...))
1772
1773 self.assertEqual(self.signature(C),
1774 ((('b', ..., ..., "positional_or_keyword"),),
1775 ...))
1776
1777 class CM(type):
1778 def __init__(cls, name, bases, dct, *, bar=2):
1779 return super().__init__(name, bases, dct)
1780 class C(metaclass=CM):
1781 def __init__(self, b):
1782 pass
1783
1784 self.assertEqual(self.signature(CM),
1785 ((('name', ..., ..., "positional_or_keyword"),
1786 ('bases', ..., ..., "positional_or_keyword"),
1787 ('dct', ..., ..., "positional_or_keyword"),
1788 ('bar', 2, ..., "keyword_only")),
1789 ...))
1790
1791 def test_signature_on_callable_objects(self):
1792 class Foo:
1793 def __call__(self, a):
1794 pass
1795
1796 self.assertEqual(self.signature(Foo()),
1797 ((('a', ..., ..., "positional_or_keyword"),),
1798 ...))
1799
1800 class Spam:
1801 pass
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001802 with self.assertRaisesRegex(TypeError, "is not a callable object"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001803 inspect.signature(Spam())
1804
1805 class Bar(Spam, Foo):
1806 pass
1807
1808 self.assertEqual(self.signature(Bar()),
1809 ((('a', ..., ..., "positional_or_keyword"),),
1810 ...))
1811
1812 class ToFail:
1813 __call__ = type
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001814 with self.assertRaisesRegex(ValueError, "not supported by signature"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001815 inspect.signature(ToFail())
1816
1817
1818 class Wrapped:
1819 pass
1820 Wrapped.__wrapped__ = lambda a: None
1821 self.assertEqual(self.signature(Wrapped),
1822 ((('a', ..., ..., "positional_or_keyword"),),
1823 ...))
1824
1825 def test_signature_on_lambdas(self):
1826 self.assertEqual(self.signature((lambda a=10: a)),
1827 ((('a', 10, ..., "positional_or_keyword"),),
1828 ...))
1829
1830 def test_signature_equality(self):
1831 def foo(a, *, b:int) -> float: pass
1832 self.assertNotEqual(inspect.signature(foo), 42)
1833
1834 def bar(a, *, b:int) -> float: pass
1835 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
1836
1837 def bar(a, *, b:int) -> int: pass
1838 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
1839
1840 def bar(a, *, b:int): pass
1841 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
1842
1843 def bar(a, *, b:int=42) -> float: pass
1844 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
1845
1846 def bar(a, *, c) -> float: pass
1847 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
1848
1849 def bar(a, b:int) -> float: pass
1850 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
1851 def spam(b:int, a) -> float: pass
1852 self.assertNotEqual(inspect.signature(spam), inspect.signature(bar))
1853
1854 def foo(*, a, b, c): pass
1855 def bar(*, c, b, a): pass
1856 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
1857
1858 def foo(*, a=1, b, c): pass
1859 def bar(*, c, b, a=1): pass
1860 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
1861
1862 def foo(pos, *, a=1, b, c): pass
1863 def bar(pos, *, c, b, a=1): pass
1864 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
1865
1866 def foo(pos, *, a, b, c): pass
1867 def bar(pos, *, c, b, a=1): pass
1868 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
1869
1870 def foo(pos, *args, a=42, b, c, **kwargs:int): pass
1871 def bar(pos, *args, c, b, a=42, **kwargs:int): pass
1872 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
1873
1874 def test_signature_unhashable(self):
1875 def foo(a): pass
1876 sig = inspect.signature(foo)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001877 with self.assertRaisesRegex(TypeError, 'unhashable type'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001878 hash(sig)
1879
1880 def test_signature_str(self):
1881 def foo(a:int=1, *, b, c=None, **kwargs) -> 42:
1882 pass
1883 self.assertEqual(str(inspect.signature(foo)),
1884 '(a:int=1, *, b, c=None, **kwargs) -> 42')
1885
1886 def foo(a:int=1, *args, b, c=None, **kwargs) -> 42:
1887 pass
1888 self.assertEqual(str(inspect.signature(foo)),
1889 '(a:int=1, *args, b, c=None, **kwargs) -> 42')
1890
1891 def foo():
1892 pass
1893 self.assertEqual(str(inspect.signature(foo)), '()')
1894
1895 def test_signature_str_positional_only(self):
1896 P = inspect.Parameter
1897
1898 def test(a_po, *, b, **kwargs):
1899 return a_po, kwargs
1900
1901 sig = inspect.signature(test)
1902 new_params = list(sig.parameters.values())
1903 new_params[0] = new_params[0].replace(kind=P.POSITIONAL_ONLY)
1904 test.__signature__ = sig.replace(parameters=new_params)
1905
1906 self.assertEqual(str(inspect.signature(test)),
1907 '(<a_po>, *, b, **kwargs)')
1908
1909 sig = inspect.signature(test)
1910 new_params = list(sig.parameters.values())
1911 new_params[0] = new_params[0].replace(name=None)
1912 test.__signature__ = sig.replace(parameters=new_params)
1913 self.assertEqual(str(inspect.signature(test)),
1914 '(<0>, *, b, **kwargs)')
1915
1916 def test_signature_replace_anno(self):
1917 def test() -> 42:
1918 pass
1919
1920 sig = inspect.signature(test)
1921 sig = sig.replace(return_annotation=None)
1922 self.assertIs(sig.return_annotation, None)
1923 sig = sig.replace(return_annotation=sig.empty)
1924 self.assertIs(sig.return_annotation, sig.empty)
1925 sig = sig.replace(return_annotation=42)
1926 self.assertEqual(sig.return_annotation, 42)
1927 self.assertEqual(sig, inspect.signature(test))
1928
1929
1930class TestParameterObject(unittest.TestCase):
1931 def test_signature_parameter_kinds(self):
1932 P = inspect.Parameter
1933 self.assertTrue(P.POSITIONAL_ONLY < P.POSITIONAL_OR_KEYWORD < \
1934 P.VAR_POSITIONAL < P.KEYWORD_ONLY < P.VAR_KEYWORD)
1935
1936 self.assertEqual(str(P.POSITIONAL_ONLY), 'POSITIONAL_ONLY')
1937 self.assertTrue('POSITIONAL_ONLY' in repr(P.POSITIONAL_ONLY))
1938
1939 def test_signature_parameter_object(self):
1940 p = inspect.Parameter('foo', default=10,
1941 kind=inspect.Parameter.POSITIONAL_ONLY)
1942 self.assertEqual(p.name, 'foo')
1943 self.assertEqual(p.default, 10)
1944 self.assertIs(p.annotation, p.empty)
1945 self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY)
1946
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001947 with self.assertRaisesRegex(ValueError, 'invalid value'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001948 inspect.Parameter('foo', default=10, kind='123')
1949
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001950 with self.assertRaisesRegex(ValueError, 'not a valid parameter name'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001951 inspect.Parameter('1', kind=inspect.Parameter.VAR_KEYWORD)
1952
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001953 with self.assertRaisesRegex(ValueError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001954 'non-positional-only parameter'):
1955 inspect.Parameter(None, kind=inspect.Parameter.VAR_KEYWORD)
1956
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001957 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001958 inspect.Parameter('a', default=42,
1959 kind=inspect.Parameter.VAR_KEYWORD)
1960
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001961 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001962 inspect.Parameter('a', default=42,
1963 kind=inspect.Parameter.VAR_POSITIONAL)
1964
1965 p = inspect.Parameter('a', default=42,
1966 kind=inspect.Parameter.POSITIONAL_OR_KEYWORD)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001967 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001968 p.replace(kind=inspect.Parameter.VAR_POSITIONAL)
1969
1970 self.assertTrue(repr(p).startswith('<Parameter'))
1971
1972 def test_signature_parameter_equality(self):
1973 P = inspect.Parameter
1974 p = P('foo', default=42, kind=inspect.Parameter.KEYWORD_ONLY)
1975
1976 self.assertEqual(p, p)
1977 self.assertNotEqual(p, 42)
1978
1979 self.assertEqual(p, P('foo', default=42,
1980 kind=inspect.Parameter.KEYWORD_ONLY))
1981
1982 def test_signature_parameter_unhashable(self):
1983 p = inspect.Parameter('foo', default=42,
1984 kind=inspect.Parameter.KEYWORD_ONLY)
1985
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001986 with self.assertRaisesRegex(TypeError, 'unhashable type'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001987 hash(p)
1988
1989 def test_signature_parameter_replace(self):
1990 p = inspect.Parameter('foo', default=42,
1991 kind=inspect.Parameter.KEYWORD_ONLY)
1992
1993 self.assertIsNot(p, p.replace())
1994 self.assertEqual(p, p.replace())
1995
1996 p2 = p.replace(annotation=1)
1997 self.assertEqual(p2.annotation, 1)
1998 p2 = p2.replace(annotation=p2.empty)
1999 self.assertEqual(p, p2)
2000
2001 p2 = p2.replace(name='bar')
2002 self.assertEqual(p2.name, 'bar')
2003 self.assertNotEqual(p2, p)
2004
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002005 with self.assertRaisesRegex(ValueError, 'not a valid parameter name'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002006 p2 = p2.replace(name=p2.empty)
2007
2008 p2 = p2.replace(name='foo', default=None)
2009 self.assertIs(p2.default, None)
2010 self.assertNotEqual(p2, p)
2011
2012 p2 = p2.replace(name='foo', default=p2.empty)
2013 self.assertIs(p2.default, p2.empty)
2014
2015
2016 p2 = p2.replace(default=42, kind=p2.POSITIONAL_OR_KEYWORD)
2017 self.assertEqual(p2.kind, p2.POSITIONAL_OR_KEYWORD)
2018 self.assertNotEqual(p2, p)
2019
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002020 with self.assertRaisesRegex(ValueError, 'invalid value for'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002021 p2 = p2.replace(kind=p2.empty)
2022
2023 p2 = p2.replace(kind=p2.KEYWORD_ONLY)
2024 self.assertEqual(p2, p)
2025
2026 def test_signature_parameter_positional_only(self):
2027 p = inspect.Parameter(None, kind=inspect.Parameter.POSITIONAL_ONLY)
2028 self.assertEqual(str(p), '<>')
2029
2030 p = p.replace(name='1')
2031 self.assertEqual(str(p), '<1>')
2032
2033 def test_signature_parameter_immutability(self):
2034 p = inspect.Parameter(None, kind=inspect.Parameter.POSITIONAL_ONLY)
2035
2036 with self.assertRaises(AttributeError):
2037 p.foo = 'bar'
2038
2039 with self.assertRaises(AttributeError):
2040 p.kind = 123
2041
2042
2043class TestSignatureBind(unittest.TestCase):
2044 @staticmethod
2045 def call(func, *args, **kwargs):
2046 sig = inspect.signature(func)
2047 ba = sig.bind(*args, **kwargs)
2048 return func(*ba.args, **ba.kwargs)
2049
2050 def test_signature_bind_empty(self):
2051 def test():
2052 return 42
2053
2054 self.assertEqual(self.call(test), 42)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002055 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002056 self.call(test, 1)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002057 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002058 self.call(test, 1, spam=10)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002059 with self.assertRaisesRegex(TypeError, 'too many keyword arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002060 self.call(test, spam=1)
2061
2062 def test_signature_bind_var(self):
2063 def test(*args, **kwargs):
2064 return args, kwargs
2065
2066 self.assertEqual(self.call(test), ((), {}))
2067 self.assertEqual(self.call(test, 1), ((1,), {}))
2068 self.assertEqual(self.call(test, 1, 2), ((1, 2), {}))
2069 self.assertEqual(self.call(test, foo='bar'), ((), {'foo': 'bar'}))
2070 self.assertEqual(self.call(test, 1, foo='bar'), ((1,), {'foo': 'bar'}))
2071 self.assertEqual(self.call(test, args=10), ((), {'args': 10}))
2072 self.assertEqual(self.call(test, 1, 2, foo='bar'),
2073 ((1, 2), {'foo': 'bar'}))
2074
2075 def test_signature_bind_just_args(self):
2076 def test(a, b, c):
2077 return a, b, c
2078
2079 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
2080
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002081 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002082 self.call(test, 1, 2, 3, 4)
2083
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002084 with self.assertRaisesRegex(TypeError, "'b' parameter lacking default"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002085 self.call(test, 1)
2086
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002087 with self.assertRaisesRegex(TypeError, "'a' parameter lacking default"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002088 self.call(test)
2089
2090 def test(a, b, c=10):
2091 return a, b, c
2092 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
2093 self.assertEqual(self.call(test, 1, 2), (1, 2, 10))
2094
2095 def test(a=1, b=2, c=3):
2096 return a, b, c
2097 self.assertEqual(self.call(test, a=10, c=13), (10, 2, 13))
2098 self.assertEqual(self.call(test, a=10), (10, 2, 3))
2099 self.assertEqual(self.call(test, b=10), (1, 10, 3))
2100
2101 def test_signature_bind_varargs_order(self):
2102 def test(*args):
2103 return args
2104
2105 self.assertEqual(self.call(test), ())
2106 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
2107
2108 def test_signature_bind_args_and_varargs(self):
2109 def test(a, b, c=3, *args):
2110 return a, b, c, args
2111
2112 self.assertEqual(self.call(test, 1, 2, 3, 4, 5), (1, 2, 3, (4, 5)))
2113 self.assertEqual(self.call(test, 1, 2), (1, 2, 3, ()))
2114 self.assertEqual(self.call(test, b=1, a=2), (2, 1, 3, ()))
2115 self.assertEqual(self.call(test, 1, b=2), (1, 2, 3, ()))
2116
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002117 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002118 "multiple values for argument 'c'"):
2119 self.call(test, 1, 2, 3, c=4)
2120
2121 def test_signature_bind_just_kwargs(self):
2122 def test(**kwargs):
2123 return kwargs
2124
2125 self.assertEqual(self.call(test), {})
2126 self.assertEqual(self.call(test, foo='bar', spam='ham'),
2127 {'foo': 'bar', 'spam': 'ham'})
2128
2129 def test_signature_bind_args_and_kwargs(self):
2130 def test(a, b, c=3, **kwargs):
2131 return a, b, c, kwargs
2132
2133 self.assertEqual(self.call(test, 1, 2), (1, 2, 3, {}))
2134 self.assertEqual(self.call(test, 1, 2, foo='bar', spam='ham'),
2135 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
2136 self.assertEqual(self.call(test, b=2, a=1, foo='bar', spam='ham'),
2137 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
2138 self.assertEqual(self.call(test, a=1, b=2, foo='bar', spam='ham'),
2139 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
2140 self.assertEqual(self.call(test, 1, b=2, foo='bar', spam='ham'),
2141 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
2142 self.assertEqual(self.call(test, 1, b=2, c=4, foo='bar', spam='ham'),
2143 (1, 2, 4, {'foo': 'bar', 'spam': 'ham'}))
2144 self.assertEqual(self.call(test, 1, 2, 4, foo='bar'),
2145 (1, 2, 4, {'foo': 'bar'}))
2146 self.assertEqual(self.call(test, c=5, a=4, b=3),
2147 (4, 3, 5, {}))
2148
2149 def test_signature_bind_kwonly(self):
2150 def test(*, foo):
2151 return foo
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002152 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002153 'too many positional arguments'):
2154 self.call(test, 1)
2155 self.assertEqual(self.call(test, foo=1), 1)
2156
2157 def test(a, *, foo=1, bar):
2158 return foo
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002159 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002160 "'bar' parameter lacking default value"):
2161 self.call(test, 1)
2162
2163 def test(foo, *, bar):
2164 return foo, bar
2165 self.assertEqual(self.call(test, 1, bar=2), (1, 2))
2166 self.assertEqual(self.call(test, bar=2, foo=1), (1, 2))
2167
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002168 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002169 'too many keyword arguments'):
2170 self.call(test, bar=2, foo=1, spam=10)
2171
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002172 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002173 'too many positional arguments'):
2174 self.call(test, 1, 2)
2175
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002176 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002177 'too many positional arguments'):
2178 self.call(test, 1, 2, bar=2)
2179
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002180 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002181 'too many keyword arguments'):
2182 self.call(test, 1, bar=2, spam='ham')
2183
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002184 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002185 "'bar' parameter lacking default value"):
2186 self.call(test, 1)
2187
2188 def test(foo, *, bar, **bin):
2189 return foo, bar, bin
2190 self.assertEqual(self.call(test, 1, bar=2), (1, 2, {}))
2191 self.assertEqual(self.call(test, foo=1, bar=2), (1, 2, {}))
2192 self.assertEqual(self.call(test, 1, bar=2, spam='ham'),
2193 (1, 2, {'spam': 'ham'}))
2194 self.assertEqual(self.call(test, spam='ham', foo=1, bar=2),
2195 (1, 2, {'spam': 'ham'}))
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002196 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002197 "'foo' parameter lacking default value"):
2198 self.call(test, spam='ham', bar=2)
2199 self.assertEqual(self.call(test, 1, bar=2, bin=1, spam=10),
2200 (1, 2, {'bin': 1, 'spam': 10}))
2201
2202 def test_signature_bind_arguments(self):
2203 def test(a, *args, b, z=100, **kwargs):
2204 pass
2205 sig = inspect.signature(test)
2206 ba = sig.bind(10, 20, b=30, c=40, args=50, kwargs=60)
2207 # we won't have 'z' argument in the bound arguments object, as we didn't
2208 # pass it to the 'bind'
2209 self.assertEqual(tuple(ba.arguments.items()),
2210 (('a', 10), ('args', (20,)), ('b', 30),
2211 ('kwargs', {'c': 40, 'args': 50, 'kwargs': 60})))
2212 self.assertEqual(ba.kwargs,
2213 {'b': 30, 'c': 40, 'args': 50, 'kwargs': 60})
2214 self.assertEqual(ba.args, (10, 20))
2215
2216 def test_signature_bind_positional_only(self):
2217 P = inspect.Parameter
2218
2219 def test(a_po, b_po, c_po=3, foo=42, *, bar=50, **kwargs):
2220 return a_po, b_po, c_po, foo, bar, kwargs
2221
2222 sig = inspect.signature(test)
2223 new_params = collections.OrderedDict(tuple(sig.parameters.items()))
2224 for name in ('a_po', 'b_po', 'c_po'):
2225 new_params[name] = new_params[name].replace(kind=P.POSITIONAL_ONLY)
2226 new_sig = sig.replace(parameters=new_params.values())
2227 test.__signature__ = new_sig
2228
2229 self.assertEqual(self.call(test, 1, 2, 4, 5, bar=6),
2230 (1, 2, 4, 5, 6, {}))
2231
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002232 with self.assertRaisesRegex(TypeError, "parameter is positional only"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002233 self.call(test, 1, 2, c_po=4)
2234
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002235 with self.assertRaisesRegex(TypeError, "parameter is positional only"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002236 self.call(test, a_po=1, b_po=2)
2237
2238
2239class TestBoundArguments(unittest.TestCase):
2240 def test_signature_bound_arguments_unhashable(self):
2241 def foo(a): pass
2242 ba = inspect.signature(foo).bind(1)
2243
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002244 with self.assertRaisesRegex(TypeError, 'unhashable type'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002245 hash(ba)
2246
2247 def test_signature_bound_arguments_equality(self):
2248 def foo(a): pass
2249 ba = inspect.signature(foo).bind(1)
2250 self.assertEqual(ba, ba)
2251
2252 ba2 = inspect.signature(foo).bind(1)
2253 self.assertEqual(ba, ba2)
2254
2255 ba3 = inspect.signature(foo).bind(2)
2256 self.assertNotEqual(ba, ba3)
2257 ba3.arguments['a'] = 1
2258 self.assertEqual(ba, ba3)
2259
2260 def bar(b): pass
2261 ba4 = inspect.signature(bar).bind(1)
2262 self.assertNotEqual(ba, ba4)
2263
2264
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00002265def test_main():
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00002266 run_unittest(
2267 TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBuggyCases,
2268 TestInterpreterStack, TestClassesAndFunctions, TestPredicates,
2269 TestGetcallargsFunctions, TestGetcallargsMethods,
Alexander Belopolskyf546e702010-12-02 00:10:11 +00002270 TestGetcallargsUnboundMethods, TestGetattrStatic, TestGetGeneratorState,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002271 TestNoEOL, TestSignatureObject, TestSignatureBind, TestParameterObject,
Nick Coghlan2f92e542012-06-23 19:39:55 +10002272 TestBoundArguments, TestGetClosureVars
Michael Foord95fc51d2010-11-20 15:07:30 +00002273 )
Martin v. Löwis893ffa42003-10-31 15:35:53 +00002274
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00002275if __name__ == "__main__":
2276 test_main()