blob: 5cbec9bb17b4593cb04720b4041f7cf347ae5a46 [file] [log] [blame]
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001import re
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00002import sys
Thomas Wouters0e3f5912006-08-11 14:57:12 +00003import types
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00004import unittest
5import inspect
R. David Murraya1b37402010-06-17 02:04:29 +00006import linecache
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007import datetime
Guido van Rossum813b0e52007-05-21 18:11:34 +00008import collections
Alexander Belopolskyf546e702010-12-02 00:10:11 +00009import os
10import shutil
Christian Heimesa3538eb2007-11-06 11:44:48 +000011from os.path import normcase
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000012
Alexander Belopolskyf546e702010-12-02 00:10:11 +000013from test.support import run_unittest, TESTFN, DirsOnSysPath
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000014
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000015from test import inspect_fodder as mod
16from test import inspect_fodder2 as mod2
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000017
R. David Murray74b89242009-05-13 17:33:03 +000018# C module for test_findsource_binary
R. David Murrayb5655772009-05-14 16:17:50 +000019import unicodedata
R. David Murray74b89242009-05-13 17:33:03 +000020
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000021# Functions tested in this suite:
22# ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode,
Christian Heimes7131fd92008-02-19 14:21:46 +000023# isbuiltin, isroutine, isgenerator, isgeneratorfunction, getmembers,
24# getdoc, getfile, getmodule, getsourcefile, getcomments, getsource,
25# getclasstree, getargspec, getargvalues, formatargspec, formatargvalues,
26# currentframe, stack, trace, isdatadescriptor
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000027
Nick Coghlanf088e5e2008-12-14 11:50:48 +000028# NOTE: There are some additional tests relating to interaction with
29# zipimport in the test_zipimport_support test module.
30
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000031modfile = mod.__file__
Thomas Wouters0e3f5912006-08-11 14:57:12 +000032if modfile.endswith(('c', 'o')):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000033 modfile = modfile[:-1]
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000034
Christian Heimesa3538eb2007-11-06 11:44:48 +000035# Normalize file names: on Windows, the case of file names of compiled
36# modules depends on the path used to start the python executable.
37modfile = normcase(modfile)
38
39def revise(filename, *args):
40 return (normcase(filename),) + args
41
Georg Brandl1a3284e2007-12-02 09:40:06 +000042import builtins
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000043
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000044git = mod.StupidGit()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000045
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000046class IsTestBase(unittest.TestCase):
47 predicates = set([inspect.isbuiltin, inspect.isclass, inspect.iscode,
48 inspect.isframe, inspect.isfunction, inspect.ismethod,
Christian Heimes7131fd92008-02-19 14:21:46 +000049 inspect.ismodule, inspect.istraceback,
50 inspect.isgenerator, inspect.isgeneratorfunction])
Tim Peters5a9fb3c2005-01-07 16:01:32 +000051
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000052 def istest(self, predicate, exp):
53 obj = eval(exp)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000054 self.assertTrue(predicate(obj), '%s(%s)' % (predicate.__name__, exp))
Tim Peters5a9fb3c2005-01-07 16:01:32 +000055
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000056 for other in self.predicates - set([predicate]):
Christian Heimes7131fd92008-02-19 14:21:46 +000057 if predicate == inspect.isgeneratorfunction and\
58 other == inspect.isfunction:
59 continue
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000060 self.assertFalse(other(obj), 'not %s(%s)' % (other.__name__, exp))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000061
Christian Heimes7131fd92008-02-19 14:21:46 +000062def generator_function_example(self):
63 for i in range(2):
64 yield i
65
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000066class TestPredicates(IsTestBase):
Christian Heimes227c8002008-03-03 20:34:40 +000067 def test_sixteen(self):
Guido van Rossumc1f779c2007-07-03 08:25:58 +000068 count = len([x for x in dir(inspect) if x.startswith('is')])
Christian Heimes7131fd92008-02-19 14:21:46 +000069 # This test is here for remember you to update Doc/library/inspect.rst
Christian Heimes78644762008-03-04 23:39:23 +000070 # which claims there are 16 such functions
Christian Heimes227c8002008-03-03 20:34:40 +000071 expected = 16
Thomas Wouters0e3f5912006-08-11 14:57:12 +000072 err_msg = "There are %d (not %d) is* functions" % (count, expected)
73 self.assertEqual(count, expected, err_msg)
Tim Peters5a9fb3c2005-01-07 16:01:32 +000074
Christian Heimes7131fd92008-02-19 14:21:46 +000075
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000076 def test_excluding_predicates(self):
Antoine Pitroud5a1a212012-06-17 23:18:07 +020077 global tb
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000078 self.istest(inspect.isbuiltin, 'sys.exit')
79 self.istest(inspect.isbuiltin, '[].append')
Neal Norwitz221085d2007-02-25 20:55:47 +000080 self.istest(inspect.iscode, 'mod.spam.__code__')
Antoine Pitroud5a1a212012-06-17 23:18:07 +020081 try:
82 1/0
83 except:
84 tb = sys.exc_info()[2]
85 self.istest(inspect.isframe, 'tb.tb_frame')
86 self.istest(inspect.istraceback, 'tb')
87 if hasattr(types, 'GetSetDescriptorType'):
88 self.istest(inspect.isgetsetdescriptor,
89 'type(tb.tb_frame).f_locals')
90 else:
91 self.assertFalse(inspect.isgetsetdescriptor(type(tb.tb_frame).f_locals))
92 finally:
93 # Clear traceback and all the frames and local variables hanging to it.
94 tb = None
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000095 self.istest(inspect.isfunction, 'mod.spam')
Christian Heimes4a22b5d2007-11-25 09:39:14 +000096 self.istest(inspect.isfunction, 'mod.StupidGit.abuse')
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000097 self.istest(inspect.ismethod, 'git.argue')
98 self.istest(inspect.ismodule, 'mod')
Guido van Rossum813b0e52007-05-21 18:11:34 +000099 self.istest(inspect.isdatadescriptor, 'collections.defaultdict.default_factory')
Christian Heimes7131fd92008-02-19 14:21:46 +0000100 self.istest(inspect.isgenerator, '(x for x in range(2))')
101 self.istest(inspect.isgeneratorfunction, 'generator_function_example')
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000102 if hasattr(types, 'MemberDescriptorType'):
103 self.istest(inspect.ismemberdescriptor, 'datetime.timedelta.days')
104 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000105 self.assertFalse(inspect.ismemberdescriptor(datetime.timedelta.days))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000106
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000107 def test_isroutine(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000108 self.assertTrue(inspect.isroutine(mod.spam))
109 self.assertTrue(inspect.isroutine([].count))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000110
Benjamin Petersonc4656002009-01-17 22:41:18 +0000111 def test_isclass(self):
112 self.istest(inspect.isclass, 'mod.StupidGit')
113 self.assertTrue(inspect.isclass(list))
114
115 class CustomGetattr(object):
116 def __getattr__(self, attr):
117 return None
118 self.assertFalse(inspect.isclass(CustomGetattr()))
119
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000120 def test_get_slot_members(self):
121 class C(object):
122 __slots__ = ("a", "b")
123
124 x = C()
125 x.a = 42
126 members = dict(inspect.getmembers(x))
Benjamin Peterson577473f2010-01-19 00:09:57 +0000127 self.assertIn('a', members)
128 self.assertNotIn('b', members)
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000129
Benjamin Petersona0dfa822009-11-13 02:25:08 +0000130 def test_isabstract(self):
131 from abc import ABCMeta, abstractmethod
132
133 class AbstractClassExample(metaclass=ABCMeta):
134
135 @abstractmethod
136 def foo(self):
137 pass
138
139 class ClassExample(AbstractClassExample):
140 def foo(self):
141 pass
142
143 a = ClassExample()
144
145 # Test general behaviour.
146 self.assertTrue(inspect.isabstract(AbstractClassExample))
147 self.assertFalse(inspect.isabstract(ClassExample))
148 self.assertFalse(inspect.isabstract(a))
149 self.assertFalse(inspect.isabstract(int))
150 self.assertFalse(inspect.isabstract(5))
151
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000152
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000153class TestInterpreterStack(IsTestBase):
154 def __init__(self, *args, **kwargs):
155 unittest.TestCase.__init__(self, *args, **kwargs)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000156
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000157 git.abuse(7, 8, 9)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000158
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000159 def test_abuse_done(self):
160 self.istest(inspect.istraceback, 'git.ex[2]')
161 self.istest(inspect.isframe, 'mod.fr')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000162
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000163 def test_stack(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000164 self.assertTrue(len(mod.st) >= 5)
Christian Heimesa3538eb2007-11-06 11:44:48 +0000165 self.assertEqual(revise(*mod.st[0][1:]),
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000166 (modfile, 16, 'eggs', [' st = inspect.stack()\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000167 self.assertEqual(revise(*mod.st[1][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000168 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000169 self.assertEqual(revise(*mod.st[2][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000170 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000171 self.assertEqual(revise(*mod.st[3][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000172 (modfile, 39, 'abuse', [' self.argue(a, b, c)\n'], 0))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000173
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000174 def test_trace(self):
175 self.assertEqual(len(git.tr), 3)
Florent Xiclunac8575922010-03-24 17:37:49 +0000176 self.assertEqual(revise(*git.tr[0][1:]),
177 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
178 self.assertEqual(revise(*git.tr[1][1:]),
179 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
180 self.assertEqual(revise(*git.tr[2][1:]),
181 (modfile, 18, 'eggs', [' q = y / 0\n'], 0))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000182
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000183 def test_frame(self):
184 args, varargs, varkw, locals = inspect.getargvalues(mod.fr)
185 self.assertEqual(args, ['x', 'y'])
186 self.assertEqual(varargs, None)
187 self.assertEqual(varkw, None)
188 self.assertEqual(locals, {'x': 11, 'p': 11, 'y': 14})
189 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
190 '(x=11, y=14)')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000191
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000192 def test_previous_frame(self):
193 args, varargs, varkw, locals = inspect.getargvalues(mod.fr.f_back)
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000194 self.assertEqual(args, ['a', 'b', 'c', 'd', 'e', 'f'])
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000195 self.assertEqual(varargs, 'g')
196 self.assertEqual(varkw, 'h')
197 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000198 '(a=7, b=8, c=9, d=3, e=4, f=5, *g=(), **h={})')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000199
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000200class GetSourceBase(unittest.TestCase):
201 # Subclasses must override.
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000202 fodderModule = None
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000203
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000204 def __init__(self, *args, **kwargs):
205 unittest.TestCase.__init__(self, *args, **kwargs)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000206
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000207 with open(inspect.getsourcefile(self.fodderModule)) as fp:
Philip Jenveya27c5bd2009-05-28 06:09:08 +0000208 self.source = fp.read()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000209
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000210 def sourcerange(self, top, bottom):
211 lines = self.source.split("\n")
212 return "\n".join(lines[top-1:bottom]) + "\n"
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000213
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000214 def assertSourceEqual(self, obj, top, bottom):
215 self.assertEqual(inspect.getsource(obj),
216 self.sourcerange(top, bottom))
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000217
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000218class TestRetrievingSourceCode(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000219 fodderModule = mod
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000220
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000221 def test_getclasses(self):
222 classes = inspect.getmembers(mod, inspect.isclass)
223 self.assertEqual(classes,
224 [('FesteringGob', mod.FesteringGob),
225 ('MalodorousPervert', mod.MalodorousPervert),
226 ('ParrotDroppings', mod.ParrotDroppings),
Serhiy Storchaka362c1b52013-09-05 17:14:32 +0300227 ('StupidGit', mod.StupidGit),
228 ('Tit', mod.MalodorousPervert),
229 ])
230 tree = inspect.getclasstree([cls[1] for cls in classes])
231 self.assertEqual(tree,
232 [(object, ()),
233 [(mod.ParrotDroppings, (object,)),
234 [(mod.FesteringGob, (mod.MalodorousPervert,
235 mod.ParrotDroppings))
236 ],
237 (mod.StupidGit, (object,)),
238 [(mod.MalodorousPervert, (mod.StupidGit,)),
239 [(mod.FesteringGob, (mod.MalodorousPervert,
240 mod.ParrotDroppings))
241 ]
242 ]
243 ]
244 ])
245 tree = inspect.getclasstree([cls[1] for cls in classes], True)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000246 self.assertEqual(tree,
Thomas Wouters725af872006-04-15 09:13:19 +0000247 [(object, ()),
248 [(mod.ParrotDroppings, (object,)),
249 (mod.StupidGit, (object,)),
250 [(mod.MalodorousPervert, (mod.StupidGit,)),
251 [(mod.FesteringGob, (mod.MalodorousPervert,
252 mod.ParrotDroppings))
253 ]
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000254 ]
255 ]
256 ])
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000257
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000258 def test_getfunctions(self):
259 functions = inspect.getmembers(mod, inspect.isfunction)
260 self.assertEqual(functions, [('eggs', mod.eggs),
261 ('spam', mod.spam)])
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000262
R. David Murray378c0cf2010-02-24 01:46:21 +0000263 @unittest.skipIf(sys.flags.optimize >= 2,
264 "Docstrings are omitted with -O2 and above")
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000265 def test_getdoc(self):
266 self.assertEqual(inspect.getdoc(mod), 'A module docstring.')
267 self.assertEqual(inspect.getdoc(mod.StupidGit),
268 'A longer,\n\nindented\n\ndocstring.')
269 self.assertEqual(inspect.getdoc(git.abuse),
270 'Another\n\ndocstring\n\ncontaining\n\ntabs')
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000271
Georg Brandl0c77a822008-06-10 16:37:50 +0000272 def test_cleandoc(self):
273 self.assertEqual(inspect.cleandoc('An\n indented\n docstring.'),
274 'An\nindented\ndocstring.')
275
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000276 def test_getcomments(self):
277 self.assertEqual(inspect.getcomments(mod), '# line 1\n')
278 self.assertEqual(inspect.getcomments(mod.StupidGit), '# line 20\n')
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000279
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000280 def test_getmodule(self):
Thomas Wouters89f507f2006-12-13 04:49:30 +0000281 # Check actual module
282 self.assertEqual(inspect.getmodule(mod), mod)
283 # Check class (uses __module__ attribute)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000284 self.assertEqual(inspect.getmodule(mod.StupidGit), mod)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000285 # Check a method (no __module__ attribute, falls back to filename)
286 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
287 # Do it again (check the caching isn't broken)
288 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
289 # Check a builtin
Georg Brandl1a3284e2007-12-02 09:40:06 +0000290 self.assertEqual(inspect.getmodule(str), sys.modules["builtins"])
Thomas Wouters89f507f2006-12-13 04:49:30 +0000291 # Check filename override
292 self.assertEqual(inspect.getmodule(None, modfile), mod)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000293
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000294 def test_getsource(self):
295 self.assertSourceEqual(git.abuse, 29, 39)
296 self.assertSourceEqual(mod.StupidGit, 21, 46)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000297
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000298 def test_getsourcefile(self):
Christian Heimesa3538eb2007-11-06 11:44:48 +0000299 self.assertEqual(normcase(inspect.getsourcefile(mod.spam)), modfile)
300 self.assertEqual(normcase(inspect.getsourcefile(git.abuse)), modfile)
R. David Murraya1b37402010-06-17 02:04:29 +0000301 fn = "_non_existing_filename_used_for_sourcefile_test.py"
302 co = compile("None", fn, "exec")
R. David Murray4155f972010-06-17 13:23:18 +0000303 self.assertEqual(inspect.getsourcefile(co), None)
R. David Murraya1b37402010-06-17 02:04:29 +0000304 linecache.cache[co.co_filename] = (1, None, "None", co.co_filename)
Antoine Pitrou5d62a612012-07-08 13:48:46 +0200305 try:
306 self.assertEqual(normcase(inspect.getsourcefile(co)), fn)
307 finally:
308 del linecache.cache[co.co_filename]
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000309
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000310 def test_getfile(self):
311 self.assertEqual(inspect.getfile(mod.StupidGit), mod.__file__)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000312
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000313 def test_getmodule_recursion(self):
Christian Heimes45f9af32007-11-27 21:50:00 +0000314 from types import ModuleType
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000315 name = '__inspect_dummy'
Christian Heimes45f9af32007-11-27 21:50:00 +0000316 m = sys.modules[name] = ModuleType(name)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000317 m.__file__ = "<string>" # hopefully not a real filename...
318 m.__loader__ = "dummy" # pretend the filename is understood by a loader
Georg Brandl7cae87c2006-09-06 06:51:57 +0000319 exec("def x(): pass", m.__dict__)
Neal Norwitz221085d2007-02-25 20:55:47 +0000320 self.assertEqual(inspect.getsourcefile(m.x.__code__), '<string>')
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000321 del sys.modules[name]
322 inspect.getmodule(compile('a=10','','single'))
323
Benjamin Peterson9620cc02011-06-11 15:53:11 -0500324 def test_proceed_with_fake_filename(self):
325 '''doctest monkeypatches linecache to enable inspection'''
326 fn, source = '<test>', 'def x(): pass\n'
327 getlines = linecache.getlines
328 def monkey(filename, module_globals=None):
329 if filename == fn:
Ezio Melottid8b509b2011-09-28 17:37:55 +0300330 return source.splitlines(keepends=True)
Benjamin Peterson9620cc02011-06-11 15:53:11 -0500331 else:
332 return getlines(filename, module_globals)
333 linecache.getlines = monkey
334 try:
335 ns = {}
336 exec(compile(source, fn, 'single'), ns)
337 inspect.getsource(ns["x"])
338 finally:
339 linecache.getlines = getlines
340
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000341class TestDecorators(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000342 fodderModule = mod2
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000343
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000344 def test_wrapped_decorator(self):
Christian Heimes09aaa882008-02-23 15:01:06 +0000345 self.assertSourceEqual(mod2.wrapped, 14, 17)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000346
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000347 def test_replacing_decorator(self):
348 self.assertSourceEqual(mod2.gone, 9, 10)
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000349
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000350class TestOneliners(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000351 fodderModule = mod2
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000352 def test_oneline_lambda(self):
353 # Test inspect.getsource with a one-line lambda function.
354 self.assertSourceEqual(mod2.oll, 25, 25)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000355
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000356 def test_threeline_lambda(self):
357 # Test inspect.getsource with a three-line lambda function,
358 # where the second and third lines are _not_ indented.
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000359 self.assertSourceEqual(mod2.tll, 28, 30)
360
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000361 def test_twoline_indented_lambda(self):
362 # Test inspect.getsource with a two-line lambda function,
363 # where the second line _is_ indented.
364 self.assertSourceEqual(mod2.tlli, 33, 34)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000365
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000366 def test_onelinefunc(self):
367 # Test inspect.getsource with a regular one-line function.
368 self.assertSourceEqual(mod2.onelinefunc, 37, 37)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000369
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000370 def test_manyargs(self):
371 # Test inspect.getsource with a regular function where
372 # the arguments are on two lines and _not_ indented and
373 # the body on the second line with the last arguments.
374 self.assertSourceEqual(mod2.manyargs, 40, 41)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000375
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000376 def test_twolinefunc(self):
377 # Test inspect.getsource with a regular function where
378 # the body is on two lines, following the argument list and
379 # continued on the next line by a \\.
380 self.assertSourceEqual(mod2.twolinefunc, 44, 45)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000381
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000382 def test_lambda_in_list(self):
383 # Test inspect.getsource with a one-line lambda function
384 # defined in a list, indented.
385 self.assertSourceEqual(mod2.a[1], 49, 49)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000386
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000387 def test_anonymous(self):
388 # Test inspect.getsource with a lambda function defined
389 # as argument to another function.
390 self.assertSourceEqual(mod2.anonymous, 55, 55)
391
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000392class TestBuggyCases(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000393 fodderModule = mod2
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000394
395 def test_with_comment(self):
396 self.assertSourceEqual(mod2.with_comment, 58, 59)
397
398 def test_multiline_sig(self):
399 self.assertSourceEqual(mod2.multiline_sig[0], 63, 64)
400
Armin Rigodd5c0232005-09-25 11:45:45 +0000401 def test_nested_class(self):
402 self.assertSourceEqual(mod2.func69().func71, 71, 72)
403
404 def test_one_liner_followed_by_non_name(self):
405 self.assertSourceEqual(mod2.func77, 77, 77)
406
407 def test_one_liner_dedent_non_name(self):
408 self.assertSourceEqual(mod2.cls82.func83, 83, 83)
409
410 def test_with_comment_instead_of_docstring(self):
411 self.assertSourceEqual(mod2.func88, 88, 90)
412
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000413 def test_method_in_dynamic_class(self):
414 self.assertSourceEqual(mod2.method_in_dynamic_class, 95, 97)
415
R. David Murrayb5655772009-05-14 16:17:50 +0000416 @unittest.skipIf(
417 not hasattr(unicodedata, '__file__') or
418 unicodedata.__file__[-4:] in (".pyc", ".pyo"),
419 "unicodedata is not an external binary module")
R. David Murray74b89242009-05-13 17:33:03 +0000420 def test_findsource_binary(self):
R. David Murrayb5655772009-05-14 16:17:50 +0000421 self.assertRaises(IOError, inspect.getsource, unicodedata)
422 self.assertRaises(IOError, inspect.findsource, unicodedata)
R. David Murray74b89242009-05-13 17:33:03 +0000423
R. David Murraya1b37402010-06-17 02:04:29 +0000424 def test_findsource_code_in_linecache(self):
425 lines = ["x=1"]
426 co = compile(lines[0], "_dynamically_created_file", "exec")
427 self.assertRaises(IOError, inspect.findsource, co)
428 self.assertRaises(IOError, inspect.getsource, co)
429 linecache.cache[co.co_filename] = (1, None, lines, co.co_filename)
Antoine Pitrou5d62a612012-07-08 13:48:46 +0200430 try:
431 self.assertEqual(inspect.findsource(co), (lines,0))
432 self.assertEqual(inspect.getsource(co), lines[0])
433 finally:
434 del linecache.cache[co.co_filename]
R. David Murraya1b37402010-06-17 02:04:29 +0000435
Ezio Melotti1b145922013-03-30 05:17:24 +0200436 def test_findsource_without_filename(self):
437 for fname in ['', '<string>']:
438 co = compile('x=1', fname, "exec")
439 self.assertRaises(IOError, inspect.findsource, co)
440 self.assertRaises(IOError, inspect.getsource, co)
441
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000442class TestNoEOL(GetSourceBase):
443 def __init__(self, *args, **kwargs):
444 self.tempdir = TESTFN + '_dir'
445 os.mkdir(self.tempdir)
446 with open(os.path.join(self.tempdir,
447 'inspect_fodder3%spy' % os.extsep), 'w') as f:
448 f.write("class X:\n pass # No EOL")
449 with DirsOnSysPath(self.tempdir):
450 import inspect_fodder3 as mod3
451 self.fodderModule = mod3
452 GetSourceBase.__init__(self, *args, **kwargs)
453
454 def tearDown(self):
455 shutil.rmtree(self.tempdir)
456
457 def test_class(self):
458 self.assertSourceEqual(self.fodderModule.X, 1, 2)
459
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100460
461class _BrokenDataDescriptor(object):
462 """
463 A broken data descriptor. See bug #1785.
464 """
465 def __get__(*args):
466 raise AssertionError("should not __get__ data descriptors")
467
468 def __set__(*args):
469 raise RuntimeError
470
471 def __getattr__(*args):
472 raise AssertionError("should not __getattr__ data descriptors")
473
474
475class _BrokenMethodDescriptor(object):
476 """
477 A broken method descriptor. See bug #1785.
478 """
479 def __get__(*args):
480 raise AssertionError("should not __get__ method descriptors")
481
482 def __getattr__(*args):
483 raise AssertionError("should not __getattr__ method descriptors")
484
485
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000486# Helper for testing classify_class_attrs.
Tim Peters13b49d32001-09-23 02:00:29 +0000487def attrs_wo_objs(cls):
488 return [t[:3] for t in inspect.classify_class_attrs(cls)]
489
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100490
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000491class TestClassesAndFunctions(unittest.TestCase):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000492 def test_newstyle_mro(self):
493 # The same w/ new-class MRO.
494 class A(object): pass
495 class B(A): pass
496 class C(A): pass
497 class D(B, C): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000498
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000499 expected = (D, B, C, A, object)
500 got = inspect.getmro(D)
501 self.assertEqual(expected, got)
Tim Peters13b49d32001-09-23 02:00:29 +0000502
Christian Heimes3795b532007-11-08 13:48:53 +0000503 def assertArgSpecEquals(self, routine, args_e, varargs_e=None,
504 varkw_e=None, defaults_e=None, formatted=None):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000505 args, varargs, varkw, defaults = inspect.getargspec(routine)
506 self.assertEqual(args, args_e)
507 self.assertEqual(varargs, varargs_e)
508 self.assertEqual(varkw, varkw_e)
509 self.assertEqual(defaults, defaults_e)
510 if formatted is not None:
511 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults),
512 formatted)
Tim Peters13b49d32001-09-23 02:00:29 +0000513
Christian Heimes3795b532007-11-08 13:48:53 +0000514 def assertFullArgSpecEquals(self, routine, args_e, varargs_e=None,
515 varkw_e=None, defaults_e=None,
516 kwonlyargs_e=[], kwonlydefaults_e=None,
517 ann_e={}, formatted=None):
518 args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \
519 inspect.getfullargspec(routine)
520 self.assertEqual(args, args_e)
521 self.assertEqual(varargs, varargs_e)
522 self.assertEqual(varkw, varkw_e)
523 self.assertEqual(defaults, defaults_e)
524 self.assertEqual(kwonlyargs, kwonlyargs_e)
525 self.assertEqual(kwonlydefaults, kwonlydefaults_e)
526 self.assertEqual(ann, ann_e)
527 if formatted is not None:
528 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults,
529 kwonlyargs, kwonlydefaults, ann),
530 formatted)
531
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000532 def test_getargspec(self):
Christian Heimes3795b532007-11-08 13:48:53 +0000533 self.assertArgSpecEquals(mod.eggs, ['x', 'y'], formatted='(x, y)')
Tim Peters13b49d32001-09-23 02:00:29 +0000534
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000535 self.assertArgSpecEquals(mod.spam,
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000536 ['a', 'b', 'c', 'd', 'e', 'f'],
537 'g', 'h', (3, 4, 5),
538 '(a, b, c, d=3, e=4, f=5, *g, **h)')
Tim Peters13b49d32001-09-23 02:00:29 +0000539
Christian Heimes3795b532007-11-08 13:48:53 +0000540 self.assertRaises(ValueError, self.assertArgSpecEquals,
541 mod2.keyworded, [])
542
543 self.assertRaises(ValueError, self.assertArgSpecEquals,
544 mod2.annotated, [])
Benjamin Peterson9953a8d2009-01-17 04:15:01 +0000545 self.assertRaises(ValueError, self.assertArgSpecEquals,
546 mod2.keyword_only_arg, [])
547
Christian Heimes3795b532007-11-08 13:48:53 +0000548
549 def test_getfullargspec(self):
550 self.assertFullArgSpecEquals(mod2.keyworded, [], varargs_e='arg1',
551 kwonlyargs_e=['arg2'],
552 kwonlydefaults_e={'arg2':1},
553 formatted='(*arg1, arg2=1)')
554
555 self.assertFullArgSpecEquals(mod2.annotated, ['arg1'],
Christian Heimesc9543e42007-11-28 08:28:28 +0000556 ann_e={'arg1' : list},
Christian Heimes3795b532007-11-08 13:48:53 +0000557 formatted='(arg1: list)')
Benjamin Peterson9953a8d2009-01-17 04:15:01 +0000558 self.assertFullArgSpecEquals(mod2.keyword_only_arg, [],
559 kwonlyargs_e=['arg'],
560 formatted='(*, arg)')
561
Christian Heimes3795b532007-11-08 13:48:53 +0000562
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000563 def test_getargspec_method(self):
564 class A(object):
565 def m(self):
566 pass
567 self.assertArgSpecEquals(A.m, ['self'])
Tim Peters13b49d32001-09-23 02:00:29 +0000568
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000569 def test_classify_newstyle(self):
570 class A(object):
Tim Peters13b49d32001-09-23 02:00:29 +0000571
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000572 def s(): pass
573 s = staticmethod(s)
Tim Peters13b49d32001-09-23 02:00:29 +0000574
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000575 def c(cls): pass
576 c = classmethod(c)
Tim Peters13b49d32001-09-23 02:00:29 +0000577
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000578 def getp(self): pass
579 p = property(getp)
Tim Peters13b49d32001-09-23 02:00:29 +0000580
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000581 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000582
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000583 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000584
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000585 datablob = '1'
Tim Peters13b49d32001-09-23 02:00:29 +0000586
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100587 dd = _BrokenDataDescriptor()
588 md = _BrokenMethodDescriptor()
589
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000590 attrs = attrs_wo_objs(A)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000591 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
592 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
593 self.assertIn(('p', 'property', A), attrs, 'missing property')
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000594 self.assertIn(('m', 'method', A), attrs,
595 'missing plain method: %r' % attrs)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000596 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
597 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100598 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
599 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000600
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000601 class B(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000602
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000603 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000604
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000605 attrs = attrs_wo_objs(B)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000606 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
607 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
608 self.assertIn(('p', 'property', A), attrs, 'missing property')
609 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
610 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
611 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100612 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
613 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000614
615
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000616 class C(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000617
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000618 def m(self): pass
619 def c(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000620
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000621 attrs = attrs_wo_objs(C)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000622 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
623 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
624 self.assertIn(('p', 'property', A), attrs, 'missing property')
625 self.assertIn(('m', 'method', C), attrs, 'missing plain method')
626 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
627 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100628 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
629 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000630
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000631 class D(B, C):
Tim Peters13b49d32001-09-23 02:00:29 +0000632
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000633 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000634
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000635 attrs = attrs_wo_objs(D)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000636 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
637 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
638 self.assertIn(('p', 'property', A), attrs, 'missing property')
639 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
640 self.assertIn(('m1', 'method', D), attrs, 'missing plain method')
641 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100642 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
643 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
644
645 def test_classify_builtin_types(self):
646 # Simple sanity check that all built-in types can have their
647 # attributes classified.
648 for name in dir(__builtins__):
649 builtin = getattr(__builtins__, name)
650 if isinstance(builtin, type):
651 inspect.classify_class_attrs(builtin)
652
653 def test_getmembers_descriptors(self):
654 class A(object):
655 dd = _BrokenDataDescriptor()
656 md = _BrokenMethodDescriptor()
657
658 def pred_wrapper(pred):
659 # A quick'n'dirty way to discard standard attributes of new-style
660 # classes.
661 class Empty(object):
662 pass
663 def wrapped(x):
664 if '__name__' in dir(x) and hasattr(Empty, x.__name__):
665 return False
666 return pred(x)
667 return wrapped
668
669 ismethoddescriptor = pred_wrapper(inspect.ismethoddescriptor)
670 isdatadescriptor = pred_wrapper(inspect.isdatadescriptor)
671
672 self.assertEqual(inspect.getmembers(A, ismethoddescriptor),
673 [('md', A.__dict__['md'])])
674 self.assertEqual(inspect.getmembers(A, isdatadescriptor),
675 [('dd', A.__dict__['dd'])])
676
677 class B(A):
678 pass
679
680 self.assertEqual(inspect.getmembers(B, ismethoddescriptor),
681 [('md', A.__dict__['md'])])
682 self.assertEqual(inspect.getmembers(B, isdatadescriptor),
683 [('dd', A.__dict__['dd'])])
684
Antoine Pitrou0c603812012-01-18 17:40:18 +0100685 def test_getmembers_method(self):
686 class B:
687 def f(self):
688 pass
689
690 self.assertIn(('f', B.f), inspect.getmembers(B))
691 self.assertNotIn(('f', B.f), inspect.getmembers(B, inspect.ismethod))
692 b = B()
693 self.assertIn(('f', b.f), inspect.getmembers(b))
694 self.assertIn(('f', b.f), inspect.getmembers(b, inspect.ismethod))
695
Jeremy Hyltonc4bf5ed2003-06-27 18:43:12 +0000696
Nick Coghlan2f92e542012-06-23 19:39:55 +1000697_global_ref = object()
698class TestGetClosureVars(unittest.TestCase):
699
700 def test_name_resolution(self):
701 # Basic test of the 4 different resolution mechanisms
702 def f(nonlocal_ref):
703 def g(local_ref):
704 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
705 return g
706 _arg = object()
707 nonlocal_vars = {"nonlocal_ref": _arg}
708 global_vars = {"_global_ref": _global_ref}
709 builtin_vars = {"print": print}
710 unbound_names = {"unbound_ref"}
711 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
712 builtin_vars, unbound_names)
713 self.assertEqual(inspect.getclosurevars(f(_arg)), expected)
714
715 def test_generator_closure(self):
716 def f(nonlocal_ref):
717 def g(local_ref):
718 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
719 yield
720 return g
721 _arg = object()
722 nonlocal_vars = {"nonlocal_ref": _arg}
723 global_vars = {"_global_ref": _global_ref}
724 builtin_vars = {"print": print}
725 unbound_names = {"unbound_ref"}
726 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
727 builtin_vars, unbound_names)
728 self.assertEqual(inspect.getclosurevars(f(_arg)), expected)
729
730 def test_method_closure(self):
731 class C:
732 def f(self, nonlocal_ref):
733 def g(local_ref):
734 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
735 return g
736 _arg = object()
737 nonlocal_vars = {"nonlocal_ref": _arg}
738 global_vars = {"_global_ref": _global_ref}
739 builtin_vars = {"print": print}
740 unbound_names = {"unbound_ref"}
741 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
742 builtin_vars, unbound_names)
743 self.assertEqual(inspect.getclosurevars(C().f(_arg)), expected)
744
745 def test_nonlocal_vars(self):
746 # More complex tests of nonlocal resolution
747 def _nonlocal_vars(f):
748 return inspect.getclosurevars(f).nonlocals
749
750 def make_adder(x):
751 def add(y):
752 return x + y
753 return add
754
755 def curry(func, arg1):
756 return lambda arg2: func(arg1, arg2)
757
758 def less_than(a, b):
759 return a < b
760
761 # The infamous Y combinator.
762 def Y(le):
763 def g(f):
764 return le(lambda x: f(f)(x))
765 Y.g_ref = g
766 return g(g)
767
768 def check_y_combinator(func):
769 self.assertEqual(_nonlocal_vars(func), {'f': Y.g_ref})
770
771 inc = make_adder(1)
772 add_two = make_adder(2)
773 greater_than_five = curry(less_than, 5)
774
775 self.assertEqual(_nonlocal_vars(inc), {'x': 1})
776 self.assertEqual(_nonlocal_vars(add_two), {'x': 2})
777 self.assertEqual(_nonlocal_vars(greater_than_five),
778 {'arg1': 5, 'func': less_than})
779 self.assertEqual(_nonlocal_vars((lambda x: lambda y: x + y)(3)),
780 {'x': 3})
781 Y(check_y_combinator)
782
783 def test_getclosurevars_empty(self):
784 def foo(): pass
785 _empty = inspect.ClosureVars({}, {}, {}, set())
786 self.assertEqual(inspect.getclosurevars(lambda: True), _empty)
787 self.assertEqual(inspect.getclosurevars(foo), _empty)
788
789 def test_getclosurevars_error(self):
790 class T: pass
791 self.assertRaises(TypeError, inspect.getclosurevars, 1)
792 self.assertRaises(TypeError, inspect.getclosurevars, list)
793 self.assertRaises(TypeError, inspect.getclosurevars, {})
794
Nick Coghlan6c6e2542012-06-23 20:07:39 +1000795 def _private_globals(self):
796 code = """def f(): print(path)"""
797 ns = {}
798 exec(code, ns)
799 return ns["f"], ns
800
801 def test_builtins_fallback(self):
802 f, ns = self._private_globals()
803 ns.pop("__builtins__", None)
804 expected = inspect.ClosureVars({}, {}, {"print":print}, {"path"})
805 self.assertEqual(inspect.getclosurevars(f), expected)
806
807 def test_builtins_as_dict(self):
808 f, ns = self._private_globals()
809 ns["__builtins__"] = {"path":1}
810 expected = inspect.ClosureVars({}, {}, {"path":1}, {"print"})
811 self.assertEqual(inspect.getclosurevars(f), expected)
812
813 def test_builtins_as_module(self):
814 f, ns = self._private_globals()
815 ns["__builtins__"] = os
816 expected = inspect.ClosureVars({}, {}, {"path":os.path}, {"print"})
817 self.assertEqual(inspect.getclosurevars(f), expected)
818
Nick Coghlan2f92e542012-06-23 19:39:55 +1000819
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000820class TestGetcallargsFunctions(unittest.TestCase):
821
822 def assertEqualCallArgs(self, func, call_params_string, locs=None):
823 locs = dict(locs or {}, func=func)
824 r1 = eval('func(%s)' % call_params_string, None, locs)
825 r2 = eval('inspect.getcallargs(func, %s)' % call_params_string, None,
826 locs)
827 self.assertEqual(r1, r2)
828
829 def assertEqualException(self, func, call_param_string, locs=None):
830 locs = dict(locs or {}, func=func)
831 try:
832 eval('func(%s)' % call_param_string, None, locs)
833 except Exception as e:
834 ex1 = e
835 else:
836 self.fail('Exception not raised')
837 try:
838 eval('inspect.getcallargs(func, %s)' % call_param_string, None,
839 locs)
840 except Exception as e:
841 ex2 = e
842 else:
843 self.fail('Exception not raised')
844 self.assertIs(type(ex1), type(ex2))
845 self.assertEqual(str(ex1), str(ex2))
846 del ex1, ex2
847
848 def makeCallable(self, signature):
849 """Create a function that returns its locals()"""
850 code = "lambda %s: locals()"
851 return eval(code % signature)
852
853 def test_plain(self):
854 f = self.makeCallable('a, b=1')
855 self.assertEqualCallArgs(f, '2')
856 self.assertEqualCallArgs(f, '2, 3')
857 self.assertEqualCallArgs(f, 'a=2')
858 self.assertEqualCallArgs(f, 'b=3, a=2')
859 self.assertEqualCallArgs(f, '2, b=3')
860 # expand *iterable / **mapping
861 self.assertEqualCallArgs(f, '*(2,)')
862 self.assertEqualCallArgs(f, '*[2]')
863 self.assertEqualCallArgs(f, '*(2, 3)')
864 self.assertEqualCallArgs(f, '*[2, 3]')
865 self.assertEqualCallArgs(f, '**{"a":2}')
866 self.assertEqualCallArgs(f, 'b=3, **{"a":2}')
867 self.assertEqualCallArgs(f, '2, **{"b":3}')
868 self.assertEqualCallArgs(f, '**{"b":3, "a":2}')
869 # expand UserList / UserDict
870 self.assertEqualCallArgs(f, '*collections.UserList([2])')
871 self.assertEqualCallArgs(f, '*collections.UserList([2, 3])')
872 self.assertEqualCallArgs(f, '**collections.UserDict(a=2)')
873 self.assertEqualCallArgs(f, '2, **collections.UserDict(b=3)')
874 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3)')
875
876 def test_varargs(self):
877 f = self.makeCallable('a, b=1, *c')
878 self.assertEqualCallArgs(f, '2')
879 self.assertEqualCallArgs(f, '2, 3')
880 self.assertEqualCallArgs(f, '2, 3, 4')
881 self.assertEqualCallArgs(f, '*(2,3,4)')
882 self.assertEqualCallArgs(f, '2, *[3,4]')
883 self.assertEqualCallArgs(f, '2, 3, *collections.UserList([4])')
884
885 def test_varkw(self):
886 f = self.makeCallable('a, b=1, **c')
887 self.assertEqualCallArgs(f, 'a=2')
888 self.assertEqualCallArgs(f, '2, b=3, c=4')
889 self.assertEqualCallArgs(f, 'b=3, a=2, c=4')
890 self.assertEqualCallArgs(f, 'c=4, **{"a":2, "b":3}')
891 self.assertEqualCallArgs(f, '2, c=4, **{"b":3}')
892 self.assertEqualCallArgs(f, 'b=2, **{"a":3, "c":4}')
893 self.assertEqualCallArgs(f, '**collections.UserDict(a=2, b=3, c=4)')
894 self.assertEqualCallArgs(f, '2, c=4, **collections.UserDict(b=3)')
895 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3, c=4)')
896
Benjamin Peterson6a2638b2011-03-28 17:32:31 -0500897 def test_varkw_only(self):
898 # issue11256:
899 f = self.makeCallable('**c')
900 self.assertEqualCallArgs(f, '')
901 self.assertEqualCallArgs(f, 'a=1')
902 self.assertEqualCallArgs(f, 'a=1, b=2')
903 self.assertEqualCallArgs(f, 'c=3, **{"a": 1, "b": 2}')
904 self.assertEqualCallArgs(f, '**collections.UserDict(a=1, b=2)')
905 self.assertEqualCallArgs(f, 'c=3, **collections.UserDict(a=1, b=2)')
906
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000907 def test_keyword_only(self):
908 f = self.makeCallable('a=3, *, c, d=2')
909 self.assertEqualCallArgs(f, 'c=3')
910 self.assertEqualCallArgs(f, 'c=3, a=3')
911 self.assertEqualCallArgs(f, 'a=2, c=4')
912 self.assertEqualCallArgs(f, '4, c=4')
913 self.assertEqualException(f, '')
914 self.assertEqualException(f, '3')
915 self.assertEqualException(f, 'a=3')
916 self.assertEqualException(f, 'd=4')
917
Benjamin Peterson6a2638b2011-03-28 17:32:31 -0500918 f = self.makeCallable('*, c, d=2')
919 self.assertEqualCallArgs(f, 'c=3')
920 self.assertEqualCallArgs(f, 'c=3, d=4')
921 self.assertEqualCallArgs(f, 'd=4, c=3')
922
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000923 def test_multiple_features(self):
924 f = self.makeCallable('a, b=2, *f, **g')
925 self.assertEqualCallArgs(f, '2, 3, 7')
926 self.assertEqualCallArgs(f, '2, 3, x=8')
927 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
928 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9')
929 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9')
930 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
931 '[2, 3, (4,[5,6])]), **{"y":9, "z":10}')
932 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
933 '(4,[5,6])]), **collections.UserDict('
934 'y=9, z=10)')
935
Benjamin Peterson6a2638b2011-03-28 17:32:31 -0500936 f = self.makeCallable('a, b=2, *f, x, y=99, **g')
937 self.assertEqualCallArgs(f, '2, 3, x=8')
938 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
939 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9, z=10')
940 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9, z=10')
941 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
942 '[2, 3, (4,[5,6])]), q=0, **{"y":9, "z":10}')
943 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
944 '(4,[5,6])]), q=0, **collections.UserDict('
945 'y=9, z=10)')
946
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000947 def test_errors(self):
948 f0 = self.makeCallable('')
949 f1 = self.makeCallable('a, b')
950 f2 = self.makeCallable('a, b=1')
951 # f0 takes no arguments
952 self.assertEqualException(f0, '1')
953 self.assertEqualException(f0, 'x=1')
954 self.assertEqualException(f0, '1,x=1')
955 # f1 takes exactly 2 arguments
956 self.assertEqualException(f1, '')
957 self.assertEqualException(f1, '1')
958 self.assertEqualException(f1, 'a=2')
959 self.assertEqualException(f1, 'b=3')
960 # f2 takes at least 1 argument
961 self.assertEqualException(f2, '')
962 self.assertEqualException(f2, 'b=3')
963 for f in f1, f2:
964 # f1/f2 takes exactly/at most 2 arguments
965 self.assertEqualException(f, '2, 3, 4')
966 self.assertEqualException(f, '1, 2, 3, a=1')
967 self.assertEqualException(f, '2, 3, 4, c=5')
Georg Brandl178e5ea2012-02-21 00:32:36 +0100968 # XXX: success of this one depends on dict order
969 ## self.assertEqualException(f, '2, 3, 4, a=1, c=5')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000970 # f got an unexpected keyword argument
971 self.assertEqualException(f, 'c=2')
972 self.assertEqualException(f, '2, c=3')
973 self.assertEqualException(f, '2, 3, c=4')
974 self.assertEqualException(f, '2, c=4, b=3')
975 self.assertEqualException(f, '**{u"\u03c0\u03b9": 4}')
976 # f got multiple values for keyword argument
977 self.assertEqualException(f, '1, a=2')
978 self.assertEqualException(f, '1, **{"a":2}')
979 self.assertEqualException(f, '1, 2, b=3')
980 # XXX: Python inconsistency
981 # - for functions and bound methods: unexpected keyword 'c'
982 # - for unbound methods: multiple values for keyword 'a'
983 #self.assertEqualException(f, '1, c=3, a=2')
Benjamin Peterson6a2638b2011-03-28 17:32:31 -0500984 # issue11256:
985 f3 = self.makeCallable('**c')
986 self.assertEqualException(f3, '1, 2')
987 self.assertEqualException(f3, '1, 2, a=1, b=2')
988 f4 = self.makeCallable('*, a, b=0')
989 self.assertEqualException(f3, '1, 2')
990 self.assertEqualException(f3, '1, 2, a=1, b=2')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000991
992class TestGetcallargsMethods(TestGetcallargsFunctions):
993
994 def setUp(self):
995 class Foo(object):
996 pass
997 self.cls = Foo
998 self.inst = Foo()
999
1000 def makeCallable(self, signature):
1001 assert 'self' not in signature
1002 mk = super(TestGetcallargsMethods, self).makeCallable
1003 self.cls.method = mk('self, ' + signature)
1004 return self.inst.method
1005
1006class TestGetcallargsUnboundMethods(TestGetcallargsMethods):
1007
1008 def makeCallable(self, signature):
1009 super(TestGetcallargsUnboundMethods, self).makeCallable(signature)
1010 return self.cls.method
1011
1012 def assertEqualCallArgs(self, func, call_params_string, locs=None):
1013 return super(TestGetcallargsUnboundMethods, self).assertEqualCallArgs(
1014 *self._getAssertEqualParams(func, call_params_string, locs))
1015
1016 def assertEqualException(self, func, call_params_string, locs=None):
1017 return super(TestGetcallargsUnboundMethods, self).assertEqualException(
1018 *self._getAssertEqualParams(func, call_params_string, locs))
1019
1020 def _getAssertEqualParams(self, func, call_params_string, locs=None):
1021 assert 'inst' not in call_params_string
1022 locs = dict(locs or {}, inst=self.inst)
1023 return (func, 'inst,' + call_params_string, locs)
1024
Michael Foord95fc51d2010-11-20 15:07:30 +00001025
1026class TestGetattrStatic(unittest.TestCase):
1027
1028 def test_basic(self):
1029 class Thing(object):
1030 x = object()
1031
1032 thing = Thing()
1033 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1034 self.assertEqual(inspect.getattr_static(thing, 'x', None), Thing.x)
1035 with self.assertRaises(AttributeError):
1036 inspect.getattr_static(thing, 'y')
1037
1038 self.assertEqual(inspect.getattr_static(thing, 'y', 3), 3)
1039
1040 def test_inherited(self):
1041 class Thing(object):
1042 x = object()
1043 class OtherThing(Thing):
1044 pass
1045
1046 something = OtherThing()
1047 self.assertEqual(inspect.getattr_static(something, 'x'), Thing.x)
1048
1049 def test_instance_attr(self):
1050 class Thing(object):
1051 x = 2
1052 def __init__(self, x):
1053 self.x = x
1054 thing = Thing(3)
1055 self.assertEqual(inspect.getattr_static(thing, 'x'), 3)
1056 del thing.x
1057 self.assertEqual(inspect.getattr_static(thing, 'x'), 2)
1058
1059 def test_property(self):
1060 class Thing(object):
1061 @property
1062 def x(self):
1063 raise AttributeError("I'm pretending not to exist")
1064 thing = Thing()
1065 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1066
Ezio Melotti75cbd732011-04-28 00:59:29 +03001067 def test_descriptor_raises_AttributeError(self):
Michael Foord95fc51d2010-11-20 15:07:30 +00001068 class descriptor(object):
1069 def __get__(*_):
1070 raise AttributeError("I'm pretending not to exist")
1071 desc = descriptor()
1072 class Thing(object):
1073 x = desc
1074 thing = Thing()
1075 self.assertEqual(inspect.getattr_static(thing, 'x'), desc)
1076
1077 def test_classAttribute(self):
1078 class Thing(object):
1079 x = object()
1080
1081 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.x)
1082
1083 def test_inherited_classattribute(self):
1084 class Thing(object):
1085 x = object()
1086 class OtherThing(Thing):
1087 pass
1088
1089 self.assertEqual(inspect.getattr_static(OtherThing, 'x'), Thing.x)
1090
1091 def test_slots(self):
1092 class Thing(object):
1093 y = 'bar'
1094 __slots__ = ['x']
1095 def __init__(self):
1096 self.x = 'foo'
1097 thing = Thing()
1098 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1099 self.assertEqual(inspect.getattr_static(thing, 'y'), 'bar')
1100
1101 del thing.x
1102 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1103
1104 def test_metaclass(self):
1105 class meta(type):
1106 attr = 'foo'
1107 class Thing(object, metaclass=meta):
1108 pass
1109 self.assertEqual(inspect.getattr_static(Thing, 'attr'), 'foo')
1110
1111 class sub(meta):
1112 pass
1113 class OtherThing(object, metaclass=sub):
1114 x = 3
1115 self.assertEqual(inspect.getattr_static(OtherThing, 'attr'), 'foo')
1116
1117 class OtherOtherThing(OtherThing):
1118 pass
1119 # this test is odd, but it was added as it exposed a bug
1120 self.assertEqual(inspect.getattr_static(OtherOtherThing, 'x'), 3)
1121
1122 def test_no_dict_no_slots(self):
1123 self.assertEqual(inspect.getattr_static(1, 'foo', None), None)
1124 self.assertNotEqual(inspect.getattr_static('foo', 'lower'), None)
1125
1126 def test_no_dict_no_slots_instance_member(self):
1127 # returns descriptor
1128 with open(__file__) as handle:
1129 self.assertEqual(inspect.getattr_static(handle, 'name'), type(handle).name)
1130
1131 def test_inherited_slots(self):
1132 # returns descriptor
1133 class Thing(object):
1134 __slots__ = ['x']
1135 def __init__(self):
1136 self.x = 'foo'
1137
1138 class OtherThing(Thing):
1139 pass
1140 # it would be nice if this worked...
1141 # we get the descriptor instead of the instance attribute
1142 self.assertEqual(inspect.getattr_static(OtherThing(), 'x'), Thing.x)
1143
1144 def test_descriptor(self):
1145 class descriptor(object):
1146 def __get__(self, instance, owner):
1147 return 3
1148 class Foo(object):
1149 d = descriptor()
1150
1151 foo = Foo()
1152
1153 # for a non data descriptor we return the instance attribute
1154 foo.__dict__['d'] = 1
1155 self.assertEqual(inspect.getattr_static(foo, 'd'), 1)
1156
1157 # if the descriptor is a data-desciptor we should return the
1158 # descriptor
1159 descriptor.__set__ = lambda s, i, v: None
1160 self.assertEqual(inspect.getattr_static(foo, 'd'), Foo.__dict__['d'])
1161
1162
1163 def test_metaclass_with_descriptor(self):
1164 class descriptor(object):
1165 def __get__(self, instance, owner):
1166 return 3
1167 class meta(type):
1168 d = descriptor()
1169 class Thing(object, metaclass=meta):
1170 pass
1171 self.assertEqual(inspect.getattr_static(Thing, 'd'), meta.__dict__['d'])
1172
1173
Michael Foordcc7ebb82010-11-20 16:20:16 +00001174 def test_class_as_property(self):
1175 class Base(object):
1176 foo = 3
1177
1178 class Something(Base):
Michael Foord35184ed2010-11-20 16:58:30 +00001179 executed = False
Michael Foordcc7ebb82010-11-20 16:20:16 +00001180 @property
1181 def __class__(self):
Michael Foord35184ed2010-11-20 16:58:30 +00001182 self.executed = True
Michael Foordcc7ebb82010-11-20 16:20:16 +00001183 return object
1184
Michael Foord35184ed2010-11-20 16:58:30 +00001185 instance = Something()
1186 self.assertEqual(inspect.getattr_static(instance, 'foo'), 3)
1187 self.assertFalse(instance.executed)
Michael Foordcc7ebb82010-11-20 16:20:16 +00001188 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1189
Michael Foorde5162652010-11-20 16:40:44 +00001190 def test_mro_as_property(self):
1191 class Meta(type):
1192 @property
1193 def __mro__(self):
1194 return (object,)
1195
1196 class Base(object):
1197 foo = 3
1198
1199 class Something(Base, metaclass=Meta):
1200 pass
1201
1202 self.assertEqual(inspect.getattr_static(Something(), 'foo'), 3)
1203 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1204
Michael Foorddcebe0f2011-03-15 19:20:44 -04001205 def test_dict_as_property(self):
1206 test = self
1207 test.called = False
1208
1209 class Foo(dict):
1210 a = 3
1211 @property
1212 def __dict__(self):
1213 test.called = True
1214 return {}
1215
1216 foo = Foo()
1217 foo.a = 4
1218 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1219 self.assertFalse(test.called)
1220
1221 def test_custom_object_dict(self):
1222 test = self
1223 test.called = False
1224
1225 class Custom(dict):
1226 def get(self, key, default=None):
1227 test.called = True
1228 super().get(key, default)
1229
1230 class Foo(object):
1231 a = 3
1232 foo = Foo()
1233 foo.__dict__ = Custom()
1234 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1235 self.assertFalse(test.called)
1236
1237 def test_metaclass_dict_as_property(self):
1238 class Meta(type):
1239 @property
1240 def __dict__(self):
1241 self.executed = True
1242
1243 class Thing(metaclass=Meta):
1244 executed = False
1245
1246 def __init__(self):
1247 self.spam = 42
1248
1249 instance = Thing()
1250 self.assertEqual(inspect.getattr_static(instance, "spam"), 42)
1251 self.assertFalse(Thing.executed)
Michael Foorde5162652010-11-20 16:40:44 +00001252
Michael Foorda51623b2011-12-18 22:01:40 +00001253 def test_module(self):
1254 sentinel = object()
1255 self.assertIsNot(inspect.getattr_static(sys, "version", sentinel),
1256 sentinel)
1257
Michael Foord3ba95f82011-12-22 01:13:37 +00001258 def test_metaclass_with_metaclass_with_dict_as_property(self):
1259 class MetaMeta(type):
1260 @property
1261 def __dict__(self):
1262 self.executed = True
1263 return dict(spam=42)
1264
1265 class Meta(type, metaclass=MetaMeta):
1266 executed = False
1267
1268 class Thing(metaclass=Meta):
1269 pass
1270
1271 with self.assertRaises(AttributeError):
1272 inspect.getattr_static(Thing, "spam")
1273 self.assertFalse(Thing.executed)
1274
Nick Coghlane0f04652010-11-21 03:44:04 +00001275class TestGetGeneratorState(unittest.TestCase):
1276
1277 def setUp(self):
1278 def number_generator():
1279 for number in range(5):
1280 yield number
1281 self.generator = number_generator()
1282
1283 def _generatorstate(self):
1284 return inspect.getgeneratorstate(self.generator)
1285
1286 def test_created(self):
1287 self.assertEqual(self._generatorstate(), inspect.GEN_CREATED)
1288
1289 def test_suspended(self):
1290 next(self.generator)
1291 self.assertEqual(self._generatorstate(), inspect.GEN_SUSPENDED)
1292
1293 def test_closed_after_exhaustion(self):
1294 for i in self.generator:
1295 pass
1296 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1297
1298 def test_closed_after_immediate_exception(self):
1299 with self.assertRaises(RuntimeError):
1300 self.generator.throw(RuntimeError)
1301 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1302
1303 def test_running(self):
1304 # As mentioned on issue #10220, checking for the RUNNING state only
1305 # makes sense inside the generator itself.
1306 # The following generator checks for this by using the closure's
1307 # reference to self and the generator state checking helper method
1308 def running_check_generator():
1309 for number in range(5):
1310 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1311 yield number
1312 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1313 self.generator = running_check_generator()
1314 # Running up to the first yield
1315 next(self.generator)
1316 # Running after the first yield
1317 next(self.generator)
1318
Nick Coghlan7921b9f2010-11-30 06:36:04 +00001319 def test_easy_debugging(self):
1320 # repr() and str() of a generator state should contain the state name
1321 names = 'GEN_CREATED GEN_RUNNING GEN_SUSPENDED GEN_CLOSED'.split()
1322 for name in names:
1323 state = getattr(inspect, name)
1324 self.assertIn(name, repr(state))
1325 self.assertIn(name, str(state))
1326
Nick Coghlan04e2e3f2012-06-23 19:52:05 +10001327 def test_getgeneratorlocals(self):
1328 def each(lst, a=None):
1329 b=(1, 2, 3)
1330 for v in lst:
1331 if v == 3:
1332 c = 12
1333 yield v
1334
1335 numbers = each([1, 2, 3])
1336 self.assertEqual(inspect.getgeneratorlocals(numbers),
1337 {'a': None, 'lst': [1, 2, 3]})
1338 next(numbers)
1339 self.assertEqual(inspect.getgeneratorlocals(numbers),
1340 {'a': None, 'lst': [1, 2, 3], 'v': 1,
1341 'b': (1, 2, 3)})
1342 next(numbers)
1343 self.assertEqual(inspect.getgeneratorlocals(numbers),
1344 {'a': None, 'lst': [1, 2, 3], 'v': 2,
1345 'b': (1, 2, 3)})
1346 next(numbers)
1347 self.assertEqual(inspect.getgeneratorlocals(numbers),
1348 {'a': None, 'lst': [1, 2, 3], 'v': 3,
1349 'b': (1, 2, 3), 'c': 12})
1350 try:
1351 next(numbers)
1352 except StopIteration:
1353 pass
1354 self.assertEqual(inspect.getgeneratorlocals(numbers), {})
1355
1356 def test_getgeneratorlocals_empty(self):
1357 def yield_one():
1358 yield 1
1359 one = yield_one()
1360 self.assertEqual(inspect.getgeneratorlocals(one), {})
1361 try:
1362 next(one)
1363 except StopIteration:
1364 pass
1365 self.assertEqual(inspect.getgeneratorlocals(one), {})
1366
1367 def test_getgeneratorlocals_error(self):
1368 self.assertRaises(TypeError, inspect.getgeneratorlocals, 1)
1369 self.assertRaises(TypeError, inspect.getgeneratorlocals, lambda x: True)
1370 self.assertRaises(TypeError, inspect.getgeneratorlocals, set)
1371 self.assertRaises(TypeError, inspect.getgeneratorlocals, (2,3))
1372
Nick Coghlane0f04652010-11-21 03:44:04 +00001373
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001374class TestSignatureObject(unittest.TestCase):
1375 @staticmethod
1376 def signature(func):
1377 sig = inspect.signature(func)
1378 return (tuple((param.name,
1379 (... if param.default is param.empty else param.default),
1380 (... if param.annotation is param.empty
1381 else param.annotation),
1382 str(param.kind).lower())
1383 for param in sig.parameters.values()),
1384 (... if sig.return_annotation is sig.empty
1385 else sig.return_annotation))
1386
1387 def test_signature_object(self):
1388 S = inspect.Signature
1389 P = inspect.Parameter
1390
1391 self.assertEqual(str(S()), '()')
1392
1393 def test(po, pk, *args, ko, **kwargs):
1394 pass
1395 sig = inspect.signature(test)
1396 po = sig.parameters['po'].replace(kind=P.POSITIONAL_ONLY)
1397 pk = sig.parameters['pk']
1398 args = sig.parameters['args']
1399 ko = sig.parameters['ko']
1400 kwargs = sig.parameters['kwargs']
1401
1402 S((po, pk, args, ko, kwargs))
1403
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001404 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001405 S((pk, po, args, ko, kwargs))
1406
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001407 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001408 S((po, args, pk, ko, kwargs))
1409
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001410 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001411 S((args, po, pk, ko, kwargs))
1412
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001413 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001414 S((po, pk, args, kwargs, ko))
1415
1416 kwargs2 = kwargs.replace(name='args')
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001417 with self.assertRaisesRegex(ValueError, 'duplicate parameter name'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001418 S((po, pk, args, kwargs2, ko))
1419
1420 def test_signature_immutability(self):
1421 def test(a):
1422 pass
1423 sig = inspect.signature(test)
1424
1425 with self.assertRaises(AttributeError):
1426 sig.foo = 'bar'
1427
1428 with self.assertRaises(TypeError):
1429 sig.parameters['a'] = None
1430
1431 def test_signature_on_noarg(self):
1432 def test():
1433 pass
1434 self.assertEqual(self.signature(test), ((), ...))
1435
1436 def test_signature_on_wargs(self):
1437 def test(a, b:'foo') -> 123:
1438 pass
1439 self.assertEqual(self.signature(test),
1440 ((('a', ..., ..., "positional_or_keyword"),
1441 ('b', ..., 'foo', "positional_or_keyword")),
1442 123))
1443
1444 def test_signature_on_wkwonly(self):
1445 def test(*, a:float, b:str) -> int:
1446 pass
1447 self.assertEqual(self.signature(test),
1448 ((('a', ..., float, "keyword_only"),
1449 ('b', ..., str, "keyword_only")),
1450 int))
1451
1452 def test_signature_on_complex_args(self):
1453 def test(a, b:'foo'=10, *args:'bar', spam:'baz', ham=123, **kwargs:int):
1454 pass
1455 self.assertEqual(self.signature(test),
1456 ((('a', ..., ..., "positional_or_keyword"),
1457 ('b', 10, 'foo', "positional_or_keyword"),
1458 ('args', ..., 'bar', "var_positional"),
1459 ('spam', ..., 'baz', "keyword_only"),
1460 ('ham', 123, ..., "keyword_only"),
1461 ('kwargs', ..., int, "var_keyword")),
1462 ...))
1463
1464 def test_signature_on_builtin_function(self):
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001465 with self.assertRaisesRegex(ValueError, 'not supported by signature'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001466 inspect.signature(type)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001467 with self.assertRaisesRegex(ValueError, 'not supported by signature'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001468 # support for 'wrapper_descriptor'
1469 inspect.signature(type.__call__)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001470 with self.assertRaisesRegex(ValueError, 'not supported by signature'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001471 # support for 'method-wrapper'
1472 inspect.signature(min.__call__)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001473 with self.assertRaisesRegex(ValueError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001474 'no signature found for builtin function'):
1475 # support for 'method-wrapper'
1476 inspect.signature(min)
1477
1478 def test_signature_on_non_function(self):
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001479 with self.assertRaisesRegex(TypeError, 'is not a callable object'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001480 inspect.signature(42)
1481
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001482 with self.assertRaisesRegex(TypeError, 'is not a Python function'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001483 inspect.Signature.from_function(42)
1484
1485 def test_signature_on_method(self):
1486 class Test:
1487 def foo(self, arg1, arg2=1) -> int:
1488 pass
1489
1490 meth = Test().foo
1491
1492 self.assertEqual(self.signature(meth),
1493 ((('arg1', ..., ..., "positional_or_keyword"),
1494 ('arg2', 1, ..., "positional_or_keyword")),
1495 int))
1496
1497 def test_signature_on_classmethod(self):
1498 class Test:
1499 @classmethod
1500 def foo(cls, arg1, *, arg2=1):
1501 pass
1502
1503 meth = Test().foo
1504 self.assertEqual(self.signature(meth),
1505 ((('arg1', ..., ..., "positional_or_keyword"),
1506 ('arg2', 1, ..., "keyword_only")),
1507 ...))
1508
1509 meth = Test.foo
1510 self.assertEqual(self.signature(meth),
1511 ((('arg1', ..., ..., "positional_or_keyword"),
1512 ('arg2', 1, ..., "keyword_only")),
1513 ...))
1514
1515 def test_signature_on_staticmethod(self):
1516 class Test:
1517 @staticmethod
1518 def foo(cls, *, arg):
1519 pass
1520
1521 meth = Test().foo
1522 self.assertEqual(self.signature(meth),
1523 ((('cls', ..., ..., "positional_or_keyword"),
1524 ('arg', ..., ..., "keyword_only")),
1525 ...))
1526
1527 meth = Test.foo
1528 self.assertEqual(self.signature(meth),
1529 ((('cls', ..., ..., "positional_or_keyword"),
1530 ('arg', ..., ..., "keyword_only")),
1531 ...))
1532
1533 def test_signature_on_partial(self):
1534 from functools import partial
1535
1536 def test():
1537 pass
1538
1539 self.assertEqual(self.signature(partial(test)), ((), ...))
1540
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001541 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001542 inspect.signature(partial(test, 1))
1543
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001544 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001545 inspect.signature(partial(test, a=1))
1546
1547 def test(a, b, *, c, d):
1548 pass
1549
1550 self.assertEqual(self.signature(partial(test)),
1551 ((('a', ..., ..., "positional_or_keyword"),
1552 ('b', ..., ..., "positional_or_keyword"),
1553 ('c', ..., ..., "keyword_only"),
1554 ('d', ..., ..., "keyword_only")),
1555 ...))
1556
1557 self.assertEqual(self.signature(partial(test, 1)),
1558 ((('b', ..., ..., "positional_or_keyword"),
1559 ('c', ..., ..., "keyword_only"),
1560 ('d', ..., ..., "keyword_only")),
1561 ...))
1562
1563 self.assertEqual(self.signature(partial(test, 1, c=2)),
1564 ((('b', ..., ..., "positional_or_keyword"),
1565 ('c', 2, ..., "keyword_only"),
1566 ('d', ..., ..., "keyword_only")),
1567 ...))
1568
1569 self.assertEqual(self.signature(partial(test, b=1, c=2)),
1570 ((('a', ..., ..., "positional_or_keyword"),
1571 ('b', 1, ..., "positional_or_keyword"),
1572 ('c', 2, ..., "keyword_only"),
1573 ('d', ..., ..., "keyword_only")),
1574 ...))
1575
1576 self.assertEqual(self.signature(partial(test, 0, b=1, c=2)),
1577 ((('b', 1, ..., "positional_or_keyword"),
1578 ('c', 2, ..., "keyword_only"),
1579 ('d', ..., ..., "keyword_only"),),
1580 ...))
1581
1582 def test(a, *args, b, **kwargs):
1583 pass
1584
1585 self.assertEqual(self.signature(partial(test, 1)),
1586 ((('args', ..., ..., "var_positional"),
1587 ('b', ..., ..., "keyword_only"),
1588 ('kwargs', ..., ..., "var_keyword")),
1589 ...))
1590
1591 self.assertEqual(self.signature(partial(test, 1, 2, 3)),
1592 ((('args', ..., ..., "var_positional"),
1593 ('b', ..., ..., "keyword_only"),
1594 ('kwargs', ..., ..., "var_keyword")),
1595 ...))
1596
1597
1598 self.assertEqual(self.signature(partial(test, 1, 2, 3, test=True)),
1599 ((('args', ..., ..., "var_positional"),
1600 ('b', ..., ..., "keyword_only"),
1601 ('kwargs', ..., ..., "var_keyword")),
1602 ...))
1603
1604 self.assertEqual(self.signature(partial(test, 1, 2, 3, test=1, b=0)),
1605 ((('args', ..., ..., "var_positional"),
1606 ('b', 0, ..., "keyword_only"),
1607 ('kwargs', ..., ..., "var_keyword")),
1608 ...))
1609
1610 self.assertEqual(self.signature(partial(test, b=0)),
1611 ((('a', ..., ..., "positional_or_keyword"),
1612 ('args', ..., ..., "var_positional"),
1613 ('b', 0, ..., "keyword_only"),
1614 ('kwargs', ..., ..., "var_keyword")),
1615 ...))
1616
1617 self.assertEqual(self.signature(partial(test, b=0, test=1)),
1618 ((('a', ..., ..., "positional_or_keyword"),
1619 ('args', ..., ..., "var_positional"),
1620 ('b', 0, ..., "keyword_only"),
1621 ('kwargs', ..., ..., "var_keyword")),
1622 ...))
1623
1624 def test(a, b, c:int) -> 42:
1625 pass
1626
1627 sig = test.__signature__ = inspect.signature(test)
1628
1629 self.assertEqual(self.signature(partial(partial(test, 1))),
1630 ((('b', ..., ..., "positional_or_keyword"),
1631 ('c', ..., int, "positional_or_keyword")),
1632 42))
1633
1634 self.assertEqual(self.signature(partial(partial(test, 1), 2)),
1635 ((('c', ..., int, "positional_or_keyword"),),
1636 42))
1637
1638 psig = inspect.signature(partial(partial(test, 1), 2))
1639
1640 def foo(a):
1641 return a
1642 _foo = partial(partial(foo, a=10), a=20)
1643 self.assertEqual(self.signature(_foo),
1644 ((('a', 20, ..., "positional_or_keyword"),),
1645 ...))
1646 # check that we don't have any side-effects in signature(),
1647 # and the partial object is still functioning
1648 self.assertEqual(_foo(), 20)
1649
1650 def foo(a, b, c):
1651 return a, b, c
1652 _foo = partial(partial(foo, 1, b=20), b=30)
1653 self.assertEqual(self.signature(_foo),
1654 ((('b', 30, ..., "positional_or_keyword"),
1655 ('c', ..., ..., "positional_or_keyword")),
1656 ...))
1657 self.assertEqual(_foo(c=10), (1, 30, 10))
1658 _foo = partial(_foo, 2) # now 'b' has two values -
1659 # positional and keyword
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001660 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001661 inspect.signature(_foo)
1662
1663 def foo(a, b, c, *, d):
1664 return a, b, c, d
1665 _foo = partial(partial(foo, d=20, c=20), b=10, d=30)
1666 self.assertEqual(self.signature(_foo),
1667 ((('a', ..., ..., "positional_or_keyword"),
1668 ('b', 10, ..., "positional_or_keyword"),
1669 ('c', 20, ..., "positional_or_keyword"),
1670 ('d', 30, ..., "keyword_only")),
1671 ...))
1672 ba = inspect.signature(_foo).bind(a=200, b=11)
1673 self.assertEqual(_foo(*ba.args, **ba.kwargs), (200, 11, 20, 30))
1674
1675 def foo(a=1, b=2, c=3):
1676 return a, b, c
1677 _foo = partial(foo, a=10, c=13)
1678 ba = inspect.signature(_foo).bind(11)
1679 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 2, 13))
1680 ba = inspect.signature(_foo).bind(11, 12)
1681 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
1682 ba = inspect.signature(_foo).bind(11, b=12)
1683 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
1684 ba = inspect.signature(_foo).bind(b=12)
1685 self.assertEqual(_foo(*ba.args, **ba.kwargs), (10, 12, 13))
1686 _foo = partial(_foo, b=10)
1687 ba = inspect.signature(_foo).bind(12, 14)
1688 self.assertEqual(_foo(*ba.args, **ba.kwargs), (12, 14, 13))
1689
1690 def test_signature_on_decorated(self):
1691 import functools
1692
1693 def decorator(func):
1694 @functools.wraps(func)
1695 def wrapper(*args, **kwargs) -> int:
1696 return func(*args, **kwargs)
1697 return wrapper
1698
1699 class Foo:
1700 @decorator
1701 def bar(self, a, b):
1702 pass
1703
1704 self.assertEqual(self.signature(Foo.bar),
1705 ((('self', ..., ..., "positional_or_keyword"),
1706 ('a', ..., ..., "positional_or_keyword"),
1707 ('b', ..., ..., "positional_or_keyword")),
1708 ...))
1709
1710 self.assertEqual(self.signature(Foo().bar),
1711 ((('a', ..., ..., "positional_or_keyword"),
1712 ('b', ..., ..., "positional_or_keyword")),
1713 ...))
1714
1715 # Test that we handle method wrappers correctly
1716 def decorator(func):
1717 @functools.wraps(func)
1718 def wrapper(*args, **kwargs) -> int:
1719 return func(42, *args, **kwargs)
1720 sig = inspect.signature(func)
1721 new_params = tuple(sig.parameters.values())[1:]
1722 wrapper.__signature__ = sig.replace(parameters=new_params)
1723 return wrapper
1724
1725 class Foo:
1726 @decorator
1727 def __call__(self, a, b):
1728 pass
1729
1730 self.assertEqual(self.signature(Foo.__call__),
1731 ((('a', ..., ..., "positional_or_keyword"),
1732 ('b', ..., ..., "positional_or_keyword")),
1733 ...))
1734
1735 self.assertEqual(self.signature(Foo().__call__),
1736 ((('b', ..., ..., "positional_or_keyword"),),
1737 ...))
1738
1739 def test_signature_on_class(self):
1740 class C:
1741 def __init__(self, a):
1742 pass
1743
1744 self.assertEqual(self.signature(C),
1745 ((('a', ..., ..., "positional_or_keyword"),),
1746 ...))
1747
1748 class CM(type):
1749 def __call__(cls, a):
1750 pass
1751 class C(metaclass=CM):
1752 def __init__(self, b):
1753 pass
1754
1755 self.assertEqual(self.signature(C),
1756 ((('a', ..., ..., "positional_or_keyword"),),
1757 ...))
1758
1759 class CM(type):
1760 def __new__(mcls, name, bases, dct, *, foo=1):
1761 return super().__new__(mcls, name, bases, dct)
1762 class C(metaclass=CM):
1763 def __init__(self, b):
1764 pass
1765
1766 self.assertEqual(self.signature(C),
1767 ((('b', ..., ..., "positional_or_keyword"),),
1768 ...))
1769
1770 self.assertEqual(self.signature(CM),
1771 ((('name', ..., ..., "positional_or_keyword"),
1772 ('bases', ..., ..., "positional_or_keyword"),
1773 ('dct', ..., ..., "positional_or_keyword"),
1774 ('foo', 1, ..., "keyword_only")),
1775 ...))
1776
1777 class CMM(type):
1778 def __new__(mcls, name, bases, dct, *, foo=1):
1779 return super().__new__(mcls, name, bases, dct)
1780 def __call__(cls, nm, bs, dt):
1781 return type(nm, bs, dt)
1782 class CM(type, metaclass=CMM):
1783 def __new__(mcls, name, bases, dct, *, bar=2):
1784 return super().__new__(mcls, name, bases, dct)
1785 class C(metaclass=CM):
1786 def __init__(self, b):
1787 pass
1788
1789 self.assertEqual(self.signature(CMM),
1790 ((('name', ..., ..., "positional_or_keyword"),
1791 ('bases', ..., ..., "positional_or_keyword"),
1792 ('dct', ..., ..., "positional_or_keyword"),
1793 ('foo', 1, ..., "keyword_only")),
1794 ...))
1795
1796 self.assertEqual(self.signature(CM),
1797 ((('nm', ..., ..., "positional_or_keyword"),
1798 ('bs', ..., ..., "positional_or_keyword"),
1799 ('dt', ..., ..., "positional_or_keyword")),
1800 ...))
1801
1802 self.assertEqual(self.signature(C),
1803 ((('b', ..., ..., "positional_or_keyword"),),
1804 ...))
1805
1806 class CM(type):
1807 def __init__(cls, name, bases, dct, *, bar=2):
1808 return super().__init__(name, bases, dct)
1809 class C(metaclass=CM):
1810 def __init__(self, b):
1811 pass
1812
1813 self.assertEqual(self.signature(CM),
1814 ((('name', ..., ..., "positional_or_keyword"),
1815 ('bases', ..., ..., "positional_or_keyword"),
1816 ('dct', ..., ..., "positional_or_keyword"),
1817 ('bar', 2, ..., "keyword_only")),
1818 ...))
1819
1820 def test_signature_on_callable_objects(self):
1821 class Foo:
1822 def __call__(self, a):
1823 pass
1824
1825 self.assertEqual(self.signature(Foo()),
1826 ((('a', ..., ..., "positional_or_keyword"),),
1827 ...))
1828
1829 class Spam:
1830 pass
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001831 with self.assertRaisesRegex(TypeError, "is not a callable object"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001832 inspect.signature(Spam())
1833
1834 class Bar(Spam, Foo):
1835 pass
1836
1837 self.assertEqual(self.signature(Bar()),
1838 ((('a', ..., ..., "positional_or_keyword"),),
1839 ...))
1840
1841 class ToFail:
1842 __call__ = type
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001843 with self.assertRaisesRegex(ValueError, "not supported by signature"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001844 inspect.signature(ToFail())
1845
1846
1847 class Wrapped:
1848 pass
1849 Wrapped.__wrapped__ = lambda a: None
1850 self.assertEqual(self.signature(Wrapped),
1851 ((('a', ..., ..., "positional_or_keyword"),),
1852 ...))
1853
1854 def test_signature_on_lambdas(self):
1855 self.assertEqual(self.signature((lambda a=10: a)),
1856 ((('a', 10, ..., "positional_or_keyword"),),
1857 ...))
1858
1859 def test_signature_equality(self):
1860 def foo(a, *, b:int) -> float: pass
1861 self.assertNotEqual(inspect.signature(foo), 42)
1862
1863 def bar(a, *, b:int) -> float: pass
1864 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
1865
1866 def bar(a, *, b:int) -> int: pass
1867 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
1868
1869 def bar(a, *, b:int): pass
1870 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
1871
1872 def bar(a, *, b:int=42) -> float: pass
1873 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
1874
1875 def bar(a, *, c) -> float: pass
1876 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
1877
1878 def bar(a, b:int) -> float: pass
1879 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
1880 def spam(b:int, a) -> float: pass
1881 self.assertNotEqual(inspect.signature(spam), inspect.signature(bar))
1882
1883 def foo(*, a, b, c): pass
1884 def bar(*, c, b, a): pass
1885 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
1886
1887 def foo(*, a=1, b, c): pass
1888 def bar(*, c, b, a=1): pass
1889 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
1890
1891 def foo(pos, *, a=1, b, c): pass
1892 def bar(pos, *, c, b, a=1): pass
1893 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
1894
1895 def foo(pos, *, a, b, c): pass
1896 def bar(pos, *, c, b, a=1): pass
1897 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
1898
1899 def foo(pos, *args, a=42, b, c, **kwargs:int): pass
1900 def bar(pos, *args, c, b, a=42, **kwargs:int): pass
1901 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
1902
1903 def test_signature_unhashable(self):
1904 def foo(a): pass
1905 sig = inspect.signature(foo)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001906 with self.assertRaisesRegex(TypeError, 'unhashable type'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001907 hash(sig)
1908
1909 def test_signature_str(self):
1910 def foo(a:int=1, *, b, c=None, **kwargs) -> 42:
1911 pass
1912 self.assertEqual(str(inspect.signature(foo)),
1913 '(a:int=1, *, b, c=None, **kwargs) -> 42')
1914
1915 def foo(a:int=1, *args, b, c=None, **kwargs) -> 42:
1916 pass
1917 self.assertEqual(str(inspect.signature(foo)),
1918 '(a:int=1, *args, b, c=None, **kwargs) -> 42')
1919
1920 def foo():
1921 pass
1922 self.assertEqual(str(inspect.signature(foo)), '()')
1923
1924 def test_signature_str_positional_only(self):
1925 P = inspect.Parameter
1926
1927 def test(a_po, *, b, **kwargs):
1928 return a_po, kwargs
1929
1930 sig = inspect.signature(test)
1931 new_params = list(sig.parameters.values())
1932 new_params[0] = new_params[0].replace(kind=P.POSITIONAL_ONLY)
1933 test.__signature__ = sig.replace(parameters=new_params)
1934
1935 self.assertEqual(str(inspect.signature(test)),
1936 '(<a_po>, *, b, **kwargs)')
1937
1938 sig = inspect.signature(test)
1939 new_params = list(sig.parameters.values())
1940 new_params[0] = new_params[0].replace(name=None)
1941 test.__signature__ = sig.replace(parameters=new_params)
1942 self.assertEqual(str(inspect.signature(test)),
1943 '(<0>, *, b, **kwargs)')
1944
1945 def test_signature_replace_anno(self):
1946 def test() -> 42:
1947 pass
1948
1949 sig = inspect.signature(test)
1950 sig = sig.replace(return_annotation=None)
1951 self.assertIs(sig.return_annotation, None)
1952 sig = sig.replace(return_annotation=sig.empty)
1953 self.assertIs(sig.return_annotation, sig.empty)
1954 sig = sig.replace(return_annotation=42)
1955 self.assertEqual(sig.return_annotation, 42)
1956 self.assertEqual(sig, inspect.signature(test))
1957
1958
1959class TestParameterObject(unittest.TestCase):
1960 def test_signature_parameter_kinds(self):
1961 P = inspect.Parameter
1962 self.assertTrue(P.POSITIONAL_ONLY < P.POSITIONAL_OR_KEYWORD < \
1963 P.VAR_POSITIONAL < P.KEYWORD_ONLY < P.VAR_KEYWORD)
1964
1965 self.assertEqual(str(P.POSITIONAL_ONLY), 'POSITIONAL_ONLY')
1966 self.assertTrue('POSITIONAL_ONLY' in repr(P.POSITIONAL_ONLY))
1967
1968 def test_signature_parameter_object(self):
1969 p = inspect.Parameter('foo', default=10,
1970 kind=inspect.Parameter.POSITIONAL_ONLY)
1971 self.assertEqual(p.name, 'foo')
1972 self.assertEqual(p.default, 10)
1973 self.assertIs(p.annotation, p.empty)
1974 self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY)
1975
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001976 with self.assertRaisesRegex(ValueError, 'invalid value'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001977 inspect.Parameter('foo', default=10, kind='123')
1978
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001979 with self.assertRaisesRegex(ValueError, 'not a valid parameter name'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001980 inspect.Parameter('1', kind=inspect.Parameter.VAR_KEYWORD)
1981
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001982 with self.assertRaisesRegex(ValueError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001983 'non-positional-only parameter'):
1984 inspect.Parameter(None, kind=inspect.Parameter.VAR_KEYWORD)
1985
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001986 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001987 inspect.Parameter('a', default=42,
1988 kind=inspect.Parameter.VAR_KEYWORD)
1989
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001990 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001991 inspect.Parameter('a', default=42,
1992 kind=inspect.Parameter.VAR_POSITIONAL)
1993
1994 p = inspect.Parameter('a', default=42,
1995 kind=inspect.Parameter.POSITIONAL_OR_KEYWORD)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001996 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001997 p.replace(kind=inspect.Parameter.VAR_POSITIONAL)
1998
1999 self.assertTrue(repr(p).startswith('<Parameter'))
2000
2001 def test_signature_parameter_equality(self):
2002 P = inspect.Parameter
2003 p = P('foo', default=42, kind=inspect.Parameter.KEYWORD_ONLY)
2004
2005 self.assertEqual(p, p)
2006 self.assertNotEqual(p, 42)
2007
2008 self.assertEqual(p, P('foo', default=42,
2009 kind=inspect.Parameter.KEYWORD_ONLY))
2010
2011 def test_signature_parameter_unhashable(self):
2012 p = inspect.Parameter('foo', default=42,
2013 kind=inspect.Parameter.KEYWORD_ONLY)
2014
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002015 with self.assertRaisesRegex(TypeError, 'unhashable type'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002016 hash(p)
2017
2018 def test_signature_parameter_replace(self):
2019 p = inspect.Parameter('foo', default=42,
2020 kind=inspect.Parameter.KEYWORD_ONLY)
2021
2022 self.assertIsNot(p, p.replace())
2023 self.assertEqual(p, p.replace())
2024
2025 p2 = p.replace(annotation=1)
2026 self.assertEqual(p2.annotation, 1)
2027 p2 = p2.replace(annotation=p2.empty)
2028 self.assertEqual(p, p2)
2029
2030 p2 = p2.replace(name='bar')
2031 self.assertEqual(p2.name, 'bar')
2032 self.assertNotEqual(p2, p)
2033
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002034 with self.assertRaisesRegex(ValueError, 'not a valid parameter name'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002035 p2 = p2.replace(name=p2.empty)
2036
2037 p2 = p2.replace(name='foo', default=None)
2038 self.assertIs(p2.default, None)
2039 self.assertNotEqual(p2, p)
2040
2041 p2 = p2.replace(name='foo', default=p2.empty)
2042 self.assertIs(p2.default, p2.empty)
2043
2044
2045 p2 = p2.replace(default=42, kind=p2.POSITIONAL_OR_KEYWORD)
2046 self.assertEqual(p2.kind, p2.POSITIONAL_OR_KEYWORD)
2047 self.assertNotEqual(p2, p)
2048
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002049 with self.assertRaisesRegex(ValueError, 'invalid value for'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002050 p2 = p2.replace(kind=p2.empty)
2051
2052 p2 = p2.replace(kind=p2.KEYWORD_ONLY)
2053 self.assertEqual(p2, p)
2054
2055 def test_signature_parameter_positional_only(self):
2056 p = inspect.Parameter(None, kind=inspect.Parameter.POSITIONAL_ONLY)
2057 self.assertEqual(str(p), '<>')
2058
2059 p = p.replace(name='1')
2060 self.assertEqual(str(p), '<1>')
2061
2062 def test_signature_parameter_immutability(self):
2063 p = inspect.Parameter(None, kind=inspect.Parameter.POSITIONAL_ONLY)
2064
2065 with self.assertRaises(AttributeError):
2066 p.foo = 'bar'
2067
2068 with self.assertRaises(AttributeError):
2069 p.kind = 123
2070
2071
2072class TestSignatureBind(unittest.TestCase):
2073 @staticmethod
2074 def call(func, *args, **kwargs):
2075 sig = inspect.signature(func)
2076 ba = sig.bind(*args, **kwargs)
2077 return func(*ba.args, **ba.kwargs)
2078
2079 def test_signature_bind_empty(self):
2080 def test():
2081 return 42
2082
2083 self.assertEqual(self.call(test), 42)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002084 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002085 self.call(test, 1)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002086 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002087 self.call(test, 1, spam=10)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002088 with self.assertRaisesRegex(TypeError, 'too many keyword arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002089 self.call(test, spam=1)
2090
2091 def test_signature_bind_var(self):
2092 def test(*args, **kwargs):
2093 return args, kwargs
2094
2095 self.assertEqual(self.call(test), ((), {}))
2096 self.assertEqual(self.call(test, 1), ((1,), {}))
2097 self.assertEqual(self.call(test, 1, 2), ((1, 2), {}))
2098 self.assertEqual(self.call(test, foo='bar'), ((), {'foo': 'bar'}))
2099 self.assertEqual(self.call(test, 1, foo='bar'), ((1,), {'foo': 'bar'}))
2100 self.assertEqual(self.call(test, args=10), ((), {'args': 10}))
2101 self.assertEqual(self.call(test, 1, 2, foo='bar'),
2102 ((1, 2), {'foo': 'bar'}))
2103
2104 def test_signature_bind_just_args(self):
2105 def test(a, b, c):
2106 return a, b, c
2107
2108 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
2109
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002110 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002111 self.call(test, 1, 2, 3, 4)
2112
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002113 with self.assertRaisesRegex(TypeError, "'b' parameter lacking default"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002114 self.call(test, 1)
2115
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002116 with self.assertRaisesRegex(TypeError, "'a' parameter lacking default"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002117 self.call(test)
2118
2119 def test(a, b, c=10):
2120 return a, b, c
2121 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
2122 self.assertEqual(self.call(test, 1, 2), (1, 2, 10))
2123
2124 def test(a=1, b=2, c=3):
2125 return a, b, c
2126 self.assertEqual(self.call(test, a=10, c=13), (10, 2, 13))
2127 self.assertEqual(self.call(test, a=10), (10, 2, 3))
2128 self.assertEqual(self.call(test, b=10), (1, 10, 3))
2129
2130 def test_signature_bind_varargs_order(self):
2131 def test(*args):
2132 return args
2133
2134 self.assertEqual(self.call(test), ())
2135 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
2136
2137 def test_signature_bind_args_and_varargs(self):
2138 def test(a, b, c=3, *args):
2139 return a, b, c, args
2140
2141 self.assertEqual(self.call(test, 1, 2, 3, 4, 5), (1, 2, 3, (4, 5)))
2142 self.assertEqual(self.call(test, 1, 2), (1, 2, 3, ()))
2143 self.assertEqual(self.call(test, b=1, a=2), (2, 1, 3, ()))
2144 self.assertEqual(self.call(test, 1, b=2), (1, 2, 3, ()))
2145
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002146 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002147 "multiple values for argument 'c'"):
2148 self.call(test, 1, 2, 3, c=4)
2149
2150 def test_signature_bind_just_kwargs(self):
2151 def test(**kwargs):
2152 return kwargs
2153
2154 self.assertEqual(self.call(test), {})
2155 self.assertEqual(self.call(test, foo='bar', spam='ham'),
2156 {'foo': 'bar', 'spam': 'ham'})
2157
2158 def test_signature_bind_args_and_kwargs(self):
2159 def test(a, b, c=3, **kwargs):
2160 return a, b, c, kwargs
2161
2162 self.assertEqual(self.call(test, 1, 2), (1, 2, 3, {}))
2163 self.assertEqual(self.call(test, 1, 2, foo='bar', spam='ham'),
2164 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
2165 self.assertEqual(self.call(test, b=2, a=1, foo='bar', spam='ham'),
2166 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
2167 self.assertEqual(self.call(test, a=1, b=2, foo='bar', spam='ham'),
2168 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
2169 self.assertEqual(self.call(test, 1, b=2, foo='bar', spam='ham'),
2170 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
2171 self.assertEqual(self.call(test, 1, b=2, c=4, foo='bar', spam='ham'),
2172 (1, 2, 4, {'foo': 'bar', 'spam': 'ham'}))
2173 self.assertEqual(self.call(test, 1, 2, 4, foo='bar'),
2174 (1, 2, 4, {'foo': 'bar'}))
2175 self.assertEqual(self.call(test, c=5, a=4, b=3),
2176 (4, 3, 5, {}))
2177
2178 def test_signature_bind_kwonly(self):
2179 def test(*, foo):
2180 return foo
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002181 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002182 'too many positional arguments'):
2183 self.call(test, 1)
2184 self.assertEqual(self.call(test, foo=1), 1)
2185
2186 def test(a, *, foo=1, bar):
2187 return foo
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002188 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002189 "'bar' parameter lacking default value"):
2190 self.call(test, 1)
2191
2192 def test(foo, *, bar):
2193 return foo, bar
2194 self.assertEqual(self.call(test, 1, bar=2), (1, 2))
2195 self.assertEqual(self.call(test, bar=2, foo=1), (1, 2))
2196
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002197 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002198 'too many keyword arguments'):
2199 self.call(test, bar=2, foo=1, spam=10)
2200
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002201 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002202 'too many positional arguments'):
2203 self.call(test, 1, 2)
2204
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002205 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002206 'too many positional arguments'):
2207 self.call(test, 1, 2, bar=2)
2208
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002209 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002210 'too many keyword arguments'):
2211 self.call(test, 1, bar=2, spam='ham')
2212
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002213 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002214 "'bar' parameter lacking default value"):
2215 self.call(test, 1)
2216
2217 def test(foo, *, bar, **bin):
2218 return foo, bar, bin
2219 self.assertEqual(self.call(test, 1, bar=2), (1, 2, {}))
2220 self.assertEqual(self.call(test, foo=1, bar=2), (1, 2, {}))
2221 self.assertEqual(self.call(test, 1, bar=2, spam='ham'),
2222 (1, 2, {'spam': 'ham'}))
2223 self.assertEqual(self.call(test, spam='ham', foo=1, bar=2),
2224 (1, 2, {'spam': 'ham'}))
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002225 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002226 "'foo' parameter lacking default value"):
2227 self.call(test, spam='ham', bar=2)
2228 self.assertEqual(self.call(test, 1, bar=2, bin=1, spam=10),
2229 (1, 2, {'bin': 1, 'spam': 10}))
2230
2231 def test_signature_bind_arguments(self):
2232 def test(a, *args, b, z=100, **kwargs):
2233 pass
2234 sig = inspect.signature(test)
2235 ba = sig.bind(10, 20, b=30, c=40, args=50, kwargs=60)
2236 # we won't have 'z' argument in the bound arguments object, as we didn't
2237 # pass it to the 'bind'
2238 self.assertEqual(tuple(ba.arguments.items()),
2239 (('a', 10), ('args', (20,)), ('b', 30),
2240 ('kwargs', {'c': 40, 'args': 50, 'kwargs': 60})))
2241 self.assertEqual(ba.kwargs,
2242 {'b': 30, 'c': 40, 'args': 50, 'kwargs': 60})
2243 self.assertEqual(ba.args, (10, 20))
2244
2245 def test_signature_bind_positional_only(self):
2246 P = inspect.Parameter
2247
2248 def test(a_po, b_po, c_po=3, foo=42, *, bar=50, **kwargs):
2249 return a_po, b_po, c_po, foo, bar, kwargs
2250
2251 sig = inspect.signature(test)
2252 new_params = collections.OrderedDict(tuple(sig.parameters.items()))
2253 for name in ('a_po', 'b_po', 'c_po'):
2254 new_params[name] = new_params[name].replace(kind=P.POSITIONAL_ONLY)
2255 new_sig = sig.replace(parameters=new_params.values())
2256 test.__signature__ = new_sig
2257
2258 self.assertEqual(self.call(test, 1, 2, 4, 5, bar=6),
2259 (1, 2, 4, 5, 6, {}))
2260
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002261 with self.assertRaisesRegex(TypeError, "parameter is positional only"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002262 self.call(test, 1, 2, c_po=4)
2263
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002264 with self.assertRaisesRegex(TypeError, "parameter is positional only"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002265 self.call(test, a_po=1, b_po=2)
2266
Antoine Pitroubd41d1b2013-01-29 21:20:57 +01002267 def test_signature_bind_with_self_arg(self):
2268 # Issue #17071: one of the parameters is named "self
2269 def test(a, self, b):
2270 pass
2271 sig = inspect.signature(test)
2272 ba = sig.bind(1, 2, 3)
2273 self.assertEqual(ba.args, (1, 2, 3))
2274 ba = sig.bind(1, self=2, b=3)
2275 self.assertEqual(ba.args, (1, 2, 3))
2276
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002277
2278class TestBoundArguments(unittest.TestCase):
2279 def test_signature_bound_arguments_unhashable(self):
2280 def foo(a): pass
2281 ba = inspect.signature(foo).bind(1)
2282
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002283 with self.assertRaisesRegex(TypeError, 'unhashable type'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002284 hash(ba)
2285
2286 def test_signature_bound_arguments_equality(self):
2287 def foo(a): pass
2288 ba = inspect.signature(foo).bind(1)
2289 self.assertEqual(ba, ba)
2290
2291 ba2 = inspect.signature(foo).bind(1)
2292 self.assertEqual(ba, ba2)
2293
2294 ba3 = inspect.signature(foo).bind(2)
2295 self.assertNotEqual(ba, ba3)
2296 ba3.arguments['a'] = 1
2297 self.assertEqual(ba, ba3)
2298
2299 def bar(b): pass
2300 ba4 = inspect.signature(bar).bind(1)
2301 self.assertNotEqual(ba, ba4)
2302
2303
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00002304def test_main():
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00002305 run_unittest(
2306 TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBuggyCases,
2307 TestInterpreterStack, TestClassesAndFunctions, TestPredicates,
2308 TestGetcallargsFunctions, TestGetcallargsMethods,
Alexander Belopolskyf546e702010-12-02 00:10:11 +00002309 TestGetcallargsUnboundMethods, TestGetattrStatic, TestGetGeneratorState,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002310 TestNoEOL, TestSignatureObject, TestSignatureBind, TestParameterObject,
Nick Coghlan2f92e542012-06-23 19:39:55 +10002311 TestBoundArguments, TestGetClosureVars
Michael Foord95fc51d2010-11-20 15:07:30 +00002312 )
Martin v. Löwis893ffa42003-10-31 15:35:53 +00002313
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00002314if __name__ == "__main__":
2315 test_main()