blob: fb5fe17e22c750b2af08355f94bcd031b02e4e55 [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
Nick Coghlane8c45d62013-07-28 20:00:01 +100011import functools
Nick Coghlanf94a16b2013-09-22 22:46:49 +100012import importlib
Christian Heimesa3538eb2007-11-06 11:44:48 +000013from os.path import normcase
Brett Cannon634a8fc2013-10-02 10:25:42 -040014try:
15 from concurrent.futures import ThreadPoolExecutor
16except ImportError:
17 ThreadPoolExecutor = None
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000018
Alexander Belopolskyf546e702010-12-02 00:10:11 +000019from test.support import run_unittest, TESTFN, DirsOnSysPath
Nick Coghlanf94a16b2013-09-22 22:46:49 +100020from test.script_helper import assert_python_ok, assert_python_failure
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000021from test import inspect_fodder as mod
22from test import inspect_fodder2 as mod2
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000023
R. David Murray74b89242009-05-13 17:33:03 +000024# C module for test_findsource_binary
R. David Murrayb5655772009-05-14 16:17:50 +000025import unicodedata
R. David Murray74b89242009-05-13 17:33:03 +000026
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000027# Functions tested in this suite:
28# ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode,
Christian Heimes7131fd92008-02-19 14:21:46 +000029# isbuiltin, isroutine, isgenerator, isgeneratorfunction, getmembers,
30# getdoc, getfile, getmodule, getsourcefile, getcomments, getsource,
31# getclasstree, getargspec, getargvalues, formatargspec, formatargvalues,
32# currentframe, stack, trace, isdatadescriptor
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000033
Nick Coghlanf088e5e2008-12-14 11:50:48 +000034# NOTE: There are some additional tests relating to interaction with
35# zipimport in the test_zipimport_support test module.
36
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000037modfile = mod.__file__
Thomas Wouters0e3f5912006-08-11 14:57:12 +000038if modfile.endswith(('c', 'o')):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000039 modfile = modfile[:-1]
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000040
Christian Heimesa3538eb2007-11-06 11:44:48 +000041# Normalize file names: on Windows, the case of file names of compiled
42# modules depends on the path used to start the python executable.
43modfile = normcase(modfile)
44
45def revise(filename, *args):
46 return (normcase(filename),) + args
47
Georg Brandl1a3284e2007-12-02 09:40:06 +000048import builtins
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000049
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000050git = mod.StupidGit()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000051
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000052class IsTestBase(unittest.TestCase):
53 predicates = set([inspect.isbuiltin, inspect.isclass, inspect.iscode,
54 inspect.isframe, inspect.isfunction, inspect.ismethod,
Christian Heimes7131fd92008-02-19 14:21:46 +000055 inspect.ismodule, inspect.istraceback,
56 inspect.isgenerator, inspect.isgeneratorfunction])
Tim Peters5a9fb3c2005-01-07 16:01:32 +000057
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000058 def istest(self, predicate, exp):
59 obj = eval(exp)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000060 self.assertTrue(predicate(obj), '%s(%s)' % (predicate.__name__, exp))
Tim Peters5a9fb3c2005-01-07 16:01:32 +000061
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000062 for other in self.predicates - set([predicate]):
Christian Heimes7131fd92008-02-19 14:21:46 +000063 if predicate == inspect.isgeneratorfunction and\
64 other == inspect.isfunction:
65 continue
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000066 self.assertFalse(other(obj), 'not %s(%s)' % (other.__name__, exp))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000067
Christian Heimes7131fd92008-02-19 14:21:46 +000068def generator_function_example(self):
69 for i in range(2):
70 yield i
71
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000072class TestPredicates(IsTestBase):
Christian Heimes227c8002008-03-03 20:34:40 +000073 def test_sixteen(self):
Guido van Rossumc1f779c2007-07-03 08:25:58 +000074 count = len([x for x in dir(inspect) if x.startswith('is')])
Christian Heimes7131fd92008-02-19 14:21:46 +000075 # This test is here for remember you to update Doc/library/inspect.rst
Christian Heimes78644762008-03-04 23:39:23 +000076 # which claims there are 16 such functions
Christian Heimes227c8002008-03-03 20:34:40 +000077 expected = 16
Thomas Wouters0e3f5912006-08-11 14:57:12 +000078 err_msg = "There are %d (not %d) is* functions" % (count, expected)
79 self.assertEqual(count, expected, err_msg)
Tim Peters5a9fb3c2005-01-07 16:01:32 +000080
Christian Heimes7131fd92008-02-19 14:21:46 +000081
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000082 def test_excluding_predicates(self):
Antoine Pitroud5a1a212012-06-17 23:18:07 +020083 global tb
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000084 self.istest(inspect.isbuiltin, 'sys.exit')
85 self.istest(inspect.isbuiltin, '[].append')
Neal Norwitz221085d2007-02-25 20:55:47 +000086 self.istest(inspect.iscode, 'mod.spam.__code__')
Antoine Pitroud5a1a212012-06-17 23:18:07 +020087 try:
88 1/0
89 except:
90 tb = sys.exc_info()[2]
91 self.istest(inspect.isframe, 'tb.tb_frame')
92 self.istest(inspect.istraceback, 'tb')
93 if hasattr(types, 'GetSetDescriptorType'):
94 self.istest(inspect.isgetsetdescriptor,
95 'type(tb.tb_frame).f_locals')
96 else:
97 self.assertFalse(inspect.isgetsetdescriptor(type(tb.tb_frame).f_locals))
98 finally:
99 # Clear traceback and all the frames and local variables hanging to it.
100 tb = None
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000101 self.istest(inspect.isfunction, 'mod.spam')
Christian Heimes4a22b5d2007-11-25 09:39:14 +0000102 self.istest(inspect.isfunction, 'mod.StupidGit.abuse')
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000103 self.istest(inspect.ismethod, 'git.argue')
104 self.istest(inspect.ismodule, 'mod')
Guido van Rossum813b0e52007-05-21 18:11:34 +0000105 self.istest(inspect.isdatadescriptor, 'collections.defaultdict.default_factory')
Christian Heimes7131fd92008-02-19 14:21:46 +0000106 self.istest(inspect.isgenerator, '(x for x in range(2))')
107 self.istest(inspect.isgeneratorfunction, 'generator_function_example')
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000108 if hasattr(types, 'MemberDescriptorType'):
109 self.istest(inspect.ismemberdescriptor, 'datetime.timedelta.days')
110 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000111 self.assertFalse(inspect.ismemberdescriptor(datetime.timedelta.days))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000112
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000113 def test_isroutine(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000114 self.assertTrue(inspect.isroutine(mod.spam))
115 self.assertTrue(inspect.isroutine([].count))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000116
Benjamin Petersonc4656002009-01-17 22:41:18 +0000117 def test_isclass(self):
118 self.istest(inspect.isclass, 'mod.StupidGit')
119 self.assertTrue(inspect.isclass(list))
120
121 class CustomGetattr(object):
122 def __getattr__(self, attr):
123 return None
124 self.assertFalse(inspect.isclass(CustomGetattr()))
125
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000126 def test_get_slot_members(self):
127 class C(object):
128 __slots__ = ("a", "b")
129
130 x = C()
131 x.a = 42
132 members = dict(inspect.getmembers(x))
Benjamin Peterson577473f2010-01-19 00:09:57 +0000133 self.assertIn('a', members)
134 self.assertNotIn('b', members)
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000135
Benjamin Petersona0dfa822009-11-13 02:25:08 +0000136 def test_isabstract(self):
137 from abc import ABCMeta, abstractmethod
138
139 class AbstractClassExample(metaclass=ABCMeta):
140
141 @abstractmethod
142 def foo(self):
143 pass
144
145 class ClassExample(AbstractClassExample):
146 def foo(self):
147 pass
148
149 a = ClassExample()
150
151 # Test general behaviour.
152 self.assertTrue(inspect.isabstract(AbstractClassExample))
153 self.assertFalse(inspect.isabstract(ClassExample))
154 self.assertFalse(inspect.isabstract(a))
155 self.assertFalse(inspect.isabstract(int))
156 self.assertFalse(inspect.isabstract(5))
157
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000158
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000159class TestInterpreterStack(IsTestBase):
160 def __init__(self, *args, **kwargs):
161 unittest.TestCase.__init__(self, *args, **kwargs)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000162
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000163 git.abuse(7, 8, 9)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000164
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000165 def test_abuse_done(self):
166 self.istest(inspect.istraceback, 'git.ex[2]')
167 self.istest(inspect.isframe, 'mod.fr')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000168
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000169 def test_stack(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000170 self.assertTrue(len(mod.st) >= 5)
Christian Heimesa3538eb2007-11-06 11:44:48 +0000171 self.assertEqual(revise(*mod.st[0][1:]),
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000172 (modfile, 16, 'eggs', [' st = inspect.stack()\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000173 self.assertEqual(revise(*mod.st[1][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000174 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000175 self.assertEqual(revise(*mod.st[2][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000176 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000177 self.assertEqual(revise(*mod.st[3][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000178 (modfile, 39, 'abuse', [' self.argue(a, b, c)\n'], 0))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000179
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000180 def test_trace(self):
181 self.assertEqual(len(git.tr), 3)
Florent Xiclunac8575922010-03-24 17:37:49 +0000182 self.assertEqual(revise(*git.tr[0][1:]),
183 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
184 self.assertEqual(revise(*git.tr[1][1:]),
185 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
186 self.assertEqual(revise(*git.tr[2][1:]),
187 (modfile, 18, 'eggs', [' q = y / 0\n'], 0))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000188
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000189 def test_frame(self):
190 args, varargs, varkw, locals = inspect.getargvalues(mod.fr)
191 self.assertEqual(args, ['x', 'y'])
192 self.assertEqual(varargs, None)
193 self.assertEqual(varkw, None)
194 self.assertEqual(locals, {'x': 11, 'p': 11, 'y': 14})
195 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
196 '(x=11, y=14)')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000197
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000198 def test_previous_frame(self):
199 args, varargs, varkw, locals = inspect.getargvalues(mod.fr.f_back)
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000200 self.assertEqual(args, ['a', 'b', 'c', 'd', 'e', 'f'])
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000201 self.assertEqual(varargs, 'g')
202 self.assertEqual(varkw, 'h')
203 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000204 '(a=7, b=8, c=9, d=3, e=4, f=5, *g=(), **h={})')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000205
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000206class GetSourceBase(unittest.TestCase):
207 # Subclasses must override.
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000208 fodderModule = None
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000209
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000210 def __init__(self, *args, **kwargs):
211 unittest.TestCase.__init__(self, *args, **kwargs)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000212
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000213 with open(inspect.getsourcefile(self.fodderModule)) as fp:
Philip Jenveya27c5bd2009-05-28 06:09:08 +0000214 self.source = fp.read()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000215
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000216 def sourcerange(self, top, bottom):
217 lines = self.source.split("\n")
218 return "\n".join(lines[top-1:bottom]) + "\n"
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000219
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000220 def assertSourceEqual(self, obj, top, bottom):
221 self.assertEqual(inspect.getsource(obj),
222 self.sourcerange(top, bottom))
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000223
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000224class TestRetrievingSourceCode(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000225 fodderModule = mod
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000226
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000227 def test_getclasses(self):
228 classes = inspect.getmembers(mod, inspect.isclass)
229 self.assertEqual(classes,
230 [('FesteringGob', mod.FesteringGob),
231 ('MalodorousPervert', mod.MalodorousPervert),
232 ('ParrotDroppings', mod.ParrotDroppings),
Serhiy Storchaka362c1b52013-09-05 17:14:32 +0300233 ('StupidGit', mod.StupidGit),
234 ('Tit', mod.MalodorousPervert),
235 ])
236 tree = inspect.getclasstree([cls[1] for cls in classes])
237 self.assertEqual(tree,
238 [(object, ()),
239 [(mod.ParrotDroppings, (object,)),
240 [(mod.FesteringGob, (mod.MalodorousPervert,
241 mod.ParrotDroppings))
242 ],
243 (mod.StupidGit, (object,)),
244 [(mod.MalodorousPervert, (mod.StupidGit,)),
245 [(mod.FesteringGob, (mod.MalodorousPervert,
246 mod.ParrotDroppings))
247 ]
248 ]
249 ]
250 ])
251 tree = inspect.getclasstree([cls[1] for cls in classes], True)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000252 self.assertEqual(tree,
Thomas Wouters725af872006-04-15 09:13:19 +0000253 [(object, ()),
254 [(mod.ParrotDroppings, (object,)),
255 (mod.StupidGit, (object,)),
256 [(mod.MalodorousPervert, (mod.StupidGit,)),
257 [(mod.FesteringGob, (mod.MalodorousPervert,
258 mod.ParrotDroppings))
259 ]
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000260 ]
261 ]
262 ])
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000263
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000264 def test_getfunctions(self):
265 functions = inspect.getmembers(mod, inspect.isfunction)
266 self.assertEqual(functions, [('eggs', mod.eggs),
267 ('spam', mod.spam)])
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000268
R. David Murray378c0cf2010-02-24 01:46:21 +0000269 @unittest.skipIf(sys.flags.optimize >= 2,
270 "Docstrings are omitted with -O2 and above")
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000271 def test_getdoc(self):
272 self.assertEqual(inspect.getdoc(mod), 'A module docstring.')
273 self.assertEqual(inspect.getdoc(mod.StupidGit),
274 'A longer,\n\nindented\n\ndocstring.')
275 self.assertEqual(inspect.getdoc(git.abuse),
276 'Another\n\ndocstring\n\ncontaining\n\ntabs')
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000277
Georg Brandl0c77a822008-06-10 16:37:50 +0000278 def test_cleandoc(self):
279 self.assertEqual(inspect.cleandoc('An\n indented\n docstring.'),
280 'An\nindented\ndocstring.')
281
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000282 def test_getcomments(self):
283 self.assertEqual(inspect.getcomments(mod), '# line 1\n')
284 self.assertEqual(inspect.getcomments(mod.StupidGit), '# line 20\n')
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000285
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000286 def test_getmodule(self):
Thomas Wouters89f507f2006-12-13 04:49:30 +0000287 # Check actual module
288 self.assertEqual(inspect.getmodule(mod), mod)
289 # Check class (uses __module__ attribute)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000290 self.assertEqual(inspect.getmodule(mod.StupidGit), mod)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000291 # Check a method (no __module__ attribute, falls back to filename)
292 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
293 # Do it again (check the caching isn't broken)
294 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
295 # Check a builtin
Georg Brandl1a3284e2007-12-02 09:40:06 +0000296 self.assertEqual(inspect.getmodule(str), sys.modules["builtins"])
Thomas Wouters89f507f2006-12-13 04:49:30 +0000297 # Check filename override
298 self.assertEqual(inspect.getmodule(None, modfile), mod)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000299
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000300 def test_getsource(self):
301 self.assertSourceEqual(git.abuse, 29, 39)
302 self.assertSourceEqual(mod.StupidGit, 21, 46)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000303
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000304 def test_getsourcefile(self):
Christian Heimesa3538eb2007-11-06 11:44:48 +0000305 self.assertEqual(normcase(inspect.getsourcefile(mod.spam)), modfile)
306 self.assertEqual(normcase(inspect.getsourcefile(git.abuse)), modfile)
R. David Murraya1b37402010-06-17 02:04:29 +0000307 fn = "_non_existing_filename_used_for_sourcefile_test.py"
308 co = compile("None", fn, "exec")
R. David Murray4155f972010-06-17 13:23:18 +0000309 self.assertEqual(inspect.getsourcefile(co), None)
R. David Murraya1b37402010-06-17 02:04:29 +0000310 linecache.cache[co.co_filename] = (1, None, "None", co.co_filename)
Antoine Pitrou5d62a612012-07-08 13:48:46 +0200311 try:
312 self.assertEqual(normcase(inspect.getsourcefile(co)), fn)
313 finally:
314 del linecache.cache[co.co_filename]
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000315
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000316 def test_getfile(self):
317 self.assertEqual(inspect.getfile(mod.StupidGit), mod.__file__)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000318
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000319 def test_getmodule_recursion(self):
Christian Heimes45f9af32007-11-27 21:50:00 +0000320 from types import ModuleType
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000321 name = '__inspect_dummy'
Christian Heimes45f9af32007-11-27 21:50:00 +0000322 m = sys.modules[name] = ModuleType(name)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000323 m.__file__ = "<string>" # hopefully not a real filename...
324 m.__loader__ = "dummy" # pretend the filename is understood by a loader
Georg Brandl7cae87c2006-09-06 06:51:57 +0000325 exec("def x(): pass", m.__dict__)
Neal Norwitz221085d2007-02-25 20:55:47 +0000326 self.assertEqual(inspect.getsourcefile(m.x.__code__), '<string>')
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000327 del sys.modules[name]
328 inspect.getmodule(compile('a=10','','single'))
329
Benjamin Peterson9620cc02011-06-11 15:53:11 -0500330 def test_proceed_with_fake_filename(self):
331 '''doctest monkeypatches linecache to enable inspection'''
332 fn, source = '<test>', 'def x(): pass\n'
333 getlines = linecache.getlines
334 def monkey(filename, module_globals=None):
335 if filename == fn:
Ezio Melottid8b509b2011-09-28 17:37:55 +0300336 return source.splitlines(keepends=True)
Benjamin Peterson9620cc02011-06-11 15:53:11 -0500337 else:
338 return getlines(filename, module_globals)
339 linecache.getlines = monkey
340 try:
341 ns = {}
342 exec(compile(source, fn, 'single'), ns)
343 inspect.getsource(ns["x"])
344 finally:
345 linecache.getlines = getlines
346
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000347class TestDecorators(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000348 fodderModule = mod2
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000349
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000350 def test_wrapped_decorator(self):
Christian Heimes09aaa882008-02-23 15:01:06 +0000351 self.assertSourceEqual(mod2.wrapped, 14, 17)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000352
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000353 def test_replacing_decorator(self):
354 self.assertSourceEqual(mod2.gone, 9, 10)
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000355
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000356class TestOneliners(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000357 fodderModule = mod2
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000358 def test_oneline_lambda(self):
359 # Test inspect.getsource with a one-line lambda function.
360 self.assertSourceEqual(mod2.oll, 25, 25)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000361
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000362 def test_threeline_lambda(self):
363 # Test inspect.getsource with a three-line lambda function,
364 # where the second and third lines are _not_ indented.
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000365 self.assertSourceEqual(mod2.tll, 28, 30)
366
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000367 def test_twoline_indented_lambda(self):
368 # Test inspect.getsource with a two-line lambda function,
369 # where the second line _is_ indented.
370 self.assertSourceEqual(mod2.tlli, 33, 34)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000371
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000372 def test_onelinefunc(self):
373 # Test inspect.getsource with a regular one-line function.
374 self.assertSourceEqual(mod2.onelinefunc, 37, 37)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000375
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000376 def test_manyargs(self):
377 # Test inspect.getsource with a regular function where
378 # the arguments are on two lines and _not_ indented and
379 # the body on the second line with the last arguments.
380 self.assertSourceEqual(mod2.manyargs, 40, 41)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000381
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000382 def test_twolinefunc(self):
383 # Test inspect.getsource with a regular function where
384 # the body is on two lines, following the argument list and
385 # continued on the next line by a \\.
386 self.assertSourceEqual(mod2.twolinefunc, 44, 45)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000387
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000388 def test_lambda_in_list(self):
389 # Test inspect.getsource with a one-line lambda function
390 # defined in a list, indented.
391 self.assertSourceEqual(mod2.a[1], 49, 49)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000392
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000393 def test_anonymous(self):
394 # Test inspect.getsource with a lambda function defined
395 # as argument to another function.
396 self.assertSourceEqual(mod2.anonymous, 55, 55)
397
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000398class TestBuggyCases(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000399 fodderModule = mod2
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000400
401 def test_with_comment(self):
402 self.assertSourceEqual(mod2.with_comment, 58, 59)
403
404 def test_multiline_sig(self):
405 self.assertSourceEqual(mod2.multiline_sig[0], 63, 64)
406
Armin Rigodd5c0232005-09-25 11:45:45 +0000407 def test_nested_class(self):
408 self.assertSourceEqual(mod2.func69().func71, 71, 72)
409
410 def test_one_liner_followed_by_non_name(self):
411 self.assertSourceEqual(mod2.func77, 77, 77)
412
413 def test_one_liner_dedent_non_name(self):
414 self.assertSourceEqual(mod2.cls82.func83, 83, 83)
415
416 def test_with_comment_instead_of_docstring(self):
417 self.assertSourceEqual(mod2.func88, 88, 90)
418
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000419 def test_method_in_dynamic_class(self):
420 self.assertSourceEqual(mod2.method_in_dynamic_class, 95, 97)
421
R. David Murrayb5655772009-05-14 16:17:50 +0000422 @unittest.skipIf(
423 not hasattr(unicodedata, '__file__') or
424 unicodedata.__file__[-4:] in (".pyc", ".pyo"),
425 "unicodedata is not an external binary module")
R. David Murray74b89242009-05-13 17:33:03 +0000426 def test_findsource_binary(self):
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200427 self.assertRaises(OSError, inspect.getsource, unicodedata)
428 self.assertRaises(OSError, inspect.findsource, unicodedata)
R. David Murray74b89242009-05-13 17:33:03 +0000429
R. David Murraya1b37402010-06-17 02:04:29 +0000430 def test_findsource_code_in_linecache(self):
431 lines = ["x=1"]
432 co = compile(lines[0], "_dynamically_created_file", "exec")
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200433 self.assertRaises(OSError, inspect.findsource, co)
434 self.assertRaises(OSError, inspect.getsource, co)
R. David Murraya1b37402010-06-17 02:04:29 +0000435 linecache.cache[co.co_filename] = (1, None, lines, co.co_filename)
Antoine Pitrou5d62a612012-07-08 13:48:46 +0200436 try:
437 self.assertEqual(inspect.findsource(co), (lines,0))
438 self.assertEqual(inspect.getsource(co), lines[0])
439 finally:
440 del linecache.cache[co.co_filename]
R. David Murraya1b37402010-06-17 02:04:29 +0000441
Ezio Melotti1b145922013-03-30 05:17:24 +0200442 def test_findsource_without_filename(self):
443 for fname in ['', '<string>']:
444 co = compile('x=1', fname, "exec")
445 self.assertRaises(IOError, inspect.findsource, co)
446 self.assertRaises(IOError, inspect.getsource, co)
447
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000448class TestNoEOL(GetSourceBase):
449 def __init__(self, *args, **kwargs):
450 self.tempdir = TESTFN + '_dir'
451 os.mkdir(self.tempdir)
452 with open(os.path.join(self.tempdir,
453 'inspect_fodder3%spy' % os.extsep), 'w') as f:
454 f.write("class X:\n pass # No EOL")
455 with DirsOnSysPath(self.tempdir):
456 import inspect_fodder3 as mod3
457 self.fodderModule = mod3
458 GetSourceBase.__init__(self, *args, **kwargs)
459
460 def tearDown(self):
461 shutil.rmtree(self.tempdir)
462
463 def test_class(self):
464 self.assertSourceEqual(self.fodderModule.X, 1, 2)
465
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100466
467class _BrokenDataDescriptor(object):
468 """
469 A broken data descriptor. See bug #1785.
470 """
471 def __get__(*args):
472 raise AssertionError("should not __get__ data descriptors")
473
474 def __set__(*args):
475 raise RuntimeError
476
477 def __getattr__(*args):
478 raise AssertionError("should not __getattr__ data descriptors")
479
480
481class _BrokenMethodDescriptor(object):
482 """
483 A broken method descriptor. See bug #1785.
484 """
485 def __get__(*args):
486 raise AssertionError("should not __get__ method descriptors")
487
488 def __getattr__(*args):
489 raise AssertionError("should not __getattr__ method descriptors")
490
491
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000492# Helper for testing classify_class_attrs.
Tim Peters13b49d32001-09-23 02:00:29 +0000493def attrs_wo_objs(cls):
494 return [t[:3] for t in inspect.classify_class_attrs(cls)]
495
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100496
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000497class TestClassesAndFunctions(unittest.TestCase):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000498 def test_newstyle_mro(self):
499 # The same w/ new-class MRO.
500 class A(object): pass
501 class B(A): pass
502 class C(A): pass
503 class D(B, C): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000504
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000505 expected = (D, B, C, A, object)
506 got = inspect.getmro(D)
507 self.assertEqual(expected, got)
Tim Peters13b49d32001-09-23 02:00:29 +0000508
Christian Heimes3795b532007-11-08 13:48:53 +0000509 def assertArgSpecEquals(self, routine, args_e, varargs_e=None,
510 varkw_e=None, defaults_e=None, formatted=None):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000511 args, varargs, varkw, defaults = inspect.getargspec(routine)
512 self.assertEqual(args, args_e)
513 self.assertEqual(varargs, varargs_e)
514 self.assertEqual(varkw, varkw_e)
515 self.assertEqual(defaults, defaults_e)
516 if formatted is not None:
517 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults),
518 formatted)
Tim Peters13b49d32001-09-23 02:00:29 +0000519
Christian Heimes3795b532007-11-08 13:48:53 +0000520 def assertFullArgSpecEquals(self, routine, args_e, varargs_e=None,
521 varkw_e=None, defaults_e=None,
522 kwonlyargs_e=[], kwonlydefaults_e=None,
523 ann_e={}, formatted=None):
524 args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \
525 inspect.getfullargspec(routine)
526 self.assertEqual(args, args_e)
527 self.assertEqual(varargs, varargs_e)
528 self.assertEqual(varkw, varkw_e)
529 self.assertEqual(defaults, defaults_e)
530 self.assertEqual(kwonlyargs, kwonlyargs_e)
531 self.assertEqual(kwonlydefaults, kwonlydefaults_e)
532 self.assertEqual(ann, ann_e)
533 if formatted is not None:
534 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults,
535 kwonlyargs, kwonlydefaults, ann),
536 formatted)
537
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000538 def test_getargspec(self):
Christian Heimes3795b532007-11-08 13:48:53 +0000539 self.assertArgSpecEquals(mod.eggs, ['x', 'y'], formatted='(x, y)')
Tim Peters13b49d32001-09-23 02:00:29 +0000540
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000541 self.assertArgSpecEquals(mod.spam,
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000542 ['a', 'b', 'c', 'd', 'e', 'f'],
543 'g', 'h', (3, 4, 5),
544 '(a, b, c, d=3, e=4, f=5, *g, **h)')
Tim Peters13b49d32001-09-23 02:00:29 +0000545
Christian Heimes3795b532007-11-08 13:48:53 +0000546 self.assertRaises(ValueError, self.assertArgSpecEquals,
547 mod2.keyworded, [])
548
549 self.assertRaises(ValueError, self.assertArgSpecEquals,
550 mod2.annotated, [])
Benjamin Peterson9953a8d2009-01-17 04:15:01 +0000551 self.assertRaises(ValueError, self.assertArgSpecEquals,
552 mod2.keyword_only_arg, [])
553
Christian Heimes3795b532007-11-08 13:48:53 +0000554
555 def test_getfullargspec(self):
556 self.assertFullArgSpecEquals(mod2.keyworded, [], varargs_e='arg1',
557 kwonlyargs_e=['arg2'],
558 kwonlydefaults_e={'arg2':1},
559 formatted='(*arg1, arg2=1)')
560
561 self.assertFullArgSpecEquals(mod2.annotated, ['arg1'],
Christian Heimesc9543e42007-11-28 08:28:28 +0000562 ann_e={'arg1' : list},
Christian Heimes3795b532007-11-08 13:48:53 +0000563 formatted='(arg1: list)')
Benjamin Peterson9953a8d2009-01-17 04:15:01 +0000564 self.assertFullArgSpecEquals(mod2.keyword_only_arg, [],
565 kwonlyargs_e=['arg'],
566 formatted='(*, arg)')
567
Christian Heimes3795b532007-11-08 13:48:53 +0000568
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000569 def test_getargspec_method(self):
570 class A(object):
571 def m(self):
572 pass
573 self.assertArgSpecEquals(A.m, ['self'])
Tim Peters13b49d32001-09-23 02:00:29 +0000574
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000575 def test_classify_newstyle(self):
576 class A(object):
Tim Peters13b49d32001-09-23 02:00:29 +0000577
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000578 def s(): pass
579 s = staticmethod(s)
Tim Peters13b49d32001-09-23 02:00:29 +0000580
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000581 def c(cls): pass
582 c = classmethod(c)
Tim Peters13b49d32001-09-23 02:00:29 +0000583
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000584 def getp(self): pass
585 p = property(getp)
Tim Peters13b49d32001-09-23 02:00:29 +0000586
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000587 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000588
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000589 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000590
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000591 datablob = '1'
Tim Peters13b49d32001-09-23 02:00:29 +0000592
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100593 dd = _BrokenDataDescriptor()
594 md = _BrokenMethodDescriptor()
595
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000596 attrs = attrs_wo_objs(A)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000597 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
598 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
599 self.assertIn(('p', 'property', A), attrs, 'missing property')
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000600 self.assertIn(('m', 'method', A), attrs,
601 'missing plain method: %r' % attrs)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000602 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
603 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100604 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
605 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000606
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000607 class B(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000608
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000609 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000610
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000611 attrs = attrs_wo_objs(B)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000612 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
613 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
614 self.assertIn(('p', 'property', A), attrs, 'missing property')
615 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
616 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
617 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100618 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
619 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000620
621
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000622 class C(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000623
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000624 def m(self): pass
625 def c(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000626
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000627 attrs = attrs_wo_objs(C)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000628 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
629 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
630 self.assertIn(('p', 'property', A), attrs, 'missing property')
631 self.assertIn(('m', 'method', C), attrs, 'missing plain method')
632 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
633 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100634 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
635 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000636
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000637 class D(B, C):
Tim Peters13b49d32001-09-23 02:00:29 +0000638
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000639 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000640
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000641 attrs = attrs_wo_objs(D)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000642 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
643 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
644 self.assertIn(('p', 'property', A), attrs, 'missing property')
645 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
646 self.assertIn(('m1', 'method', D), attrs, 'missing plain method')
647 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100648 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
649 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
650
651 def test_classify_builtin_types(self):
652 # Simple sanity check that all built-in types can have their
653 # attributes classified.
654 for name in dir(__builtins__):
655 builtin = getattr(__builtins__, name)
656 if isinstance(builtin, type):
657 inspect.classify_class_attrs(builtin)
658
Ethan Furmane03ea372013-09-25 07:14:41 -0700659 def test_classify_VirtualAttribute(self):
660 class VA:
661 @types.DynamicClassAttribute
662 def ham(self):
663 return 'eggs'
664 should_find = inspect.Attribute('ham', 'data', VA, VA.__dict__['ham'])
665 self.assertIn(should_find, inspect.classify_class_attrs(VA))
666
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100667 def test_getmembers_descriptors(self):
668 class A(object):
669 dd = _BrokenDataDescriptor()
670 md = _BrokenMethodDescriptor()
671
672 def pred_wrapper(pred):
673 # A quick'n'dirty way to discard standard attributes of new-style
674 # classes.
675 class Empty(object):
676 pass
677 def wrapped(x):
678 if '__name__' in dir(x) and hasattr(Empty, x.__name__):
679 return False
680 return pred(x)
681 return wrapped
682
683 ismethoddescriptor = pred_wrapper(inspect.ismethoddescriptor)
684 isdatadescriptor = pred_wrapper(inspect.isdatadescriptor)
685
686 self.assertEqual(inspect.getmembers(A, ismethoddescriptor),
687 [('md', A.__dict__['md'])])
688 self.assertEqual(inspect.getmembers(A, isdatadescriptor),
689 [('dd', A.__dict__['dd'])])
690
691 class B(A):
692 pass
693
694 self.assertEqual(inspect.getmembers(B, ismethoddescriptor),
695 [('md', A.__dict__['md'])])
696 self.assertEqual(inspect.getmembers(B, isdatadescriptor),
697 [('dd', A.__dict__['dd'])])
698
Antoine Pitrou0c603812012-01-18 17:40:18 +0100699 def test_getmembers_method(self):
700 class B:
701 def f(self):
702 pass
703
704 self.assertIn(('f', B.f), inspect.getmembers(B))
705 self.assertNotIn(('f', B.f), inspect.getmembers(B, inspect.ismethod))
706 b = B()
707 self.assertIn(('f', b.f), inspect.getmembers(b))
708 self.assertIn(('f', b.f), inspect.getmembers(b, inspect.ismethod))
709
Ethan Furmane03ea372013-09-25 07:14:41 -0700710 def test_getmembers_VirtualAttribute(self):
711 class A:
712 @types.DynamicClassAttribute
713 def eggs(self):
714 return 'spam'
715 self.assertIn(('eggs', A.__dict__['eggs']), inspect.getmembers(A))
716
Jeremy Hyltonc4bf5ed2003-06-27 18:43:12 +0000717
Nick Coghlan2f92e542012-06-23 19:39:55 +1000718_global_ref = object()
719class TestGetClosureVars(unittest.TestCase):
720
721 def test_name_resolution(self):
722 # Basic test of the 4 different resolution mechanisms
723 def f(nonlocal_ref):
724 def g(local_ref):
725 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
726 return g
727 _arg = object()
728 nonlocal_vars = {"nonlocal_ref": _arg}
729 global_vars = {"_global_ref": _global_ref}
730 builtin_vars = {"print": print}
731 unbound_names = {"unbound_ref"}
732 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
733 builtin_vars, unbound_names)
734 self.assertEqual(inspect.getclosurevars(f(_arg)), expected)
735
736 def test_generator_closure(self):
737 def f(nonlocal_ref):
738 def g(local_ref):
739 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
740 yield
741 return g
742 _arg = object()
743 nonlocal_vars = {"nonlocal_ref": _arg}
744 global_vars = {"_global_ref": _global_ref}
745 builtin_vars = {"print": print}
746 unbound_names = {"unbound_ref"}
747 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
748 builtin_vars, unbound_names)
749 self.assertEqual(inspect.getclosurevars(f(_arg)), expected)
750
751 def test_method_closure(self):
752 class C:
753 def f(self, nonlocal_ref):
754 def g(local_ref):
755 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
756 return g
757 _arg = object()
758 nonlocal_vars = {"nonlocal_ref": _arg}
759 global_vars = {"_global_ref": _global_ref}
760 builtin_vars = {"print": print}
761 unbound_names = {"unbound_ref"}
762 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
763 builtin_vars, unbound_names)
764 self.assertEqual(inspect.getclosurevars(C().f(_arg)), expected)
765
766 def test_nonlocal_vars(self):
767 # More complex tests of nonlocal resolution
768 def _nonlocal_vars(f):
769 return inspect.getclosurevars(f).nonlocals
770
771 def make_adder(x):
772 def add(y):
773 return x + y
774 return add
775
776 def curry(func, arg1):
777 return lambda arg2: func(arg1, arg2)
778
779 def less_than(a, b):
780 return a < b
781
782 # The infamous Y combinator.
783 def Y(le):
784 def g(f):
785 return le(lambda x: f(f)(x))
786 Y.g_ref = g
787 return g(g)
788
789 def check_y_combinator(func):
790 self.assertEqual(_nonlocal_vars(func), {'f': Y.g_ref})
791
792 inc = make_adder(1)
793 add_two = make_adder(2)
794 greater_than_five = curry(less_than, 5)
795
796 self.assertEqual(_nonlocal_vars(inc), {'x': 1})
797 self.assertEqual(_nonlocal_vars(add_two), {'x': 2})
798 self.assertEqual(_nonlocal_vars(greater_than_five),
799 {'arg1': 5, 'func': less_than})
800 self.assertEqual(_nonlocal_vars((lambda x: lambda y: x + y)(3)),
801 {'x': 3})
802 Y(check_y_combinator)
803
804 def test_getclosurevars_empty(self):
805 def foo(): pass
806 _empty = inspect.ClosureVars({}, {}, {}, set())
807 self.assertEqual(inspect.getclosurevars(lambda: True), _empty)
808 self.assertEqual(inspect.getclosurevars(foo), _empty)
809
810 def test_getclosurevars_error(self):
811 class T: pass
812 self.assertRaises(TypeError, inspect.getclosurevars, 1)
813 self.assertRaises(TypeError, inspect.getclosurevars, list)
814 self.assertRaises(TypeError, inspect.getclosurevars, {})
815
Nick Coghlan6c6e2542012-06-23 20:07:39 +1000816 def _private_globals(self):
817 code = """def f(): print(path)"""
818 ns = {}
819 exec(code, ns)
820 return ns["f"], ns
821
822 def test_builtins_fallback(self):
823 f, ns = self._private_globals()
824 ns.pop("__builtins__", None)
825 expected = inspect.ClosureVars({}, {}, {"print":print}, {"path"})
826 self.assertEqual(inspect.getclosurevars(f), expected)
827
828 def test_builtins_as_dict(self):
829 f, ns = self._private_globals()
830 ns["__builtins__"] = {"path":1}
831 expected = inspect.ClosureVars({}, {}, {"path":1}, {"print"})
832 self.assertEqual(inspect.getclosurevars(f), expected)
833
834 def test_builtins_as_module(self):
835 f, ns = self._private_globals()
836 ns["__builtins__"] = os
837 expected = inspect.ClosureVars({}, {}, {"path":os.path}, {"print"})
838 self.assertEqual(inspect.getclosurevars(f), expected)
839
Nick Coghlan2f92e542012-06-23 19:39:55 +1000840
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000841class TestGetcallargsFunctions(unittest.TestCase):
842
843 def assertEqualCallArgs(self, func, call_params_string, locs=None):
844 locs = dict(locs or {}, func=func)
845 r1 = eval('func(%s)' % call_params_string, None, locs)
846 r2 = eval('inspect.getcallargs(func, %s)' % call_params_string, None,
847 locs)
848 self.assertEqual(r1, r2)
849
850 def assertEqualException(self, func, call_param_string, locs=None):
851 locs = dict(locs or {}, func=func)
852 try:
853 eval('func(%s)' % call_param_string, None, locs)
854 except Exception as e:
855 ex1 = e
856 else:
857 self.fail('Exception not raised')
858 try:
859 eval('inspect.getcallargs(func, %s)' % call_param_string, None,
860 locs)
861 except Exception as e:
862 ex2 = e
863 else:
864 self.fail('Exception not raised')
865 self.assertIs(type(ex1), type(ex2))
866 self.assertEqual(str(ex1), str(ex2))
867 del ex1, ex2
868
869 def makeCallable(self, signature):
870 """Create a function that returns its locals()"""
871 code = "lambda %s: locals()"
872 return eval(code % signature)
873
874 def test_plain(self):
875 f = self.makeCallable('a, b=1')
876 self.assertEqualCallArgs(f, '2')
877 self.assertEqualCallArgs(f, '2, 3')
878 self.assertEqualCallArgs(f, 'a=2')
879 self.assertEqualCallArgs(f, 'b=3, a=2')
880 self.assertEqualCallArgs(f, '2, b=3')
881 # expand *iterable / **mapping
882 self.assertEqualCallArgs(f, '*(2,)')
883 self.assertEqualCallArgs(f, '*[2]')
884 self.assertEqualCallArgs(f, '*(2, 3)')
885 self.assertEqualCallArgs(f, '*[2, 3]')
886 self.assertEqualCallArgs(f, '**{"a":2}')
887 self.assertEqualCallArgs(f, 'b=3, **{"a":2}')
888 self.assertEqualCallArgs(f, '2, **{"b":3}')
889 self.assertEqualCallArgs(f, '**{"b":3, "a":2}')
890 # expand UserList / UserDict
891 self.assertEqualCallArgs(f, '*collections.UserList([2])')
892 self.assertEqualCallArgs(f, '*collections.UserList([2, 3])')
893 self.assertEqualCallArgs(f, '**collections.UserDict(a=2)')
894 self.assertEqualCallArgs(f, '2, **collections.UserDict(b=3)')
895 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3)')
896
897 def test_varargs(self):
898 f = self.makeCallable('a, b=1, *c')
899 self.assertEqualCallArgs(f, '2')
900 self.assertEqualCallArgs(f, '2, 3')
901 self.assertEqualCallArgs(f, '2, 3, 4')
902 self.assertEqualCallArgs(f, '*(2,3,4)')
903 self.assertEqualCallArgs(f, '2, *[3,4]')
904 self.assertEqualCallArgs(f, '2, 3, *collections.UserList([4])')
905
906 def test_varkw(self):
907 f = self.makeCallable('a, b=1, **c')
908 self.assertEqualCallArgs(f, 'a=2')
909 self.assertEqualCallArgs(f, '2, b=3, c=4')
910 self.assertEqualCallArgs(f, 'b=3, a=2, c=4')
911 self.assertEqualCallArgs(f, 'c=4, **{"a":2, "b":3}')
912 self.assertEqualCallArgs(f, '2, c=4, **{"b":3}')
913 self.assertEqualCallArgs(f, 'b=2, **{"a":3, "c":4}')
914 self.assertEqualCallArgs(f, '**collections.UserDict(a=2, b=3, c=4)')
915 self.assertEqualCallArgs(f, '2, c=4, **collections.UserDict(b=3)')
916 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3, c=4)')
917
Benjamin Peterson6a2638b2011-03-28 17:32:31 -0500918 def test_varkw_only(self):
919 # issue11256:
920 f = self.makeCallable('**c')
921 self.assertEqualCallArgs(f, '')
922 self.assertEqualCallArgs(f, 'a=1')
923 self.assertEqualCallArgs(f, 'a=1, b=2')
924 self.assertEqualCallArgs(f, 'c=3, **{"a": 1, "b": 2}')
925 self.assertEqualCallArgs(f, '**collections.UserDict(a=1, b=2)')
926 self.assertEqualCallArgs(f, 'c=3, **collections.UserDict(a=1, b=2)')
927
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000928 def test_keyword_only(self):
929 f = self.makeCallable('a=3, *, c, d=2')
930 self.assertEqualCallArgs(f, 'c=3')
931 self.assertEqualCallArgs(f, 'c=3, a=3')
932 self.assertEqualCallArgs(f, 'a=2, c=4')
933 self.assertEqualCallArgs(f, '4, c=4')
934 self.assertEqualException(f, '')
935 self.assertEqualException(f, '3')
936 self.assertEqualException(f, 'a=3')
937 self.assertEqualException(f, 'd=4')
938
Benjamin Peterson6a2638b2011-03-28 17:32:31 -0500939 f = self.makeCallable('*, c, d=2')
940 self.assertEqualCallArgs(f, 'c=3')
941 self.assertEqualCallArgs(f, 'c=3, d=4')
942 self.assertEqualCallArgs(f, 'd=4, c=3')
943
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000944 def test_multiple_features(self):
945 f = self.makeCallable('a, b=2, *f, **g')
946 self.assertEqualCallArgs(f, '2, 3, 7')
947 self.assertEqualCallArgs(f, '2, 3, x=8')
948 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
949 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9')
950 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9')
951 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
952 '[2, 3, (4,[5,6])]), **{"y":9, "z":10}')
953 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
954 '(4,[5,6])]), **collections.UserDict('
955 'y=9, z=10)')
956
Benjamin Peterson6a2638b2011-03-28 17:32:31 -0500957 f = self.makeCallable('a, b=2, *f, x, y=99, **g')
958 self.assertEqualCallArgs(f, '2, 3, x=8')
959 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
960 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9, z=10')
961 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9, z=10')
962 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
963 '[2, 3, (4,[5,6])]), q=0, **{"y":9, "z":10}')
964 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
965 '(4,[5,6])]), q=0, **collections.UserDict('
966 'y=9, z=10)')
967
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000968 def test_errors(self):
969 f0 = self.makeCallable('')
970 f1 = self.makeCallable('a, b')
971 f2 = self.makeCallable('a, b=1')
972 # f0 takes no arguments
973 self.assertEqualException(f0, '1')
974 self.assertEqualException(f0, 'x=1')
975 self.assertEqualException(f0, '1,x=1')
976 # f1 takes exactly 2 arguments
977 self.assertEqualException(f1, '')
978 self.assertEqualException(f1, '1')
979 self.assertEqualException(f1, 'a=2')
980 self.assertEqualException(f1, 'b=3')
981 # f2 takes at least 1 argument
982 self.assertEqualException(f2, '')
983 self.assertEqualException(f2, 'b=3')
984 for f in f1, f2:
985 # f1/f2 takes exactly/at most 2 arguments
986 self.assertEqualException(f, '2, 3, 4')
987 self.assertEqualException(f, '1, 2, 3, a=1')
988 self.assertEqualException(f, '2, 3, 4, c=5')
Georg Brandl178e5ea2012-02-21 00:32:36 +0100989 # XXX: success of this one depends on dict order
990 ## self.assertEqualException(f, '2, 3, 4, a=1, c=5')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000991 # f got an unexpected keyword argument
992 self.assertEqualException(f, 'c=2')
993 self.assertEqualException(f, '2, c=3')
994 self.assertEqualException(f, '2, 3, c=4')
995 self.assertEqualException(f, '2, c=4, b=3')
996 self.assertEqualException(f, '**{u"\u03c0\u03b9": 4}')
997 # f got multiple values for keyword argument
998 self.assertEqualException(f, '1, a=2')
999 self.assertEqualException(f, '1, **{"a":2}')
1000 self.assertEqualException(f, '1, 2, b=3')
1001 # XXX: Python inconsistency
1002 # - for functions and bound methods: unexpected keyword 'c'
1003 # - for unbound methods: multiple values for keyword 'a'
1004 #self.assertEqualException(f, '1, c=3, a=2')
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001005 # issue11256:
1006 f3 = self.makeCallable('**c')
1007 self.assertEqualException(f3, '1, 2')
1008 self.assertEqualException(f3, '1, 2, a=1, b=2')
1009 f4 = self.makeCallable('*, a, b=0')
1010 self.assertEqualException(f3, '1, 2')
1011 self.assertEqualException(f3, '1, 2, a=1, b=2')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001012
1013class TestGetcallargsMethods(TestGetcallargsFunctions):
1014
1015 def setUp(self):
1016 class Foo(object):
1017 pass
1018 self.cls = Foo
1019 self.inst = Foo()
1020
1021 def makeCallable(self, signature):
1022 assert 'self' not in signature
1023 mk = super(TestGetcallargsMethods, self).makeCallable
1024 self.cls.method = mk('self, ' + signature)
1025 return self.inst.method
1026
1027class TestGetcallargsUnboundMethods(TestGetcallargsMethods):
1028
1029 def makeCallable(self, signature):
1030 super(TestGetcallargsUnboundMethods, self).makeCallable(signature)
1031 return self.cls.method
1032
1033 def assertEqualCallArgs(self, func, call_params_string, locs=None):
1034 return super(TestGetcallargsUnboundMethods, self).assertEqualCallArgs(
1035 *self._getAssertEqualParams(func, call_params_string, locs))
1036
1037 def assertEqualException(self, func, call_params_string, locs=None):
1038 return super(TestGetcallargsUnboundMethods, self).assertEqualException(
1039 *self._getAssertEqualParams(func, call_params_string, locs))
1040
1041 def _getAssertEqualParams(self, func, call_params_string, locs=None):
1042 assert 'inst' not in call_params_string
1043 locs = dict(locs or {}, inst=self.inst)
1044 return (func, 'inst,' + call_params_string, locs)
1045
Michael Foord95fc51d2010-11-20 15:07:30 +00001046
1047class TestGetattrStatic(unittest.TestCase):
1048
1049 def test_basic(self):
1050 class Thing(object):
1051 x = object()
1052
1053 thing = Thing()
1054 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1055 self.assertEqual(inspect.getattr_static(thing, 'x', None), Thing.x)
1056 with self.assertRaises(AttributeError):
1057 inspect.getattr_static(thing, 'y')
1058
1059 self.assertEqual(inspect.getattr_static(thing, 'y', 3), 3)
1060
1061 def test_inherited(self):
1062 class Thing(object):
1063 x = object()
1064 class OtherThing(Thing):
1065 pass
1066
1067 something = OtherThing()
1068 self.assertEqual(inspect.getattr_static(something, 'x'), Thing.x)
1069
1070 def test_instance_attr(self):
1071 class Thing(object):
1072 x = 2
1073 def __init__(self, x):
1074 self.x = x
1075 thing = Thing(3)
1076 self.assertEqual(inspect.getattr_static(thing, 'x'), 3)
1077 del thing.x
1078 self.assertEqual(inspect.getattr_static(thing, 'x'), 2)
1079
1080 def test_property(self):
1081 class Thing(object):
1082 @property
1083 def x(self):
1084 raise AttributeError("I'm pretending not to exist")
1085 thing = Thing()
1086 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1087
Ezio Melotti75cbd732011-04-28 00:59:29 +03001088 def test_descriptor_raises_AttributeError(self):
Michael Foord95fc51d2010-11-20 15:07:30 +00001089 class descriptor(object):
1090 def __get__(*_):
1091 raise AttributeError("I'm pretending not to exist")
1092 desc = descriptor()
1093 class Thing(object):
1094 x = desc
1095 thing = Thing()
1096 self.assertEqual(inspect.getattr_static(thing, 'x'), desc)
1097
1098 def test_classAttribute(self):
1099 class Thing(object):
1100 x = object()
1101
1102 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.x)
1103
Ethan Furmane03ea372013-09-25 07:14:41 -07001104 def test_classVirtualAttribute(self):
1105 class Thing(object):
1106 @types.DynamicClassAttribute
1107 def x(self):
1108 return self._x
1109 _x = object()
1110
1111 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.__dict__['x'])
1112
Michael Foord95fc51d2010-11-20 15:07:30 +00001113 def test_inherited_classattribute(self):
1114 class Thing(object):
1115 x = object()
1116 class OtherThing(Thing):
1117 pass
1118
1119 self.assertEqual(inspect.getattr_static(OtherThing, 'x'), Thing.x)
1120
1121 def test_slots(self):
1122 class Thing(object):
1123 y = 'bar'
1124 __slots__ = ['x']
1125 def __init__(self):
1126 self.x = 'foo'
1127 thing = Thing()
1128 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1129 self.assertEqual(inspect.getattr_static(thing, 'y'), 'bar')
1130
1131 del thing.x
1132 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1133
1134 def test_metaclass(self):
1135 class meta(type):
1136 attr = 'foo'
1137 class Thing(object, metaclass=meta):
1138 pass
1139 self.assertEqual(inspect.getattr_static(Thing, 'attr'), 'foo')
1140
1141 class sub(meta):
1142 pass
1143 class OtherThing(object, metaclass=sub):
1144 x = 3
1145 self.assertEqual(inspect.getattr_static(OtherThing, 'attr'), 'foo')
1146
1147 class OtherOtherThing(OtherThing):
1148 pass
1149 # this test is odd, but it was added as it exposed a bug
1150 self.assertEqual(inspect.getattr_static(OtherOtherThing, 'x'), 3)
1151
1152 def test_no_dict_no_slots(self):
1153 self.assertEqual(inspect.getattr_static(1, 'foo', None), None)
1154 self.assertNotEqual(inspect.getattr_static('foo', 'lower'), None)
1155
1156 def test_no_dict_no_slots_instance_member(self):
1157 # returns descriptor
1158 with open(__file__) as handle:
1159 self.assertEqual(inspect.getattr_static(handle, 'name'), type(handle).name)
1160
1161 def test_inherited_slots(self):
1162 # returns descriptor
1163 class Thing(object):
1164 __slots__ = ['x']
1165 def __init__(self):
1166 self.x = 'foo'
1167
1168 class OtherThing(Thing):
1169 pass
1170 # it would be nice if this worked...
1171 # we get the descriptor instead of the instance attribute
1172 self.assertEqual(inspect.getattr_static(OtherThing(), 'x'), Thing.x)
1173
1174 def test_descriptor(self):
1175 class descriptor(object):
1176 def __get__(self, instance, owner):
1177 return 3
1178 class Foo(object):
1179 d = descriptor()
1180
1181 foo = Foo()
1182
1183 # for a non data descriptor we return the instance attribute
1184 foo.__dict__['d'] = 1
1185 self.assertEqual(inspect.getattr_static(foo, 'd'), 1)
1186
1187 # if the descriptor is a data-desciptor we should return the
1188 # descriptor
1189 descriptor.__set__ = lambda s, i, v: None
1190 self.assertEqual(inspect.getattr_static(foo, 'd'), Foo.__dict__['d'])
1191
1192
1193 def test_metaclass_with_descriptor(self):
1194 class descriptor(object):
1195 def __get__(self, instance, owner):
1196 return 3
1197 class meta(type):
1198 d = descriptor()
1199 class Thing(object, metaclass=meta):
1200 pass
1201 self.assertEqual(inspect.getattr_static(Thing, 'd'), meta.__dict__['d'])
1202
1203
Michael Foordcc7ebb82010-11-20 16:20:16 +00001204 def test_class_as_property(self):
1205 class Base(object):
1206 foo = 3
1207
1208 class Something(Base):
Michael Foord35184ed2010-11-20 16:58:30 +00001209 executed = False
Michael Foordcc7ebb82010-11-20 16:20:16 +00001210 @property
1211 def __class__(self):
Michael Foord35184ed2010-11-20 16:58:30 +00001212 self.executed = True
Michael Foordcc7ebb82010-11-20 16:20:16 +00001213 return object
1214
Michael Foord35184ed2010-11-20 16:58:30 +00001215 instance = Something()
1216 self.assertEqual(inspect.getattr_static(instance, 'foo'), 3)
1217 self.assertFalse(instance.executed)
Michael Foordcc7ebb82010-11-20 16:20:16 +00001218 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1219
Michael Foorde5162652010-11-20 16:40:44 +00001220 def test_mro_as_property(self):
1221 class Meta(type):
1222 @property
1223 def __mro__(self):
1224 return (object,)
1225
1226 class Base(object):
1227 foo = 3
1228
1229 class Something(Base, metaclass=Meta):
1230 pass
1231
1232 self.assertEqual(inspect.getattr_static(Something(), 'foo'), 3)
1233 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1234
Michael Foorddcebe0f2011-03-15 19:20:44 -04001235 def test_dict_as_property(self):
1236 test = self
1237 test.called = False
1238
1239 class Foo(dict):
1240 a = 3
1241 @property
1242 def __dict__(self):
1243 test.called = True
1244 return {}
1245
1246 foo = Foo()
1247 foo.a = 4
1248 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1249 self.assertFalse(test.called)
1250
1251 def test_custom_object_dict(self):
1252 test = self
1253 test.called = False
1254
1255 class Custom(dict):
1256 def get(self, key, default=None):
1257 test.called = True
1258 super().get(key, default)
1259
1260 class Foo(object):
1261 a = 3
1262 foo = Foo()
1263 foo.__dict__ = Custom()
1264 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1265 self.assertFalse(test.called)
1266
1267 def test_metaclass_dict_as_property(self):
1268 class Meta(type):
1269 @property
1270 def __dict__(self):
1271 self.executed = True
1272
1273 class Thing(metaclass=Meta):
1274 executed = False
1275
1276 def __init__(self):
1277 self.spam = 42
1278
1279 instance = Thing()
1280 self.assertEqual(inspect.getattr_static(instance, "spam"), 42)
1281 self.assertFalse(Thing.executed)
Michael Foorde5162652010-11-20 16:40:44 +00001282
Michael Foorda51623b2011-12-18 22:01:40 +00001283 def test_module(self):
1284 sentinel = object()
1285 self.assertIsNot(inspect.getattr_static(sys, "version", sentinel),
1286 sentinel)
1287
Michael Foord3ba95f82011-12-22 01:13:37 +00001288 def test_metaclass_with_metaclass_with_dict_as_property(self):
1289 class MetaMeta(type):
1290 @property
1291 def __dict__(self):
1292 self.executed = True
1293 return dict(spam=42)
1294
1295 class Meta(type, metaclass=MetaMeta):
1296 executed = False
1297
1298 class Thing(metaclass=Meta):
1299 pass
1300
1301 with self.assertRaises(AttributeError):
1302 inspect.getattr_static(Thing, "spam")
1303 self.assertFalse(Thing.executed)
1304
Nick Coghlane0f04652010-11-21 03:44:04 +00001305class TestGetGeneratorState(unittest.TestCase):
1306
1307 def setUp(self):
1308 def number_generator():
1309 for number in range(5):
1310 yield number
1311 self.generator = number_generator()
1312
1313 def _generatorstate(self):
1314 return inspect.getgeneratorstate(self.generator)
1315
1316 def test_created(self):
1317 self.assertEqual(self._generatorstate(), inspect.GEN_CREATED)
1318
1319 def test_suspended(self):
1320 next(self.generator)
1321 self.assertEqual(self._generatorstate(), inspect.GEN_SUSPENDED)
1322
1323 def test_closed_after_exhaustion(self):
1324 for i in self.generator:
1325 pass
1326 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1327
1328 def test_closed_after_immediate_exception(self):
1329 with self.assertRaises(RuntimeError):
1330 self.generator.throw(RuntimeError)
1331 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1332
1333 def test_running(self):
1334 # As mentioned on issue #10220, checking for the RUNNING state only
1335 # makes sense inside the generator itself.
1336 # The following generator checks for this by using the closure's
1337 # reference to self and the generator state checking helper method
1338 def running_check_generator():
1339 for number in range(5):
1340 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1341 yield number
1342 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1343 self.generator = running_check_generator()
1344 # Running up to the first yield
1345 next(self.generator)
1346 # Running after the first yield
1347 next(self.generator)
1348
Nick Coghlan7921b9f2010-11-30 06:36:04 +00001349 def test_easy_debugging(self):
1350 # repr() and str() of a generator state should contain the state name
1351 names = 'GEN_CREATED GEN_RUNNING GEN_SUSPENDED GEN_CLOSED'.split()
1352 for name in names:
1353 state = getattr(inspect, name)
1354 self.assertIn(name, repr(state))
1355 self.assertIn(name, str(state))
1356
Nick Coghlan04e2e3f2012-06-23 19:52:05 +10001357 def test_getgeneratorlocals(self):
1358 def each(lst, a=None):
1359 b=(1, 2, 3)
1360 for v in lst:
1361 if v == 3:
1362 c = 12
1363 yield v
1364
1365 numbers = each([1, 2, 3])
1366 self.assertEqual(inspect.getgeneratorlocals(numbers),
1367 {'a': None, 'lst': [1, 2, 3]})
1368 next(numbers)
1369 self.assertEqual(inspect.getgeneratorlocals(numbers),
1370 {'a': None, 'lst': [1, 2, 3], 'v': 1,
1371 'b': (1, 2, 3)})
1372 next(numbers)
1373 self.assertEqual(inspect.getgeneratorlocals(numbers),
1374 {'a': None, 'lst': [1, 2, 3], 'v': 2,
1375 'b': (1, 2, 3)})
1376 next(numbers)
1377 self.assertEqual(inspect.getgeneratorlocals(numbers),
1378 {'a': None, 'lst': [1, 2, 3], 'v': 3,
1379 'b': (1, 2, 3), 'c': 12})
1380 try:
1381 next(numbers)
1382 except StopIteration:
1383 pass
1384 self.assertEqual(inspect.getgeneratorlocals(numbers), {})
1385
1386 def test_getgeneratorlocals_empty(self):
1387 def yield_one():
1388 yield 1
1389 one = yield_one()
1390 self.assertEqual(inspect.getgeneratorlocals(one), {})
1391 try:
1392 next(one)
1393 except StopIteration:
1394 pass
1395 self.assertEqual(inspect.getgeneratorlocals(one), {})
1396
1397 def test_getgeneratorlocals_error(self):
1398 self.assertRaises(TypeError, inspect.getgeneratorlocals, 1)
1399 self.assertRaises(TypeError, inspect.getgeneratorlocals, lambda x: True)
1400 self.assertRaises(TypeError, inspect.getgeneratorlocals, set)
1401 self.assertRaises(TypeError, inspect.getgeneratorlocals, (2,3))
1402
Nick Coghlane0f04652010-11-21 03:44:04 +00001403
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001404class TestSignatureObject(unittest.TestCase):
1405 @staticmethod
1406 def signature(func):
1407 sig = inspect.signature(func)
1408 return (tuple((param.name,
1409 (... if param.default is param.empty else param.default),
1410 (... if param.annotation is param.empty
1411 else param.annotation),
1412 str(param.kind).lower())
1413 for param in sig.parameters.values()),
1414 (... if sig.return_annotation is sig.empty
1415 else sig.return_annotation))
1416
1417 def test_signature_object(self):
1418 S = inspect.Signature
1419 P = inspect.Parameter
1420
1421 self.assertEqual(str(S()), '()')
1422
1423 def test(po, pk, *args, ko, **kwargs):
1424 pass
1425 sig = inspect.signature(test)
1426 po = sig.parameters['po'].replace(kind=P.POSITIONAL_ONLY)
1427 pk = sig.parameters['pk']
1428 args = sig.parameters['args']
1429 ko = sig.parameters['ko']
1430 kwargs = sig.parameters['kwargs']
1431
1432 S((po, pk, args, ko, kwargs))
1433
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001434 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001435 S((pk, po, args, ko, kwargs))
1436
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001437 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001438 S((po, args, pk, ko, kwargs))
1439
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001440 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001441 S((args, po, pk, ko, kwargs))
1442
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001443 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001444 S((po, pk, args, kwargs, ko))
1445
1446 kwargs2 = kwargs.replace(name='args')
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001447 with self.assertRaisesRegex(ValueError, 'duplicate parameter name'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001448 S((po, pk, args, kwargs2, ko))
1449
1450 def test_signature_immutability(self):
1451 def test(a):
1452 pass
1453 sig = inspect.signature(test)
1454
1455 with self.assertRaises(AttributeError):
1456 sig.foo = 'bar'
1457
1458 with self.assertRaises(TypeError):
1459 sig.parameters['a'] = None
1460
1461 def test_signature_on_noarg(self):
1462 def test():
1463 pass
1464 self.assertEqual(self.signature(test), ((), ...))
1465
1466 def test_signature_on_wargs(self):
1467 def test(a, b:'foo') -> 123:
1468 pass
1469 self.assertEqual(self.signature(test),
1470 ((('a', ..., ..., "positional_or_keyword"),
1471 ('b', ..., 'foo', "positional_or_keyword")),
1472 123))
1473
1474 def test_signature_on_wkwonly(self):
1475 def test(*, a:float, b:str) -> int:
1476 pass
1477 self.assertEqual(self.signature(test),
1478 ((('a', ..., float, "keyword_only"),
1479 ('b', ..., str, "keyword_only")),
1480 int))
1481
1482 def test_signature_on_complex_args(self):
1483 def test(a, b:'foo'=10, *args:'bar', spam:'baz', ham=123, **kwargs:int):
1484 pass
1485 self.assertEqual(self.signature(test),
1486 ((('a', ..., ..., "positional_or_keyword"),
1487 ('b', 10, 'foo', "positional_or_keyword"),
1488 ('args', ..., 'bar', "var_positional"),
1489 ('spam', ..., 'baz', "keyword_only"),
1490 ('ham', 123, ..., "keyword_only"),
1491 ('kwargs', ..., int, "var_keyword")),
1492 ...))
1493
1494 def test_signature_on_builtin_function(self):
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001495 with self.assertRaisesRegex(ValueError, 'not supported by signature'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001496 inspect.signature(type)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001497 with self.assertRaisesRegex(ValueError, 'not supported by signature'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001498 # support for 'wrapper_descriptor'
1499 inspect.signature(type.__call__)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001500 with self.assertRaisesRegex(ValueError, 'not supported by signature'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001501 # support for 'method-wrapper'
1502 inspect.signature(min.__call__)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001503 with self.assertRaisesRegex(ValueError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001504 'no signature found for builtin function'):
1505 # support for 'method-wrapper'
1506 inspect.signature(min)
1507
1508 def test_signature_on_non_function(self):
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001509 with self.assertRaisesRegex(TypeError, 'is not a callable object'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001510 inspect.signature(42)
1511
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001512 with self.assertRaisesRegex(TypeError, 'is not a Python function'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001513 inspect.Signature.from_function(42)
1514
1515 def test_signature_on_method(self):
1516 class Test:
1517 def foo(self, arg1, arg2=1) -> int:
1518 pass
1519
1520 meth = Test().foo
1521
1522 self.assertEqual(self.signature(meth),
1523 ((('arg1', ..., ..., "positional_or_keyword"),
1524 ('arg2', 1, ..., "positional_or_keyword")),
1525 int))
1526
1527 def test_signature_on_classmethod(self):
1528 class Test:
1529 @classmethod
1530 def foo(cls, arg1, *, arg2=1):
1531 pass
1532
1533 meth = Test().foo
1534 self.assertEqual(self.signature(meth),
1535 ((('arg1', ..., ..., "positional_or_keyword"),
1536 ('arg2', 1, ..., "keyword_only")),
1537 ...))
1538
1539 meth = Test.foo
1540 self.assertEqual(self.signature(meth),
1541 ((('arg1', ..., ..., "positional_or_keyword"),
1542 ('arg2', 1, ..., "keyword_only")),
1543 ...))
1544
1545 def test_signature_on_staticmethod(self):
1546 class Test:
1547 @staticmethod
1548 def foo(cls, *, arg):
1549 pass
1550
1551 meth = Test().foo
1552 self.assertEqual(self.signature(meth),
1553 ((('cls', ..., ..., "positional_or_keyword"),
1554 ('arg', ..., ..., "keyword_only")),
1555 ...))
1556
1557 meth = Test.foo
1558 self.assertEqual(self.signature(meth),
1559 ((('cls', ..., ..., "positional_or_keyword"),
1560 ('arg', ..., ..., "keyword_only")),
1561 ...))
1562
1563 def test_signature_on_partial(self):
1564 from functools import partial
1565
1566 def test():
1567 pass
1568
1569 self.assertEqual(self.signature(partial(test)), ((), ...))
1570
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001571 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001572 inspect.signature(partial(test, 1))
1573
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001574 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001575 inspect.signature(partial(test, a=1))
1576
1577 def test(a, b, *, c, d):
1578 pass
1579
1580 self.assertEqual(self.signature(partial(test)),
1581 ((('a', ..., ..., "positional_or_keyword"),
1582 ('b', ..., ..., "positional_or_keyword"),
1583 ('c', ..., ..., "keyword_only"),
1584 ('d', ..., ..., "keyword_only")),
1585 ...))
1586
1587 self.assertEqual(self.signature(partial(test, 1)),
1588 ((('b', ..., ..., "positional_or_keyword"),
1589 ('c', ..., ..., "keyword_only"),
1590 ('d', ..., ..., "keyword_only")),
1591 ...))
1592
1593 self.assertEqual(self.signature(partial(test, 1, c=2)),
1594 ((('b', ..., ..., "positional_or_keyword"),
1595 ('c', 2, ..., "keyword_only"),
1596 ('d', ..., ..., "keyword_only")),
1597 ...))
1598
1599 self.assertEqual(self.signature(partial(test, b=1, c=2)),
1600 ((('a', ..., ..., "positional_or_keyword"),
1601 ('b', 1, ..., "positional_or_keyword"),
1602 ('c', 2, ..., "keyword_only"),
1603 ('d', ..., ..., "keyword_only")),
1604 ...))
1605
1606 self.assertEqual(self.signature(partial(test, 0, b=1, c=2)),
1607 ((('b', 1, ..., "positional_or_keyword"),
1608 ('c', 2, ..., "keyword_only"),
1609 ('d', ..., ..., "keyword_only"),),
1610 ...))
1611
1612 def test(a, *args, b, **kwargs):
1613 pass
1614
1615 self.assertEqual(self.signature(partial(test, 1)),
1616 ((('args', ..., ..., "var_positional"),
1617 ('b', ..., ..., "keyword_only"),
1618 ('kwargs', ..., ..., "var_keyword")),
1619 ...))
1620
1621 self.assertEqual(self.signature(partial(test, 1, 2, 3)),
1622 ((('args', ..., ..., "var_positional"),
1623 ('b', ..., ..., "keyword_only"),
1624 ('kwargs', ..., ..., "var_keyword")),
1625 ...))
1626
1627
1628 self.assertEqual(self.signature(partial(test, 1, 2, 3, test=True)),
1629 ((('args', ..., ..., "var_positional"),
1630 ('b', ..., ..., "keyword_only"),
1631 ('kwargs', ..., ..., "var_keyword")),
1632 ...))
1633
1634 self.assertEqual(self.signature(partial(test, 1, 2, 3, test=1, b=0)),
1635 ((('args', ..., ..., "var_positional"),
1636 ('b', 0, ..., "keyword_only"),
1637 ('kwargs', ..., ..., "var_keyword")),
1638 ...))
1639
1640 self.assertEqual(self.signature(partial(test, b=0)),
1641 ((('a', ..., ..., "positional_or_keyword"),
1642 ('args', ..., ..., "var_positional"),
1643 ('b', 0, ..., "keyword_only"),
1644 ('kwargs', ..., ..., "var_keyword")),
1645 ...))
1646
1647 self.assertEqual(self.signature(partial(test, b=0, test=1)),
1648 ((('a', ..., ..., "positional_or_keyword"),
1649 ('args', ..., ..., "var_positional"),
1650 ('b', 0, ..., "keyword_only"),
1651 ('kwargs', ..., ..., "var_keyword")),
1652 ...))
1653
1654 def test(a, b, c:int) -> 42:
1655 pass
1656
1657 sig = test.__signature__ = inspect.signature(test)
1658
1659 self.assertEqual(self.signature(partial(partial(test, 1))),
1660 ((('b', ..., ..., "positional_or_keyword"),
1661 ('c', ..., int, "positional_or_keyword")),
1662 42))
1663
1664 self.assertEqual(self.signature(partial(partial(test, 1), 2)),
1665 ((('c', ..., int, "positional_or_keyword"),),
1666 42))
1667
1668 psig = inspect.signature(partial(partial(test, 1), 2))
1669
1670 def foo(a):
1671 return a
1672 _foo = partial(partial(foo, a=10), a=20)
1673 self.assertEqual(self.signature(_foo),
1674 ((('a', 20, ..., "positional_or_keyword"),),
1675 ...))
1676 # check that we don't have any side-effects in signature(),
1677 # and the partial object is still functioning
1678 self.assertEqual(_foo(), 20)
1679
1680 def foo(a, b, c):
1681 return a, b, c
1682 _foo = partial(partial(foo, 1, b=20), b=30)
1683 self.assertEqual(self.signature(_foo),
1684 ((('b', 30, ..., "positional_or_keyword"),
1685 ('c', ..., ..., "positional_or_keyword")),
1686 ...))
1687 self.assertEqual(_foo(c=10), (1, 30, 10))
1688 _foo = partial(_foo, 2) # now 'b' has two values -
1689 # positional and keyword
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001690 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001691 inspect.signature(_foo)
1692
1693 def foo(a, b, c, *, d):
1694 return a, b, c, d
1695 _foo = partial(partial(foo, d=20, c=20), b=10, d=30)
1696 self.assertEqual(self.signature(_foo),
1697 ((('a', ..., ..., "positional_or_keyword"),
1698 ('b', 10, ..., "positional_or_keyword"),
1699 ('c', 20, ..., "positional_or_keyword"),
1700 ('d', 30, ..., "keyword_only")),
1701 ...))
1702 ba = inspect.signature(_foo).bind(a=200, b=11)
1703 self.assertEqual(_foo(*ba.args, **ba.kwargs), (200, 11, 20, 30))
1704
1705 def foo(a=1, b=2, c=3):
1706 return a, b, c
1707 _foo = partial(foo, a=10, c=13)
1708 ba = inspect.signature(_foo).bind(11)
1709 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 2, 13))
1710 ba = inspect.signature(_foo).bind(11, 12)
1711 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
1712 ba = inspect.signature(_foo).bind(11, b=12)
1713 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
1714 ba = inspect.signature(_foo).bind(b=12)
1715 self.assertEqual(_foo(*ba.args, **ba.kwargs), (10, 12, 13))
1716 _foo = partial(_foo, b=10)
1717 ba = inspect.signature(_foo).bind(12, 14)
1718 self.assertEqual(_foo(*ba.args, **ba.kwargs), (12, 14, 13))
1719
1720 def test_signature_on_decorated(self):
1721 import functools
1722
1723 def decorator(func):
1724 @functools.wraps(func)
1725 def wrapper(*args, **kwargs) -> int:
1726 return func(*args, **kwargs)
1727 return wrapper
1728
1729 class Foo:
1730 @decorator
1731 def bar(self, a, b):
1732 pass
1733
1734 self.assertEqual(self.signature(Foo.bar),
1735 ((('self', ..., ..., "positional_or_keyword"),
1736 ('a', ..., ..., "positional_or_keyword"),
1737 ('b', ..., ..., "positional_or_keyword")),
1738 ...))
1739
1740 self.assertEqual(self.signature(Foo().bar),
1741 ((('a', ..., ..., "positional_or_keyword"),
1742 ('b', ..., ..., "positional_or_keyword")),
1743 ...))
1744
1745 # Test that we handle method wrappers correctly
1746 def decorator(func):
1747 @functools.wraps(func)
1748 def wrapper(*args, **kwargs) -> int:
1749 return func(42, *args, **kwargs)
1750 sig = inspect.signature(func)
1751 new_params = tuple(sig.parameters.values())[1:]
1752 wrapper.__signature__ = sig.replace(parameters=new_params)
1753 return wrapper
1754
1755 class Foo:
1756 @decorator
1757 def __call__(self, a, b):
1758 pass
1759
1760 self.assertEqual(self.signature(Foo.__call__),
1761 ((('a', ..., ..., "positional_or_keyword"),
1762 ('b', ..., ..., "positional_or_keyword")),
1763 ...))
1764
1765 self.assertEqual(self.signature(Foo().__call__),
1766 ((('b', ..., ..., "positional_or_keyword"),),
1767 ...))
1768
Nick Coghlane8c45d62013-07-28 20:00:01 +10001769 # Test we handle __signature__ partway down the wrapper stack
1770 def wrapped_foo_call():
1771 pass
1772 wrapped_foo_call.__wrapped__ = Foo.__call__
1773
1774 self.assertEqual(self.signature(wrapped_foo_call),
1775 ((('a', ..., ..., "positional_or_keyword"),
1776 ('b', ..., ..., "positional_or_keyword")),
1777 ...))
1778
1779
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001780 def test_signature_on_class(self):
1781 class C:
1782 def __init__(self, a):
1783 pass
1784
1785 self.assertEqual(self.signature(C),
1786 ((('a', ..., ..., "positional_or_keyword"),),
1787 ...))
1788
1789 class CM(type):
1790 def __call__(cls, a):
1791 pass
1792 class C(metaclass=CM):
1793 def __init__(self, b):
1794 pass
1795
1796 self.assertEqual(self.signature(C),
1797 ((('a', ..., ..., "positional_or_keyword"),),
1798 ...))
1799
1800 class CM(type):
1801 def __new__(mcls, name, bases, dct, *, foo=1):
1802 return super().__new__(mcls, name, bases, dct)
1803 class C(metaclass=CM):
1804 def __init__(self, b):
1805 pass
1806
1807 self.assertEqual(self.signature(C),
1808 ((('b', ..., ..., "positional_or_keyword"),),
1809 ...))
1810
1811 self.assertEqual(self.signature(CM),
1812 ((('name', ..., ..., "positional_or_keyword"),
1813 ('bases', ..., ..., "positional_or_keyword"),
1814 ('dct', ..., ..., "positional_or_keyword"),
1815 ('foo', 1, ..., "keyword_only")),
1816 ...))
1817
1818 class CMM(type):
1819 def __new__(mcls, name, bases, dct, *, foo=1):
1820 return super().__new__(mcls, name, bases, dct)
1821 def __call__(cls, nm, bs, dt):
1822 return type(nm, bs, dt)
1823 class CM(type, metaclass=CMM):
1824 def __new__(mcls, name, bases, dct, *, bar=2):
1825 return super().__new__(mcls, name, bases, dct)
1826 class C(metaclass=CM):
1827 def __init__(self, b):
1828 pass
1829
1830 self.assertEqual(self.signature(CMM),
1831 ((('name', ..., ..., "positional_or_keyword"),
1832 ('bases', ..., ..., "positional_or_keyword"),
1833 ('dct', ..., ..., "positional_or_keyword"),
1834 ('foo', 1, ..., "keyword_only")),
1835 ...))
1836
1837 self.assertEqual(self.signature(CM),
1838 ((('nm', ..., ..., "positional_or_keyword"),
1839 ('bs', ..., ..., "positional_or_keyword"),
1840 ('dt', ..., ..., "positional_or_keyword")),
1841 ...))
1842
1843 self.assertEqual(self.signature(C),
1844 ((('b', ..., ..., "positional_or_keyword"),),
1845 ...))
1846
1847 class CM(type):
1848 def __init__(cls, name, bases, dct, *, bar=2):
1849 return super().__init__(name, bases, dct)
1850 class C(metaclass=CM):
1851 def __init__(self, b):
1852 pass
1853
1854 self.assertEqual(self.signature(CM),
1855 ((('name', ..., ..., "positional_or_keyword"),
1856 ('bases', ..., ..., "positional_or_keyword"),
1857 ('dct', ..., ..., "positional_or_keyword"),
1858 ('bar', 2, ..., "keyword_only")),
1859 ...))
1860
1861 def test_signature_on_callable_objects(self):
1862 class Foo:
1863 def __call__(self, a):
1864 pass
1865
1866 self.assertEqual(self.signature(Foo()),
1867 ((('a', ..., ..., "positional_or_keyword"),),
1868 ...))
1869
1870 class Spam:
1871 pass
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001872 with self.assertRaisesRegex(TypeError, "is not a callable object"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001873 inspect.signature(Spam())
1874
1875 class Bar(Spam, Foo):
1876 pass
1877
1878 self.assertEqual(self.signature(Bar()),
1879 ((('a', ..., ..., "positional_or_keyword"),),
1880 ...))
1881
1882 class ToFail:
1883 __call__ = type
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001884 with self.assertRaisesRegex(ValueError, "not supported by signature"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001885 inspect.signature(ToFail())
1886
1887
1888 class Wrapped:
1889 pass
1890 Wrapped.__wrapped__ = lambda a: None
1891 self.assertEqual(self.signature(Wrapped),
1892 ((('a', ..., ..., "positional_or_keyword"),),
1893 ...))
Nick Coghlane8c45d62013-07-28 20:00:01 +10001894 # wrapper loop:
1895 Wrapped.__wrapped__ = Wrapped
1896 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
1897 self.signature(Wrapped)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001898
1899 def test_signature_on_lambdas(self):
1900 self.assertEqual(self.signature((lambda a=10: a)),
1901 ((('a', 10, ..., "positional_or_keyword"),),
1902 ...))
1903
1904 def test_signature_equality(self):
1905 def foo(a, *, b:int) -> float: pass
1906 self.assertNotEqual(inspect.signature(foo), 42)
1907
1908 def bar(a, *, b:int) -> float: pass
1909 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
1910
1911 def bar(a, *, b:int) -> int: pass
1912 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
1913
1914 def bar(a, *, b:int): pass
1915 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
1916
1917 def bar(a, *, b:int=42) -> float: pass
1918 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
1919
1920 def bar(a, *, c) -> float: pass
1921 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
1922
1923 def bar(a, b:int) -> float: pass
1924 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
1925 def spam(b:int, a) -> float: pass
1926 self.assertNotEqual(inspect.signature(spam), inspect.signature(bar))
1927
1928 def foo(*, a, b, c): pass
1929 def bar(*, c, b, a): pass
1930 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
1931
1932 def foo(*, a=1, b, c): pass
1933 def bar(*, c, b, a=1): pass
1934 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
1935
1936 def foo(pos, *, a=1, b, c): pass
1937 def bar(pos, *, c, b, a=1): pass
1938 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
1939
1940 def foo(pos, *, a, b, c): pass
1941 def bar(pos, *, c, b, a=1): pass
1942 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
1943
1944 def foo(pos, *args, a=42, b, c, **kwargs:int): pass
1945 def bar(pos, *args, c, b, a=42, **kwargs:int): pass
1946 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
1947
1948 def test_signature_unhashable(self):
1949 def foo(a): pass
1950 sig = inspect.signature(foo)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001951 with self.assertRaisesRegex(TypeError, 'unhashable type'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001952 hash(sig)
1953
1954 def test_signature_str(self):
1955 def foo(a:int=1, *, b, c=None, **kwargs) -> 42:
1956 pass
1957 self.assertEqual(str(inspect.signature(foo)),
1958 '(a:int=1, *, b, c=None, **kwargs) -> 42')
1959
1960 def foo(a:int=1, *args, b, c=None, **kwargs) -> 42:
1961 pass
1962 self.assertEqual(str(inspect.signature(foo)),
1963 '(a:int=1, *args, b, c=None, **kwargs) -> 42')
1964
1965 def foo():
1966 pass
1967 self.assertEqual(str(inspect.signature(foo)), '()')
1968
1969 def test_signature_str_positional_only(self):
1970 P = inspect.Parameter
1971
1972 def test(a_po, *, b, **kwargs):
1973 return a_po, kwargs
1974
1975 sig = inspect.signature(test)
1976 new_params = list(sig.parameters.values())
1977 new_params[0] = new_params[0].replace(kind=P.POSITIONAL_ONLY)
1978 test.__signature__ = sig.replace(parameters=new_params)
1979
1980 self.assertEqual(str(inspect.signature(test)),
1981 '(<a_po>, *, b, **kwargs)')
1982
1983 sig = inspect.signature(test)
1984 new_params = list(sig.parameters.values())
1985 new_params[0] = new_params[0].replace(name=None)
1986 test.__signature__ = sig.replace(parameters=new_params)
1987 self.assertEqual(str(inspect.signature(test)),
1988 '(<0>, *, b, **kwargs)')
1989
1990 def test_signature_replace_anno(self):
1991 def test() -> 42:
1992 pass
1993
1994 sig = inspect.signature(test)
1995 sig = sig.replace(return_annotation=None)
1996 self.assertIs(sig.return_annotation, None)
1997 sig = sig.replace(return_annotation=sig.empty)
1998 self.assertIs(sig.return_annotation, sig.empty)
1999 sig = sig.replace(return_annotation=42)
2000 self.assertEqual(sig.return_annotation, 42)
2001 self.assertEqual(sig, inspect.signature(test))
2002
2003
2004class TestParameterObject(unittest.TestCase):
2005 def test_signature_parameter_kinds(self):
2006 P = inspect.Parameter
2007 self.assertTrue(P.POSITIONAL_ONLY < P.POSITIONAL_OR_KEYWORD < \
2008 P.VAR_POSITIONAL < P.KEYWORD_ONLY < P.VAR_KEYWORD)
2009
2010 self.assertEqual(str(P.POSITIONAL_ONLY), 'POSITIONAL_ONLY')
2011 self.assertTrue('POSITIONAL_ONLY' in repr(P.POSITIONAL_ONLY))
2012
2013 def test_signature_parameter_object(self):
2014 p = inspect.Parameter('foo', default=10,
2015 kind=inspect.Parameter.POSITIONAL_ONLY)
2016 self.assertEqual(p.name, 'foo')
2017 self.assertEqual(p.default, 10)
2018 self.assertIs(p.annotation, p.empty)
2019 self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY)
2020
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002021 with self.assertRaisesRegex(ValueError, 'invalid value'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002022 inspect.Parameter('foo', default=10, kind='123')
2023
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002024 with self.assertRaisesRegex(ValueError, 'not a valid parameter name'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002025 inspect.Parameter('1', kind=inspect.Parameter.VAR_KEYWORD)
2026
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002027 with self.assertRaisesRegex(ValueError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002028 'non-positional-only parameter'):
2029 inspect.Parameter(None, kind=inspect.Parameter.VAR_KEYWORD)
2030
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002031 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002032 inspect.Parameter('a', default=42,
2033 kind=inspect.Parameter.VAR_KEYWORD)
2034
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002035 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002036 inspect.Parameter('a', default=42,
2037 kind=inspect.Parameter.VAR_POSITIONAL)
2038
2039 p = inspect.Parameter('a', default=42,
2040 kind=inspect.Parameter.POSITIONAL_OR_KEYWORD)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002041 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002042 p.replace(kind=inspect.Parameter.VAR_POSITIONAL)
2043
2044 self.assertTrue(repr(p).startswith('<Parameter'))
2045
2046 def test_signature_parameter_equality(self):
2047 P = inspect.Parameter
2048 p = P('foo', default=42, kind=inspect.Parameter.KEYWORD_ONLY)
2049
2050 self.assertEqual(p, p)
2051 self.assertNotEqual(p, 42)
2052
2053 self.assertEqual(p, P('foo', default=42,
2054 kind=inspect.Parameter.KEYWORD_ONLY))
2055
2056 def test_signature_parameter_unhashable(self):
2057 p = inspect.Parameter('foo', default=42,
2058 kind=inspect.Parameter.KEYWORD_ONLY)
2059
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002060 with self.assertRaisesRegex(TypeError, 'unhashable type'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002061 hash(p)
2062
2063 def test_signature_parameter_replace(self):
2064 p = inspect.Parameter('foo', default=42,
2065 kind=inspect.Parameter.KEYWORD_ONLY)
2066
2067 self.assertIsNot(p, p.replace())
2068 self.assertEqual(p, p.replace())
2069
2070 p2 = p.replace(annotation=1)
2071 self.assertEqual(p2.annotation, 1)
2072 p2 = p2.replace(annotation=p2.empty)
2073 self.assertEqual(p, p2)
2074
2075 p2 = p2.replace(name='bar')
2076 self.assertEqual(p2.name, 'bar')
2077 self.assertNotEqual(p2, p)
2078
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002079 with self.assertRaisesRegex(ValueError, 'not a valid parameter name'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002080 p2 = p2.replace(name=p2.empty)
2081
2082 p2 = p2.replace(name='foo', default=None)
2083 self.assertIs(p2.default, None)
2084 self.assertNotEqual(p2, p)
2085
2086 p2 = p2.replace(name='foo', default=p2.empty)
2087 self.assertIs(p2.default, p2.empty)
2088
2089
2090 p2 = p2.replace(default=42, kind=p2.POSITIONAL_OR_KEYWORD)
2091 self.assertEqual(p2.kind, p2.POSITIONAL_OR_KEYWORD)
2092 self.assertNotEqual(p2, p)
2093
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002094 with self.assertRaisesRegex(ValueError, 'invalid value for'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002095 p2 = p2.replace(kind=p2.empty)
2096
2097 p2 = p2.replace(kind=p2.KEYWORD_ONLY)
2098 self.assertEqual(p2, p)
2099
2100 def test_signature_parameter_positional_only(self):
2101 p = inspect.Parameter(None, kind=inspect.Parameter.POSITIONAL_ONLY)
2102 self.assertEqual(str(p), '<>')
2103
2104 p = p.replace(name='1')
2105 self.assertEqual(str(p), '<1>')
2106
2107 def test_signature_parameter_immutability(self):
2108 p = inspect.Parameter(None, kind=inspect.Parameter.POSITIONAL_ONLY)
2109
2110 with self.assertRaises(AttributeError):
2111 p.foo = 'bar'
2112
2113 with self.assertRaises(AttributeError):
2114 p.kind = 123
2115
2116
2117class TestSignatureBind(unittest.TestCase):
2118 @staticmethod
2119 def call(func, *args, **kwargs):
2120 sig = inspect.signature(func)
2121 ba = sig.bind(*args, **kwargs)
2122 return func(*ba.args, **ba.kwargs)
2123
2124 def test_signature_bind_empty(self):
2125 def test():
2126 return 42
2127
2128 self.assertEqual(self.call(test), 42)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002129 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002130 self.call(test, 1)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002131 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002132 self.call(test, 1, spam=10)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002133 with self.assertRaisesRegex(TypeError, 'too many keyword arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002134 self.call(test, spam=1)
2135
2136 def test_signature_bind_var(self):
2137 def test(*args, **kwargs):
2138 return args, kwargs
2139
2140 self.assertEqual(self.call(test), ((), {}))
2141 self.assertEqual(self.call(test, 1), ((1,), {}))
2142 self.assertEqual(self.call(test, 1, 2), ((1, 2), {}))
2143 self.assertEqual(self.call(test, foo='bar'), ((), {'foo': 'bar'}))
2144 self.assertEqual(self.call(test, 1, foo='bar'), ((1,), {'foo': 'bar'}))
2145 self.assertEqual(self.call(test, args=10), ((), {'args': 10}))
2146 self.assertEqual(self.call(test, 1, 2, foo='bar'),
2147 ((1, 2), {'foo': 'bar'}))
2148
2149 def test_signature_bind_just_args(self):
2150 def test(a, b, c):
2151 return a, b, c
2152
2153 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
2154
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002155 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002156 self.call(test, 1, 2, 3, 4)
2157
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002158 with self.assertRaisesRegex(TypeError, "'b' parameter lacking default"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002159 self.call(test, 1)
2160
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002161 with self.assertRaisesRegex(TypeError, "'a' parameter lacking default"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002162 self.call(test)
2163
2164 def test(a, b, c=10):
2165 return a, b, c
2166 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
2167 self.assertEqual(self.call(test, 1, 2), (1, 2, 10))
2168
2169 def test(a=1, b=2, c=3):
2170 return a, b, c
2171 self.assertEqual(self.call(test, a=10, c=13), (10, 2, 13))
2172 self.assertEqual(self.call(test, a=10), (10, 2, 3))
2173 self.assertEqual(self.call(test, b=10), (1, 10, 3))
2174
2175 def test_signature_bind_varargs_order(self):
2176 def test(*args):
2177 return args
2178
2179 self.assertEqual(self.call(test), ())
2180 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
2181
2182 def test_signature_bind_args_and_varargs(self):
2183 def test(a, b, c=3, *args):
2184 return a, b, c, args
2185
2186 self.assertEqual(self.call(test, 1, 2, 3, 4, 5), (1, 2, 3, (4, 5)))
2187 self.assertEqual(self.call(test, 1, 2), (1, 2, 3, ()))
2188 self.assertEqual(self.call(test, b=1, a=2), (2, 1, 3, ()))
2189 self.assertEqual(self.call(test, 1, b=2), (1, 2, 3, ()))
2190
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002191 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002192 "multiple values for argument 'c'"):
2193 self.call(test, 1, 2, 3, c=4)
2194
2195 def test_signature_bind_just_kwargs(self):
2196 def test(**kwargs):
2197 return kwargs
2198
2199 self.assertEqual(self.call(test), {})
2200 self.assertEqual(self.call(test, foo='bar', spam='ham'),
2201 {'foo': 'bar', 'spam': 'ham'})
2202
2203 def test_signature_bind_args_and_kwargs(self):
2204 def test(a, b, c=3, **kwargs):
2205 return a, b, c, kwargs
2206
2207 self.assertEqual(self.call(test, 1, 2), (1, 2, 3, {}))
2208 self.assertEqual(self.call(test, 1, 2, foo='bar', spam='ham'),
2209 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
2210 self.assertEqual(self.call(test, b=2, a=1, foo='bar', spam='ham'),
2211 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
2212 self.assertEqual(self.call(test, a=1, b=2, foo='bar', spam='ham'),
2213 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
2214 self.assertEqual(self.call(test, 1, b=2, foo='bar', spam='ham'),
2215 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
2216 self.assertEqual(self.call(test, 1, b=2, c=4, foo='bar', spam='ham'),
2217 (1, 2, 4, {'foo': 'bar', 'spam': 'ham'}))
2218 self.assertEqual(self.call(test, 1, 2, 4, foo='bar'),
2219 (1, 2, 4, {'foo': 'bar'}))
2220 self.assertEqual(self.call(test, c=5, a=4, b=3),
2221 (4, 3, 5, {}))
2222
2223 def test_signature_bind_kwonly(self):
2224 def test(*, foo):
2225 return foo
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002226 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002227 'too many positional arguments'):
2228 self.call(test, 1)
2229 self.assertEqual(self.call(test, foo=1), 1)
2230
2231 def test(a, *, foo=1, bar):
2232 return foo
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002233 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002234 "'bar' parameter lacking default value"):
2235 self.call(test, 1)
2236
2237 def test(foo, *, bar):
2238 return foo, bar
2239 self.assertEqual(self.call(test, 1, bar=2), (1, 2))
2240 self.assertEqual(self.call(test, bar=2, foo=1), (1, 2))
2241
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002242 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002243 'too many keyword arguments'):
2244 self.call(test, bar=2, foo=1, spam=10)
2245
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002246 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002247 'too many positional arguments'):
2248 self.call(test, 1, 2)
2249
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002250 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002251 'too many positional arguments'):
2252 self.call(test, 1, 2, bar=2)
2253
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002254 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002255 'too many keyword arguments'):
2256 self.call(test, 1, bar=2, spam='ham')
2257
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002258 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002259 "'bar' parameter lacking default value"):
2260 self.call(test, 1)
2261
2262 def test(foo, *, bar, **bin):
2263 return foo, bar, bin
2264 self.assertEqual(self.call(test, 1, bar=2), (1, 2, {}))
2265 self.assertEqual(self.call(test, foo=1, bar=2), (1, 2, {}))
2266 self.assertEqual(self.call(test, 1, bar=2, spam='ham'),
2267 (1, 2, {'spam': 'ham'}))
2268 self.assertEqual(self.call(test, spam='ham', foo=1, bar=2),
2269 (1, 2, {'spam': 'ham'}))
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002270 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002271 "'foo' parameter lacking default value"):
2272 self.call(test, spam='ham', bar=2)
2273 self.assertEqual(self.call(test, 1, bar=2, bin=1, spam=10),
2274 (1, 2, {'bin': 1, 'spam': 10}))
2275
2276 def test_signature_bind_arguments(self):
2277 def test(a, *args, b, z=100, **kwargs):
2278 pass
2279 sig = inspect.signature(test)
2280 ba = sig.bind(10, 20, b=30, c=40, args=50, kwargs=60)
2281 # we won't have 'z' argument in the bound arguments object, as we didn't
2282 # pass it to the 'bind'
2283 self.assertEqual(tuple(ba.arguments.items()),
2284 (('a', 10), ('args', (20,)), ('b', 30),
2285 ('kwargs', {'c': 40, 'args': 50, 'kwargs': 60})))
2286 self.assertEqual(ba.kwargs,
2287 {'b': 30, 'c': 40, 'args': 50, 'kwargs': 60})
2288 self.assertEqual(ba.args, (10, 20))
2289
2290 def test_signature_bind_positional_only(self):
2291 P = inspect.Parameter
2292
2293 def test(a_po, b_po, c_po=3, foo=42, *, bar=50, **kwargs):
2294 return a_po, b_po, c_po, foo, bar, kwargs
2295
2296 sig = inspect.signature(test)
2297 new_params = collections.OrderedDict(tuple(sig.parameters.items()))
2298 for name in ('a_po', 'b_po', 'c_po'):
2299 new_params[name] = new_params[name].replace(kind=P.POSITIONAL_ONLY)
2300 new_sig = sig.replace(parameters=new_params.values())
2301 test.__signature__ = new_sig
2302
2303 self.assertEqual(self.call(test, 1, 2, 4, 5, bar=6),
2304 (1, 2, 4, 5, 6, {}))
2305
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002306 with self.assertRaisesRegex(TypeError, "parameter is positional only"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002307 self.call(test, 1, 2, c_po=4)
2308
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002309 with self.assertRaisesRegex(TypeError, "parameter is positional only"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002310 self.call(test, a_po=1, b_po=2)
2311
Antoine Pitroubd41d1b2013-01-29 21:20:57 +01002312 def test_signature_bind_with_self_arg(self):
2313 # Issue #17071: one of the parameters is named "self
2314 def test(a, self, b):
2315 pass
2316 sig = inspect.signature(test)
2317 ba = sig.bind(1, 2, 3)
2318 self.assertEqual(ba.args, (1, 2, 3))
2319 ba = sig.bind(1, self=2, b=3)
2320 self.assertEqual(ba.args, (1, 2, 3))
2321
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002322
2323class TestBoundArguments(unittest.TestCase):
2324 def test_signature_bound_arguments_unhashable(self):
2325 def foo(a): pass
2326 ba = inspect.signature(foo).bind(1)
2327
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002328 with self.assertRaisesRegex(TypeError, 'unhashable type'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002329 hash(ba)
2330
2331 def test_signature_bound_arguments_equality(self):
2332 def foo(a): pass
2333 ba = inspect.signature(foo).bind(1)
2334 self.assertEqual(ba, ba)
2335
2336 ba2 = inspect.signature(foo).bind(1)
2337 self.assertEqual(ba, ba2)
2338
2339 ba3 = inspect.signature(foo).bind(2)
2340 self.assertNotEqual(ba, ba3)
2341 ba3.arguments['a'] = 1
2342 self.assertEqual(ba, ba3)
2343
2344 def bar(b): pass
2345 ba4 = inspect.signature(bar).bind(1)
2346 self.assertNotEqual(ba, ba4)
2347
2348
Nick Coghlane8c45d62013-07-28 20:00:01 +10002349class TestUnwrap(unittest.TestCase):
2350
2351 def test_unwrap_one(self):
2352 def func(a, b):
2353 return a + b
2354 wrapper = functools.lru_cache(maxsize=20)(func)
2355 self.assertIs(inspect.unwrap(wrapper), func)
2356
2357 def test_unwrap_several(self):
2358 def func(a, b):
2359 return a + b
2360 wrapper = func
2361 for __ in range(10):
2362 @functools.wraps(wrapper)
2363 def wrapper():
2364 pass
2365 self.assertIsNot(wrapper.__wrapped__, func)
2366 self.assertIs(inspect.unwrap(wrapper), func)
2367
2368 def test_stop(self):
2369 def func1(a, b):
2370 return a + b
2371 @functools.wraps(func1)
2372 def func2():
2373 pass
2374 @functools.wraps(func2)
2375 def wrapper():
2376 pass
2377 func2.stop_here = 1
2378 unwrapped = inspect.unwrap(wrapper,
2379 stop=(lambda f: hasattr(f, "stop_here")))
2380 self.assertIs(unwrapped, func2)
2381
2382 def test_cycle(self):
2383 def func1(): pass
2384 func1.__wrapped__ = func1
2385 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
2386 inspect.unwrap(func1)
2387
2388 def func2(): pass
2389 func2.__wrapped__ = func1
2390 func1.__wrapped__ = func2
2391 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
2392 inspect.unwrap(func1)
2393 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
2394 inspect.unwrap(func2)
2395
2396 def test_unhashable(self):
2397 def func(): pass
2398 func.__wrapped__ = None
2399 class C:
2400 __hash__ = None
2401 __wrapped__ = func
2402 self.assertIsNone(inspect.unwrap(C()))
2403
Nick Coghlanf94a16b2013-09-22 22:46:49 +10002404class TestMain(unittest.TestCase):
2405 def test_only_source(self):
2406 module = importlib.import_module('unittest')
2407 rc, out, err = assert_python_ok('-m', 'inspect',
2408 'unittest')
2409 lines = out.decode().splitlines()
2410 # ignore the final newline
2411 self.assertEqual(lines[:-1], inspect.getsource(module).splitlines())
2412 self.assertEqual(err, b'')
2413
Brett Cannon634a8fc2013-10-02 10:25:42 -04002414 @unittest.skipIf(ThreadPoolExecutor is None,
Brett Cannon0de3f012013-10-02 10:58:58 -04002415 'threads required to test __qualname__ for source files')
Nick Coghlanf94a16b2013-09-22 22:46:49 +10002416 def test_qualname_source(self):
Nick Coghlanf94a16b2013-09-22 22:46:49 +10002417 rc, out, err = assert_python_ok('-m', 'inspect',
2418 'concurrent.futures:ThreadPoolExecutor')
2419 lines = out.decode().splitlines()
2420 # ignore the final newline
2421 self.assertEqual(lines[:-1],
Brett Cannon634a8fc2013-10-02 10:25:42 -04002422 inspect.getsource(ThreadPoolExecutor).splitlines())
Nick Coghlanf94a16b2013-09-22 22:46:49 +10002423 self.assertEqual(err, b'')
2424
2425 def test_builtins(self):
2426 module = importlib.import_module('unittest')
2427 _, out, err = assert_python_failure('-m', 'inspect',
2428 'sys')
2429 lines = err.decode().splitlines()
2430 self.assertEqual(lines, ["Can't get info for builtin modules."])
2431
2432 def test_details(self):
2433 module = importlib.import_module('unittest')
2434 rc, out, err = assert_python_ok('-m', 'inspect',
2435 'unittest', '--details')
2436 output = out.decode()
2437 # Just a quick sanity check on the output
2438 self.assertIn(module.__name__, output)
2439 self.assertIn(module.__file__, output)
2440 self.assertIn(module.__cached__, output)
2441 self.assertEqual(err, b'')
2442
2443
2444
Nick Coghlane8c45d62013-07-28 20:00:01 +10002445
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00002446def test_main():
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00002447 run_unittest(
2448 TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBuggyCases,
2449 TestInterpreterStack, TestClassesAndFunctions, TestPredicates,
2450 TestGetcallargsFunctions, TestGetcallargsMethods,
Alexander Belopolskyf546e702010-12-02 00:10:11 +00002451 TestGetcallargsUnboundMethods, TestGetattrStatic, TestGetGeneratorState,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002452 TestNoEOL, TestSignatureObject, TestSignatureBind, TestParameterObject,
Nick Coghlanf94a16b2013-09-22 22:46:49 +10002453 TestBoundArguments, TestGetClosureVars, TestUnwrap, TestMain
Michael Foord95fc51d2010-11-20 15:07:30 +00002454 )
Martin v. Löwis893ffa42003-10-31 15:35:53 +00002455
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00002456if __name__ == "__main__":
2457 test_main()