blob: 12a315ebb15a558eb618c458453272211601ec1b [file] [log] [blame]
Larry Hastings5c661892014-01-24 06:17:25 -08001import _testcapi
Guido van Rossum813b0e52007-05-21 18:11:34 +00002import collections
Larry Hastings5c661892014-01-24 06:17:25 -08003import datetime
Nick Coghlane8c45d62013-07-28 20:00:01 +10004import functools
Nick Coghlanf94a16b2013-09-22 22:46:49 +10005import importlib
Larry Hastings5c661892014-01-24 06:17:25 -08006import inspect
7import io
8import linecache
9import os
Christian Heimesa3538eb2007-11-06 11:44:48 +000010from os.path import normcase
Larry Hastings5c661892014-01-24 06:17:25 -080011import _pickle
12import re
13import shutil
14import sys
15import types
16import unicodedata
17import unittest
18
Brett Cannon634a8fc2013-10-02 10:25:42 -040019try:
20 from concurrent.futures import ThreadPoolExecutor
21except ImportError:
22 ThreadPoolExecutor = None
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000023
Alexander Belopolskyf546e702010-12-02 00:10:11 +000024from test.support import run_unittest, TESTFN, DirsOnSysPath
Larry Hastingsfcafe432013-11-23 17:35:48 -080025from test.support import MISSING_C_DOCSTRINGS
Nick Coghlanf94a16b2013-09-22 22:46:49 +100026from test.script_helper import assert_python_ok, assert_python_failure
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000027from test import inspect_fodder as mod
28from test import inspect_fodder2 as mod2
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000029
R. David Murray74b89242009-05-13 17:33:03 +000030
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000031# Functions tested in this suite:
32# ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode,
Christian Heimes7131fd92008-02-19 14:21:46 +000033# isbuiltin, isroutine, isgenerator, isgeneratorfunction, getmembers,
34# getdoc, getfile, getmodule, getsourcefile, getcomments, getsource,
35# getclasstree, getargspec, getargvalues, formatargspec, formatargvalues,
36# currentframe, stack, trace, isdatadescriptor
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000037
Nick Coghlanf088e5e2008-12-14 11:50:48 +000038# NOTE: There are some additional tests relating to interaction with
39# zipimport in the test_zipimport_support test module.
40
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000041modfile = mod.__file__
Thomas Wouters0e3f5912006-08-11 14:57:12 +000042if modfile.endswith(('c', 'o')):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000043 modfile = modfile[:-1]
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000044
Christian Heimesa3538eb2007-11-06 11:44:48 +000045# Normalize file names: on Windows, the case of file names of compiled
46# modules depends on the path used to start the python executable.
47modfile = normcase(modfile)
48
49def revise(filename, *args):
50 return (normcase(filename),) + args
51
Georg Brandl1a3284e2007-12-02 09:40:06 +000052import builtins
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000053
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000054git = mod.StupidGit()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000055
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000056class IsTestBase(unittest.TestCase):
57 predicates = set([inspect.isbuiltin, inspect.isclass, inspect.iscode,
58 inspect.isframe, inspect.isfunction, inspect.ismethod,
Christian Heimes7131fd92008-02-19 14:21:46 +000059 inspect.ismodule, inspect.istraceback,
60 inspect.isgenerator, inspect.isgeneratorfunction])
Tim Peters5a9fb3c2005-01-07 16:01:32 +000061
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000062 def istest(self, predicate, exp):
63 obj = eval(exp)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000064 self.assertTrue(predicate(obj), '%s(%s)' % (predicate.__name__, exp))
Tim Peters5a9fb3c2005-01-07 16:01:32 +000065
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000066 for other in self.predicates - set([predicate]):
Christian Heimes7131fd92008-02-19 14:21:46 +000067 if predicate == inspect.isgeneratorfunction and\
68 other == inspect.isfunction:
69 continue
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000070 self.assertFalse(other(obj), 'not %s(%s)' % (other.__name__, exp))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000071
Christian Heimes7131fd92008-02-19 14:21:46 +000072def generator_function_example(self):
73 for i in range(2):
74 yield i
75
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000076class TestPredicates(IsTestBase):
Christian Heimes227c8002008-03-03 20:34:40 +000077 def test_sixteen(self):
Guido van Rossumc1f779c2007-07-03 08:25:58 +000078 count = len([x for x in dir(inspect) if x.startswith('is')])
Christian Heimes7131fd92008-02-19 14:21:46 +000079 # This test is here for remember you to update Doc/library/inspect.rst
Christian Heimes78644762008-03-04 23:39:23 +000080 # which claims there are 16 such functions
Christian Heimes227c8002008-03-03 20:34:40 +000081 expected = 16
Thomas Wouters0e3f5912006-08-11 14:57:12 +000082 err_msg = "There are %d (not %d) is* functions" % (count, expected)
83 self.assertEqual(count, expected, err_msg)
Tim Peters5a9fb3c2005-01-07 16:01:32 +000084
Christian Heimes7131fd92008-02-19 14:21:46 +000085
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000086 def test_excluding_predicates(self):
Antoine Pitroud5a1a212012-06-17 23:18:07 +020087 global tb
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000088 self.istest(inspect.isbuiltin, 'sys.exit')
89 self.istest(inspect.isbuiltin, '[].append')
Neal Norwitz221085d2007-02-25 20:55:47 +000090 self.istest(inspect.iscode, 'mod.spam.__code__')
Antoine Pitroud5a1a212012-06-17 23:18:07 +020091 try:
92 1/0
93 except:
94 tb = sys.exc_info()[2]
95 self.istest(inspect.isframe, 'tb.tb_frame')
96 self.istest(inspect.istraceback, 'tb')
97 if hasattr(types, 'GetSetDescriptorType'):
98 self.istest(inspect.isgetsetdescriptor,
99 'type(tb.tb_frame).f_locals')
100 else:
101 self.assertFalse(inspect.isgetsetdescriptor(type(tb.tb_frame).f_locals))
102 finally:
103 # Clear traceback and all the frames and local variables hanging to it.
104 tb = None
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000105 self.istest(inspect.isfunction, 'mod.spam')
Christian Heimes4a22b5d2007-11-25 09:39:14 +0000106 self.istest(inspect.isfunction, 'mod.StupidGit.abuse')
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000107 self.istest(inspect.ismethod, 'git.argue')
108 self.istest(inspect.ismodule, 'mod')
Guido van Rossum813b0e52007-05-21 18:11:34 +0000109 self.istest(inspect.isdatadescriptor, 'collections.defaultdict.default_factory')
Christian Heimes7131fd92008-02-19 14:21:46 +0000110 self.istest(inspect.isgenerator, '(x for x in range(2))')
111 self.istest(inspect.isgeneratorfunction, 'generator_function_example')
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000112 if hasattr(types, 'MemberDescriptorType'):
113 self.istest(inspect.ismemberdescriptor, 'datetime.timedelta.days')
114 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000115 self.assertFalse(inspect.ismemberdescriptor(datetime.timedelta.days))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000116
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000117 def test_isroutine(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000118 self.assertTrue(inspect.isroutine(mod.spam))
119 self.assertTrue(inspect.isroutine([].count))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000120
Benjamin Petersonc4656002009-01-17 22:41:18 +0000121 def test_isclass(self):
122 self.istest(inspect.isclass, 'mod.StupidGit')
123 self.assertTrue(inspect.isclass(list))
124
125 class CustomGetattr(object):
126 def __getattr__(self, attr):
127 return None
128 self.assertFalse(inspect.isclass(CustomGetattr()))
129
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000130 def test_get_slot_members(self):
131 class C(object):
132 __slots__ = ("a", "b")
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000133 x = C()
134 x.a = 42
135 members = dict(inspect.getmembers(x))
Benjamin Peterson577473f2010-01-19 00:09:57 +0000136 self.assertIn('a', members)
137 self.assertNotIn('b', members)
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000138
Benjamin Petersona0dfa822009-11-13 02:25:08 +0000139 def test_isabstract(self):
140 from abc import ABCMeta, abstractmethod
141
142 class AbstractClassExample(metaclass=ABCMeta):
143
144 @abstractmethod
145 def foo(self):
146 pass
147
148 class ClassExample(AbstractClassExample):
149 def foo(self):
150 pass
151
152 a = ClassExample()
153
154 # Test general behaviour.
155 self.assertTrue(inspect.isabstract(AbstractClassExample))
156 self.assertFalse(inspect.isabstract(ClassExample))
157 self.assertFalse(inspect.isabstract(a))
158 self.assertFalse(inspect.isabstract(int))
159 self.assertFalse(inspect.isabstract(5))
160
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000161
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000162class TestInterpreterStack(IsTestBase):
163 def __init__(self, *args, **kwargs):
164 unittest.TestCase.__init__(self, *args, **kwargs)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000165
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000166 git.abuse(7, 8, 9)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000167
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000168 def test_abuse_done(self):
169 self.istest(inspect.istraceback, 'git.ex[2]')
170 self.istest(inspect.isframe, 'mod.fr')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000171
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000172 def test_stack(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000173 self.assertTrue(len(mod.st) >= 5)
Christian Heimesa3538eb2007-11-06 11:44:48 +0000174 self.assertEqual(revise(*mod.st[0][1:]),
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000175 (modfile, 16, 'eggs', [' st = inspect.stack()\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000176 self.assertEqual(revise(*mod.st[1][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000177 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000178 self.assertEqual(revise(*mod.st[2][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000179 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000180 self.assertEqual(revise(*mod.st[3][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000181 (modfile, 39, 'abuse', [' self.argue(a, b, c)\n'], 0))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000182
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000183 def test_trace(self):
184 self.assertEqual(len(git.tr), 3)
Florent Xiclunac8575922010-03-24 17:37:49 +0000185 self.assertEqual(revise(*git.tr[0][1:]),
186 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
187 self.assertEqual(revise(*git.tr[1][1:]),
188 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
189 self.assertEqual(revise(*git.tr[2][1:]),
190 (modfile, 18, 'eggs', [' q = y / 0\n'], 0))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000191
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000192 def test_frame(self):
193 args, varargs, varkw, locals = inspect.getargvalues(mod.fr)
194 self.assertEqual(args, ['x', 'y'])
195 self.assertEqual(varargs, None)
196 self.assertEqual(varkw, None)
197 self.assertEqual(locals, {'x': 11, 'p': 11, 'y': 14})
198 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
199 '(x=11, y=14)')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000200
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000201 def test_previous_frame(self):
202 args, varargs, varkw, locals = inspect.getargvalues(mod.fr.f_back)
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000203 self.assertEqual(args, ['a', 'b', 'c', 'd', 'e', 'f'])
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000204 self.assertEqual(varargs, 'g')
205 self.assertEqual(varkw, 'h')
206 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000207 '(a=7, b=8, c=9, d=3, e=4, f=5, *g=(), **h={})')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000208
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000209class GetSourceBase(unittest.TestCase):
210 # Subclasses must override.
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000211 fodderModule = None
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000212
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000213 def __init__(self, *args, **kwargs):
214 unittest.TestCase.__init__(self, *args, **kwargs)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000215
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000216 with open(inspect.getsourcefile(self.fodderModule)) as fp:
Philip Jenveya27c5bd2009-05-28 06:09:08 +0000217 self.source = fp.read()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000218
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000219 def sourcerange(self, top, bottom):
220 lines = self.source.split("\n")
221 return "\n".join(lines[top-1:bottom]) + "\n"
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000222
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000223 def assertSourceEqual(self, obj, top, bottom):
224 self.assertEqual(inspect.getsource(obj),
225 self.sourcerange(top, bottom))
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000226
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000227class TestRetrievingSourceCode(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000228 fodderModule = mod
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000229
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000230 def test_getclasses(self):
231 classes = inspect.getmembers(mod, inspect.isclass)
232 self.assertEqual(classes,
233 [('FesteringGob', mod.FesteringGob),
234 ('MalodorousPervert', mod.MalodorousPervert),
235 ('ParrotDroppings', mod.ParrotDroppings),
Serhiy Storchaka362c1b52013-09-05 17:14:32 +0300236 ('StupidGit', mod.StupidGit),
237 ('Tit', mod.MalodorousPervert),
238 ])
239 tree = inspect.getclasstree([cls[1] for cls in classes])
240 self.assertEqual(tree,
241 [(object, ()),
242 [(mod.ParrotDroppings, (object,)),
243 [(mod.FesteringGob, (mod.MalodorousPervert,
244 mod.ParrotDroppings))
245 ],
246 (mod.StupidGit, (object,)),
247 [(mod.MalodorousPervert, (mod.StupidGit,)),
248 [(mod.FesteringGob, (mod.MalodorousPervert,
249 mod.ParrotDroppings))
250 ]
251 ]
252 ]
253 ])
254 tree = inspect.getclasstree([cls[1] for cls in classes], True)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000255 self.assertEqual(tree,
Thomas Wouters725af872006-04-15 09:13:19 +0000256 [(object, ()),
257 [(mod.ParrotDroppings, (object,)),
258 (mod.StupidGit, (object,)),
259 [(mod.MalodorousPervert, (mod.StupidGit,)),
260 [(mod.FesteringGob, (mod.MalodorousPervert,
261 mod.ParrotDroppings))
262 ]
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000263 ]
264 ]
265 ])
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000266
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000267 def test_getfunctions(self):
268 functions = inspect.getmembers(mod, inspect.isfunction)
269 self.assertEqual(functions, [('eggs', mod.eggs),
270 ('spam', mod.spam)])
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000271
R. David Murray378c0cf2010-02-24 01:46:21 +0000272 @unittest.skipIf(sys.flags.optimize >= 2,
273 "Docstrings are omitted with -O2 and above")
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000274 def test_getdoc(self):
275 self.assertEqual(inspect.getdoc(mod), 'A module docstring.')
276 self.assertEqual(inspect.getdoc(mod.StupidGit),
277 'A longer,\n\nindented\n\ndocstring.')
278 self.assertEqual(inspect.getdoc(git.abuse),
279 'Another\n\ndocstring\n\ncontaining\n\ntabs')
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000280
Georg Brandl0c77a822008-06-10 16:37:50 +0000281 def test_cleandoc(self):
282 self.assertEqual(inspect.cleandoc('An\n indented\n docstring.'),
283 'An\nindented\ndocstring.')
284
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000285 def test_getcomments(self):
286 self.assertEqual(inspect.getcomments(mod), '# line 1\n')
287 self.assertEqual(inspect.getcomments(mod.StupidGit), '# line 20\n')
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000288
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000289 def test_getmodule(self):
Thomas Wouters89f507f2006-12-13 04:49:30 +0000290 # Check actual module
291 self.assertEqual(inspect.getmodule(mod), mod)
292 # Check class (uses __module__ attribute)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000293 self.assertEqual(inspect.getmodule(mod.StupidGit), mod)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000294 # Check a method (no __module__ attribute, falls back to filename)
295 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
296 # Do it again (check the caching isn't broken)
297 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
298 # Check a builtin
Georg Brandl1a3284e2007-12-02 09:40:06 +0000299 self.assertEqual(inspect.getmodule(str), sys.modules["builtins"])
Thomas Wouters89f507f2006-12-13 04:49:30 +0000300 # Check filename override
301 self.assertEqual(inspect.getmodule(None, modfile), mod)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000302
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000303 def test_getsource(self):
304 self.assertSourceEqual(git.abuse, 29, 39)
305 self.assertSourceEqual(mod.StupidGit, 21, 46)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000306
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000307 def test_getsourcefile(self):
Christian Heimesa3538eb2007-11-06 11:44:48 +0000308 self.assertEqual(normcase(inspect.getsourcefile(mod.spam)), modfile)
309 self.assertEqual(normcase(inspect.getsourcefile(git.abuse)), modfile)
R. David Murraya1b37402010-06-17 02:04:29 +0000310 fn = "_non_existing_filename_used_for_sourcefile_test.py"
311 co = compile("None", fn, "exec")
R. David Murray4155f972010-06-17 13:23:18 +0000312 self.assertEqual(inspect.getsourcefile(co), None)
R. David Murraya1b37402010-06-17 02:04:29 +0000313 linecache.cache[co.co_filename] = (1, None, "None", co.co_filename)
Antoine Pitrou5d62a612012-07-08 13:48:46 +0200314 try:
315 self.assertEqual(normcase(inspect.getsourcefile(co)), fn)
316 finally:
317 del linecache.cache[co.co_filename]
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000318
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000319 def test_getfile(self):
320 self.assertEqual(inspect.getfile(mod.StupidGit), mod.__file__)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000321
Yury Selivanov2eed8b72014-01-27 13:24:56 -0500322 def test_getfile_class_without_module(self):
323 class CM(type):
324 @property
325 def __module__(cls):
326 raise AttributeError
327 class C(metaclass=CM):
328 pass
329 with self.assertRaises(TypeError):
330 inspect.getfile(C)
331
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000332 def test_getmodule_recursion(self):
Christian Heimes45f9af32007-11-27 21:50:00 +0000333 from types import ModuleType
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000334 name = '__inspect_dummy'
Christian Heimes45f9af32007-11-27 21:50:00 +0000335 m = sys.modules[name] = ModuleType(name)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000336 m.__file__ = "<string>" # hopefully not a real filename...
337 m.__loader__ = "dummy" # pretend the filename is understood by a loader
Georg Brandl7cae87c2006-09-06 06:51:57 +0000338 exec("def x(): pass", m.__dict__)
Neal Norwitz221085d2007-02-25 20:55:47 +0000339 self.assertEqual(inspect.getsourcefile(m.x.__code__), '<string>')
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000340 del sys.modules[name]
341 inspect.getmodule(compile('a=10','','single'))
342
Benjamin Peterson9620cc02011-06-11 15:53:11 -0500343 def test_proceed_with_fake_filename(self):
344 '''doctest monkeypatches linecache to enable inspection'''
345 fn, source = '<test>', 'def x(): pass\n'
346 getlines = linecache.getlines
347 def monkey(filename, module_globals=None):
348 if filename == fn:
Ezio Melottid8b509b2011-09-28 17:37:55 +0300349 return source.splitlines(keepends=True)
Benjamin Peterson9620cc02011-06-11 15:53:11 -0500350 else:
351 return getlines(filename, module_globals)
352 linecache.getlines = monkey
353 try:
354 ns = {}
355 exec(compile(source, fn, 'single'), ns)
356 inspect.getsource(ns["x"])
357 finally:
358 linecache.getlines = getlines
359
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000360class TestDecorators(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000361 fodderModule = mod2
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000362
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000363 def test_wrapped_decorator(self):
Christian Heimes09aaa882008-02-23 15:01:06 +0000364 self.assertSourceEqual(mod2.wrapped, 14, 17)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000365
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000366 def test_replacing_decorator(self):
367 self.assertSourceEqual(mod2.gone, 9, 10)
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000368
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000369class TestOneliners(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000370 fodderModule = mod2
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000371 def test_oneline_lambda(self):
372 # Test inspect.getsource with a one-line lambda function.
373 self.assertSourceEqual(mod2.oll, 25, 25)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000374
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000375 def test_threeline_lambda(self):
376 # Test inspect.getsource with a three-line lambda function,
377 # where the second and third lines are _not_ indented.
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000378 self.assertSourceEqual(mod2.tll, 28, 30)
379
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000380 def test_twoline_indented_lambda(self):
381 # Test inspect.getsource with a two-line lambda function,
382 # where the second line _is_ indented.
383 self.assertSourceEqual(mod2.tlli, 33, 34)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000384
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000385 def test_onelinefunc(self):
386 # Test inspect.getsource with a regular one-line function.
387 self.assertSourceEqual(mod2.onelinefunc, 37, 37)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000388
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000389 def test_manyargs(self):
390 # Test inspect.getsource with a regular function where
391 # the arguments are on two lines and _not_ indented and
392 # the body on the second line with the last arguments.
393 self.assertSourceEqual(mod2.manyargs, 40, 41)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000394
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000395 def test_twolinefunc(self):
396 # Test inspect.getsource with a regular function where
397 # the body is on two lines, following the argument list and
398 # continued on the next line by a \\.
399 self.assertSourceEqual(mod2.twolinefunc, 44, 45)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000400
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000401 def test_lambda_in_list(self):
402 # Test inspect.getsource with a one-line lambda function
403 # defined in a list, indented.
404 self.assertSourceEqual(mod2.a[1], 49, 49)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000405
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000406 def test_anonymous(self):
407 # Test inspect.getsource with a lambda function defined
408 # as argument to another function.
409 self.assertSourceEqual(mod2.anonymous, 55, 55)
410
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000411class TestBuggyCases(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000412 fodderModule = mod2
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000413
414 def test_with_comment(self):
415 self.assertSourceEqual(mod2.with_comment, 58, 59)
416
417 def test_multiline_sig(self):
418 self.assertSourceEqual(mod2.multiline_sig[0], 63, 64)
419
Armin Rigodd5c0232005-09-25 11:45:45 +0000420 def test_nested_class(self):
421 self.assertSourceEqual(mod2.func69().func71, 71, 72)
422
423 def test_one_liner_followed_by_non_name(self):
424 self.assertSourceEqual(mod2.func77, 77, 77)
425
426 def test_one_liner_dedent_non_name(self):
427 self.assertSourceEqual(mod2.cls82.func83, 83, 83)
428
429 def test_with_comment_instead_of_docstring(self):
430 self.assertSourceEqual(mod2.func88, 88, 90)
431
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000432 def test_method_in_dynamic_class(self):
433 self.assertSourceEqual(mod2.method_in_dynamic_class, 95, 97)
434
R. David Murrayb5655772009-05-14 16:17:50 +0000435 @unittest.skipIf(
436 not hasattr(unicodedata, '__file__') or
437 unicodedata.__file__[-4:] in (".pyc", ".pyo"),
438 "unicodedata is not an external binary module")
R. David Murray74b89242009-05-13 17:33:03 +0000439 def test_findsource_binary(self):
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200440 self.assertRaises(OSError, inspect.getsource, unicodedata)
441 self.assertRaises(OSError, inspect.findsource, unicodedata)
R. David Murray74b89242009-05-13 17:33:03 +0000442
R. David Murraya1b37402010-06-17 02:04:29 +0000443 def test_findsource_code_in_linecache(self):
444 lines = ["x=1"]
445 co = compile(lines[0], "_dynamically_created_file", "exec")
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200446 self.assertRaises(OSError, inspect.findsource, co)
447 self.assertRaises(OSError, inspect.getsource, co)
R. David Murraya1b37402010-06-17 02:04:29 +0000448 linecache.cache[co.co_filename] = (1, None, lines, co.co_filename)
Antoine Pitrou5d62a612012-07-08 13:48:46 +0200449 try:
450 self.assertEqual(inspect.findsource(co), (lines,0))
451 self.assertEqual(inspect.getsource(co), lines[0])
452 finally:
453 del linecache.cache[co.co_filename]
R. David Murraya1b37402010-06-17 02:04:29 +0000454
Ezio Melotti1b145922013-03-30 05:17:24 +0200455 def test_findsource_without_filename(self):
456 for fname in ['', '<string>']:
457 co = compile('x=1', fname, "exec")
458 self.assertRaises(IOError, inspect.findsource, co)
459 self.assertRaises(IOError, inspect.getsource, co)
460
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000461class TestNoEOL(GetSourceBase):
462 def __init__(self, *args, **kwargs):
463 self.tempdir = TESTFN + '_dir'
464 os.mkdir(self.tempdir)
465 with open(os.path.join(self.tempdir,
466 'inspect_fodder3%spy' % os.extsep), 'w') as f:
467 f.write("class X:\n pass # No EOL")
468 with DirsOnSysPath(self.tempdir):
469 import inspect_fodder3 as mod3
470 self.fodderModule = mod3
471 GetSourceBase.__init__(self, *args, **kwargs)
472
473 def tearDown(self):
474 shutil.rmtree(self.tempdir)
475
476 def test_class(self):
477 self.assertSourceEqual(self.fodderModule.X, 1, 2)
478
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100479
480class _BrokenDataDescriptor(object):
481 """
482 A broken data descriptor. See bug #1785.
483 """
484 def __get__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700485 raise AttributeError("broken data descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100486
487 def __set__(*args):
488 raise RuntimeError
489
490 def __getattr__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700491 raise AttributeError("broken data descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100492
493
494class _BrokenMethodDescriptor(object):
495 """
496 A broken method descriptor. See bug #1785.
497 """
498 def __get__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700499 raise AttributeError("broken method descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100500
501 def __getattr__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700502 raise AttributeError("broken method descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100503
504
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000505# Helper for testing classify_class_attrs.
Tim Peters13b49d32001-09-23 02:00:29 +0000506def attrs_wo_objs(cls):
507 return [t[:3] for t in inspect.classify_class_attrs(cls)]
508
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100509
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000510class TestClassesAndFunctions(unittest.TestCase):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000511 def test_newstyle_mro(self):
512 # The same w/ new-class MRO.
513 class A(object): pass
514 class B(A): pass
515 class C(A): pass
516 class D(B, C): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000517
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000518 expected = (D, B, C, A, object)
519 got = inspect.getmro(D)
520 self.assertEqual(expected, got)
Tim Peters13b49d32001-09-23 02:00:29 +0000521
Christian Heimes3795b532007-11-08 13:48:53 +0000522 def assertArgSpecEquals(self, routine, args_e, varargs_e=None,
523 varkw_e=None, defaults_e=None, formatted=None):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000524 args, varargs, varkw, defaults = inspect.getargspec(routine)
525 self.assertEqual(args, args_e)
526 self.assertEqual(varargs, varargs_e)
527 self.assertEqual(varkw, varkw_e)
528 self.assertEqual(defaults, defaults_e)
529 if formatted is not None:
530 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults),
531 formatted)
Tim Peters13b49d32001-09-23 02:00:29 +0000532
Christian Heimes3795b532007-11-08 13:48:53 +0000533 def assertFullArgSpecEquals(self, routine, args_e, varargs_e=None,
534 varkw_e=None, defaults_e=None,
535 kwonlyargs_e=[], kwonlydefaults_e=None,
536 ann_e={}, formatted=None):
537 args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \
538 inspect.getfullargspec(routine)
539 self.assertEqual(args, args_e)
540 self.assertEqual(varargs, varargs_e)
541 self.assertEqual(varkw, varkw_e)
542 self.assertEqual(defaults, defaults_e)
543 self.assertEqual(kwonlyargs, kwonlyargs_e)
544 self.assertEqual(kwonlydefaults, kwonlydefaults_e)
545 self.assertEqual(ann, ann_e)
546 if formatted is not None:
547 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults,
548 kwonlyargs, kwonlydefaults, ann),
549 formatted)
550
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000551 def test_getargspec(self):
Christian Heimes3795b532007-11-08 13:48:53 +0000552 self.assertArgSpecEquals(mod.eggs, ['x', 'y'], formatted='(x, y)')
Tim Peters13b49d32001-09-23 02:00:29 +0000553
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000554 self.assertArgSpecEquals(mod.spam,
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000555 ['a', 'b', 'c', 'd', 'e', 'f'],
556 'g', 'h', (3, 4, 5),
557 '(a, b, c, d=3, e=4, f=5, *g, **h)')
Tim Peters13b49d32001-09-23 02:00:29 +0000558
Christian Heimes3795b532007-11-08 13:48:53 +0000559 self.assertRaises(ValueError, self.assertArgSpecEquals,
560 mod2.keyworded, [])
561
562 self.assertRaises(ValueError, self.assertArgSpecEquals,
563 mod2.annotated, [])
Benjamin Peterson9953a8d2009-01-17 04:15:01 +0000564 self.assertRaises(ValueError, self.assertArgSpecEquals,
565 mod2.keyword_only_arg, [])
566
Christian Heimes3795b532007-11-08 13:48:53 +0000567
568 def test_getfullargspec(self):
569 self.assertFullArgSpecEquals(mod2.keyworded, [], varargs_e='arg1',
570 kwonlyargs_e=['arg2'],
571 kwonlydefaults_e={'arg2':1},
572 formatted='(*arg1, arg2=1)')
573
574 self.assertFullArgSpecEquals(mod2.annotated, ['arg1'],
Christian Heimesc9543e42007-11-28 08:28:28 +0000575 ann_e={'arg1' : list},
Christian Heimes3795b532007-11-08 13:48:53 +0000576 formatted='(arg1: list)')
Benjamin Peterson9953a8d2009-01-17 04:15:01 +0000577 self.assertFullArgSpecEquals(mod2.keyword_only_arg, [],
578 kwonlyargs_e=['arg'],
579 formatted='(*, arg)')
580
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500581 def test_getfullargspec_signature_attr(self):
582 def test():
583 pass
584 spam_param = inspect.Parameter('spam', inspect.Parameter.POSITIONAL_ONLY)
585 test.__signature__ = inspect.Signature(parameters=(spam_param,))
586
587 self.assertFullArgSpecEquals(test, args_e=['spam'], formatted='(spam)')
588
Yury Selivanov4cb93912014-01-29 11:54:12 -0500589 def test_getfullargspec_signature_annos(self):
590 def test(a:'spam') -> 'ham': pass
591 spec = inspect.getfullargspec(test)
592 self.assertEqual(test.__annotations__, spec.annotations)
593
594 def test(): pass
595 spec = inspect.getfullargspec(test)
596 self.assertEqual(test.__annotations__, spec.annotations)
597
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500598 @unittest.skipIf(MISSING_C_DOCSTRINGS,
599 "Signature information for builtins requires docstrings")
600 def test_getfullargspec_builtin_methods(self):
601 self.assertFullArgSpecEquals(_pickle.Pickler.dump,
602 args_e=['self', 'obj'], formatted='(self, obj)')
603
604 self.assertFullArgSpecEquals(_pickle.Pickler(io.BytesIO()).dump,
605 args_e=['self', 'obj'], formatted='(self, obj)')
606
607 @unittest.skipIf(MISSING_C_DOCSTRINGS,
608 "Signature information for builtins requires docstrings")
609 def test_getfullagrspec_builtin_func(self):
610 builtin = _testcapi.docstring_with_signature_with_defaults
611 spec = inspect.getfullargspec(builtin)
612 self.assertEqual(spec.defaults[0], 'avocado')
613
614 @unittest.skipIf(MISSING_C_DOCSTRINGS,
615 "Signature information for builtins requires docstrings")
616 def test_getfullagrspec_builtin_func_no_signature(self):
617 builtin = _testcapi.docstring_no_signature
618 with self.assertRaises(TypeError):
619 inspect.getfullargspec(builtin)
Christian Heimes3795b532007-11-08 13:48:53 +0000620
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000621 def test_getargspec_method(self):
622 class A(object):
623 def m(self):
624 pass
625 self.assertArgSpecEquals(A.m, ['self'])
Tim Peters13b49d32001-09-23 02:00:29 +0000626
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000627 def test_classify_newstyle(self):
628 class A(object):
Tim Peters13b49d32001-09-23 02:00:29 +0000629
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000630 def s(): pass
631 s = staticmethod(s)
Tim Peters13b49d32001-09-23 02:00:29 +0000632
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000633 def c(cls): pass
634 c = classmethod(c)
Tim Peters13b49d32001-09-23 02:00:29 +0000635
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000636 def getp(self): pass
637 p = property(getp)
Tim Peters13b49d32001-09-23 02:00:29 +0000638
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000639 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000640
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000641 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000642
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000643 datablob = '1'
Tim Peters13b49d32001-09-23 02:00:29 +0000644
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100645 dd = _BrokenDataDescriptor()
646 md = _BrokenMethodDescriptor()
647
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000648 attrs = attrs_wo_objs(A)
Yury Selivanov0860a0b2014-01-31 14:28:44 -0500649
650 self.assertIn(('__new__', 'method', object), attrs, 'missing __new__')
651 self.assertIn(('__init__', 'method', object), attrs, 'missing __init__')
652
Benjamin Peterson577473f2010-01-19 00:09:57 +0000653 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
654 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
655 self.assertIn(('p', 'property', A), attrs, 'missing property')
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000656 self.assertIn(('m', 'method', A), attrs,
657 'missing plain method: %r' % attrs)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000658 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
659 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100660 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
661 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000662
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000663 class B(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000664
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000665 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000666
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000667 attrs = attrs_wo_objs(B)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000668 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
669 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
670 self.assertIn(('p', 'property', A), attrs, 'missing property')
671 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
672 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
673 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100674 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
675 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000676
677
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000678 class C(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000679
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000680 def m(self): pass
681 def c(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000682
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000683 attrs = attrs_wo_objs(C)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000684 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
685 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
686 self.assertIn(('p', 'property', A), attrs, 'missing property')
687 self.assertIn(('m', 'method', C), attrs, 'missing plain method')
688 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
689 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100690 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
691 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000692
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000693 class D(B, C):
Tim Peters13b49d32001-09-23 02:00:29 +0000694
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000695 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000696
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000697 attrs = attrs_wo_objs(D)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000698 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
699 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
700 self.assertIn(('p', 'property', A), attrs, 'missing property')
701 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
702 self.assertIn(('m1', 'method', D), attrs, 'missing plain method')
703 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100704 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
705 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
706
707 def test_classify_builtin_types(self):
708 # Simple sanity check that all built-in types can have their
709 # attributes classified.
710 for name in dir(__builtins__):
711 builtin = getattr(__builtins__, name)
712 if isinstance(builtin, type):
713 inspect.classify_class_attrs(builtin)
714
Ethan Furman63c141c2013-10-18 00:27:39 -0700715 def test_classify_DynamicClassAttribute(self):
716 class Meta(type):
717 def __getattr__(self, name):
718 if name == 'ham':
719 return 'spam'
720 return super().__getattr__(name)
721 class VA(metaclass=Meta):
Ethan Furmane03ea372013-09-25 07:14:41 -0700722 @types.DynamicClassAttribute
723 def ham(self):
724 return 'eggs'
Ethan Furman63c141c2013-10-18 00:27:39 -0700725 should_find_dca = inspect.Attribute('ham', 'data', VA, VA.__dict__['ham'])
726 self.assertIn(should_find_dca, inspect.classify_class_attrs(VA))
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700727 should_find_ga = inspect.Attribute('ham', 'data', Meta, 'spam')
Ethan Furman63c141c2013-10-18 00:27:39 -0700728 self.assertIn(should_find_ga, inspect.classify_class_attrs(VA))
729
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700730 def test_classify_metaclass_class_attribute(self):
731 class Meta(type):
732 fish = 'slap'
733 def __dir__(self):
734 return ['__class__', '__modules__', '__name__', 'fish']
735 class Class(metaclass=Meta):
736 pass
737 should_find = inspect.Attribute('fish', 'data', Meta, 'slap')
738 self.assertIn(should_find, inspect.classify_class_attrs(Class))
739
Ethan Furman63c141c2013-10-18 00:27:39 -0700740 def test_classify_VirtualAttribute(self):
741 class Meta(type):
742 def __dir__(cls):
743 return ['__class__', '__module__', '__name__', 'BOOM']
744 def __getattr__(self, name):
745 if name =='BOOM':
746 return 42
747 return super().__getattr(name)
748 class Class(metaclass=Meta):
749 pass
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700750 should_find = inspect.Attribute('BOOM', 'data', Meta, 42)
Ethan Furman63c141c2013-10-18 00:27:39 -0700751 self.assertIn(should_find, inspect.classify_class_attrs(Class))
752
753 def test_classify_VirtualAttribute_multi_classes(self):
754 class Meta1(type):
755 def __dir__(cls):
756 return ['__class__', '__module__', '__name__', 'one']
757 def __getattr__(self, name):
758 if name =='one':
759 return 1
760 return super().__getattr__(name)
761 class Meta2(type):
762 def __dir__(cls):
763 return ['__class__', '__module__', '__name__', 'two']
764 def __getattr__(self, name):
765 if name =='two':
766 return 2
767 return super().__getattr__(name)
768 class Meta3(Meta1, Meta2):
769 def __dir__(cls):
770 return list(sorted(set(['__class__', '__module__', '__name__', 'three'] +
771 Meta1.__dir__(cls) + Meta2.__dir__(cls))))
772 def __getattr__(self, name):
773 if name =='three':
774 return 3
775 return super().__getattr__(name)
776 class Class1(metaclass=Meta1):
777 pass
778 class Class2(Class1, metaclass=Meta3):
779 pass
780
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700781 should_find1 = inspect.Attribute('one', 'data', Meta1, 1)
782 should_find2 = inspect.Attribute('two', 'data', Meta2, 2)
783 should_find3 = inspect.Attribute('three', 'data', Meta3, 3)
Ethan Furman63c141c2013-10-18 00:27:39 -0700784 cca = inspect.classify_class_attrs(Class2)
785 for sf in (should_find1, should_find2, should_find3):
786 self.assertIn(sf, cca)
787
788 def test_classify_class_attrs_with_buggy_dir(self):
789 class M(type):
790 def __dir__(cls):
791 return ['__class__', '__name__', 'missing']
792 class C(metaclass=M):
793 pass
794 attrs = [a[0] for a in inspect.classify_class_attrs(C)]
795 self.assertNotIn('missing', attrs)
Ethan Furmane03ea372013-09-25 07:14:41 -0700796
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100797 def test_getmembers_descriptors(self):
798 class A(object):
799 dd = _BrokenDataDescriptor()
800 md = _BrokenMethodDescriptor()
801
802 def pred_wrapper(pred):
803 # A quick'n'dirty way to discard standard attributes of new-style
804 # classes.
805 class Empty(object):
806 pass
807 def wrapped(x):
808 if '__name__' in dir(x) and hasattr(Empty, x.__name__):
809 return False
810 return pred(x)
811 return wrapped
812
813 ismethoddescriptor = pred_wrapper(inspect.ismethoddescriptor)
814 isdatadescriptor = pred_wrapper(inspect.isdatadescriptor)
815
816 self.assertEqual(inspect.getmembers(A, ismethoddescriptor),
817 [('md', A.__dict__['md'])])
818 self.assertEqual(inspect.getmembers(A, isdatadescriptor),
819 [('dd', A.__dict__['dd'])])
820
821 class B(A):
822 pass
823
824 self.assertEqual(inspect.getmembers(B, ismethoddescriptor),
825 [('md', A.__dict__['md'])])
826 self.assertEqual(inspect.getmembers(B, isdatadescriptor),
827 [('dd', A.__dict__['dd'])])
828
Antoine Pitrou0c603812012-01-18 17:40:18 +0100829 def test_getmembers_method(self):
830 class B:
831 def f(self):
832 pass
833
834 self.assertIn(('f', B.f), inspect.getmembers(B))
835 self.assertNotIn(('f', B.f), inspect.getmembers(B, inspect.ismethod))
836 b = B()
837 self.assertIn(('f', b.f), inspect.getmembers(b))
838 self.assertIn(('f', b.f), inspect.getmembers(b, inspect.ismethod))
839
Ethan Furmane03ea372013-09-25 07:14:41 -0700840 def test_getmembers_VirtualAttribute(self):
Ethan Furman63c141c2013-10-18 00:27:39 -0700841 class M(type):
842 def __getattr__(cls, name):
843 if name == 'eggs':
844 return 'scrambled'
845 return super().__getattr__(name)
846 class A(metaclass=M):
Ethan Furmane03ea372013-09-25 07:14:41 -0700847 @types.DynamicClassAttribute
848 def eggs(self):
849 return 'spam'
Ethan Furman63c141c2013-10-18 00:27:39 -0700850 self.assertIn(('eggs', 'scrambled'), inspect.getmembers(A))
851 self.assertIn(('eggs', 'spam'), inspect.getmembers(A()))
852
853 def test_getmembers_with_buggy_dir(self):
854 class M(type):
855 def __dir__(cls):
856 return ['__class__', '__name__', 'missing']
857 class C(metaclass=M):
858 pass
859 attrs = [a[0] for a in inspect.getmembers(C)]
860 self.assertNotIn('missing', attrs)
Ethan Furmane03ea372013-09-25 07:14:41 -0700861
Jeremy Hyltonc4bf5ed2003-06-27 18:43:12 +0000862
Nick Coghlan2f92e542012-06-23 19:39:55 +1000863_global_ref = object()
864class TestGetClosureVars(unittest.TestCase):
865
866 def test_name_resolution(self):
867 # Basic test of the 4 different resolution mechanisms
868 def f(nonlocal_ref):
869 def g(local_ref):
870 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
871 return g
872 _arg = object()
873 nonlocal_vars = {"nonlocal_ref": _arg}
874 global_vars = {"_global_ref": _global_ref}
875 builtin_vars = {"print": print}
876 unbound_names = {"unbound_ref"}
877 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
878 builtin_vars, unbound_names)
879 self.assertEqual(inspect.getclosurevars(f(_arg)), expected)
880
881 def test_generator_closure(self):
882 def f(nonlocal_ref):
883 def g(local_ref):
884 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
885 yield
886 return g
887 _arg = object()
888 nonlocal_vars = {"nonlocal_ref": _arg}
889 global_vars = {"_global_ref": _global_ref}
890 builtin_vars = {"print": print}
891 unbound_names = {"unbound_ref"}
892 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
893 builtin_vars, unbound_names)
894 self.assertEqual(inspect.getclosurevars(f(_arg)), expected)
895
896 def test_method_closure(self):
897 class C:
898 def f(self, nonlocal_ref):
899 def g(local_ref):
900 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
901 return g
902 _arg = object()
903 nonlocal_vars = {"nonlocal_ref": _arg}
904 global_vars = {"_global_ref": _global_ref}
905 builtin_vars = {"print": print}
906 unbound_names = {"unbound_ref"}
907 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
908 builtin_vars, unbound_names)
909 self.assertEqual(inspect.getclosurevars(C().f(_arg)), expected)
910
911 def test_nonlocal_vars(self):
912 # More complex tests of nonlocal resolution
913 def _nonlocal_vars(f):
914 return inspect.getclosurevars(f).nonlocals
915
916 def make_adder(x):
917 def add(y):
918 return x + y
919 return add
920
921 def curry(func, arg1):
922 return lambda arg2: func(arg1, arg2)
923
924 def less_than(a, b):
925 return a < b
926
927 # The infamous Y combinator.
928 def Y(le):
929 def g(f):
930 return le(lambda x: f(f)(x))
931 Y.g_ref = g
932 return g(g)
933
934 def check_y_combinator(func):
935 self.assertEqual(_nonlocal_vars(func), {'f': Y.g_ref})
936
937 inc = make_adder(1)
938 add_two = make_adder(2)
939 greater_than_five = curry(less_than, 5)
940
941 self.assertEqual(_nonlocal_vars(inc), {'x': 1})
942 self.assertEqual(_nonlocal_vars(add_two), {'x': 2})
943 self.assertEqual(_nonlocal_vars(greater_than_five),
944 {'arg1': 5, 'func': less_than})
945 self.assertEqual(_nonlocal_vars((lambda x: lambda y: x + y)(3)),
946 {'x': 3})
947 Y(check_y_combinator)
948
949 def test_getclosurevars_empty(self):
950 def foo(): pass
951 _empty = inspect.ClosureVars({}, {}, {}, set())
952 self.assertEqual(inspect.getclosurevars(lambda: True), _empty)
953 self.assertEqual(inspect.getclosurevars(foo), _empty)
954
955 def test_getclosurevars_error(self):
956 class T: pass
957 self.assertRaises(TypeError, inspect.getclosurevars, 1)
958 self.assertRaises(TypeError, inspect.getclosurevars, list)
959 self.assertRaises(TypeError, inspect.getclosurevars, {})
960
Nick Coghlan6c6e2542012-06-23 20:07:39 +1000961 def _private_globals(self):
962 code = """def f(): print(path)"""
963 ns = {}
964 exec(code, ns)
965 return ns["f"], ns
966
967 def test_builtins_fallback(self):
968 f, ns = self._private_globals()
969 ns.pop("__builtins__", None)
970 expected = inspect.ClosureVars({}, {}, {"print":print}, {"path"})
971 self.assertEqual(inspect.getclosurevars(f), expected)
972
973 def test_builtins_as_dict(self):
974 f, ns = self._private_globals()
975 ns["__builtins__"] = {"path":1}
976 expected = inspect.ClosureVars({}, {}, {"path":1}, {"print"})
977 self.assertEqual(inspect.getclosurevars(f), expected)
978
979 def test_builtins_as_module(self):
980 f, ns = self._private_globals()
981 ns["__builtins__"] = os
982 expected = inspect.ClosureVars({}, {}, {"path":os.path}, {"print"})
983 self.assertEqual(inspect.getclosurevars(f), expected)
984
Nick Coghlan2f92e542012-06-23 19:39:55 +1000985
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000986class TestGetcallargsFunctions(unittest.TestCase):
987
988 def assertEqualCallArgs(self, func, call_params_string, locs=None):
989 locs = dict(locs or {}, func=func)
990 r1 = eval('func(%s)' % call_params_string, None, locs)
991 r2 = eval('inspect.getcallargs(func, %s)' % call_params_string, None,
992 locs)
993 self.assertEqual(r1, r2)
994
995 def assertEqualException(self, func, call_param_string, locs=None):
996 locs = dict(locs or {}, func=func)
997 try:
998 eval('func(%s)' % call_param_string, None, locs)
999 except Exception as e:
1000 ex1 = e
1001 else:
1002 self.fail('Exception not raised')
1003 try:
1004 eval('inspect.getcallargs(func, %s)' % call_param_string, None,
1005 locs)
1006 except Exception as e:
1007 ex2 = e
1008 else:
1009 self.fail('Exception not raised')
1010 self.assertIs(type(ex1), type(ex2))
1011 self.assertEqual(str(ex1), str(ex2))
1012 del ex1, ex2
1013
1014 def makeCallable(self, signature):
1015 """Create a function that returns its locals()"""
1016 code = "lambda %s: locals()"
1017 return eval(code % signature)
1018
1019 def test_plain(self):
1020 f = self.makeCallable('a, b=1')
1021 self.assertEqualCallArgs(f, '2')
1022 self.assertEqualCallArgs(f, '2, 3')
1023 self.assertEqualCallArgs(f, 'a=2')
1024 self.assertEqualCallArgs(f, 'b=3, a=2')
1025 self.assertEqualCallArgs(f, '2, b=3')
1026 # expand *iterable / **mapping
1027 self.assertEqualCallArgs(f, '*(2,)')
1028 self.assertEqualCallArgs(f, '*[2]')
1029 self.assertEqualCallArgs(f, '*(2, 3)')
1030 self.assertEqualCallArgs(f, '*[2, 3]')
1031 self.assertEqualCallArgs(f, '**{"a":2}')
1032 self.assertEqualCallArgs(f, 'b=3, **{"a":2}')
1033 self.assertEqualCallArgs(f, '2, **{"b":3}')
1034 self.assertEqualCallArgs(f, '**{"b":3, "a":2}')
1035 # expand UserList / UserDict
1036 self.assertEqualCallArgs(f, '*collections.UserList([2])')
1037 self.assertEqualCallArgs(f, '*collections.UserList([2, 3])')
1038 self.assertEqualCallArgs(f, '**collections.UserDict(a=2)')
1039 self.assertEqualCallArgs(f, '2, **collections.UserDict(b=3)')
1040 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3)')
1041
1042 def test_varargs(self):
1043 f = self.makeCallable('a, b=1, *c')
1044 self.assertEqualCallArgs(f, '2')
1045 self.assertEqualCallArgs(f, '2, 3')
1046 self.assertEqualCallArgs(f, '2, 3, 4')
1047 self.assertEqualCallArgs(f, '*(2,3,4)')
1048 self.assertEqualCallArgs(f, '2, *[3,4]')
1049 self.assertEqualCallArgs(f, '2, 3, *collections.UserList([4])')
1050
1051 def test_varkw(self):
1052 f = self.makeCallable('a, b=1, **c')
1053 self.assertEqualCallArgs(f, 'a=2')
1054 self.assertEqualCallArgs(f, '2, b=3, c=4')
1055 self.assertEqualCallArgs(f, 'b=3, a=2, c=4')
1056 self.assertEqualCallArgs(f, 'c=4, **{"a":2, "b":3}')
1057 self.assertEqualCallArgs(f, '2, c=4, **{"b":3}')
1058 self.assertEqualCallArgs(f, 'b=2, **{"a":3, "c":4}')
1059 self.assertEqualCallArgs(f, '**collections.UserDict(a=2, b=3, c=4)')
1060 self.assertEqualCallArgs(f, '2, c=4, **collections.UserDict(b=3)')
1061 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3, c=4)')
1062
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001063 def test_varkw_only(self):
1064 # issue11256:
1065 f = self.makeCallable('**c')
1066 self.assertEqualCallArgs(f, '')
1067 self.assertEqualCallArgs(f, 'a=1')
1068 self.assertEqualCallArgs(f, 'a=1, b=2')
1069 self.assertEqualCallArgs(f, 'c=3, **{"a": 1, "b": 2}')
1070 self.assertEqualCallArgs(f, '**collections.UserDict(a=1, b=2)')
1071 self.assertEqualCallArgs(f, 'c=3, **collections.UserDict(a=1, b=2)')
1072
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001073 def test_keyword_only(self):
1074 f = self.makeCallable('a=3, *, c, d=2')
1075 self.assertEqualCallArgs(f, 'c=3')
1076 self.assertEqualCallArgs(f, 'c=3, a=3')
1077 self.assertEqualCallArgs(f, 'a=2, c=4')
1078 self.assertEqualCallArgs(f, '4, c=4')
1079 self.assertEqualException(f, '')
1080 self.assertEqualException(f, '3')
1081 self.assertEqualException(f, 'a=3')
1082 self.assertEqualException(f, 'd=4')
1083
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001084 f = self.makeCallable('*, c, d=2')
1085 self.assertEqualCallArgs(f, 'c=3')
1086 self.assertEqualCallArgs(f, 'c=3, d=4')
1087 self.assertEqualCallArgs(f, 'd=4, c=3')
1088
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001089 def test_multiple_features(self):
1090 f = self.makeCallable('a, b=2, *f, **g')
1091 self.assertEqualCallArgs(f, '2, 3, 7')
1092 self.assertEqualCallArgs(f, '2, 3, x=8')
1093 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
1094 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9')
1095 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9')
1096 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
1097 '[2, 3, (4,[5,6])]), **{"y":9, "z":10}')
1098 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
1099 '(4,[5,6])]), **collections.UserDict('
1100 'y=9, z=10)')
1101
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001102 f = self.makeCallable('a, b=2, *f, x, y=99, **g')
1103 self.assertEqualCallArgs(f, '2, 3, x=8')
1104 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
1105 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9, z=10')
1106 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9, z=10')
1107 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
1108 '[2, 3, (4,[5,6])]), q=0, **{"y":9, "z":10}')
1109 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
1110 '(4,[5,6])]), q=0, **collections.UserDict('
1111 'y=9, z=10)')
1112
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001113 def test_errors(self):
1114 f0 = self.makeCallable('')
1115 f1 = self.makeCallable('a, b')
1116 f2 = self.makeCallable('a, b=1')
1117 # f0 takes no arguments
1118 self.assertEqualException(f0, '1')
1119 self.assertEqualException(f0, 'x=1')
1120 self.assertEqualException(f0, '1,x=1')
1121 # f1 takes exactly 2 arguments
1122 self.assertEqualException(f1, '')
1123 self.assertEqualException(f1, '1')
1124 self.assertEqualException(f1, 'a=2')
1125 self.assertEqualException(f1, 'b=3')
1126 # f2 takes at least 1 argument
1127 self.assertEqualException(f2, '')
1128 self.assertEqualException(f2, 'b=3')
1129 for f in f1, f2:
1130 # f1/f2 takes exactly/at most 2 arguments
1131 self.assertEqualException(f, '2, 3, 4')
1132 self.assertEqualException(f, '1, 2, 3, a=1')
1133 self.assertEqualException(f, '2, 3, 4, c=5')
Georg Brandl178e5ea2012-02-21 00:32:36 +01001134 # XXX: success of this one depends on dict order
1135 ## self.assertEqualException(f, '2, 3, 4, a=1, c=5')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001136 # f got an unexpected keyword argument
1137 self.assertEqualException(f, 'c=2')
1138 self.assertEqualException(f, '2, c=3')
1139 self.assertEqualException(f, '2, 3, c=4')
1140 self.assertEqualException(f, '2, c=4, b=3')
1141 self.assertEqualException(f, '**{u"\u03c0\u03b9": 4}')
1142 # f got multiple values for keyword argument
1143 self.assertEqualException(f, '1, a=2')
1144 self.assertEqualException(f, '1, **{"a":2}')
1145 self.assertEqualException(f, '1, 2, b=3')
1146 # XXX: Python inconsistency
1147 # - for functions and bound methods: unexpected keyword 'c'
1148 # - for unbound methods: multiple values for keyword 'a'
1149 #self.assertEqualException(f, '1, c=3, a=2')
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001150 # issue11256:
1151 f3 = self.makeCallable('**c')
1152 self.assertEqualException(f3, '1, 2')
1153 self.assertEqualException(f3, '1, 2, a=1, b=2')
1154 f4 = self.makeCallable('*, a, b=0')
1155 self.assertEqualException(f3, '1, 2')
1156 self.assertEqualException(f3, '1, 2, a=1, b=2')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001157
1158class TestGetcallargsMethods(TestGetcallargsFunctions):
1159
1160 def setUp(self):
1161 class Foo(object):
1162 pass
1163 self.cls = Foo
1164 self.inst = Foo()
1165
1166 def makeCallable(self, signature):
1167 assert 'self' not in signature
1168 mk = super(TestGetcallargsMethods, self).makeCallable
1169 self.cls.method = mk('self, ' + signature)
1170 return self.inst.method
1171
1172class TestGetcallargsUnboundMethods(TestGetcallargsMethods):
1173
1174 def makeCallable(self, signature):
1175 super(TestGetcallargsUnboundMethods, self).makeCallable(signature)
1176 return self.cls.method
1177
1178 def assertEqualCallArgs(self, func, call_params_string, locs=None):
1179 return super(TestGetcallargsUnboundMethods, self).assertEqualCallArgs(
1180 *self._getAssertEqualParams(func, call_params_string, locs))
1181
1182 def assertEqualException(self, func, call_params_string, locs=None):
1183 return super(TestGetcallargsUnboundMethods, self).assertEqualException(
1184 *self._getAssertEqualParams(func, call_params_string, locs))
1185
1186 def _getAssertEqualParams(self, func, call_params_string, locs=None):
1187 assert 'inst' not in call_params_string
1188 locs = dict(locs or {}, inst=self.inst)
1189 return (func, 'inst,' + call_params_string, locs)
1190
Michael Foord95fc51d2010-11-20 15:07:30 +00001191
1192class TestGetattrStatic(unittest.TestCase):
1193
1194 def test_basic(self):
1195 class Thing(object):
1196 x = object()
1197
1198 thing = Thing()
1199 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1200 self.assertEqual(inspect.getattr_static(thing, 'x', None), Thing.x)
1201 with self.assertRaises(AttributeError):
1202 inspect.getattr_static(thing, 'y')
1203
1204 self.assertEqual(inspect.getattr_static(thing, 'y', 3), 3)
1205
1206 def test_inherited(self):
1207 class Thing(object):
1208 x = object()
1209 class OtherThing(Thing):
1210 pass
1211
1212 something = OtherThing()
1213 self.assertEqual(inspect.getattr_static(something, 'x'), Thing.x)
1214
1215 def test_instance_attr(self):
1216 class Thing(object):
1217 x = 2
1218 def __init__(self, x):
1219 self.x = x
1220 thing = Thing(3)
1221 self.assertEqual(inspect.getattr_static(thing, 'x'), 3)
1222 del thing.x
1223 self.assertEqual(inspect.getattr_static(thing, 'x'), 2)
1224
1225 def test_property(self):
1226 class Thing(object):
1227 @property
1228 def x(self):
1229 raise AttributeError("I'm pretending not to exist")
1230 thing = Thing()
1231 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1232
Ezio Melotti75cbd732011-04-28 00:59:29 +03001233 def test_descriptor_raises_AttributeError(self):
Michael Foord95fc51d2010-11-20 15:07:30 +00001234 class descriptor(object):
1235 def __get__(*_):
1236 raise AttributeError("I'm pretending not to exist")
1237 desc = descriptor()
1238 class Thing(object):
1239 x = desc
1240 thing = Thing()
1241 self.assertEqual(inspect.getattr_static(thing, 'x'), desc)
1242
1243 def test_classAttribute(self):
1244 class Thing(object):
1245 x = object()
1246
1247 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.x)
1248
Ethan Furmane03ea372013-09-25 07:14:41 -07001249 def test_classVirtualAttribute(self):
1250 class Thing(object):
1251 @types.DynamicClassAttribute
1252 def x(self):
1253 return self._x
1254 _x = object()
1255
1256 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.__dict__['x'])
1257
Michael Foord95fc51d2010-11-20 15:07:30 +00001258 def test_inherited_classattribute(self):
1259 class Thing(object):
1260 x = object()
1261 class OtherThing(Thing):
1262 pass
1263
1264 self.assertEqual(inspect.getattr_static(OtherThing, 'x'), Thing.x)
1265
1266 def test_slots(self):
1267 class Thing(object):
1268 y = 'bar'
1269 __slots__ = ['x']
1270 def __init__(self):
1271 self.x = 'foo'
1272 thing = Thing()
1273 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1274 self.assertEqual(inspect.getattr_static(thing, 'y'), 'bar')
1275
1276 del thing.x
1277 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1278
1279 def test_metaclass(self):
1280 class meta(type):
1281 attr = 'foo'
1282 class Thing(object, metaclass=meta):
1283 pass
1284 self.assertEqual(inspect.getattr_static(Thing, 'attr'), 'foo')
1285
1286 class sub(meta):
1287 pass
1288 class OtherThing(object, metaclass=sub):
1289 x = 3
1290 self.assertEqual(inspect.getattr_static(OtherThing, 'attr'), 'foo')
1291
1292 class OtherOtherThing(OtherThing):
1293 pass
1294 # this test is odd, but it was added as it exposed a bug
1295 self.assertEqual(inspect.getattr_static(OtherOtherThing, 'x'), 3)
1296
1297 def test_no_dict_no_slots(self):
1298 self.assertEqual(inspect.getattr_static(1, 'foo', None), None)
1299 self.assertNotEqual(inspect.getattr_static('foo', 'lower'), None)
1300
1301 def test_no_dict_no_slots_instance_member(self):
1302 # returns descriptor
1303 with open(__file__) as handle:
1304 self.assertEqual(inspect.getattr_static(handle, 'name'), type(handle).name)
1305
1306 def test_inherited_slots(self):
1307 # returns descriptor
1308 class Thing(object):
1309 __slots__ = ['x']
1310 def __init__(self):
1311 self.x = 'foo'
1312
1313 class OtherThing(Thing):
1314 pass
1315 # it would be nice if this worked...
1316 # we get the descriptor instead of the instance attribute
1317 self.assertEqual(inspect.getattr_static(OtherThing(), 'x'), Thing.x)
1318
1319 def test_descriptor(self):
1320 class descriptor(object):
1321 def __get__(self, instance, owner):
1322 return 3
1323 class Foo(object):
1324 d = descriptor()
1325
1326 foo = Foo()
1327
1328 # for a non data descriptor we return the instance attribute
1329 foo.__dict__['d'] = 1
1330 self.assertEqual(inspect.getattr_static(foo, 'd'), 1)
1331
1332 # if the descriptor is a data-desciptor we should return the
1333 # descriptor
1334 descriptor.__set__ = lambda s, i, v: None
1335 self.assertEqual(inspect.getattr_static(foo, 'd'), Foo.__dict__['d'])
1336
1337
1338 def test_metaclass_with_descriptor(self):
1339 class descriptor(object):
1340 def __get__(self, instance, owner):
1341 return 3
1342 class meta(type):
1343 d = descriptor()
1344 class Thing(object, metaclass=meta):
1345 pass
1346 self.assertEqual(inspect.getattr_static(Thing, 'd'), meta.__dict__['d'])
1347
1348
Michael Foordcc7ebb82010-11-20 16:20:16 +00001349 def test_class_as_property(self):
1350 class Base(object):
1351 foo = 3
1352
1353 class Something(Base):
Michael Foord35184ed2010-11-20 16:58:30 +00001354 executed = False
Michael Foordcc7ebb82010-11-20 16:20:16 +00001355 @property
1356 def __class__(self):
Michael Foord35184ed2010-11-20 16:58:30 +00001357 self.executed = True
Michael Foordcc7ebb82010-11-20 16:20:16 +00001358 return object
1359
Michael Foord35184ed2010-11-20 16:58:30 +00001360 instance = Something()
1361 self.assertEqual(inspect.getattr_static(instance, 'foo'), 3)
1362 self.assertFalse(instance.executed)
Michael Foordcc7ebb82010-11-20 16:20:16 +00001363 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1364
Michael Foorde5162652010-11-20 16:40:44 +00001365 def test_mro_as_property(self):
1366 class Meta(type):
1367 @property
1368 def __mro__(self):
1369 return (object,)
1370
1371 class Base(object):
1372 foo = 3
1373
1374 class Something(Base, metaclass=Meta):
1375 pass
1376
1377 self.assertEqual(inspect.getattr_static(Something(), 'foo'), 3)
1378 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1379
Michael Foorddcebe0f2011-03-15 19:20:44 -04001380 def test_dict_as_property(self):
1381 test = self
1382 test.called = False
1383
1384 class Foo(dict):
1385 a = 3
1386 @property
1387 def __dict__(self):
1388 test.called = True
1389 return {}
1390
1391 foo = Foo()
1392 foo.a = 4
1393 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1394 self.assertFalse(test.called)
1395
1396 def test_custom_object_dict(self):
1397 test = self
1398 test.called = False
1399
1400 class Custom(dict):
1401 def get(self, key, default=None):
1402 test.called = True
1403 super().get(key, default)
1404
1405 class Foo(object):
1406 a = 3
1407 foo = Foo()
1408 foo.__dict__ = Custom()
1409 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1410 self.assertFalse(test.called)
1411
1412 def test_metaclass_dict_as_property(self):
1413 class Meta(type):
1414 @property
1415 def __dict__(self):
1416 self.executed = True
1417
1418 class Thing(metaclass=Meta):
1419 executed = False
1420
1421 def __init__(self):
1422 self.spam = 42
1423
1424 instance = Thing()
1425 self.assertEqual(inspect.getattr_static(instance, "spam"), 42)
1426 self.assertFalse(Thing.executed)
Michael Foorde5162652010-11-20 16:40:44 +00001427
Michael Foorda51623b2011-12-18 22:01:40 +00001428 def test_module(self):
1429 sentinel = object()
1430 self.assertIsNot(inspect.getattr_static(sys, "version", sentinel),
1431 sentinel)
1432
Michael Foord3ba95f82011-12-22 01:13:37 +00001433 def test_metaclass_with_metaclass_with_dict_as_property(self):
1434 class MetaMeta(type):
1435 @property
1436 def __dict__(self):
1437 self.executed = True
1438 return dict(spam=42)
1439
1440 class Meta(type, metaclass=MetaMeta):
1441 executed = False
1442
1443 class Thing(metaclass=Meta):
1444 pass
1445
1446 with self.assertRaises(AttributeError):
1447 inspect.getattr_static(Thing, "spam")
1448 self.assertFalse(Thing.executed)
1449
Nick Coghlane0f04652010-11-21 03:44:04 +00001450class TestGetGeneratorState(unittest.TestCase):
1451
1452 def setUp(self):
1453 def number_generator():
1454 for number in range(5):
1455 yield number
1456 self.generator = number_generator()
1457
1458 def _generatorstate(self):
1459 return inspect.getgeneratorstate(self.generator)
1460
1461 def test_created(self):
1462 self.assertEqual(self._generatorstate(), inspect.GEN_CREATED)
1463
1464 def test_suspended(self):
1465 next(self.generator)
1466 self.assertEqual(self._generatorstate(), inspect.GEN_SUSPENDED)
1467
1468 def test_closed_after_exhaustion(self):
1469 for i in self.generator:
1470 pass
1471 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1472
1473 def test_closed_after_immediate_exception(self):
1474 with self.assertRaises(RuntimeError):
1475 self.generator.throw(RuntimeError)
1476 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1477
1478 def test_running(self):
1479 # As mentioned on issue #10220, checking for the RUNNING state only
1480 # makes sense inside the generator itself.
1481 # The following generator checks for this by using the closure's
1482 # reference to self and the generator state checking helper method
1483 def running_check_generator():
1484 for number in range(5):
1485 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1486 yield number
1487 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1488 self.generator = running_check_generator()
1489 # Running up to the first yield
1490 next(self.generator)
1491 # Running after the first yield
1492 next(self.generator)
1493
Nick Coghlan7921b9f2010-11-30 06:36:04 +00001494 def test_easy_debugging(self):
1495 # repr() and str() of a generator state should contain the state name
1496 names = 'GEN_CREATED GEN_RUNNING GEN_SUSPENDED GEN_CLOSED'.split()
1497 for name in names:
1498 state = getattr(inspect, name)
1499 self.assertIn(name, repr(state))
1500 self.assertIn(name, str(state))
1501
Nick Coghlan04e2e3f2012-06-23 19:52:05 +10001502 def test_getgeneratorlocals(self):
1503 def each(lst, a=None):
1504 b=(1, 2, 3)
1505 for v in lst:
1506 if v == 3:
1507 c = 12
1508 yield v
1509
1510 numbers = each([1, 2, 3])
1511 self.assertEqual(inspect.getgeneratorlocals(numbers),
1512 {'a': None, 'lst': [1, 2, 3]})
1513 next(numbers)
1514 self.assertEqual(inspect.getgeneratorlocals(numbers),
1515 {'a': None, 'lst': [1, 2, 3], 'v': 1,
1516 'b': (1, 2, 3)})
1517 next(numbers)
1518 self.assertEqual(inspect.getgeneratorlocals(numbers),
1519 {'a': None, 'lst': [1, 2, 3], 'v': 2,
1520 'b': (1, 2, 3)})
1521 next(numbers)
1522 self.assertEqual(inspect.getgeneratorlocals(numbers),
1523 {'a': None, 'lst': [1, 2, 3], 'v': 3,
1524 'b': (1, 2, 3), 'c': 12})
1525 try:
1526 next(numbers)
1527 except StopIteration:
1528 pass
1529 self.assertEqual(inspect.getgeneratorlocals(numbers), {})
1530
1531 def test_getgeneratorlocals_empty(self):
1532 def yield_one():
1533 yield 1
1534 one = yield_one()
1535 self.assertEqual(inspect.getgeneratorlocals(one), {})
1536 try:
1537 next(one)
1538 except StopIteration:
1539 pass
1540 self.assertEqual(inspect.getgeneratorlocals(one), {})
1541
1542 def test_getgeneratorlocals_error(self):
1543 self.assertRaises(TypeError, inspect.getgeneratorlocals, 1)
1544 self.assertRaises(TypeError, inspect.getgeneratorlocals, lambda x: True)
1545 self.assertRaises(TypeError, inspect.getgeneratorlocals, set)
1546 self.assertRaises(TypeError, inspect.getgeneratorlocals, (2,3))
1547
Nick Coghlane0f04652010-11-21 03:44:04 +00001548
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001549class TestSignatureObject(unittest.TestCase):
1550 @staticmethod
1551 def signature(func):
1552 sig = inspect.signature(func)
1553 return (tuple((param.name,
1554 (... if param.default is param.empty else param.default),
1555 (... if param.annotation is param.empty
1556 else param.annotation),
1557 str(param.kind).lower())
1558 for param in sig.parameters.values()),
1559 (... if sig.return_annotation is sig.empty
1560 else sig.return_annotation))
1561
1562 def test_signature_object(self):
1563 S = inspect.Signature
1564 P = inspect.Parameter
1565
1566 self.assertEqual(str(S()), '()')
1567
Yury Selivanov07a9e452014-01-29 10:58:16 -05001568 def test(po, pk, pod=42, pkd=100, *args, ko, **kwargs):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001569 pass
1570 sig = inspect.signature(test)
1571 po = sig.parameters['po'].replace(kind=P.POSITIONAL_ONLY)
Yury Selivanov07a9e452014-01-29 10:58:16 -05001572 pod = sig.parameters['pod'].replace(kind=P.POSITIONAL_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001573 pk = sig.parameters['pk']
Yury Selivanov07a9e452014-01-29 10:58:16 -05001574 pkd = sig.parameters['pkd']
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001575 args = sig.parameters['args']
1576 ko = sig.parameters['ko']
1577 kwargs = sig.parameters['kwargs']
1578
1579 S((po, pk, args, ko, kwargs))
1580
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001581 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001582 S((pk, po, args, ko, kwargs))
1583
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001584 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001585 S((po, args, pk, ko, kwargs))
1586
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001587 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001588 S((args, po, pk, ko, kwargs))
1589
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001590 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001591 S((po, pk, args, kwargs, ko))
1592
1593 kwargs2 = kwargs.replace(name='args')
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001594 with self.assertRaisesRegex(ValueError, 'duplicate parameter name'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001595 S((po, pk, args, kwargs2, ko))
1596
Yury Selivanov07a9e452014-01-29 10:58:16 -05001597 with self.assertRaisesRegex(ValueError, 'follows default argument'):
1598 S((pod, po))
1599
1600 with self.assertRaisesRegex(ValueError, 'follows default argument'):
1601 S((po, pkd, pk))
1602
1603 with self.assertRaisesRegex(ValueError, 'follows default argument'):
1604 S((pkd, pk))
1605
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001606 def test_signature_immutability(self):
1607 def test(a):
1608 pass
1609 sig = inspect.signature(test)
1610
1611 with self.assertRaises(AttributeError):
1612 sig.foo = 'bar'
1613
1614 with self.assertRaises(TypeError):
1615 sig.parameters['a'] = None
1616
1617 def test_signature_on_noarg(self):
1618 def test():
1619 pass
1620 self.assertEqual(self.signature(test), ((), ...))
1621
1622 def test_signature_on_wargs(self):
1623 def test(a, b:'foo') -> 123:
1624 pass
1625 self.assertEqual(self.signature(test),
1626 ((('a', ..., ..., "positional_or_keyword"),
1627 ('b', ..., 'foo', "positional_or_keyword")),
1628 123))
1629
1630 def test_signature_on_wkwonly(self):
1631 def test(*, a:float, b:str) -> int:
1632 pass
1633 self.assertEqual(self.signature(test),
1634 ((('a', ..., float, "keyword_only"),
1635 ('b', ..., str, "keyword_only")),
1636 int))
1637
1638 def test_signature_on_complex_args(self):
1639 def test(a, b:'foo'=10, *args:'bar', spam:'baz', ham=123, **kwargs:int):
1640 pass
1641 self.assertEqual(self.signature(test),
1642 ((('a', ..., ..., "positional_or_keyword"),
1643 ('b', 10, 'foo', "positional_or_keyword"),
1644 ('args', ..., 'bar', "var_positional"),
1645 ('spam', ..., 'baz', "keyword_only"),
1646 ('ham', 123, ..., "keyword_only"),
1647 ('kwargs', ..., int, "var_keyword")),
1648 ...))
1649
Larry Hastingsfcafe432013-11-23 17:35:48 -08001650 @unittest.skipIf(MISSING_C_DOCSTRINGS,
1651 "Signature information for builtins requires docstrings")
1652 def test_signature_on_builtins(self):
Larry Hastings16c51912014-01-07 11:53:01 -08001653
Larry Hastings5c661892014-01-24 06:17:25 -08001654 def test_unbound_method(o):
1655 """Use this to test unbound methods (things that should have a self)"""
1656 signature = inspect.signature(o)
1657 self.assertTrue(isinstance(signature, inspect.Signature))
1658 self.assertEqual(list(signature.parameters.values())[0].name, 'self')
1659 return signature
1660
1661 def test_callable(o):
1662 """Use this to test bound methods or normal callables (things that don't expect self)"""
1663 signature = inspect.signature(o)
1664 self.assertTrue(isinstance(signature, inspect.Signature))
1665 if signature.parameters:
1666 self.assertNotEqual(list(signature.parameters.values())[0].name, 'self')
1667 return signature
1668
1669 signature = test_callable(_testcapi.docstring_with_signature_with_defaults)
Larry Hastings16c51912014-01-07 11:53:01 -08001670 def p(name): return signature.parameters[name].default
1671 self.assertEqual(p('s'), 'avocado')
Larry Hastings2a727912014-01-16 11:32:01 -08001672 self.assertEqual(p('b'), b'bytes')
Larry Hastings16c51912014-01-07 11:53:01 -08001673 self.assertEqual(p('d'), 3.14)
1674 self.assertEqual(p('i'), 35)
Larry Hastings16c51912014-01-07 11:53:01 -08001675 self.assertEqual(p('n'), None)
1676 self.assertEqual(p('t'), True)
1677 self.assertEqual(p('f'), False)
Larry Hastings2a727912014-01-16 11:32:01 -08001678 self.assertEqual(p('local'), 3)
1679 self.assertEqual(p('sys'), sys.maxsize)
1680 self.assertEqual(p('exp'), sys.maxsize - 1)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001681
Larry Hastings5c661892014-01-24 06:17:25 -08001682 test_callable(type)
1683 test_callable(object)
1684
1685 # normal method
1686 # (PyMethodDescr_Type, "method_descriptor")
1687 test_unbound_method(_pickle.Pickler.dump)
1688 d = _pickle.Pickler(io.StringIO())
1689 test_callable(d.dump)
1690
1691 # static method
1692 test_callable(str.maketrans)
1693 test_callable('abc'.maketrans)
1694
1695 # class method
1696 test_callable(dict.fromkeys)
1697 test_callable({}.fromkeys)
1698
1699 # wrapper around slot (PyWrapperDescr_Type, "wrapper_descriptor")
1700 test_unbound_method(type.__call__)
1701 test_unbound_method(int.__add__)
1702 test_callable((3).__add__)
1703
1704 # _PyMethodWrapper_Type
1705 # support for 'method-wrapper'
1706 test_callable(min.__call__)
1707
1708 class ThisWorksNow:
1709 __call__ = type
1710 test_callable(ThisWorksNow())
1711
Yury Selivanov76c6c592014-01-29 10:52:57 -05001712 @unittest.skipIf(MISSING_C_DOCSTRINGS,
1713 "Signature information for builtins requires docstrings")
1714 def test_signature_on_decorated_builtins(self):
1715 func = _testcapi.docstring_with_signature_with_defaults
1716
1717 def decorator(func):
1718 @functools.wraps(func)
1719 def wrapper(*args, **kwargs) -> int:
1720 return func(*args, **kwargs)
1721 return wrapper
1722
1723 decorated_func = decorator(func)
1724
1725 self.assertEqual(inspect.signature(func),
1726 inspect.signature(decorated_func))
Larry Hastings5c661892014-01-24 06:17:25 -08001727
1728 def test_signature_on_builtins_no_signature(self):
1729 with self.assertRaisesRegex(ValueError, 'no signature found for builtin'):
1730 inspect.signature(_testcapi.docstring_no_signature)
1731
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001732 def test_signature_on_non_function(self):
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001733 with self.assertRaisesRegex(TypeError, 'is not a callable object'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001734 inspect.signature(42)
1735
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001736 with self.assertRaisesRegex(TypeError, 'is not a Python function'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001737 inspect.Signature.from_function(42)
1738
Yury Selivanovb77511d2014-01-29 10:46:14 -05001739 def test_signature_from_builtin_errors(self):
1740 with self.assertRaisesRegex(TypeError, 'is not a Python builtin'):
1741 inspect.Signature.from_builtin(42)
1742
Yury Selivanov63da7c72014-01-31 14:48:37 -05001743 def test_signature_from_functionlike_object(self):
1744 def func(a,b, *args, kwonly=True, kwonlyreq, **kwargs):
1745 pass
1746
1747 class funclike:
1748 # Has to be callable, and have correct
1749 # __code__, __annotations__, __defaults__, __name__,
1750 # and __kwdefaults__ attributes
1751
1752 def __init__(self, func):
1753 self.__name__ = func.__name__
1754 self.__code__ = func.__code__
1755 self.__annotations__ = func.__annotations__
1756 self.__defaults__ = func.__defaults__
1757 self.__kwdefaults__ = func.__kwdefaults__
1758 self.func = func
1759
1760 def __call__(self, *args, **kwargs):
1761 return self.func(*args, **kwargs)
1762
1763 sig_func = inspect.Signature.from_function(func)
1764
1765 sig_funclike = inspect.Signature.from_function(funclike(func))
1766 self.assertEqual(sig_funclike, sig_func)
1767
1768 sig_funclike = inspect.signature(funclike(func))
1769 self.assertEqual(sig_funclike, sig_func)
1770
1771 # If object is not a duck type of function, then
1772 # signature will try to get a signature for its '__call__'
1773 # method
1774 fl = funclike(func)
1775 del fl.__defaults__
1776 self.assertEqual(self.signature(fl),
1777 ((('args', ..., ..., "var_positional"),
1778 ('kwargs', ..., ..., "var_keyword")),
1779 ...))
1780
1781 def test_signature_functionlike_class(self):
1782 # We only want to duck type function-like objects,
1783 # not classes.
1784
1785 def func(a,b, *args, kwonly=True, kwonlyreq, **kwargs):
1786 pass
1787
1788 class funclike:
1789 def __init__(self, marker):
1790 pass
1791
1792 __name__ = func.__name__
1793 __code__ = func.__code__
1794 __annotations__ = func.__annotations__
1795 __defaults__ = func.__defaults__
1796 __kwdefaults__ = func.__kwdefaults__
1797
1798 with self.assertRaisesRegex(TypeError, 'is not a Python function'):
1799 inspect.Signature.from_function(funclike)
1800
1801 self.assertEqual(str(inspect.signature(funclike)), '(marker)')
1802
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001803 def test_signature_on_method(self):
1804 class Test:
Yury Selivanov62560fb2014-01-28 12:26:24 -05001805 def __init__(*args):
1806 pass
1807 def m1(self, arg1, arg2=1) -> int:
1808 pass
1809 def m2(*args):
1810 pass
1811 def __call__(*, a):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001812 pass
1813
Yury Selivanov62560fb2014-01-28 12:26:24 -05001814 self.assertEqual(self.signature(Test().m1),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001815 ((('arg1', ..., ..., "positional_or_keyword"),
1816 ('arg2', 1, ..., "positional_or_keyword")),
1817 int))
1818
Yury Selivanov62560fb2014-01-28 12:26:24 -05001819 self.assertEqual(self.signature(Test().m2),
1820 ((('args', ..., ..., "var_positional"),),
1821 ...))
1822
1823 self.assertEqual(self.signature(Test),
1824 ((('args', ..., ..., "var_positional"),),
1825 ...))
1826
1827 with self.assertRaisesRegex(ValueError, 'invalid method signature'):
1828 self.signature(Test())
1829
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001830 def test_signature_on_classmethod(self):
1831 class Test:
1832 @classmethod
1833 def foo(cls, arg1, *, arg2=1):
1834 pass
1835
1836 meth = Test().foo
1837 self.assertEqual(self.signature(meth),
1838 ((('arg1', ..., ..., "positional_or_keyword"),
1839 ('arg2', 1, ..., "keyword_only")),
1840 ...))
1841
1842 meth = Test.foo
1843 self.assertEqual(self.signature(meth),
1844 ((('arg1', ..., ..., "positional_or_keyword"),
1845 ('arg2', 1, ..., "keyword_only")),
1846 ...))
1847
1848 def test_signature_on_staticmethod(self):
1849 class Test:
1850 @staticmethod
1851 def foo(cls, *, arg):
1852 pass
1853
1854 meth = Test().foo
1855 self.assertEqual(self.signature(meth),
1856 ((('cls', ..., ..., "positional_or_keyword"),
1857 ('arg', ..., ..., "keyword_only")),
1858 ...))
1859
1860 meth = Test.foo
1861 self.assertEqual(self.signature(meth),
1862 ((('cls', ..., ..., "positional_or_keyword"),
1863 ('arg', ..., ..., "keyword_only")),
1864 ...))
1865
1866 def test_signature_on_partial(self):
1867 from functools import partial
1868
1869 def test():
1870 pass
1871
1872 self.assertEqual(self.signature(partial(test)), ((), ...))
1873
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001874 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001875 inspect.signature(partial(test, 1))
1876
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001877 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001878 inspect.signature(partial(test, a=1))
1879
1880 def test(a, b, *, c, d):
1881 pass
1882
1883 self.assertEqual(self.signature(partial(test)),
1884 ((('a', ..., ..., "positional_or_keyword"),
1885 ('b', ..., ..., "positional_or_keyword"),
1886 ('c', ..., ..., "keyword_only"),
1887 ('d', ..., ..., "keyword_only")),
1888 ...))
1889
1890 self.assertEqual(self.signature(partial(test, 1)),
1891 ((('b', ..., ..., "positional_or_keyword"),
1892 ('c', ..., ..., "keyword_only"),
1893 ('d', ..., ..., "keyword_only")),
1894 ...))
1895
1896 self.assertEqual(self.signature(partial(test, 1, c=2)),
1897 ((('b', ..., ..., "positional_or_keyword"),
1898 ('c', 2, ..., "keyword_only"),
1899 ('d', ..., ..., "keyword_only")),
1900 ...))
1901
1902 self.assertEqual(self.signature(partial(test, b=1, c=2)),
1903 ((('a', ..., ..., "positional_or_keyword"),
1904 ('b', 1, ..., "positional_or_keyword"),
1905 ('c', 2, ..., "keyword_only"),
1906 ('d', ..., ..., "keyword_only")),
1907 ...))
1908
1909 self.assertEqual(self.signature(partial(test, 0, b=1, c=2)),
1910 ((('b', 1, ..., "positional_or_keyword"),
1911 ('c', 2, ..., "keyword_only"),
1912 ('d', ..., ..., "keyword_only"),),
1913 ...))
1914
1915 def test(a, *args, b, **kwargs):
1916 pass
1917
1918 self.assertEqual(self.signature(partial(test, 1)),
1919 ((('args', ..., ..., "var_positional"),
1920 ('b', ..., ..., "keyword_only"),
1921 ('kwargs', ..., ..., "var_keyword")),
1922 ...))
1923
1924 self.assertEqual(self.signature(partial(test, 1, 2, 3)),
1925 ((('args', ..., ..., "var_positional"),
1926 ('b', ..., ..., "keyword_only"),
1927 ('kwargs', ..., ..., "var_keyword")),
1928 ...))
1929
1930
1931 self.assertEqual(self.signature(partial(test, 1, 2, 3, test=True)),
1932 ((('args', ..., ..., "var_positional"),
1933 ('b', ..., ..., "keyword_only"),
1934 ('kwargs', ..., ..., "var_keyword")),
1935 ...))
1936
1937 self.assertEqual(self.signature(partial(test, 1, 2, 3, test=1, b=0)),
1938 ((('args', ..., ..., "var_positional"),
1939 ('b', 0, ..., "keyword_only"),
1940 ('kwargs', ..., ..., "var_keyword")),
1941 ...))
1942
1943 self.assertEqual(self.signature(partial(test, b=0)),
1944 ((('a', ..., ..., "positional_or_keyword"),
1945 ('args', ..., ..., "var_positional"),
1946 ('b', 0, ..., "keyword_only"),
1947 ('kwargs', ..., ..., "var_keyword")),
1948 ...))
1949
1950 self.assertEqual(self.signature(partial(test, b=0, test=1)),
1951 ((('a', ..., ..., "positional_or_keyword"),
1952 ('args', ..., ..., "var_positional"),
1953 ('b', 0, ..., "keyword_only"),
1954 ('kwargs', ..., ..., "var_keyword")),
1955 ...))
1956
1957 def test(a, b, c:int) -> 42:
1958 pass
1959
1960 sig = test.__signature__ = inspect.signature(test)
1961
1962 self.assertEqual(self.signature(partial(partial(test, 1))),
1963 ((('b', ..., ..., "positional_or_keyword"),
1964 ('c', ..., int, "positional_or_keyword")),
1965 42))
1966
1967 self.assertEqual(self.signature(partial(partial(test, 1), 2)),
1968 ((('c', ..., int, "positional_or_keyword"),),
1969 42))
1970
1971 psig = inspect.signature(partial(partial(test, 1), 2))
1972
1973 def foo(a):
1974 return a
1975 _foo = partial(partial(foo, a=10), a=20)
1976 self.assertEqual(self.signature(_foo),
1977 ((('a', 20, ..., "positional_or_keyword"),),
1978 ...))
1979 # check that we don't have any side-effects in signature(),
1980 # and the partial object is still functioning
1981 self.assertEqual(_foo(), 20)
1982
1983 def foo(a, b, c):
1984 return a, b, c
1985 _foo = partial(partial(foo, 1, b=20), b=30)
1986 self.assertEqual(self.signature(_foo),
1987 ((('b', 30, ..., "positional_or_keyword"),
1988 ('c', ..., ..., "positional_or_keyword")),
1989 ...))
1990 self.assertEqual(_foo(c=10), (1, 30, 10))
1991 _foo = partial(_foo, 2) # now 'b' has two values -
1992 # positional and keyword
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001993 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001994 inspect.signature(_foo)
1995
1996 def foo(a, b, c, *, d):
1997 return a, b, c, d
1998 _foo = partial(partial(foo, d=20, c=20), b=10, d=30)
1999 self.assertEqual(self.signature(_foo),
2000 ((('a', ..., ..., "positional_or_keyword"),
2001 ('b', 10, ..., "positional_or_keyword"),
2002 ('c', 20, ..., "positional_or_keyword"),
2003 ('d', 30, ..., "keyword_only")),
2004 ...))
2005 ba = inspect.signature(_foo).bind(a=200, b=11)
2006 self.assertEqual(_foo(*ba.args, **ba.kwargs), (200, 11, 20, 30))
2007
2008 def foo(a=1, b=2, c=3):
2009 return a, b, c
2010 _foo = partial(foo, a=10, c=13)
2011 ba = inspect.signature(_foo).bind(11)
2012 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 2, 13))
2013 ba = inspect.signature(_foo).bind(11, 12)
2014 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
2015 ba = inspect.signature(_foo).bind(11, b=12)
2016 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
2017 ba = inspect.signature(_foo).bind(b=12)
2018 self.assertEqual(_foo(*ba.args, **ba.kwargs), (10, 12, 13))
2019 _foo = partial(_foo, b=10)
2020 ba = inspect.signature(_foo).bind(12, 14)
2021 self.assertEqual(_foo(*ba.args, **ba.kwargs), (12, 14, 13))
2022
Yury Selivanovda5fe4f2014-01-27 17:28:37 -05002023 def test_signature_on_partialmethod(self):
2024 from functools import partialmethod
2025
2026 class Spam:
2027 def test():
2028 pass
2029 ham = partialmethod(test)
2030
2031 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
2032 inspect.signature(Spam.ham)
2033
2034 class Spam:
2035 def test(it, a, *, c) -> 'spam':
2036 pass
2037 ham = partialmethod(test, c=1)
2038
2039 self.assertEqual(self.signature(Spam.ham),
2040 ((('it', ..., ..., 'positional_or_keyword'),
2041 ('a', ..., ..., 'positional_or_keyword'),
2042 ('c', 1, ..., 'keyword_only')),
2043 'spam'))
2044
2045 self.assertEqual(self.signature(Spam().ham),
2046 ((('a', ..., ..., 'positional_or_keyword'),
2047 ('c', 1, ..., 'keyword_only')),
2048 'spam'))
2049
Yury Selivanov0486f812014-01-29 12:18:59 -05002050 def test_signature_on_fake_partialmethod(self):
2051 def foo(a): pass
2052 foo._partialmethod = 'spam'
2053 self.assertEqual(str(inspect.signature(foo)), '(a)')
2054
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002055 def test_signature_on_decorated(self):
2056 import functools
2057
2058 def decorator(func):
2059 @functools.wraps(func)
2060 def wrapper(*args, **kwargs) -> int:
2061 return func(*args, **kwargs)
2062 return wrapper
2063
2064 class Foo:
2065 @decorator
2066 def bar(self, a, b):
2067 pass
2068
2069 self.assertEqual(self.signature(Foo.bar),
2070 ((('self', ..., ..., "positional_or_keyword"),
2071 ('a', ..., ..., "positional_or_keyword"),
2072 ('b', ..., ..., "positional_or_keyword")),
2073 ...))
2074
2075 self.assertEqual(self.signature(Foo().bar),
2076 ((('a', ..., ..., "positional_or_keyword"),
2077 ('b', ..., ..., "positional_or_keyword")),
2078 ...))
2079
2080 # Test that we handle method wrappers correctly
2081 def decorator(func):
2082 @functools.wraps(func)
2083 def wrapper(*args, **kwargs) -> int:
2084 return func(42, *args, **kwargs)
2085 sig = inspect.signature(func)
2086 new_params = tuple(sig.parameters.values())[1:]
2087 wrapper.__signature__ = sig.replace(parameters=new_params)
2088 return wrapper
2089
2090 class Foo:
2091 @decorator
2092 def __call__(self, a, b):
2093 pass
2094
2095 self.assertEqual(self.signature(Foo.__call__),
2096 ((('a', ..., ..., "positional_or_keyword"),
2097 ('b', ..., ..., "positional_or_keyword")),
2098 ...))
2099
2100 self.assertEqual(self.signature(Foo().__call__),
2101 ((('b', ..., ..., "positional_or_keyword"),),
2102 ...))
2103
Nick Coghlane8c45d62013-07-28 20:00:01 +10002104 # Test we handle __signature__ partway down the wrapper stack
2105 def wrapped_foo_call():
2106 pass
2107 wrapped_foo_call.__wrapped__ = Foo.__call__
2108
2109 self.assertEqual(self.signature(wrapped_foo_call),
2110 ((('a', ..., ..., "positional_or_keyword"),
2111 ('b', ..., ..., "positional_or_keyword")),
2112 ...))
2113
2114
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002115 def test_signature_on_class(self):
2116 class C:
2117 def __init__(self, a):
2118 pass
2119
2120 self.assertEqual(self.signature(C),
2121 ((('a', ..., ..., "positional_or_keyword"),),
2122 ...))
2123
2124 class CM(type):
2125 def __call__(cls, a):
2126 pass
2127 class C(metaclass=CM):
2128 def __init__(self, b):
2129 pass
2130
2131 self.assertEqual(self.signature(C),
2132 ((('a', ..., ..., "positional_or_keyword"),),
2133 ...))
2134
2135 class CM(type):
2136 def __new__(mcls, name, bases, dct, *, foo=1):
2137 return super().__new__(mcls, name, bases, dct)
2138 class C(metaclass=CM):
2139 def __init__(self, b):
2140 pass
2141
2142 self.assertEqual(self.signature(C),
2143 ((('b', ..., ..., "positional_or_keyword"),),
2144 ...))
2145
2146 self.assertEqual(self.signature(CM),
2147 ((('name', ..., ..., "positional_or_keyword"),
2148 ('bases', ..., ..., "positional_or_keyword"),
2149 ('dct', ..., ..., "positional_or_keyword"),
2150 ('foo', 1, ..., "keyword_only")),
2151 ...))
2152
2153 class CMM(type):
2154 def __new__(mcls, name, bases, dct, *, foo=1):
2155 return super().__new__(mcls, name, bases, dct)
2156 def __call__(cls, nm, bs, dt):
2157 return type(nm, bs, dt)
2158 class CM(type, metaclass=CMM):
2159 def __new__(mcls, name, bases, dct, *, bar=2):
2160 return super().__new__(mcls, name, bases, dct)
2161 class C(metaclass=CM):
2162 def __init__(self, b):
2163 pass
2164
2165 self.assertEqual(self.signature(CMM),
2166 ((('name', ..., ..., "positional_or_keyword"),
2167 ('bases', ..., ..., "positional_or_keyword"),
2168 ('dct', ..., ..., "positional_or_keyword"),
2169 ('foo', 1, ..., "keyword_only")),
2170 ...))
2171
2172 self.assertEqual(self.signature(CM),
2173 ((('nm', ..., ..., "positional_or_keyword"),
2174 ('bs', ..., ..., "positional_or_keyword"),
2175 ('dt', ..., ..., "positional_or_keyword")),
2176 ...))
2177
2178 self.assertEqual(self.signature(C),
2179 ((('b', ..., ..., "positional_or_keyword"),),
2180 ...))
2181
2182 class CM(type):
2183 def __init__(cls, name, bases, dct, *, bar=2):
2184 return super().__init__(name, bases, dct)
2185 class C(metaclass=CM):
2186 def __init__(self, b):
2187 pass
2188
2189 self.assertEqual(self.signature(CM),
2190 ((('name', ..., ..., "positional_or_keyword"),
2191 ('bases', ..., ..., "positional_or_keyword"),
2192 ('dct', ..., ..., "positional_or_keyword"),
2193 ('bar', 2, ..., "keyword_only")),
2194 ...))
2195
Yury Selivanov145dff82014-02-01 13:49:29 -05002196 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2197 "Signature information for builtins requires docstrings")
2198 def test_signature_on_class_without_init(self):
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002199 # Test classes without user-defined __init__ or __new__
2200 class C: pass
2201 self.assertEqual(str(inspect.signature(C)), '()')
2202 class D(C): pass
2203 self.assertEqual(str(inspect.signature(D)), '()')
2204
2205 # Test meta-classes without user-defined __init__ or __new__
2206 class C(type): pass
2207 self.assertEqual(str(inspect.signature(C)),
2208 '(object_or_name, bases, dict)')
2209 class D(C): pass
2210 self.assertEqual(str(inspect.signature(D)),
2211 '(object_or_name, bases, dict)')
2212
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002213 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2214 "Signature information for builtins requires docstrings")
2215 def test_signature_on_builtin_class(self):
2216 self.assertEqual(str(inspect.signature(_pickle.Pickler)),
2217 '(file, protocol=None, fix_imports=True)')
2218
2219 class P(_pickle.Pickler): pass
2220 class EmptyTrait: pass
2221 class P2(EmptyTrait, P): pass
2222 self.assertEqual(str(inspect.signature(P)),
2223 '(file, protocol=None, fix_imports=True)')
2224 self.assertEqual(str(inspect.signature(P2)),
2225 '(file, protocol=None, fix_imports=True)')
2226
2227 class P3(P2):
2228 def __init__(self, spam):
2229 pass
2230 self.assertEqual(str(inspect.signature(P3)), '(spam)')
2231
2232 class MetaP(type):
2233 def __call__(cls, foo, bar):
2234 pass
2235 class P4(P2, metaclass=MetaP):
2236 pass
2237 self.assertEqual(str(inspect.signature(P4)), '(foo, bar)')
2238
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002239 def test_signature_on_callable_objects(self):
2240 class Foo:
2241 def __call__(self, a):
2242 pass
2243
2244 self.assertEqual(self.signature(Foo()),
2245 ((('a', ..., ..., "positional_or_keyword"),),
2246 ...))
2247
2248 class Spam:
2249 pass
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002250 with self.assertRaisesRegex(TypeError, "is not a callable object"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002251 inspect.signature(Spam())
2252
2253 class Bar(Spam, Foo):
2254 pass
2255
2256 self.assertEqual(self.signature(Bar()),
2257 ((('a', ..., ..., "positional_or_keyword"),),
2258 ...))
2259
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002260 class Wrapped:
2261 pass
2262 Wrapped.__wrapped__ = lambda a: None
2263 self.assertEqual(self.signature(Wrapped),
2264 ((('a', ..., ..., "positional_or_keyword"),),
2265 ...))
Nick Coghlane8c45d62013-07-28 20:00:01 +10002266 # wrapper loop:
2267 Wrapped.__wrapped__ = Wrapped
2268 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
2269 self.signature(Wrapped)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002270
2271 def test_signature_on_lambdas(self):
2272 self.assertEqual(self.signature((lambda a=10: a)),
2273 ((('a', 10, ..., "positional_or_keyword"),),
2274 ...))
2275
2276 def test_signature_equality(self):
2277 def foo(a, *, b:int) -> float: pass
2278 self.assertNotEqual(inspect.signature(foo), 42)
2279
2280 def bar(a, *, b:int) -> float: pass
2281 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
2282
2283 def bar(a, *, b:int) -> int: pass
2284 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
2285
2286 def bar(a, *, b:int): pass
2287 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
2288
2289 def bar(a, *, b:int=42) -> float: pass
2290 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
2291
2292 def bar(a, *, c) -> float: pass
2293 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
2294
2295 def bar(a, b:int) -> float: pass
2296 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
2297 def spam(b:int, a) -> float: pass
2298 self.assertNotEqual(inspect.signature(spam), inspect.signature(bar))
2299
2300 def foo(*, a, b, c): pass
2301 def bar(*, c, b, a): pass
2302 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
2303
2304 def foo(*, a=1, b, c): pass
2305 def bar(*, c, b, a=1): pass
2306 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
2307
2308 def foo(pos, *, a=1, b, c): pass
2309 def bar(pos, *, c, b, a=1): pass
2310 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
2311
2312 def foo(pos, *, a, b, c): pass
2313 def bar(pos, *, c, b, a=1): pass
2314 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
2315
2316 def foo(pos, *args, a=42, b, c, **kwargs:int): pass
2317 def bar(pos, *args, c, b, a=42, **kwargs:int): pass
2318 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
2319
2320 def test_signature_unhashable(self):
2321 def foo(a): pass
2322 sig = inspect.signature(foo)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002323 with self.assertRaisesRegex(TypeError, 'unhashable type'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002324 hash(sig)
2325
2326 def test_signature_str(self):
2327 def foo(a:int=1, *, b, c=None, **kwargs) -> 42:
2328 pass
2329 self.assertEqual(str(inspect.signature(foo)),
2330 '(a:int=1, *, b, c=None, **kwargs) -> 42')
2331
2332 def foo(a:int=1, *args, b, c=None, **kwargs) -> 42:
2333 pass
2334 self.assertEqual(str(inspect.signature(foo)),
2335 '(a:int=1, *args, b, c=None, **kwargs) -> 42')
2336
2337 def foo():
2338 pass
2339 self.assertEqual(str(inspect.signature(foo)), '()')
2340
2341 def test_signature_str_positional_only(self):
2342 P = inspect.Parameter
Yury Selivanov2393dca2014-01-27 15:07:58 -05002343 S = inspect.Signature
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002344
2345 def test(a_po, *, b, **kwargs):
2346 return a_po, kwargs
2347
2348 sig = inspect.signature(test)
2349 new_params = list(sig.parameters.values())
2350 new_params[0] = new_params[0].replace(kind=P.POSITIONAL_ONLY)
2351 test.__signature__ = sig.replace(parameters=new_params)
2352
2353 self.assertEqual(str(inspect.signature(test)),
Yury Selivanov2393dca2014-01-27 15:07:58 -05002354 '(a_po, /, *, b, **kwargs)')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002355
Yury Selivanov2393dca2014-01-27 15:07:58 -05002356 self.assertEqual(str(S(parameters=[P('foo', P.POSITIONAL_ONLY)])),
2357 '(foo, /)')
2358
2359 self.assertEqual(str(S(parameters=[
2360 P('foo', P.POSITIONAL_ONLY),
2361 P('bar', P.VAR_KEYWORD)])),
2362 '(foo, /, **bar)')
2363
2364 self.assertEqual(str(S(parameters=[
2365 P('foo', P.POSITIONAL_ONLY),
2366 P('bar', P.VAR_POSITIONAL)])),
2367 '(foo, /, *bar)')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002368
2369 def test_signature_replace_anno(self):
2370 def test() -> 42:
2371 pass
2372
2373 sig = inspect.signature(test)
2374 sig = sig.replace(return_annotation=None)
2375 self.assertIs(sig.return_annotation, None)
2376 sig = sig.replace(return_annotation=sig.empty)
2377 self.assertIs(sig.return_annotation, sig.empty)
2378 sig = sig.replace(return_annotation=42)
2379 self.assertEqual(sig.return_annotation, 42)
2380 self.assertEqual(sig, inspect.signature(test))
2381
2382
2383class TestParameterObject(unittest.TestCase):
2384 def test_signature_parameter_kinds(self):
2385 P = inspect.Parameter
2386 self.assertTrue(P.POSITIONAL_ONLY < P.POSITIONAL_OR_KEYWORD < \
2387 P.VAR_POSITIONAL < P.KEYWORD_ONLY < P.VAR_KEYWORD)
2388
2389 self.assertEqual(str(P.POSITIONAL_ONLY), 'POSITIONAL_ONLY')
2390 self.assertTrue('POSITIONAL_ONLY' in repr(P.POSITIONAL_ONLY))
2391
2392 def test_signature_parameter_object(self):
2393 p = inspect.Parameter('foo', default=10,
2394 kind=inspect.Parameter.POSITIONAL_ONLY)
2395 self.assertEqual(p.name, 'foo')
2396 self.assertEqual(p.default, 10)
2397 self.assertIs(p.annotation, p.empty)
2398 self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY)
2399
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002400 with self.assertRaisesRegex(ValueError, 'invalid value'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002401 inspect.Parameter('foo', default=10, kind='123')
2402
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002403 with self.assertRaisesRegex(ValueError, 'not a valid parameter name'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002404 inspect.Parameter('1', kind=inspect.Parameter.VAR_KEYWORD)
2405
Yury Selivanov2393dca2014-01-27 15:07:58 -05002406 with self.assertRaisesRegex(TypeError, 'name must be a str'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002407 inspect.Parameter(None, kind=inspect.Parameter.VAR_KEYWORD)
2408
Yury Selivanov2393dca2014-01-27 15:07:58 -05002409 with self.assertRaisesRegex(ValueError,
2410 'is not a valid parameter name'):
2411 inspect.Parameter('$', kind=inspect.Parameter.VAR_KEYWORD)
2412
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002413 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002414 inspect.Parameter('a', default=42,
2415 kind=inspect.Parameter.VAR_KEYWORD)
2416
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002417 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002418 inspect.Parameter('a', default=42,
2419 kind=inspect.Parameter.VAR_POSITIONAL)
2420
2421 p = inspect.Parameter('a', default=42,
2422 kind=inspect.Parameter.POSITIONAL_OR_KEYWORD)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002423 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002424 p.replace(kind=inspect.Parameter.VAR_POSITIONAL)
2425
2426 self.assertTrue(repr(p).startswith('<Parameter'))
2427
2428 def test_signature_parameter_equality(self):
2429 P = inspect.Parameter
2430 p = P('foo', default=42, kind=inspect.Parameter.KEYWORD_ONLY)
2431
2432 self.assertEqual(p, p)
2433 self.assertNotEqual(p, 42)
2434
2435 self.assertEqual(p, P('foo', default=42,
2436 kind=inspect.Parameter.KEYWORD_ONLY))
2437
2438 def test_signature_parameter_unhashable(self):
2439 p = inspect.Parameter('foo', default=42,
2440 kind=inspect.Parameter.KEYWORD_ONLY)
2441
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002442 with self.assertRaisesRegex(TypeError, 'unhashable type'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002443 hash(p)
2444
2445 def test_signature_parameter_replace(self):
2446 p = inspect.Parameter('foo', default=42,
2447 kind=inspect.Parameter.KEYWORD_ONLY)
2448
2449 self.assertIsNot(p, p.replace())
2450 self.assertEqual(p, p.replace())
2451
2452 p2 = p.replace(annotation=1)
2453 self.assertEqual(p2.annotation, 1)
2454 p2 = p2.replace(annotation=p2.empty)
2455 self.assertEqual(p, p2)
2456
2457 p2 = p2.replace(name='bar')
2458 self.assertEqual(p2.name, 'bar')
2459 self.assertNotEqual(p2, p)
2460
Yury Selivanov2393dca2014-01-27 15:07:58 -05002461 with self.assertRaisesRegex(ValueError,
2462 'name is a required attribute'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002463 p2 = p2.replace(name=p2.empty)
2464
2465 p2 = p2.replace(name='foo', default=None)
2466 self.assertIs(p2.default, None)
2467 self.assertNotEqual(p2, p)
2468
2469 p2 = p2.replace(name='foo', default=p2.empty)
2470 self.assertIs(p2.default, p2.empty)
2471
2472
2473 p2 = p2.replace(default=42, kind=p2.POSITIONAL_OR_KEYWORD)
2474 self.assertEqual(p2.kind, p2.POSITIONAL_OR_KEYWORD)
2475 self.assertNotEqual(p2, p)
2476
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002477 with self.assertRaisesRegex(ValueError, 'invalid value for'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002478 p2 = p2.replace(kind=p2.empty)
2479
2480 p2 = p2.replace(kind=p2.KEYWORD_ONLY)
2481 self.assertEqual(p2, p)
2482
2483 def test_signature_parameter_positional_only(self):
Yury Selivanov2393dca2014-01-27 15:07:58 -05002484 with self.assertRaisesRegex(TypeError, 'name must be a str'):
2485 inspect.Parameter(None, kind=inspect.Parameter.POSITIONAL_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002486
2487 def test_signature_parameter_immutability(self):
Yury Selivanov2393dca2014-01-27 15:07:58 -05002488 p = inspect.Parameter('spam', kind=inspect.Parameter.KEYWORD_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002489
2490 with self.assertRaises(AttributeError):
2491 p.foo = 'bar'
2492
2493 with self.assertRaises(AttributeError):
2494 p.kind = 123
2495
2496
2497class TestSignatureBind(unittest.TestCase):
2498 @staticmethod
2499 def call(func, *args, **kwargs):
2500 sig = inspect.signature(func)
2501 ba = sig.bind(*args, **kwargs)
2502 return func(*ba.args, **ba.kwargs)
2503
2504 def test_signature_bind_empty(self):
2505 def test():
2506 return 42
2507
2508 self.assertEqual(self.call(test), 42)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002509 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002510 self.call(test, 1)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002511 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002512 self.call(test, 1, spam=10)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002513 with self.assertRaisesRegex(TypeError, 'too many keyword arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002514 self.call(test, spam=1)
2515
2516 def test_signature_bind_var(self):
2517 def test(*args, **kwargs):
2518 return args, kwargs
2519
2520 self.assertEqual(self.call(test), ((), {}))
2521 self.assertEqual(self.call(test, 1), ((1,), {}))
2522 self.assertEqual(self.call(test, 1, 2), ((1, 2), {}))
2523 self.assertEqual(self.call(test, foo='bar'), ((), {'foo': 'bar'}))
2524 self.assertEqual(self.call(test, 1, foo='bar'), ((1,), {'foo': 'bar'}))
2525 self.assertEqual(self.call(test, args=10), ((), {'args': 10}))
2526 self.assertEqual(self.call(test, 1, 2, foo='bar'),
2527 ((1, 2), {'foo': 'bar'}))
2528
2529 def test_signature_bind_just_args(self):
2530 def test(a, b, c):
2531 return a, b, c
2532
2533 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
2534
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002535 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002536 self.call(test, 1, 2, 3, 4)
2537
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002538 with self.assertRaisesRegex(TypeError, "'b' parameter lacking default"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002539 self.call(test, 1)
2540
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002541 with self.assertRaisesRegex(TypeError, "'a' parameter lacking default"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002542 self.call(test)
2543
2544 def test(a, b, c=10):
2545 return a, b, c
2546 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
2547 self.assertEqual(self.call(test, 1, 2), (1, 2, 10))
2548
2549 def test(a=1, b=2, c=3):
2550 return a, b, c
2551 self.assertEqual(self.call(test, a=10, c=13), (10, 2, 13))
2552 self.assertEqual(self.call(test, a=10), (10, 2, 3))
2553 self.assertEqual(self.call(test, b=10), (1, 10, 3))
2554
2555 def test_signature_bind_varargs_order(self):
2556 def test(*args):
2557 return args
2558
2559 self.assertEqual(self.call(test), ())
2560 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
2561
2562 def test_signature_bind_args_and_varargs(self):
2563 def test(a, b, c=3, *args):
2564 return a, b, c, args
2565
2566 self.assertEqual(self.call(test, 1, 2, 3, 4, 5), (1, 2, 3, (4, 5)))
2567 self.assertEqual(self.call(test, 1, 2), (1, 2, 3, ()))
2568 self.assertEqual(self.call(test, b=1, a=2), (2, 1, 3, ()))
2569 self.assertEqual(self.call(test, 1, b=2), (1, 2, 3, ()))
2570
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002571 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002572 "multiple values for argument 'c'"):
2573 self.call(test, 1, 2, 3, c=4)
2574
2575 def test_signature_bind_just_kwargs(self):
2576 def test(**kwargs):
2577 return kwargs
2578
2579 self.assertEqual(self.call(test), {})
2580 self.assertEqual(self.call(test, foo='bar', spam='ham'),
2581 {'foo': 'bar', 'spam': 'ham'})
2582
2583 def test_signature_bind_args_and_kwargs(self):
2584 def test(a, b, c=3, **kwargs):
2585 return a, b, c, kwargs
2586
2587 self.assertEqual(self.call(test, 1, 2), (1, 2, 3, {}))
2588 self.assertEqual(self.call(test, 1, 2, foo='bar', spam='ham'),
2589 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
2590 self.assertEqual(self.call(test, b=2, a=1, foo='bar', spam='ham'),
2591 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
2592 self.assertEqual(self.call(test, a=1, b=2, foo='bar', spam='ham'),
2593 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
2594 self.assertEqual(self.call(test, 1, b=2, foo='bar', spam='ham'),
2595 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
2596 self.assertEqual(self.call(test, 1, b=2, c=4, foo='bar', spam='ham'),
2597 (1, 2, 4, {'foo': 'bar', 'spam': 'ham'}))
2598 self.assertEqual(self.call(test, 1, 2, 4, foo='bar'),
2599 (1, 2, 4, {'foo': 'bar'}))
2600 self.assertEqual(self.call(test, c=5, a=4, b=3),
2601 (4, 3, 5, {}))
2602
2603 def test_signature_bind_kwonly(self):
2604 def test(*, foo):
2605 return foo
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002606 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002607 'too many positional arguments'):
2608 self.call(test, 1)
2609 self.assertEqual(self.call(test, foo=1), 1)
2610
2611 def test(a, *, foo=1, bar):
2612 return foo
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002613 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002614 "'bar' parameter lacking default value"):
2615 self.call(test, 1)
2616
2617 def test(foo, *, bar):
2618 return foo, bar
2619 self.assertEqual(self.call(test, 1, bar=2), (1, 2))
2620 self.assertEqual(self.call(test, bar=2, foo=1), (1, 2))
2621
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002622 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002623 'too many keyword arguments'):
2624 self.call(test, bar=2, foo=1, spam=10)
2625
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002626 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002627 'too many positional arguments'):
2628 self.call(test, 1, 2)
2629
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002630 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002631 'too many positional arguments'):
2632 self.call(test, 1, 2, bar=2)
2633
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002634 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002635 'too many keyword arguments'):
2636 self.call(test, 1, bar=2, spam='ham')
2637
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002638 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002639 "'bar' parameter lacking default value"):
2640 self.call(test, 1)
2641
2642 def test(foo, *, bar, **bin):
2643 return foo, bar, bin
2644 self.assertEqual(self.call(test, 1, bar=2), (1, 2, {}))
2645 self.assertEqual(self.call(test, foo=1, bar=2), (1, 2, {}))
2646 self.assertEqual(self.call(test, 1, bar=2, spam='ham'),
2647 (1, 2, {'spam': 'ham'}))
2648 self.assertEqual(self.call(test, spam='ham', foo=1, bar=2),
2649 (1, 2, {'spam': 'ham'}))
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002650 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002651 "'foo' parameter lacking default value"):
2652 self.call(test, spam='ham', bar=2)
2653 self.assertEqual(self.call(test, 1, bar=2, bin=1, spam=10),
2654 (1, 2, {'bin': 1, 'spam': 10}))
2655
2656 def test_signature_bind_arguments(self):
2657 def test(a, *args, b, z=100, **kwargs):
2658 pass
2659 sig = inspect.signature(test)
2660 ba = sig.bind(10, 20, b=30, c=40, args=50, kwargs=60)
2661 # we won't have 'z' argument in the bound arguments object, as we didn't
2662 # pass it to the 'bind'
2663 self.assertEqual(tuple(ba.arguments.items()),
2664 (('a', 10), ('args', (20,)), ('b', 30),
2665 ('kwargs', {'c': 40, 'args': 50, 'kwargs': 60})))
2666 self.assertEqual(ba.kwargs,
2667 {'b': 30, 'c': 40, 'args': 50, 'kwargs': 60})
2668 self.assertEqual(ba.args, (10, 20))
2669
2670 def test_signature_bind_positional_only(self):
2671 P = inspect.Parameter
2672
2673 def test(a_po, b_po, c_po=3, foo=42, *, bar=50, **kwargs):
2674 return a_po, b_po, c_po, foo, bar, kwargs
2675
2676 sig = inspect.signature(test)
2677 new_params = collections.OrderedDict(tuple(sig.parameters.items()))
2678 for name in ('a_po', 'b_po', 'c_po'):
2679 new_params[name] = new_params[name].replace(kind=P.POSITIONAL_ONLY)
2680 new_sig = sig.replace(parameters=new_params.values())
2681 test.__signature__ = new_sig
2682
2683 self.assertEqual(self.call(test, 1, 2, 4, 5, bar=6),
2684 (1, 2, 4, 5, 6, {}))
2685
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05002686 self.assertEqual(self.call(test, 1, 2),
2687 (1, 2, 3, 42, 50, {}))
2688
2689 self.assertEqual(self.call(test, 1, 2, foo=4, bar=5),
2690 (1, 2, 3, 4, 5, {}))
2691
2692 with self.assertRaisesRegex(TypeError, "but was passed as a keyword"):
2693 self.call(test, 1, 2, foo=4, bar=5, c_po=10)
2694
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002695 with self.assertRaisesRegex(TypeError, "parameter is positional only"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002696 self.call(test, 1, 2, c_po=4)
2697
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002698 with self.assertRaisesRegex(TypeError, "parameter is positional only"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002699 self.call(test, a_po=1, b_po=2)
2700
Antoine Pitroubd41d1b2013-01-29 21:20:57 +01002701 def test_signature_bind_with_self_arg(self):
2702 # Issue #17071: one of the parameters is named "self
2703 def test(a, self, b):
2704 pass
2705 sig = inspect.signature(test)
2706 ba = sig.bind(1, 2, 3)
2707 self.assertEqual(ba.args, (1, 2, 3))
2708 ba = sig.bind(1, self=2, b=3)
2709 self.assertEqual(ba.args, (1, 2, 3))
2710
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05002711 def test_signature_bind_vararg_name(self):
2712 def test(a, *args):
2713 return a, args
2714 sig = inspect.signature(test)
2715
2716 with self.assertRaisesRegex(TypeError, "too many keyword arguments"):
2717 sig.bind(a=0, args=1)
2718
2719 def test(*args, **kwargs):
2720 return args, kwargs
2721 self.assertEqual(self.call(test, args=1), ((), {'args': 1}))
2722
2723 sig = inspect.signature(test)
2724 ba = sig.bind(args=1)
2725 self.assertEqual(ba.arguments, {'kwargs': {'args': 1}})
2726
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002727
2728class TestBoundArguments(unittest.TestCase):
2729 def test_signature_bound_arguments_unhashable(self):
2730 def foo(a): pass
2731 ba = inspect.signature(foo).bind(1)
2732
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002733 with self.assertRaisesRegex(TypeError, 'unhashable type'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002734 hash(ba)
2735
2736 def test_signature_bound_arguments_equality(self):
2737 def foo(a): pass
2738 ba = inspect.signature(foo).bind(1)
2739 self.assertEqual(ba, ba)
2740
2741 ba2 = inspect.signature(foo).bind(1)
2742 self.assertEqual(ba, ba2)
2743
2744 ba3 = inspect.signature(foo).bind(2)
2745 self.assertNotEqual(ba, ba3)
2746 ba3.arguments['a'] = 1
2747 self.assertEqual(ba, ba3)
2748
2749 def bar(b): pass
2750 ba4 = inspect.signature(bar).bind(1)
2751 self.assertNotEqual(ba, ba4)
2752
2753
Yury Selivanovd82eddc2014-01-29 11:24:39 -05002754class TestSignaturePrivateHelpers(unittest.TestCase):
2755 def test_signature_get_bound_param(self):
2756 getter = inspect._signature_get_bound_param
2757
2758 self.assertEqual(getter('($self)'), 'self')
2759 self.assertEqual(getter('($self, obj)'), 'self')
2760 self.assertEqual(getter('($cls, /, obj)'), 'cls')
2761
2762
Nick Coghlane8c45d62013-07-28 20:00:01 +10002763class TestUnwrap(unittest.TestCase):
2764
2765 def test_unwrap_one(self):
2766 def func(a, b):
2767 return a + b
2768 wrapper = functools.lru_cache(maxsize=20)(func)
2769 self.assertIs(inspect.unwrap(wrapper), func)
2770
2771 def test_unwrap_several(self):
2772 def func(a, b):
2773 return a + b
2774 wrapper = func
2775 for __ in range(10):
2776 @functools.wraps(wrapper)
2777 def wrapper():
2778 pass
2779 self.assertIsNot(wrapper.__wrapped__, func)
2780 self.assertIs(inspect.unwrap(wrapper), func)
2781
2782 def test_stop(self):
2783 def func1(a, b):
2784 return a + b
2785 @functools.wraps(func1)
2786 def func2():
2787 pass
2788 @functools.wraps(func2)
2789 def wrapper():
2790 pass
2791 func2.stop_here = 1
2792 unwrapped = inspect.unwrap(wrapper,
2793 stop=(lambda f: hasattr(f, "stop_here")))
2794 self.assertIs(unwrapped, func2)
2795
2796 def test_cycle(self):
2797 def func1(): pass
2798 func1.__wrapped__ = func1
2799 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
2800 inspect.unwrap(func1)
2801
2802 def func2(): pass
2803 func2.__wrapped__ = func1
2804 func1.__wrapped__ = func2
2805 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
2806 inspect.unwrap(func1)
2807 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
2808 inspect.unwrap(func2)
2809
2810 def test_unhashable(self):
2811 def func(): pass
2812 func.__wrapped__ = None
2813 class C:
2814 __hash__ = None
2815 __wrapped__ = func
2816 self.assertIsNone(inspect.unwrap(C()))
2817
Nick Coghlanf94a16b2013-09-22 22:46:49 +10002818class TestMain(unittest.TestCase):
2819 def test_only_source(self):
2820 module = importlib.import_module('unittest')
2821 rc, out, err = assert_python_ok('-m', 'inspect',
2822 'unittest')
2823 lines = out.decode().splitlines()
2824 # ignore the final newline
2825 self.assertEqual(lines[:-1], inspect.getsource(module).splitlines())
2826 self.assertEqual(err, b'')
2827
Brett Cannon634a8fc2013-10-02 10:25:42 -04002828 @unittest.skipIf(ThreadPoolExecutor is None,
Brett Cannon0de3f012013-10-02 10:58:58 -04002829 'threads required to test __qualname__ for source files')
Nick Coghlanf94a16b2013-09-22 22:46:49 +10002830 def test_qualname_source(self):
Nick Coghlanf94a16b2013-09-22 22:46:49 +10002831 rc, out, err = assert_python_ok('-m', 'inspect',
2832 'concurrent.futures:ThreadPoolExecutor')
2833 lines = out.decode().splitlines()
2834 # ignore the final newline
2835 self.assertEqual(lines[:-1],
Brett Cannon634a8fc2013-10-02 10:25:42 -04002836 inspect.getsource(ThreadPoolExecutor).splitlines())
Nick Coghlanf94a16b2013-09-22 22:46:49 +10002837 self.assertEqual(err, b'')
2838
2839 def test_builtins(self):
2840 module = importlib.import_module('unittest')
2841 _, out, err = assert_python_failure('-m', 'inspect',
2842 'sys')
2843 lines = err.decode().splitlines()
2844 self.assertEqual(lines, ["Can't get info for builtin modules."])
2845
2846 def test_details(self):
2847 module = importlib.import_module('unittest')
2848 rc, out, err = assert_python_ok('-m', 'inspect',
2849 'unittest', '--details')
2850 output = out.decode()
2851 # Just a quick sanity check on the output
2852 self.assertIn(module.__name__, output)
2853 self.assertIn(module.__file__, output)
Serhiy Storchakab12cb6a2013-12-08 18:16:18 +02002854 if not sys.flags.optimize:
2855 self.assertIn(module.__cached__, output)
Nick Coghlanf94a16b2013-09-22 22:46:49 +10002856 self.assertEqual(err, b'')
2857
2858
2859
Nick Coghlane8c45d62013-07-28 20:00:01 +10002860
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00002861def test_main():
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00002862 run_unittest(
2863 TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBuggyCases,
2864 TestInterpreterStack, TestClassesAndFunctions, TestPredicates,
2865 TestGetcallargsFunctions, TestGetcallargsMethods,
Alexander Belopolskyf546e702010-12-02 00:10:11 +00002866 TestGetcallargsUnboundMethods, TestGetattrStatic, TestGetGeneratorState,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002867 TestNoEOL, TestSignatureObject, TestSignatureBind, TestParameterObject,
Yury Selivanovd82eddc2014-01-29 11:24:39 -05002868 TestBoundArguments, TestSignaturePrivateHelpers, TestGetClosureVars,
2869 TestUnwrap, TestMain
Michael Foord95fc51d2010-11-20 15:07:30 +00002870 )
Martin v. Löwis893ffa42003-10-31 15:35:53 +00002871
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00002872if __name__ == "__main__":
2873 test_main()