blob: 3f204191bf79b7647c60629d339c3b3653726bc9 [file] [log] [blame]
Guido van Rossum813b0e52007-05-21 18:11:34 +00001import collections
Larry Hastings5c661892014-01-24 06:17:25 -08002import datetime
Nick Coghlane8c45d62013-07-28 20:00:01 +10003import functools
Nick Coghlanf94a16b2013-09-22 22:46:49 +10004import importlib
Larry Hastings5c661892014-01-24 06:17:25 -08005import inspect
6import io
7import linecache
8import os
Christian Heimesa3538eb2007-11-06 11:44:48 +00009from os.path import normcase
Larry Hastings5c661892014-01-24 06:17:25 -080010import _pickle
11import re
12import shutil
13import sys
14import types
15import unicodedata
16import unittest
17
Brett Cannon634a8fc2013-10-02 10:25:42 -040018try:
19 from concurrent.futures import ThreadPoolExecutor
20except ImportError:
21 ThreadPoolExecutor = None
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000022
Serhiy Storchakaf28ba362014-02-07 10:10:55 +020023from test.support import run_unittest, TESTFN, DirsOnSysPath, cpython_only
Larry Hastingsfcafe432013-11-23 17:35:48 -080024from test.support import MISSING_C_DOCSTRINGS
Nick Coghlanf94a16b2013-09-22 22:46:49 +100025from test.script_helper import assert_python_ok, assert_python_failure
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000026from test import inspect_fodder as mod
27from test import inspect_fodder2 as mod2
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000028
R. David Murray74b89242009-05-13 17:33:03 +000029
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000030# Functions tested in this suite:
31# ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode,
Christian Heimes7131fd92008-02-19 14:21:46 +000032# isbuiltin, isroutine, isgenerator, isgeneratorfunction, getmembers,
33# getdoc, getfile, getmodule, getsourcefile, getcomments, getsource,
34# getclasstree, getargspec, getargvalues, formatargspec, formatargvalues,
35# currentframe, stack, trace, isdatadescriptor
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000036
Nick Coghlanf088e5e2008-12-14 11:50:48 +000037# NOTE: There are some additional tests relating to interaction with
38# zipimport in the test_zipimport_support test module.
39
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000040modfile = mod.__file__
Thomas Wouters0e3f5912006-08-11 14:57:12 +000041if modfile.endswith(('c', 'o')):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000042 modfile = modfile[:-1]
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000043
Christian Heimesa3538eb2007-11-06 11:44:48 +000044# Normalize file names: on Windows, the case of file names of compiled
45# modules depends on the path used to start the python executable.
46modfile = normcase(modfile)
47
48def revise(filename, *args):
49 return (normcase(filename),) + args
50
Georg Brandl1a3284e2007-12-02 09:40:06 +000051import builtins
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000052
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000053git = mod.StupidGit()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000054
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000055class IsTestBase(unittest.TestCase):
56 predicates = set([inspect.isbuiltin, inspect.isclass, inspect.iscode,
57 inspect.isframe, inspect.isfunction, inspect.ismethod,
Christian Heimes7131fd92008-02-19 14:21:46 +000058 inspect.ismodule, inspect.istraceback,
59 inspect.isgenerator, inspect.isgeneratorfunction])
Tim Peters5a9fb3c2005-01-07 16:01:32 +000060
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000061 def istest(self, predicate, exp):
62 obj = eval(exp)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000063 self.assertTrue(predicate(obj), '%s(%s)' % (predicate.__name__, exp))
Tim Peters5a9fb3c2005-01-07 16:01:32 +000064
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000065 for other in self.predicates - set([predicate]):
Christian Heimes7131fd92008-02-19 14:21:46 +000066 if predicate == inspect.isgeneratorfunction and\
67 other == inspect.isfunction:
68 continue
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000069 self.assertFalse(other(obj), 'not %s(%s)' % (other.__name__, exp))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000070
Christian Heimes7131fd92008-02-19 14:21:46 +000071def generator_function_example(self):
72 for i in range(2):
73 yield i
74
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000075class TestPredicates(IsTestBase):
Christian Heimes227c8002008-03-03 20:34:40 +000076 def test_sixteen(self):
Guido van Rossumc1f779c2007-07-03 08:25:58 +000077 count = len([x for x in dir(inspect) if x.startswith('is')])
Christian Heimes7131fd92008-02-19 14:21:46 +000078 # This test is here for remember you to update Doc/library/inspect.rst
Christian Heimes78644762008-03-04 23:39:23 +000079 # which claims there are 16 such functions
Christian Heimes227c8002008-03-03 20:34:40 +000080 expected = 16
Thomas Wouters0e3f5912006-08-11 14:57:12 +000081 err_msg = "There are %d (not %d) is* functions" % (count, expected)
82 self.assertEqual(count, expected, err_msg)
Tim Peters5a9fb3c2005-01-07 16:01:32 +000083
Christian Heimes7131fd92008-02-19 14:21:46 +000084
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000085 def test_excluding_predicates(self):
Antoine Pitroud5a1a212012-06-17 23:18:07 +020086 global tb
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000087 self.istest(inspect.isbuiltin, 'sys.exit')
88 self.istest(inspect.isbuiltin, '[].append')
Neal Norwitz221085d2007-02-25 20:55:47 +000089 self.istest(inspect.iscode, 'mod.spam.__code__')
Antoine Pitroud5a1a212012-06-17 23:18:07 +020090 try:
91 1/0
92 except:
93 tb = sys.exc_info()[2]
94 self.istest(inspect.isframe, 'tb.tb_frame')
95 self.istest(inspect.istraceback, 'tb')
96 if hasattr(types, 'GetSetDescriptorType'):
97 self.istest(inspect.isgetsetdescriptor,
98 'type(tb.tb_frame).f_locals')
99 else:
100 self.assertFalse(inspect.isgetsetdescriptor(type(tb.tb_frame).f_locals))
101 finally:
102 # Clear traceback and all the frames and local variables hanging to it.
103 tb = None
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000104 self.istest(inspect.isfunction, 'mod.spam')
Christian Heimes4a22b5d2007-11-25 09:39:14 +0000105 self.istest(inspect.isfunction, 'mod.StupidGit.abuse')
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000106 self.istest(inspect.ismethod, 'git.argue')
107 self.istest(inspect.ismodule, 'mod')
Guido van Rossum813b0e52007-05-21 18:11:34 +0000108 self.istest(inspect.isdatadescriptor, 'collections.defaultdict.default_factory')
Christian Heimes7131fd92008-02-19 14:21:46 +0000109 self.istest(inspect.isgenerator, '(x for x in range(2))')
110 self.istest(inspect.isgeneratorfunction, 'generator_function_example')
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000111 if hasattr(types, 'MemberDescriptorType'):
112 self.istest(inspect.ismemberdescriptor, 'datetime.timedelta.days')
113 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000114 self.assertFalse(inspect.ismemberdescriptor(datetime.timedelta.days))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000115
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000116 def test_isroutine(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000117 self.assertTrue(inspect.isroutine(mod.spam))
118 self.assertTrue(inspect.isroutine([].count))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000119
Benjamin Petersonc4656002009-01-17 22:41:18 +0000120 def test_isclass(self):
121 self.istest(inspect.isclass, 'mod.StupidGit')
122 self.assertTrue(inspect.isclass(list))
123
124 class CustomGetattr(object):
125 def __getattr__(self, attr):
126 return None
127 self.assertFalse(inspect.isclass(CustomGetattr()))
128
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000129 def test_get_slot_members(self):
130 class C(object):
131 __slots__ = ("a", "b")
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000132 x = C()
133 x.a = 42
134 members = dict(inspect.getmembers(x))
Benjamin Peterson577473f2010-01-19 00:09:57 +0000135 self.assertIn('a', members)
136 self.assertNotIn('b', members)
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000137
Benjamin Petersona0dfa822009-11-13 02:25:08 +0000138 def test_isabstract(self):
139 from abc import ABCMeta, abstractmethod
140
141 class AbstractClassExample(metaclass=ABCMeta):
142
143 @abstractmethod
144 def foo(self):
145 pass
146
147 class ClassExample(AbstractClassExample):
148 def foo(self):
149 pass
150
151 a = ClassExample()
152
153 # Test general behaviour.
154 self.assertTrue(inspect.isabstract(AbstractClassExample))
155 self.assertFalse(inspect.isabstract(ClassExample))
156 self.assertFalse(inspect.isabstract(a))
157 self.assertFalse(inspect.isabstract(int))
158 self.assertFalse(inspect.isabstract(5))
159
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000160
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000161class TestInterpreterStack(IsTestBase):
162 def __init__(self, *args, **kwargs):
163 unittest.TestCase.__init__(self, *args, **kwargs)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000164
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000165 git.abuse(7, 8, 9)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000166
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000167 def test_abuse_done(self):
168 self.istest(inspect.istraceback, 'git.ex[2]')
169 self.istest(inspect.isframe, 'mod.fr')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000170
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000171 def test_stack(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000172 self.assertTrue(len(mod.st) >= 5)
Christian Heimesa3538eb2007-11-06 11:44:48 +0000173 self.assertEqual(revise(*mod.st[0][1:]),
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000174 (modfile, 16, 'eggs', [' st = inspect.stack()\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000175 self.assertEqual(revise(*mod.st[1][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000176 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000177 self.assertEqual(revise(*mod.st[2][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000178 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000179 self.assertEqual(revise(*mod.st[3][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000180 (modfile, 39, 'abuse', [' self.argue(a, b, c)\n'], 0))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000181
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000182 def test_trace(self):
183 self.assertEqual(len(git.tr), 3)
Florent Xiclunac8575922010-03-24 17:37:49 +0000184 self.assertEqual(revise(*git.tr[0][1:]),
185 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
186 self.assertEqual(revise(*git.tr[1][1:]),
187 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
188 self.assertEqual(revise(*git.tr[2][1:]),
189 (modfile, 18, 'eggs', [' q = y / 0\n'], 0))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000190
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000191 def test_frame(self):
192 args, varargs, varkw, locals = inspect.getargvalues(mod.fr)
193 self.assertEqual(args, ['x', 'y'])
194 self.assertEqual(varargs, None)
195 self.assertEqual(varkw, None)
196 self.assertEqual(locals, {'x': 11, 'p': 11, 'y': 14})
197 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
198 '(x=11, y=14)')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000199
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000200 def test_previous_frame(self):
201 args, varargs, varkw, locals = inspect.getargvalues(mod.fr.f_back)
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000202 self.assertEqual(args, ['a', 'b', 'c', 'd', 'e', 'f'])
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000203 self.assertEqual(varargs, 'g')
204 self.assertEqual(varkw, 'h')
205 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000206 '(a=7, b=8, c=9, d=3, e=4, f=5, *g=(), **h={})')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000207
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000208class GetSourceBase(unittest.TestCase):
209 # Subclasses must override.
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000210 fodderModule = None
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000211
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000212 def __init__(self, *args, **kwargs):
213 unittest.TestCase.__init__(self, *args, **kwargs)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000214
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000215 with open(inspect.getsourcefile(self.fodderModule)) as fp:
Philip Jenveya27c5bd2009-05-28 06:09:08 +0000216 self.source = fp.read()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000217
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000218 def sourcerange(self, top, bottom):
219 lines = self.source.split("\n")
220 return "\n".join(lines[top-1:bottom]) + "\n"
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000221
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000222 def assertSourceEqual(self, obj, top, bottom):
223 self.assertEqual(inspect.getsource(obj),
224 self.sourcerange(top, bottom))
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000225
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000226class TestRetrievingSourceCode(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000227 fodderModule = mod
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000228
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000229 def test_getclasses(self):
230 classes = inspect.getmembers(mod, inspect.isclass)
231 self.assertEqual(classes,
232 [('FesteringGob', mod.FesteringGob),
233 ('MalodorousPervert', mod.MalodorousPervert),
234 ('ParrotDroppings', mod.ParrotDroppings),
Serhiy Storchaka362c1b52013-09-05 17:14:32 +0300235 ('StupidGit', mod.StupidGit),
236 ('Tit', mod.MalodorousPervert),
237 ])
238 tree = inspect.getclasstree([cls[1] for cls in classes])
239 self.assertEqual(tree,
240 [(object, ()),
241 [(mod.ParrotDroppings, (object,)),
242 [(mod.FesteringGob, (mod.MalodorousPervert,
243 mod.ParrotDroppings))
244 ],
245 (mod.StupidGit, (object,)),
246 [(mod.MalodorousPervert, (mod.StupidGit,)),
247 [(mod.FesteringGob, (mod.MalodorousPervert,
248 mod.ParrotDroppings))
249 ]
250 ]
251 ]
252 ])
253 tree = inspect.getclasstree([cls[1] for cls in classes], True)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000254 self.assertEqual(tree,
Thomas Wouters725af872006-04-15 09:13:19 +0000255 [(object, ()),
256 [(mod.ParrotDroppings, (object,)),
257 (mod.StupidGit, (object,)),
258 [(mod.MalodorousPervert, (mod.StupidGit,)),
259 [(mod.FesteringGob, (mod.MalodorousPervert,
260 mod.ParrotDroppings))
261 ]
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000262 ]
263 ]
264 ])
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000265
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000266 def test_getfunctions(self):
267 functions = inspect.getmembers(mod, inspect.isfunction)
268 self.assertEqual(functions, [('eggs', mod.eggs),
269 ('spam', mod.spam)])
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000270
R. David Murray378c0cf2010-02-24 01:46:21 +0000271 @unittest.skipIf(sys.flags.optimize >= 2,
272 "Docstrings are omitted with -O2 and above")
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000273 def test_getdoc(self):
274 self.assertEqual(inspect.getdoc(mod), 'A module docstring.')
275 self.assertEqual(inspect.getdoc(mod.StupidGit),
276 'A longer,\n\nindented\n\ndocstring.')
277 self.assertEqual(inspect.getdoc(git.abuse),
278 'Another\n\ndocstring\n\ncontaining\n\ntabs')
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000279
Georg Brandl0c77a822008-06-10 16:37:50 +0000280 def test_cleandoc(self):
281 self.assertEqual(inspect.cleandoc('An\n indented\n docstring.'),
282 'An\nindented\ndocstring.')
283
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000284 def test_getcomments(self):
285 self.assertEqual(inspect.getcomments(mod), '# line 1\n')
286 self.assertEqual(inspect.getcomments(mod.StupidGit), '# line 20\n')
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000287
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000288 def test_getmodule(self):
Thomas Wouters89f507f2006-12-13 04:49:30 +0000289 # Check actual module
290 self.assertEqual(inspect.getmodule(mod), mod)
291 # Check class (uses __module__ attribute)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000292 self.assertEqual(inspect.getmodule(mod.StupidGit), mod)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000293 # Check a method (no __module__ attribute, falls back to filename)
294 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
295 # Do it again (check the caching isn't broken)
296 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
297 # Check a builtin
Georg Brandl1a3284e2007-12-02 09:40:06 +0000298 self.assertEqual(inspect.getmodule(str), sys.modules["builtins"])
Thomas Wouters89f507f2006-12-13 04:49:30 +0000299 # Check filename override
300 self.assertEqual(inspect.getmodule(None, modfile), mod)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000301
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000302 def test_getsource(self):
303 self.assertSourceEqual(git.abuse, 29, 39)
304 self.assertSourceEqual(mod.StupidGit, 21, 46)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000305
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000306 def test_getsourcefile(self):
Christian Heimesa3538eb2007-11-06 11:44:48 +0000307 self.assertEqual(normcase(inspect.getsourcefile(mod.spam)), modfile)
308 self.assertEqual(normcase(inspect.getsourcefile(git.abuse)), modfile)
R. David Murraya1b37402010-06-17 02:04:29 +0000309 fn = "_non_existing_filename_used_for_sourcefile_test.py"
310 co = compile("None", fn, "exec")
R. David Murray4155f972010-06-17 13:23:18 +0000311 self.assertEqual(inspect.getsourcefile(co), None)
R. David Murraya1b37402010-06-17 02:04:29 +0000312 linecache.cache[co.co_filename] = (1, None, "None", co.co_filename)
Antoine Pitrou5d62a612012-07-08 13:48:46 +0200313 try:
314 self.assertEqual(normcase(inspect.getsourcefile(co)), fn)
315 finally:
316 del linecache.cache[co.co_filename]
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000317
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000318 def test_getfile(self):
319 self.assertEqual(inspect.getfile(mod.StupidGit), mod.__file__)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000320
Yury Selivanov2eed8b72014-01-27 13:24:56 -0500321 def test_getfile_class_without_module(self):
322 class CM(type):
323 @property
324 def __module__(cls):
325 raise AttributeError
326 class C(metaclass=CM):
327 pass
328 with self.assertRaises(TypeError):
329 inspect.getfile(C)
330
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000331 def test_getmodule_recursion(self):
Christian Heimes45f9af32007-11-27 21:50:00 +0000332 from types import ModuleType
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000333 name = '__inspect_dummy'
Christian Heimes45f9af32007-11-27 21:50:00 +0000334 m = sys.modules[name] = ModuleType(name)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000335 m.__file__ = "<string>" # hopefully not a real filename...
336 m.__loader__ = "dummy" # pretend the filename is understood by a loader
Georg Brandl7cae87c2006-09-06 06:51:57 +0000337 exec("def x(): pass", m.__dict__)
Neal Norwitz221085d2007-02-25 20:55:47 +0000338 self.assertEqual(inspect.getsourcefile(m.x.__code__), '<string>')
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000339 del sys.modules[name]
340 inspect.getmodule(compile('a=10','','single'))
341
Benjamin Peterson9620cc02011-06-11 15:53:11 -0500342 def test_proceed_with_fake_filename(self):
343 '''doctest monkeypatches linecache to enable inspection'''
344 fn, source = '<test>', 'def x(): pass\n'
345 getlines = linecache.getlines
346 def monkey(filename, module_globals=None):
347 if filename == fn:
Ezio Melottid8b509b2011-09-28 17:37:55 +0300348 return source.splitlines(keepends=True)
Benjamin Peterson9620cc02011-06-11 15:53:11 -0500349 else:
350 return getlines(filename, module_globals)
351 linecache.getlines = monkey
352 try:
353 ns = {}
354 exec(compile(source, fn, 'single'), ns)
355 inspect.getsource(ns["x"])
356 finally:
357 linecache.getlines = getlines
358
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000359class TestDecorators(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000360 fodderModule = mod2
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000361
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000362 def test_wrapped_decorator(self):
Christian Heimes09aaa882008-02-23 15:01:06 +0000363 self.assertSourceEqual(mod2.wrapped, 14, 17)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000364
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000365 def test_replacing_decorator(self):
366 self.assertSourceEqual(mod2.gone, 9, 10)
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000367
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000368class TestOneliners(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000369 fodderModule = mod2
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000370 def test_oneline_lambda(self):
371 # Test inspect.getsource with a one-line lambda function.
372 self.assertSourceEqual(mod2.oll, 25, 25)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000373
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000374 def test_threeline_lambda(self):
375 # Test inspect.getsource with a three-line lambda function,
376 # where the second and third lines are _not_ indented.
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000377 self.assertSourceEqual(mod2.tll, 28, 30)
378
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000379 def test_twoline_indented_lambda(self):
380 # Test inspect.getsource with a two-line lambda function,
381 # where the second line _is_ indented.
382 self.assertSourceEqual(mod2.tlli, 33, 34)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000383
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000384 def test_onelinefunc(self):
385 # Test inspect.getsource with a regular one-line function.
386 self.assertSourceEqual(mod2.onelinefunc, 37, 37)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000387
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000388 def test_manyargs(self):
389 # Test inspect.getsource with a regular function where
390 # the arguments are on two lines and _not_ indented and
391 # the body on the second line with the last arguments.
392 self.assertSourceEqual(mod2.manyargs, 40, 41)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000393
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000394 def test_twolinefunc(self):
395 # Test inspect.getsource with a regular function where
396 # the body is on two lines, following the argument list and
397 # continued on the next line by a \\.
398 self.assertSourceEqual(mod2.twolinefunc, 44, 45)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000399
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000400 def test_lambda_in_list(self):
401 # Test inspect.getsource with a one-line lambda function
402 # defined in a list, indented.
403 self.assertSourceEqual(mod2.a[1], 49, 49)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000404
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000405 def test_anonymous(self):
406 # Test inspect.getsource with a lambda function defined
407 # as argument to another function.
408 self.assertSourceEqual(mod2.anonymous, 55, 55)
409
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000410class TestBuggyCases(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000411 fodderModule = mod2
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000412
413 def test_with_comment(self):
414 self.assertSourceEqual(mod2.with_comment, 58, 59)
415
416 def test_multiline_sig(self):
417 self.assertSourceEqual(mod2.multiline_sig[0], 63, 64)
418
Armin Rigodd5c0232005-09-25 11:45:45 +0000419 def test_nested_class(self):
420 self.assertSourceEqual(mod2.func69().func71, 71, 72)
421
422 def test_one_liner_followed_by_non_name(self):
423 self.assertSourceEqual(mod2.func77, 77, 77)
424
425 def test_one_liner_dedent_non_name(self):
426 self.assertSourceEqual(mod2.cls82.func83, 83, 83)
427
428 def test_with_comment_instead_of_docstring(self):
429 self.assertSourceEqual(mod2.func88, 88, 90)
430
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000431 def test_method_in_dynamic_class(self):
432 self.assertSourceEqual(mod2.method_in_dynamic_class, 95, 97)
433
R. David Murrayb5655772009-05-14 16:17:50 +0000434 @unittest.skipIf(
435 not hasattr(unicodedata, '__file__') or
436 unicodedata.__file__[-4:] in (".pyc", ".pyo"),
437 "unicodedata is not an external binary module")
R. David Murray74b89242009-05-13 17:33:03 +0000438 def test_findsource_binary(self):
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200439 self.assertRaises(OSError, inspect.getsource, unicodedata)
440 self.assertRaises(OSError, inspect.findsource, unicodedata)
R. David Murray74b89242009-05-13 17:33:03 +0000441
R. David Murraya1b37402010-06-17 02:04:29 +0000442 def test_findsource_code_in_linecache(self):
443 lines = ["x=1"]
444 co = compile(lines[0], "_dynamically_created_file", "exec")
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200445 self.assertRaises(OSError, inspect.findsource, co)
446 self.assertRaises(OSError, inspect.getsource, co)
R. David Murraya1b37402010-06-17 02:04:29 +0000447 linecache.cache[co.co_filename] = (1, None, lines, co.co_filename)
Antoine Pitrou5d62a612012-07-08 13:48:46 +0200448 try:
449 self.assertEqual(inspect.findsource(co), (lines,0))
450 self.assertEqual(inspect.getsource(co), lines[0])
451 finally:
452 del linecache.cache[co.co_filename]
R. David Murraya1b37402010-06-17 02:04:29 +0000453
Ezio Melotti1b145922013-03-30 05:17:24 +0200454 def test_findsource_without_filename(self):
455 for fname in ['', '<string>']:
456 co = compile('x=1', fname, "exec")
457 self.assertRaises(IOError, inspect.findsource, co)
458 self.assertRaises(IOError, inspect.getsource, co)
459
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000460class TestNoEOL(GetSourceBase):
461 def __init__(self, *args, **kwargs):
462 self.tempdir = TESTFN + '_dir'
463 os.mkdir(self.tempdir)
464 with open(os.path.join(self.tempdir,
465 'inspect_fodder3%spy' % os.extsep), 'w') as f:
466 f.write("class X:\n pass # No EOL")
467 with DirsOnSysPath(self.tempdir):
468 import inspect_fodder3 as mod3
469 self.fodderModule = mod3
470 GetSourceBase.__init__(self, *args, **kwargs)
471
472 def tearDown(self):
473 shutil.rmtree(self.tempdir)
474
475 def test_class(self):
476 self.assertSourceEqual(self.fodderModule.X, 1, 2)
477
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100478
479class _BrokenDataDescriptor(object):
480 """
481 A broken data descriptor. See bug #1785.
482 """
483 def __get__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700484 raise AttributeError("broken data descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100485
486 def __set__(*args):
487 raise RuntimeError
488
489 def __getattr__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700490 raise AttributeError("broken data descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100491
492
493class _BrokenMethodDescriptor(object):
494 """
495 A broken method descriptor. See bug #1785.
496 """
497 def __get__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700498 raise AttributeError("broken method descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100499
500 def __getattr__(*args):
Ethan Furman63c141c2013-10-18 00:27:39 -0700501 raise AttributeError("broken method descriptor")
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100502
503
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000504# Helper for testing classify_class_attrs.
Tim Peters13b49d32001-09-23 02:00:29 +0000505def attrs_wo_objs(cls):
506 return [t[:3] for t in inspect.classify_class_attrs(cls)]
507
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100508
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000509class TestClassesAndFunctions(unittest.TestCase):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000510 def test_newstyle_mro(self):
511 # The same w/ new-class MRO.
512 class A(object): pass
513 class B(A): pass
514 class C(A): pass
515 class D(B, C): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000516
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000517 expected = (D, B, C, A, object)
518 got = inspect.getmro(D)
519 self.assertEqual(expected, got)
Tim Peters13b49d32001-09-23 02:00:29 +0000520
Christian Heimes3795b532007-11-08 13:48:53 +0000521 def assertArgSpecEquals(self, routine, args_e, varargs_e=None,
522 varkw_e=None, defaults_e=None, formatted=None):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000523 args, varargs, varkw, defaults = inspect.getargspec(routine)
524 self.assertEqual(args, args_e)
525 self.assertEqual(varargs, varargs_e)
526 self.assertEqual(varkw, varkw_e)
527 self.assertEqual(defaults, defaults_e)
528 if formatted is not None:
529 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults),
530 formatted)
Tim Peters13b49d32001-09-23 02:00:29 +0000531
Christian Heimes3795b532007-11-08 13:48:53 +0000532 def assertFullArgSpecEquals(self, routine, args_e, varargs_e=None,
533 varkw_e=None, defaults_e=None,
534 kwonlyargs_e=[], kwonlydefaults_e=None,
535 ann_e={}, formatted=None):
536 args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \
537 inspect.getfullargspec(routine)
538 self.assertEqual(args, args_e)
539 self.assertEqual(varargs, varargs_e)
540 self.assertEqual(varkw, varkw_e)
541 self.assertEqual(defaults, defaults_e)
542 self.assertEqual(kwonlyargs, kwonlyargs_e)
543 self.assertEqual(kwonlydefaults, kwonlydefaults_e)
544 self.assertEqual(ann, ann_e)
545 if formatted is not None:
546 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults,
547 kwonlyargs, kwonlydefaults, ann),
548 formatted)
549
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000550 def test_getargspec(self):
Christian Heimes3795b532007-11-08 13:48:53 +0000551 self.assertArgSpecEquals(mod.eggs, ['x', 'y'], formatted='(x, y)')
Tim Peters13b49d32001-09-23 02:00:29 +0000552
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000553 self.assertArgSpecEquals(mod.spam,
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000554 ['a', 'b', 'c', 'd', 'e', 'f'],
555 'g', 'h', (3, 4, 5),
556 '(a, b, c, d=3, e=4, f=5, *g, **h)')
Tim Peters13b49d32001-09-23 02:00:29 +0000557
Christian Heimes3795b532007-11-08 13:48:53 +0000558 self.assertRaises(ValueError, self.assertArgSpecEquals,
559 mod2.keyworded, [])
560
561 self.assertRaises(ValueError, self.assertArgSpecEquals,
562 mod2.annotated, [])
Benjamin Peterson9953a8d2009-01-17 04:15:01 +0000563 self.assertRaises(ValueError, self.assertArgSpecEquals,
564 mod2.keyword_only_arg, [])
565
Christian Heimes3795b532007-11-08 13:48:53 +0000566
567 def test_getfullargspec(self):
568 self.assertFullArgSpecEquals(mod2.keyworded, [], varargs_e='arg1',
569 kwonlyargs_e=['arg2'],
570 kwonlydefaults_e={'arg2':1},
571 formatted='(*arg1, arg2=1)')
572
573 self.assertFullArgSpecEquals(mod2.annotated, ['arg1'],
Christian Heimesc9543e42007-11-28 08:28:28 +0000574 ann_e={'arg1' : list},
Christian Heimes3795b532007-11-08 13:48:53 +0000575 formatted='(arg1: list)')
Benjamin Peterson9953a8d2009-01-17 04:15:01 +0000576 self.assertFullArgSpecEquals(mod2.keyword_only_arg, [],
577 kwonlyargs_e=['arg'],
578 formatted='(*, arg)')
579
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500580 def test_getfullargspec_signature_attr(self):
581 def test():
582 pass
583 spam_param = inspect.Parameter('spam', inspect.Parameter.POSITIONAL_ONLY)
584 test.__signature__ = inspect.Signature(parameters=(spam_param,))
585
586 self.assertFullArgSpecEquals(test, args_e=['spam'], formatted='(spam)')
587
Yury Selivanov4cb93912014-01-29 11:54:12 -0500588 def test_getfullargspec_signature_annos(self):
589 def test(a:'spam') -> 'ham': pass
590 spec = inspect.getfullargspec(test)
591 self.assertEqual(test.__annotations__, spec.annotations)
592
593 def test(): pass
594 spec = inspect.getfullargspec(test)
595 self.assertEqual(test.__annotations__, spec.annotations)
596
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500597 @unittest.skipIf(MISSING_C_DOCSTRINGS,
598 "Signature information for builtins requires docstrings")
599 def test_getfullargspec_builtin_methods(self):
600 self.assertFullArgSpecEquals(_pickle.Pickler.dump,
601 args_e=['self', 'obj'], formatted='(self, obj)')
602
603 self.assertFullArgSpecEquals(_pickle.Pickler(io.BytesIO()).dump,
604 args_e=['self', 'obj'], formatted='(self, obj)')
605
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200606 @cpython_only
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500607 @unittest.skipIf(MISSING_C_DOCSTRINGS,
608 "Signature information for builtins requires docstrings")
609 def test_getfullagrspec_builtin_func(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200610 import _testcapi
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500611 builtin = _testcapi.docstring_with_signature_with_defaults
612 spec = inspect.getfullargspec(builtin)
613 self.assertEqual(spec.defaults[0], 'avocado')
614
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200615 @cpython_only
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500616 @unittest.skipIf(MISSING_C_DOCSTRINGS,
617 "Signature information for builtins requires docstrings")
618 def test_getfullagrspec_builtin_func_no_signature(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200619 import _testcapi
Yury Selivanovd82eddc2014-01-29 11:24:39 -0500620 builtin = _testcapi.docstring_no_signature
621 with self.assertRaises(TypeError):
622 inspect.getfullargspec(builtin)
Christian Heimes3795b532007-11-08 13:48:53 +0000623
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000624 def test_getargspec_method(self):
625 class A(object):
626 def m(self):
627 pass
628 self.assertArgSpecEquals(A.m, ['self'])
Tim Peters13b49d32001-09-23 02:00:29 +0000629
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000630 def test_classify_newstyle(self):
631 class A(object):
Tim Peters13b49d32001-09-23 02:00:29 +0000632
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000633 def s(): pass
634 s = staticmethod(s)
Tim Peters13b49d32001-09-23 02:00:29 +0000635
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000636 def c(cls): pass
637 c = classmethod(c)
Tim Peters13b49d32001-09-23 02:00:29 +0000638
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000639 def getp(self): pass
640 p = property(getp)
Tim Peters13b49d32001-09-23 02:00:29 +0000641
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000642 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000643
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000644 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000645
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000646 datablob = '1'
Tim Peters13b49d32001-09-23 02:00:29 +0000647
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100648 dd = _BrokenDataDescriptor()
649 md = _BrokenMethodDescriptor()
650
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000651 attrs = attrs_wo_objs(A)
Yury Selivanov0860a0b2014-01-31 14:28:44 -0500652
653 self.assertIn(('__new__', 'method', object), attrs, 'missing __new__')
654 self.assertIn(('__init__', 'method', object), attrs, 'missing __init__')
655
Benjamin Peterson577473f2010-01-19 00:09:57 +0000656 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
657 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
658 self.assertIn(('p', 'property', A), attrs, 'missing property')
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000659 self.assertIn(('m', 'method', A), attrs,
660 'missing plain method: %r' % attrs)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000661 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
662 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100663 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
664 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000665
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000666 class B(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000667
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000668 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000669
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000670 attrs = attrs_wo_objs(B)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000671 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
672 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
673 self.assertIn(('p', 'property', A), attrs, 'missing property')
674 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
675 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
676 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100677 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
678 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000679
680
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000681 class C(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000682
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000683 def m(self): pass
684 def c(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000685
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000686 attrs = attrs_wo_objs(C)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000687 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
688 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
689 self.assertIn(('p', 'property', A), attrs, 'missing property')
690 self.assertIn(('m', 'method', C), attrs, 'missing plain method')
691 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
692 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100693 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
694 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000695
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000696 class D(B, C):
Tim Peters13b49d32001-09-23 02:00:29 +0000697
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000698 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000699
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000700 attrs = attrs_wo_objs(D)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000701 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
702 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
703 self.assertIn(('p', 'property', A), attrs, 'missing property')
704 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
705 self.assertIn(('m1', 'method', D), attrs, 'missing plain method')
706 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100707 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
708 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
709
710 def test_classify_builtin_types(self):
711 # Simple sanity check that all built-in types can have their
712 # attributes classified.
713 for name in dir(__builtins__):
714 builtin = getattr(__builtins__, name)
715 if isinstance(builtin, type):
716 inspect.classify_class_attrs(builtin)
717
Ethan Furman63c141c2013-10-18 00:27:39 -0700718 def test_classify_DynamicClassAttribute(self):
719 class Meta(type):
720 def __getattr__(self, name):
721 if name == 'ham':
722 return 'spam'
723 return super().__getattr__(name)
724 class VA(metaclass=Meta):
Ethan Furmane03ea372013-09-25 07:14:41 -0700725 @types.DynamicClassAttribute
726 def ham(self):
727 return 'eggs'
Ethan Furman63c141c2013-10-18 00:27:39 -0700728 should_find_dca = inspect.Attribute('ham', 'data', VA, VA.__dict__['ham'])
729 self.assertIn(should_find_dca, inspect.classify_class_attrs(VA))
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700730 should_find_ga = inspect.Attribute('ham', 'data', Meta, 'spam')
Ethan Furman63c141c2013-10-18 00:27:39 -0700731 self.assertIn(should_find_ga, inspect.classify_class_attrs(VA))
732
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700733 def test_classify_metaclass_class_attribute(self):
734 class Meta(type):
735 fish = 'slap'
736 def __dir__(self):
737 return ['__class__', '__modules__', '__name__', 'fish']
738 class Class(metaclass=Meta):
739 pass
740 should_find = inspect.Attribute('fish', 'data', Meta, 'slap')
741 self.assertIn(should_find, inspect.classify_class_attrs(Class))
742
Ethan Furman63c141c2013-10-18 00:27:39 -0700743 def test_classify_VirtualAttribute(self):
744 class Meta(type):
745 def __dir__(cls):
746 return ['__class__', '__module__', '__name__', 'BOOM']
747 def __getattr__(self, name):
748 if name =='BOOM':
749 return 42
750 return super().__getattr(name)
751 class Class(metaclass=Meta):
752 pass
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700753 should_find = inspect.Attribute('BOOM', 'data', Meta, 42)
Ethan Furman63c141c2013-10-18 00:27:39 -0700754 self.assertIn(should_find, inspect.classify_class_attrs(Class))
755
756 def test_classify_VirtualAttribute_multi_classes(self):
757 class Meta1(type):
758 def __dir__(cls):
759 return ['__class__', '__module__', '__name__', 'one']
760 def __getattr__(self, name):
761 if name =='one':
762 return 1
763 return super().__getattr__(name)
764 class Meta2(type):
765 def __dir__(cls):
766 return ['__class__', '__module__', '__name__', 'two']
767 def __getattr__(self, name):
768 if name =='two':
769 return 2
770 return super().__getattr__(name)
771 class Meta3(Meta1, Meta2):
772 def __dir__(cls):
773 return list(sorted(set(['__class__', '__module__', '__name__', 'three'] +
774 Meta1.__dir__(cls) + Meta2.__dir__(cls))))
775 def __getattr__(self, name):
776 if name =='three':
777 return 3
778 return super().__getattr__(name)
779 class Class1(metaclass=Meta1):
780 pass
781 class Class2(Class1, metaclass=Meta3):
782 pass
783
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700784 should_find1 = inspect.Attribute('one', 'data', Meta1, 1)
785 should_find2 = inspect.Attribute('two', 'data', Meta2, 2)
786 should_find3 = inspect.Attribute('three', 'data', Meta3, 3)
Ethan Furman63c141c2013-10-18 00:27:39 -0700787 cca = inspect.classify_class_attrs(Class2)
788 for sf in (should_find1, should_find2, should_find3):
789 self.assertIn(sf, cca)
790
791 def test_classify_class_attrs_with_buggy_dir(self):
792 class M(type):
793 def __dir__(cls):
794 return ['__class__', '__name__', 'missing']
795 class C(metaclass=M):
796 pass
797 attrs = [a[0] for a in inspect.classify_class_attrs(C)]
798 self.assertNotIn('missing', attrs)
Ethan Furmane03ea372013-09-25 07:14:41 -0700799
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100800 def test_getmembers_descriptors(self):
801 class A(object):
802 dd = _BrokenDataDescriptor()
803 md = _BrokenMethodDescriptor()
804
805 def pred_wrapper(pred):
806 # A quick'n'dirty way to discard standard attributes of new-style
807 # classes.
808 class Empty(object):
809 pass
810 def wrapped(x):
811 if '__name__' in dir(x) and hasattr(Empty, x.__name__):
812 return False
813 return pred(x)
814 return wrapped
815
816 ismethoddescriptor = pred_wrapper(inspect.ismethoddescriptor)
817 isdatadescriptor = pred_wrapper(inspect.isdatadescriptor)
818
819 self.assertEqual(inspect.getmembers(A, ismethoddescriptor),
820 [('md', A.__dict__['md'])])
821 self.assertEqual(inspect.getmembers(A, isdatadescriptor),
822 [('dd', A.__dict__['dd'])])
823
824 class B(A):
825 pass
826
827 self.assertEqual(inspect.getmembers(B, ismethoddescriptor),
828 [('md', A.__dict__['md'])])
829 self.assertEqual(inspect.getmembers(B, isdatadescriptor),
830 [('dd', A.__dict__['dd'])])
831
Antoine Pitrou0c603812012-01-18 17:40:18 +0100832 def test_getmembers_method(self):
833 class B:
834 def f(self):
835 pass
836
837 self.assertIn(('f', B.f), inspect.getmembers(B))
838 self.assertNotIn(('f', B.f), inspect.getmembers(B, inspect.ismethod))
839 b = B()
840 self.assertIn(('f', b.f), inspect.getmembers(b))
841 self.assertIn(('f', b.f), inspect.getmembers(b, inspect.ismethod))
842
Ethan Furmane03ea372013-09-25 07:14:41 -0700843 def test_getmembers_VirtualAttribute(self):
Ethan Furman63c141c2013-10-18 00:27:39 -0700844 class M(type):
845 def __getattr__(cls, name):
846 if name == 'eggs':
847 return 'scrambled'
848 return super().__getattr__(name)
849 class A(metaclass=M):
Ethan Furmane03ea372013-09-25 07:14:41 -0700850 @types.DynamicClassAttribute
851 def eggs(self):
852 return 'spam'
Ethan Furman63c141c2013-10-18 00:27:39 -0700853 self.assertIn(('eggs', 'scrambled'), inspect.getmembers(A))
854 self.assertIn(('eggs', 'spam'), inspect.getmembers(A()))
855
856 def test_getmembers_with_buggy_dir(self):
857 class M(type):
858 def __dir__(cls):
859 return ['__class__', '__name__', 'missing']
860 class C(metaclass=M):
861 pass
862 attrs = [a[0] for a in inspect.getmembers(C)]
863 self.assertNotIn('missing', attrs)
Ethan Furmane03ea372013-09-25 07:14:41 -0700864
Jeremy Hyltonc4bf5ed2003-06-27 18:43:12 +0000865
Nick Coghlan2f92e542012-06-23 19:39:55 +1000866_global_ref = object()
867class TestGetClosureVars(unittest.TestCase):
868
869 def test_name_resolution(self):
870 # Basic test of the 4 different resolution mechanisms
871 def f(nonlocal_ref):
872 def g(local_ref):
873 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
874 return g
875 _arg = object()
876 nonlocal_vars = {"nonlocal_ref": _arg}
877 global_vars = {"_global_ref": _global_ref}
878 builtin_vars = {"print": print}
879 unbound_names = {"unbound_ref"}
880 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
881 builtin_vars, unbound_names)
882 self.assertEqual(inspect.getclosurevars(f(_arg)), expected)
883
884 def test_generator_closure(self):
885 def f(nonlocal_ref):
886 def g(local_ref):
887 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
888 yield
889 return g
890 _arg = object()
891 nonlocal_vars = {"nonlocal_ref": _arg}
892 global_vars = {"_global_ref": _global_ref}
893 builtin_vars = {"print": print}
894 unbound_names = {"unbound_ref"}
895 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
896 builtin_vars, unbound_names)
897 self.assertEqual(inspect.getclosurevars(f(_arg)), expected)
898
899 def test_method_closure(self):
900 class C:
901 def f(self, nonlocal_ref):
902 def g(local_ref):
903 print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
904 return g
905 _arg = object()
906 nonlocal_vars = {"nonlocal_ref": _arg}
907 global_vars = {"_global_ref": _global_ref}
908 builtin_vars = {"print": print}
909 unbound_names = {"unbound_ref"}
910 expected = inspect.ClosureVars(nonlocal_vars, global_vars,
911 builtin_vars, unbound_names)
912 self.assertEqual(inspect.getclosurevars(C().f(_arg)), expected)
913
914 def test_nonlocal_vars(self):
915 # More complex tests of nonlocal resolution
916 def _nonlocal_vars(f):
917 return inspect.getclosurevars(f).nonlocals
918
919 def make_adder(x):
920 def add(y):
921 return x + y
922 return add
923
924 def curry(func, arg1):
925 return lambda arg2: func(arg1, arg2)
926
927 def less_than(a, b):
928 return a < b
929
930 # The infamous Y combinator.
931 def Y(le):
932 def g(f):
933 return le(lambda x: f(f)(x))
934 Y.g_ref = g
935 return g(g)
936
937 def check_y_combinator(func):
938 self.assertEqual(_nonlocal_vars(func), {'f': Y.g_ref})
939
940 inc = make_adder(1)
941 add_two = make_adder(2)
942 greater_than_five = curry(less_than, 5)
943
944 self.assertEqual(_nonlocal_vars(inc), {'x': 1})
945 self.assertEqual(_nonlocal_vars(add_two), {'x': 2})
946 self.assertEqual(_nonlocal_vars(greater_than_five),
947 {'arg1': 5, 'func': less_than})
948 self.assertEqual(_nonlocal_vars((lambda x: lambda y: x + y)(3)),
949 {'x': 3})
950 Y(check_y_combinator)
951
952 def test_getclosurevars_empty(self):
953 def foo(): pass
954 _empty = inspect.ClosureVars({}, {}, {}, set())
955 self.assertEqual(inspect.getclosurevars(lambda: True), _empty)
956 self.assertEqual(inspect.getclosurevars(foo), _empty)
957
958 def test_getclosurevars_error(self):
959 class T: pass
960 self.assertRaises(TypeError, inspect.getclosurevars, 1)
961 self.assertRaises(TypeError, inspect.getclosurevars, list)
962 self.assertRaises(TypeError, inspect.getclosurevars, {})
963
Nick Coghlan6c6e2542012-06-23 20:07:39 +1000964 def _private_globals(self):
965 code = """def f(): print(path)"""
966 ns = {}
967 exec(code, ns)
968 return ns["f"], ns
969
970 def test_builtins_fallback(self):
971 f, ns = self._private_globals()
972 ns.pop("__builtins__", None)
973 expected = inspect.ClosureVars({}, {}, {"print":print}, {"path"})
974 self.assertEqual(inspect.getclosurevars(f), expected)
975
976 def test_builtins_as_dict(self):
977 f, ns = self._private_globals()
978 ns["__builtins__"] = {"path":1}
979 expected = inspect.ClosureVars({}, {}, {"path":1}, {"print"})
980 self.assertEqual(inspect.getclosurevars(f), expected)
981
982 def test_builtins_as_module(self):
983 f, ns = self._private_globals()
984 ns["__builtins__"] = os
985 expected = inspect.ClosureVars({}, {}, {"path":os.path}, {"print"})
986 self.assertEqual(inspect.getclosurevars(f), expected)
987
Nick Coghlan2f92e542012-06-23 19:39:55 +1000988
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000989class TestGetcallargsFunctions(unittest.TestCase):
990
991 def assertEqualCallArgs(self, func, call_params_string, locs=None):
992 locs = dict(locs or {}, func=func)
993 r1 = eval('func(%s)' % call_params_string, None, locs)
994 r2 = eval('inspect.getcallargs(func, %s)' % call_params_string, None,
995 locs)
996 self.assertEqual(r1, r2)
997
998 def assertEqualException(self, func, call_param_string, locs=None):
999 locs = dict(locs or {}, func=func)
1000 try:
1001 eval('func(%s)' % call_param_string, None, locs)
1002 except Exception as e:
1003 ex1 = e
1004 else:
1005 self.fail('Exception not raised')
1006 try:
1007 eval('inspect.getcallargs(func, %s)' % call_param_string, None,
1008 locs)
1009 except Exception as e:
1010 ex2 = e
1011 else:
1012 self.fail('Exception not raised')
1013 self.assertIs(type(ex1), type(ex2))
1014 self.assertEqual(str(ex1), str(ex2))
1015 del ex1, ex2
1016
1017 def makeCallable(self, signature):
1018 """Create a function that returns its locals()"""
1019 code = "lambda %s: locals()"
1020 return eval(code % signature)
1021
1022 def test_plain(self):
1023 f = self.makeCallable('a, b=1')
1024 self.assertEqualCallArgs(f, '2')
1025 self.assertEqualCallArgs(f, '2, 3')
1026 self.assertEqualCallArgs(f, 'a=2')
1027 self.assertEqualCallArgs(f, 'b=3, a=2')
1028 self.assertEqualCallArgs(f, '2, b=3')
1029 # expand *iterable / **mapping
1030 self.assertEqualCallArgs(f, '*(2,)')
1031 self.assertEqualCallArgs(f, '*[2]')
1032 self.assertEqualCallArgs(f, '*(2, 3)')
1033 self.assertEqualCallArgs(f, '*[2, 3]')
1034 self.assertEqualCallArgs(f, '**{"a":2}')
1035 self.assertEqualCallArgs(f, 'b=3, **{"a":2}')
1036 self.assertEqualCallArgs(f, '2, **{"b":3}')
1037 self.assertEqualCallArgs(f, '**{"b":3, "a":2}')
1038 # expand UserList / UserDict
1039 self.assertEqualCallArgs(f, '*collections.UserList([2])')
1040 self.assertEqualCallArgs(f, '*collections.UserList([2, 3])')
1041 self.assertEqualCallArgs(f, '**collections.UserDict(a=2)')
1042 self.assertEqualCallArgs(f, '2, **collections.UserDict(b=3)')
1043 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3)')
1044
1045 def test_varargs(self):
1046 f = self.makeCallable('a, b=1, *c')
1047 self.assertEqualCallArgs(f, '2')
1048 self.assertEqualCallArgs(f, '2, 3')
1049 self.assertEqualCallArgs(f, '2, 3, 4')
1050 self.assertEqualCallArgs(f, '*(2,3,4)')
1051 self.assertEqualCallArgs(f, '2, *[3,4]')
1052 self.assertEqualCallArgs(f, '2, 3, *collections.UserList([4])')
1053
1054 def test_varkw(self):
1055 f = self.makeCallable('a, b=1, **c')
1056 self.assertEqualCallArgs(f, 'a=2')
1057 self.assertEqualCallArgs(f, '2, b=3, c=4')
1058 self.assertEqualCallArgs(f, 'b=3, a=2, c=4')
1059 self.assertEqualCallArgs(f, 'c=4, **{"a":2, "b":3}')
1060 self.assertEqualCallArgs(f, '2, c=4, **{"b":3}')
1061 self.assertEqualCallArgs(f, 'b=2, **{"a":3, "c":4}')
1062 self.assertEqualCallArgs(f, '**collections.UserDict(a=2, b=3, c=4)')
1063 self.assertEqualCallArgs(f, '2, c=4, **collections.UserDict(b=3)')
1064 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3, c=4)')
1065
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001066 def test_varkw_only(self):
1067 # issue11256:
1068 f = self.makeCallable('**c')
1069 self.assertEqualCallArgs(f, '')
1070 self.assertEqualCallArgs(f, 'a=1')
1071 self.assertEqualCallArgs(f, 'a=1, b=2')
1072 self.assertEqualCallArgs(f, 'c=3, **{"a": 1, "b": 2}')
1073 self.assertEqualCallArgs(f, '**collections.UserDict(a=1, b=2)')
1074 self.assertEqualCallArgs(f, 'c=3, **collections.UserDict(a=1, b=2)')
1075
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001076 def test_keyword_only(self):
1077 f = self.makeCallable('a=3, *, c, d=2')
1078 self.assertEqualCallArgs(f, 'c=3')
1079 self.assertEqualCallArgs(f, 'c=3, a=3')
1080 self.assertEqualCallArgs(f, 'a=2, c=4')
1081 self.assertEqualCallArgs(f, '4, c=4')
1082 self.assertEqualException(f, '')
1083 self.assertEqualException(f, '3')
1084 self.assertEqualException(f, 'a=3')
1085 self.assertEqualException(f, 'd=4')
1086
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001087 f = self.makeCallable('*, c, d=2')
1088 self.assertEqualCallArgs(f, 'c=3')
1089 self.assertEqualCallArgs(f, 'c=3, d=4')
1090 self.assertEqualCallArgs(f, 'd=4, c=3')
1091
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001092 def test_multiple_features(self):
1093 f = self.makeCallable('a, b=2, *f, **g')
1094 self.assertEqualCallArgs(f, '2, 3, 7')
1095 self.assertEqualCallArgs(f, '2, 3, x=8')
1096 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
1097 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9')
1098 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9')
1099 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
1100 '[2, 3, (4,[5,6])]), **{"y":9, "z":10}')
1101 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
1102 '(4,[5,6])]), **collections.UserDict('
1103 'y=9, z=10)')
1104
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001105 f = self.makeCallable('a, b=2, *f, x, y=99, **g')
1106 self.assertEqualCallArgs(f, '2, 3, x=8')
1107 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
1108 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9, z=10')
1109 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9, z=10')
1110 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
1111 '[2, 3, (4,[5,6])]), q=0, **{"y":9, "z":10}')
1112 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
1113 '(4,[5,6])]), q=0, **collections.UserDict('
1114 'y=9, z=10)')
1115
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001116 def test_errors(self):
1117 f0 = self.makeCallable('')
1118 f1 = self.makeCallable('a, b')
1119 f2 = self.makeCallable('a, b=1')
1120 # f0 takes no arguments
1121 self.assertEqualException(f0, '1')
1122 self.assertEqualException(f0, 'x=1')
1123 self.assertEqualException(f0, '1,x=1')
1124 # f1 takes exactly 2 arguments
1125 self.assertEqualException(f1, '')
1126 self.assertEqualException(f1, '1')
1127 self.assertEqualException(f1, 'a=2')
1128 self.assertEqualException(f1, 'b=3')
1129 # f2 takes at least 1 argument
1130 self.assertEqualException(f2, '')
1131 self.assertEqualException(f2, 'b=3')
1132 for f in f1, f2:
1133 # f1/f2 takes exactly/at most 2 arguments
1134 self.assertEqualException(f, '2, 3, 4')
1135 self.assertEqualException(f, '1, 2, 3, a=1')
1136 self.assertEqualException(f, '2, 3, 4, c=5')
Georg Brandl178e5ea2012-02-21 00:32:36 +01001137 # XXX: success of this one depends on dict order
1138 ## self.assertEqualException(f, '2, 3, 4, a=1, c=5')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001139 # f got an unexpected keyword argument
1140 self.assertEqualException(f, 'c=2')
1141 self.assertEqualException(f, '2, c=3')
1142 self.assertEqualException(f, '2, 3, c=4')
1143 self.assertEqualException(f, '2, c=4, b=3')
1144 self.assertEqualException(f, '**{u"\u03c0\u03b9": 4}')
1145 # f got multiple values for keyword argument
1146 self.assertEqualException(f, '1, a=2')
1147 self.assertEqualException(f, '1, **{"a":2}')
1148 self.assertEqualException(f, '1, 2, b=3')
1149 # XXX: Python inconsistency
1150 # - for functions and bound methods: unexpected keyword 'c'
1151 # - for unbound methods: multiple values for keyword 'a'
1152 #self.assertEqualException(f, '1, c=3, a=2')
Benjamin Peterson6a2638b2011-03-28 17:32:31 -05001153 # issue11256:
1154 f3 = self.makeCallable('**c')
1155 self.assertEqualException(f3, '1, 2')
1156 self.assertEqualException(f3, '1, 2, a=1, b=2')
1157 f4 = self.makeCallable('*, a, b=0')
1158 self.assertEqualException(f3, '1, 2')
1159 self.assertEqualException(f3, '1, 2, a=1, b=2')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001160
1161class TestGetcallargsMethods(TestGetcallargsFunctions):
1162
1163 def setUp(self):
1164 class Foo(object):
1165 pass
1166 self.cls = Foo
1167 self.inst = Foo()
1168
1169 def makeCallable(self, signature):
1170 assert 'self' not in signature
1171 mk = super(TestGetcallargsMethods, self).makeCallable
1172 self.cls.method = mk('self, ' + signature)
1173 return self.inst.method
1174
1175class TestGetcallargsUnboundMethods(TestGetcallargsMethods):
1176
1177 def makeCallable(self, signature):
1178 super(TestGetcallargsUnboundMethods, self).makeCallable(signature)
1179 return self.cls.method
1180
1181 def assertEqualCallArgs(self, func, call_params_string, locs=None):
1182 return super(TestGetcallargsUnboundMethods, self).assertEqualCallArgs(
1183 *self._getAssertEqualParams(func, call_params_string, locs))
1184
1185 def assertEqualException(self, func, call_params_string, locs=None):
1186 return super(TestGetcallargsUnboundMethods, self).assertEqualException(
1187 *self._getAssertEqualParams(func, call_params_string, locs))
1188
1189 def _getAssertEqualParams(self, func, call_params_string, locs=None):
1190 assert 'inst' not in call_params_string
1191 locs = dict(locs or {}, inst=self.inst)
1192 return (func, 'inst,' + call_params_string, locs)
1193
Michael Foord95fc51d2010-11-20 15:07:30 +00001194
1195class TestGetattrStatic(unittest.TestCase):
1196
1197 def test_basic(self):
1198 class Thing(object):
1199 x = object()
1200
1201 thing = Thing()
1202 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1203 self.assertEqual(inspect.getattr_static(thing, 'x', None), Thing.x)
1204 with self.assertRaises(AttributeError):
1205 inspect.getattr_static(thing, 'y')
1206
1207 self.assertEqual(inspect.getattr_static(thing, 'y', 3), 3)
1208
1209 def test_inherited(self):
1210 class Thing(object):
1211 x = object()
1212 class OtherThing(Thing):
1213 pass
1214
1215 something = OtherThing()
1216 self.assertEqual(inspect.getattr_static(something, 'x'), Thing.x)
1217
1218 def test_instance_attr(self):
1219 class Thing(object):
1220 x = 2
1221 def __init__(self, x):
1222 self.x = x
1223 thing = Thing(3)
1224 self.assertEqual(inspect.getattr_static(thing, 'x'), 3)
1225 del thing.x
1226 self.assertEqual(inspect.getattr_static(thing, 'x'), 2)
1227
1228 def test_property(self):
1229 class Thing(object):
1230 @property
1231 def x(self):
1232 raise AttributeError("I'm pretending not to exist")
1233 thing = Thing()
1234 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1235
Ezio Melotti75cbd732011-04-28 00:59:29 +03001236 def test_descriptor_raises_AttributeError(self):
Michael Foord95fc51d2010-11-20 15:07:30 +00001237 class descriptor(object):
1238 def __get__(*_):
1239 raise AttributeError("I'm pretending not to exist")
1240 desc = descriptor()
1241 class Thing(object):
1242 x = desc
1243 thing = Thing()
1244 self.assertEqual(inspect.getattr_static(thing, 'x'), desc)
1245
1246 def test_classAttribute(self):
1247 class Thing(object):
1248 x = object()
1249
1250 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.x)
1251
Ethan Furmane03ea372013-09-25 07:14:41 -07001252 def test_classVirtualAttribute(self):
1253 class Thing(object):
1254 @types.DynamicClassAttribute
1255 def x(self):
1256 return self._x
1257 _x = object()
1258
1259 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.__dict__['x'])
1260
Michael Foord95fc51d2010-11-20 15:07:30 +00001261 def test_inherited_classattribute(self):
1262 class Thing(object):
1263 x = object()
1264 class OtherThing(Thing):
1265 pass
1266
1267 self.assertEqual(inspect.getattr_static(OtherThing, 'x'), Thing.x)
1268
1269 def test_slots(self):
1270 class Thing(object):
1271 y = 'bar'
1272 __slots__ = ['x']
1273 def __init__(self):
1274 self.x = 'foo'
1275 thing = Thing()
1276 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1277 self.assertEqual(inspect.getattr_static(thing, 'y'), 'bar')
1278
1279 del thing.x
1280 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1281
1282 def test_metaclass(self):
1283 class meta(type):
1284 attr = 'foo'
1285 class Thing(object, metaclass=meta):
1286 pass
1287 self.assertEqual(inspect.getattr_static(Thing, 'attr'), 'foo')
1288
1289 class sub(meta):
1290 pass
1291 class OtherThing(object, metaclass=sub):
1292 x = 3
1293 self.assertEqual(inspect.getattr_static(OtherThing, 'attr'), 'foo')
1294
1295 class OtherOtherThing(OtherThing):
1296 pass
1297 # this test is odd, but it was added as it exposed a bug
1298 self.assertEqual(inspect.getattr_static(OtherOtherThing, 'x'), 3)
1299
1300 def test_no_dict_no_slots(self):
1301 self.assertEqual(inspect.getattr_static(1, 'foo', None), None)
1302 self.assertNotEqual(inspect.getattr_static('foo', 'lower'), None)
1303
1304 def test_no_dict_no_slots_instance_member(self):
1305 # returns descriptor
1306 with open(__file__) as handle:
1307 self.assertEqual(inspect.getattr_static(handle, 'name'), type(handle).name)
1308
1309 def test_inherited_slots(self):
1310 # returns descriptor
1311 class Thing(object):
1312 __slots__ = ['x']
1313 def __init__(self):
1314 self.x = 'foo'
1315
1316 class OtherThing(Thing):
1317 pass
1318 # it would be nice if this worked...
1319 # we get the descriptor instead of the instance attribute
1320 self.assertEqual(inspect.getattr_static(OtherThing(), 'x'), Thing.x)
1321
1322 def test_descriptor(self):
1323 class descriptor(object):
1324 def __get__(self, instance, owner):
1325 return 3
1326 class Foo(object):
1327 d = descriptor()
1328
1329 foo = Foo()
1330
1331 # for a non data descriptor we return the instance attribute
1332 foo.__dict__['d'] = 1
1333 self.assertEqual(inspect.getattr_static(foo, 'd'), 1)
1334
1335 # if the descriptor is a data-desciptor we should return the
1336 # descriptor
1337 descriptor.__set__ = lambda s, i, v: None
1338 self.assertEqual(inspect.getattr_static(foo, 'd'), Foo.__dict__['d'])
1339
1340
1341 def test_metaclass_with_descriptor(self):
1342 class descriptor(object):
1343 def __get__(self, instance, owner):
1344 return 3
1345 class meta(type):
1346 d = descriptor()
1347 class Thing(object, metaclass=meta):
1348 pass
1349 self.assertEqual(inspect.getattr_static(Thing, 'd'), meta.__dict__['d'])
1350
1351
Michael Foordcc7ebb82010-11-20 16:20:16 +00001352 def test_class_as_property(self):
1353 class Base(object):
1354 foo = 3
1355
1356 class Something(Base):
Michael Foord35184ed2010-11-20 16:58:30 +00001357 executed = False
Michael Foordcc7ebb82010-11-20 16:20:16 +00001358 @property
1359 def __class__(self):
Michael Foord35184ed2010-11-20 16:58:30 +00001360 self.executed = True
Michael Foordcc7ebb82010-11-20 16:20:16 +00001361 return object
1362
Michael Foord35184ed2010-11-20 16:58:30 +00001363 instance = Something()
1364 self.assertEqual(inspect.getattr_static(instance, 'foo'), 3)
1365 self.assertFalse(instance.executed)
Michael Foordcc7ebb82010-11-20 16:20:16 +00001366 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1367
Michael Foorde5162652010-11-20 16:40:44 +00001368 def test_mro_as_property(self):
1369 class Meta(type):
1370 @property
1371 def __mro__(self):
1372 return (object,)
1373
1374 class Base(object):
1375 foo = 3
1376
1377 class Something(Base, metaclass=Meta):
1378 pass
1379
1380 self.assertEqual(inspect.getattr_static(Something(), 'foo'), 3)
1381 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1382
Michael Foorddcebe0f2011-03-15 19:20:44 -04001383 def test_dict_as_property(self):
1384 test = self
1385 test.called = False
1386
1387 class Foo(dict):
1388 a = 3
1389 @property
1390 def __dict__(self):
1391 test.called = True
1392 return {}
1393
1394 foo = Foo()
1395 foo.a = 4
1396 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1397 self.assertFalse(test.called)
1398
1399 def test_custom_object_dict(self):
1400 test = self
1401 test.called = False
1402
1403 class Custom(dict):
1404 def get(self, key, default=None):
1405 test.called = True
1406 super().get(key, default)
1407
1408 class Foo(object):
1409 a = 3
1410 foo = Foo()
1411 foo.__dict__ = Custom()
1412 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1413 self.assertFalse(test.called)
1414
1415 def test_metaclass_dict_as_property(self):
1416 class Meta(type):
1417 @property
1418 def __dict__(self):
1419 self.executed = True
1420
1421 class Thing(metaclass=Meta):
1422 executed = False
1423
1424 def __init__(self):
1425 self.spam = 42
1426
1427 instance = Thing()
1428 self.assertEqual(inspect.getattr_static(instance, "spam"), 42)
1429 self.assertFalse(Thing.executed)
Michael Foorde5162652010-11-20 16:40:44 +00001430
Michael Foorda51623b2011-12-18 22:01:40 +00001431 def test_module(self):
1432 sentinel = object()
1433 self.assertIsNot(inspect.getattr_static(sys, "version", sentinel),
1434 sentinel)
1435
Michael Foord3ba95f82011-12-22 01:13:37 +00001436 def test_metaclass_with_metaclass_with_dict_as_property(self):
1437 class MetaMeta(type):
1438 @property
1439 def __dict__(self):
1440 self.executed = True
1441 return dict(spam=42)
1442
1443 class Meta(type, metaclass=MetaMeta):
1444 executed = False
1445
1446 class Thing(metaclass=Meta):
1447 pass
1448
1449 with self.assertRaises(AttributeError):
1450 inspect.getattr_static(Thing, "spam")
1451 self.assertFalse(Thing.executed)
1452
Nick Coghlane0f04652010-11-21 03:44:04 +00001453class TestGetGeneratorState(unittest.TestCase):
1454
1455 def setUp(self):
1456 def number_generator():
1457 for number in range(5):
1458 yield number
1459 self.generator = number_generator()
1460
1461 def _generatorstate(self):
1462 return inspect.getgeneratorstate(self.generator)
1463
1464 def test_created(self):
1465 self.assertEqual(self._generatorstate(), inspect.GEN_CREATED)
1466
1467 def test_suspended(self):
1468 next(self.generator)
1469 self.assertEqual(self._generatorstate(), inspect.GEN_SUSPENDED)
1470
1471 def test_closed_after_exhaustion(self):
1472 for i in self.generator:
1473 pass
1474 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1475
1476 def test_closed_after_immediate_exception(self):
1477 with self.assertRaises(RuntimeError):
1478 self.generator.throw(RuntimeError)
1479 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1480
1481 def test_running(self):
1482 # As mentioned on issue #10220, checking for the RUNNING state only
1483 # makes sense inside the generator itself.
1484 # The following generator checks for this by using the closure's
1485 # reference to self and the generator state checking helper method
1486 def running_check_generator():
1487 for number in range(5):
1488 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1489 yield number
1490 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1491 self.generator = running_check_generator()
1492 # Running up to the first yield
1493 next(self.generator)
1494 # Running after the first yield
1495 next(self.generator)
1496
Nick Coghlan7921b9f2010-11-30 06:36:04 +00001497 def test_easy_debugging(self):
1498 # repr() and str() of a generator state should contain the state name
1499 names = 'GEN_CREATED GEN_RUNNING GEN_SUSPENDED GEN_CLOSED'.split()
1500 for name in names:
1501 state = getattr(inspect, name)
1502 self.assertIn(name, repr(state))
1503 self.assertIn(name, str(state))
1504
Nick Coghlan04e2e3f2012-06-23 19:52:05 +10001505 def test_getgeneratorlocals(self):
1506 def each(lst, a=None):
1507 b=(1, 2, 3)
1508 for v in lst:
1509 if v == 3:
1510 c = 12
1511 yield v
1512
1513 numbers = each([1, 2, 3])
1514 self.assertEqual(inspect.getgeneratorlocals(numbers),
1515 {'a': None, 'lst': [1, 2, 3]})
1516 next(numbers)
1517 self.assertEqual(inspect.getgeneratorlocals(numbers),
1518 {'a': None, 'lst': [1, 2, 3], 'v': 1,
1519 'b': (1, 2, 3)})
1520 next(numbers)
1521 self.assertEqual(inspect.getgeneratorlocals(numbers),
1522 {'a': None, 'lst': [1, 2, 3], 'v': 2,
1523 'b': (1, 2, 3)})
1524 next(numbers)
1525 self.assertEqual(inspect.getgeneratorlocals(numbers),
1526 {'a': None, 'lst': [1, 2, 3], 'v': 3,
1527 'b': (1, 2, 3), 'c': 12})
1528 try:
1529 next(numbers)
1530 except StopIteration:
1531 pass
1532 self.assertEqual(inspect.getgeneratorlocals(numbers), {})
1533
1534 def test_getgeneratorlocals_empty(self):
1535 def yield_one():
1536 yield 1
1537 one = yield_one()
1538 self.assertEqual(inspect.getgeneratorlocals(one), {})
1539 try:
1540 next(one)
1541 except StopIteration:
1542 pass
1543 self.assertEqual(inspect.getgeneratorlocals(one), {})
1544
1545 def test_getgeneratorlocals_error(self):
1546 self.assertRaises(TypeError, inspect.getgeneratorlocals, 1)
1547 self.assertRaises(TypeError, inspect.getgeneratorlocals, lambda x: True)
1548 self.assertRaises(TypeError, inspect.getgeneratorlocals, set)
1549 self.assertRaises(TypeError, inspect.getgeneratorlocals, (2,3))
1550
Nick Coghlane0f04652010-11-21 03:44:04 +00001551
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001552class TestSignatureObject(unittest.TestCase):
1553 @staticmethod
1554 def signature(func):
1555 sig = inspect.signature(func)
1556 return (tuple((param.name,
1557 (... if param.default is param.empty else param.default),
1558 (... if param.annotation is param.empty
1559 else param.annotation),
1560 str(param.kind).lower())
1561 for param in sig.parameters.values()),
1562 (... if sig.return_annotation is sig.empty
1563 else sig.return_annotation))
1564
1565 def test_signature_object(self):
1566 S = inspect.Signature
1567 P = inspect.Parameter
1568
1569 self.assertEqual(str(S()), '()')
1570
Yury Selivanov07a9e452014-01-29 10:58:16 -05001571 def test(po, pk, pod=42, pkd=100, *args, ko, **kwargs):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001572 pass
1573 sig = inspect.signature(test)
1574 po = sig.parameters['po'].replace(kind=P.POSITIONAL_ONLY)
Yury Selivanov07a9e452014-01-29 10:58:16 -05001575 pod = sig.parameters['pod'].replace(kind=P.POSITIONAL_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001576 pk = sig.parameters['pk']
Yury Selivanov07a9e452014-01-29 10:58:16 -05001577 pkd = sig.parameters['pkd']
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001578 args = sig.parameters['args']
1579 ko = sig.parameters['ko']
1580 kwargs = sig.parameters['kwargs']
1581
1582 S((po, pk, 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((pk, po, args, 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((po, args, 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((args, po, pk, ko, kwargs))
1592
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001593 with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001594 S((po, pk, args, kwargs, ko))
1595
1596 kwargs2 = kwargs.replace(name='args')
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001597 with self.assertRaisesRegex(ValueError, 'duplicate parameter name'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001598 S((po, pk, args, kwargs2, ko))
1599
Yury Selivanov07a9e452014-01-29 10:58:16 -05001600 with self.assertRaisesRegex(ValueError, 'follows default argument'):
1601 S((pod, po))
1602
1603 with self.assertRaisesRegex(ValueError, 'follows default argument'):
1604 S((po, pkd, pk))
1605
1606 with self.assertRaisesRegex(ValueError, 'follows default argument'):
1607 S((pkd, pk))
1608
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001609 def test_signature_immutability(self):
1610 def test(a):
1611 pass
1612 sig = inspect.signature(test)
1613
1614 with self.assertRaises(AttributeError):
1615 sig.foo = 'bar'
1616
1617 with self.assertRaises(TypeError):
1618 sig.parameters['a'] = None
1619
1620 def test_signature_on_noarg(self):
1621 def test():
1622 pass
1623 self.assertEqual(self.signature(test), ((), ...))
1624
1625 def test_signature_on_wargs(self):
1626 def test(a, b:'foo') -> 123:
1627 pass
1628 self.assertEqual(self.signature(test),
1629 ((('a', ..., ..., "positional_or_keyword"),
1630 ('b', ..., 'foo', "positional_or_keyword")),
1631 123))
1632
1633 def test_signature_on_wkwonly(self):
1634 def test(*, a:float, b:str) -> int:
1635 pass
1636 self.assertEqual(self.signature(test),
1637 ((('a', ..., float, "keyword_only"),
1638 ('b', ..., str, "keyword_only")),
1639 int))
1640
1641 def test_signature_on_complex_args(self):
1642 def test(a, b:'foo'=10, *args:'bar', spam:'baz', ham=123, **kwargs:int):
1643 pass
1644 self.assertEqual(self.signature(test),
1645 ((('a', ..., ..., "positional_or_keyword"),
1646 ('b', 10, 'foo', "positional_or_keyword"),
1647 ('args', ..., 'bar', "var_positional"),
1648 ('spam', ..., 'baz', "keyword_only"),
1649 ('ham', 123, ..., "keyword_only"),
1650 ('kwargs', ..., int, "var_keyword")),
1651 ...))
1652
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02001653 @cpython_only
Larry Hastingsfcafe432013-11-23 17:35:48 -08001654 @unittest.skipIf(MISSING_C_DOCSTRINGS,
1655 "Signature information for builtins requires docstrings")
1656 def test_signature_on_builtins(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02001657 import _testcapi
Larry Hastings16c51912014-01-07 11:53:01 -08001658
Larry Hastings5c661892014-01-24 06:17:25 -08001659 def test_unbound_method(o):
1660 """Use this to test unbound methods (things that should have a self)"""
1661 signature = inspect.signature(o)
1662 self.assertTrue(isinstance(signature, inspect.Signature))
1663 self.assertEqual(list(signature.parameters.values())[0].name, 'self')
1664 return signature
1665
1666 def test_callable(o):
1667 """Use this to test bound methods or normal callables (things that don't expect self)"""
1668 signature = inspect.signature(o)
1669 self.assertTrue(isinstance(signature, inspect.Signature))
1670 if signature.parameters:
1671 self.assertNotEqual(list(signature.parameters.values())[0].name, 'self')
1672 return signature
1673
1674 signature = test_callable(_testcapi.docstring_with_signature_with_defaults)
Larry Hastings16c51912014-01-07 11:53:01 -08001675 def p(name): return signature.parameters[name].default
1676 self.assertEqual(p('s'), 'avocado')
Larry Hastings2a727912014-01-16 11:32:01 -08001677 self.assertEqual(p('b'), b'bytes')
Larry Hastings16c51912014-01-07 11:53:01 -08001678 self.assertEqual(p('d'), 3.14)
1679 self.assertEqual(p('i'), 35)
Larry Hastings16c51912014-01-07 11:53:01 -08001680 self.assertEqual(p('n'), None)
1681 self.assertEqual(p('t'), True)
1682 self.assertEqual(p('f'), False)
Larry Hastings2a727912014-01-16 11:32:01 -08001683 self.assertEqual(p('local'), 3)
1684 self.assertEqual(p('sys'), sys.maxsize)
1685 self.assertEqual(p('exp'), sys.maxsize - 1)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001686
Larry Hastings5c661892014-01-24 06:17:25 -08001687 test_callable(object)
1688
1689 # normal method
1690 # (PyMethodDescr_Type, "method_descriptor")
1691 test_unbound_method(_pickle.Pickler.dump)
1692 d = _pickle.Pickler(io.StringIO())
1693 test_callable(d.dump)
1694
1695 # static method
1696 test_callable(str.maketrans)
1697 test_callable('abc'.maketrans)
1698
1699 # class method
1700 test_callable(dict.fromkeys)
1701 test_callable({}.fromkeys)
1702
1703 # wrapper around slot (PyWrapperDescr_Type, "wrapper_descriptor")
1704 test_unbound_method(type.__call__)
1705 test_unbound_method(int.__add__)
1706 test_callable((3).__add__)
1707
1708 # _PyMethodWrapper_Type
1709 # support for 'method-wrapper'
1710 test_callable(min.__call__)
1711
Larry Hastings2623c8c2014-02-08 22:15:29 -08001712 # This doesn't work now.
1713 # (We don't have a valid signature for "type" in 3.4)
1714 with self.assertRaisesRegex(ValueError, "no signature found"):
1715 class ThisWorksNow:
1716 __call__ = type
1717 test_callable(ThisWorksNow())
Larry Hastings5c661892014-01-24 06:17:25 -08001718
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02001719 @cpython_only
Yury Selivanov76c6c592014-01-29 10:52:57 -05001720 @unittest.skipIf(MISSING_C_DOCSTRINGS,
1721 "Signature information for builtins requires docstrings")
1722 def test_signature_on_decorated_builtins(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02001723 import _testcapi
Yury Selivanov76c6c592014-01-29 10:52:57 -05001724 func = _testcapi.docstring_with_signature_with_defaults
1725
1726 def decorator(func):
1727 @functools.wraps(func)
1728 def wrapper(*args, **kwargs) -> int:
1729 return func(*args, **kwargs)
1730 return wrapper
1731
1732 decorated_func = decorator(func)
1733
1734 self.assertEqual(inspect.signature(func),
1735 inspect.signature(decorated_func))
Larry Hastings5c661892014-01-24 06:17:25 -08001736
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02001737 @cpython_only
Larry Hastings5c661892014-01-24 06:17:25 -08001738 def test_signature_on_builtins_no_signature(self):
Serhiy Storchakaf28ba362014-02-07 10:10:55 +02001739 import _testcapi
Larry Hastings5c661892014-01-24 06:17:25 -08001740 with self.assertRaisesRegex(ValueError, 'no signature found for builtin'):
1741 inspect.signature(_testcapi.docstring_no_signature)
1742
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001743 def test_signature_on_non_function(self):
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001744 with self.assertRaisesRegex(TypeError, 'is not a callable object'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001745 inspect.signature(42)
1746
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001747 with self.assertRaisesRegex(TypeError, 'is not a Python function'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001748 inspect.Signature.from_function(42)
1749
Yury Selivanovb77511d2014-01-29 10:46:14 -05001750 def test_signature_from_builtin_errors(self):
1751 with self.assertRaisesRegex(TypeError, 'is not a Python builtin'):
1752 inspect.Signature.from_builtin(42)
1753
Yury Selivanov63da7c72014-01-31 14:48:37 -05001754 def test_signature_from_functionlike_object(self):
1755 def func(a,b, *args, kwonly=True, kwonlyreq, **kwargs):
1756 pass
1757
1758 class funclike:
1759 # Has to be callable, and have correct
1760 # __code__, __annotations__, __defaults__, __name__,
1761 # and __kwdefaults__ attributes
1762
1763 def __init__(self, func):
1764 self.__name__ = func.__name__
1765 self.__code__ = func.__code__
1766 self.__annotations__ = func.__annotations__
1767 self.__defaults__ = func.__defaults__
1768 self.__kwdefaults__ = func.__kwdefaults__
1769 self.func = func
1770
1771 def __call__(self, *args, **kwargs):
1772 return self.func(*args, **kwargs)
1773
1774 sig_func = inspect.Signature.from_function(func)
1775
1776 sig_funclike = inspect.Signature.from_function(funclike(func))
1777 self.assertEqual(sig_funclike, sig_func)
1778
1779 sig_funclike = inspect.signature(funclike(func))
1780 self.assertEqual(sig_funclike, sig_func)
1781
1782 # If object is not a duck type of function, then
1783 # signature will try to get a signature for its '__call__'
1784 # method
1785 fl = funclike(func)
1786 del fl.__defaults__
1787 self.assertEqual(self.signature(fl),
1788 ((('args', ..., ..., "var_positional"),
1789 ('kwargs', ..., ..., "var_keyword")),
1790 ...))
1791
1792 def test_signature_functionlike_class(self):
1793 # We only want to duck type function-like objects,
1794 # not classes.
1795
1796 def func(a,b, *args, kwonly=True, kwonlyreq, **kwargs):
1797 pass
1798
1799 class funclike:
1800 def __init__(self, marker):
1801 pass
1802
1803 __name__ = func.__name__
1804 __code__ = func.__code__
1805 __annotations__ = func.__annotations__
1806 __defaults__ = func.__defaults__
1807 __kwdefaults__ = func.__kwdefaults__
1808
1809 with self.assertRaisesRegex(TypeError, 'is not a Python function'):
1810 inspect.Signature.from_function(funclike)
1811
1812 self.assertEqual(str(inspect.signature(funclike)), '(marker)')
1813
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001814 def test_signature_on_method(self):
1815 class Test:
Yury Selivanov62560fb2014-01-28 12:26:24 -05001816 def __init__(*args):
1817 pass
1818 def m1(self, arg1, arg2=1) -> int:
1819 pass
1820 def m2(*args):
1821 pass
1822 def __call__(*, a):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001823 pass
1824
Yury Selivanov62560fb2014-01-28 12:26:24 -05001825 self.assertEqual(self.signature(Test().m1),
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001826 ((('arg1', ..., ..., "positional_or_keyword"),
1827 ('arg2', 1, ..., "positional_or_keyword")),
1828 int))
1829
Yury Selivanov62560fb2014-01-28 12:26:24 -05001830 self.assertEqual(self.signature(Test().m2),
1831 ((('args', ..., ..., "var_positional"),),
1832 ...))
1833
1834 self.assertEqual(self.signature(Test),
1835 ((('args', ..., ..., "var_positional"),),
1836 ...))
1837
1838 with self.assertRaisesRegex(ValueError, 'invalid method signature'):
1839 self.signature(Test())
1840
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001841 def test_signature_on_classmethod(self):
1842 class Test:
1843 @classmethod
1844 def foo(cls, arg1, *, arg2=1):
1845 pass
1846
1847 meth = Test().foo
1848 self.assertEqual(self.signature(meth),
1849 ((('arg1', ..., ..., "positional_or_keyword"),
1850 ('arg2', 1, ..., "keyword_only")),
1851 ...))
1852
1853 meth = Test.foo
1854 self.assertEqual(self.signature(meth),
1855 ((('arg1', ..., ..., "positional_or_keyword"),
1856 ('arg2', 1, ..., "keyword_only")),
1857 ...))
1858
1859 def test_signature_on_staticmethod(self):
1860 class Test:
1861 @staticmethod
1862 def foo(cls, *, arg):
1863 pass
1864
1865 meth = Test().foo
1866 self.assertEqual(self.signature(meth),
1867 ((('cls', ..., ..., "positional_or_keyword"),
1868 ('arg', ..., ..., "keyword_only")),
1869 ...))
1870
1871 meth = Test.foo
1872 self.assertEqual(self.signature(meth),
1873 ((('cls', ..., ..., "positional_or_keyword"),
1874 ('arg', ..., ..., "keyword_only")),
1875 ...))
1876
1877 def test_signature_on_partial(self):
1878 from functools import partial
1879
1880 def test():
1881 pass
1882
1883 self.assertEqual(self.signature(partial(test)), ((), ...))
1884
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001885 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001886 inspect.signature(partial(test, 1))
1887
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02001888 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001889 inspect.signature(partial(test, a=1))
1890
1891 def test(a, b, *, c, d):
1892 pass
1893
1894 self.assertEqual(self.signature(partial(test)),
1895 ((('a', ..., ..., "positional_or_keyword"),
1896 ('b', ..., ..., "positional_or_keyword"),
1897 ('c', ..., ..., "keyword_only"),
1898 ('d', ..., ..., "keyword_only")),
1899 ...))
1900
1901 self.assertEqual(self.signature(partial(test, 1)),
1902 ((('b', ..., ..., "positional_or_keyword"),
1903 ('c', ..., ..., "keyword_only"),
1904 ('d', ..., ..., "keyword_only")),
1905 ...))
1906
1907 self.assertEqual(self.signature(partial(test, 1, c=2)),
1908 ((('b', ..., ..., "positional_or_keyword"),
1909 ('c', 2, ..., "keyword_only"),
1910 ('d', ..., ..., "keyword_only")),
1911 ...))
1912
1913 self.assertEqual(self.signature(partial(test, b=1, c=2)),
1914 ((('a', ..., ..., "positional_or_keyword"),
1915 ('b', 1, ..., "positional_or_keyword"),
1916 ('c', 2, ..., "keyword_only"),
1917 ('d', ..., ..., "keyword_only")),
1918 ...))
1919
1920 self.assertEqual(self.signature(partial(test, 0, b=1, c=2)),
1921 ((('b', 1, ..., "positional_or_keyword"),
1922 ('c', 2, ..., "keyword_only"),
1923 ('d', ..., ..., "keyword_only"),),
1924 ...))
1925
1926 def test(a, *args, b, **kwargs):
1927 pass
1928
1929 self.assertEqual(self.signature(partial(test, 1)),
1930 ((('args', ..., ..., "var_positional"),
1931 ('b', ..., ..., "keyword_only"),
1932 ('kwargs', ..., ..., "var_keyword")),
1933 ...))
1934
1935 self.assertEqual(self.signature(partial(test, 1, 2, 3)),
1936 ((('args', ..., ..., "var_positional"),
1937 ('b', ..., ..., "keyword_only"),
1938 ('kwargs', ..., ..., "var_keyword")),
1939 ...))
1940
1941
1942 self.assertEqual(self.signature(partial(test, 1, 2, 3, test=True)),
1943 ((('args', ..., ..., "var_positional"),
1944 ('b', ..., ..., "keyword_only"),
1945 ('kwargs', ..., ..., "var_keyword")),
1946 ...))
1947
1948 self.assertEqual(self.signature(partial(test, 1, 2, 3, test=1, b=0)),
1949 ((('args', ..., ..., "var_positional"),
1950 ('b', 0, ..., "keyword_only"),
1951 ('kwargs', ..., ..., "var_keyword")),
1952 ...))
1953
1954 self.assertEqual(self.signature(partial(test, b=0)),
1955 ((('a', ..., ..., "positional_or_keyword"),
1956 ('args', ..., ..., "var_positional"),
1957 ('b', 0, ..., "keyword_only"),
1958 ('kwargs', ..., ..., "var_keyword")),
1959 ...))
1960
1961 self.assertEqual(self.signature(partial(test, b=0, test=1)),
1962 ((('a', ..., ..., "positional_or_keyword"),
1963 ('args', ..., ..., "var_positional"),
1964 ('b', 0, ..., "keyword_only"),
1965 ('kwargs', ..., ..., "var_keyword")),
1966 ...))
1967
1968 def test(a, b, c:int) -> 42:
1969 pass
1970
1971 sig = test.__signature__ = inspect.signature(test)
1972
1973 self.assertEqual(self.signature(partial(partial(test, 1))),
1974 ((('b', ..., ..., "positional_or_keyword"),
1975 ('c', ..., int, "positional_or_keyword")),
1976 42))
1977
1978 self.assertEqual(self.signature(partial(partial(test, 1), 2)),
1979 ((('c', ..., int, "positional_or_keyword"),),
1980 42))
1981
1982 psig = inspect.signature(partial(partial(test, 1), 2))
1983
1984 def foo(a):
1985 return a
1986 _foo = partial(partial(foo, a=10), a=20)
1987 self.assertEqual(self.signature(_foo),
1988 ((('a', 20, ..., "positional_or_keyword"),),
1989 ...))
1990 # check that we don't have any side-effects in signature(),
1991 # and the partial object is still functioning
1992 self.assertEqual(_foo(), 20)
1993
1994 def foo(a, b, c):
1995 return a, b, c
1996 _foo = partial(partial(foo, 1, b=20), b=30)
1997 self.assertEqual(self.signature(_foo),
1998 ((('b', 30, ..., "positional_or_keyword"),
1999 ('c', ..., ..., "positional_or_keyword")),
2000 ...))
2001 self.assertEqual(_foo(c=10), (1, 30, 10))
2002 _foo = partial(_foo, 2) # now 'b' has two values -
2003 # positional and keyword
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002004 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002005 inspect.signature(_foo)
2006
2007 def foo(a, b, c, *, d):
2008 return a, b, c, d
2009 _foo = partial(partial(foo, d=20, c=20), b=10, d=30)
2010 self.assertEqual(self.signature(_foo),
2011 ((('a', ..., ..., "positional_or_keyword"),
2012 ('b', 10, ..., "positional_or_keyword"),
2013 ('c', 20, ..., "positional_or_keyword"),
2014 ('d', 30, ..., "keyword_only")),
2015 ...))
2016 ba = inspect.signature(_foo).bind(a=200, b=11)
2017 self.assertEqual(_foo(*ba.args, **ba.kwargs), (200, 11, 20, 30))
2018
2019 def foo(a=1, b=2, c=3):
2020 return a, b, c
2021 _foo = partial(foo, a=10, c=13)
2022 ba = inspect.signature(_foo).bind(11)
2023 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 2, 13))
2024 ba = inspect.signature(_foo).bind(11, 12)
2025 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
2026 ba = inspect.signature(_foo).bind(11, b=12)
2027 self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
2028 ba = inspect.signature(_foo).bind(b=12)
2029 self.assertEqual(_foo(*ba.args, **ba.kwargs), (10, 12, 13))
2030 _foo = partial(_foo, b=10)
2031 ba = inspect.signature(_foo).bind(12, 14)
2032 self.assertEqual(_foo(*ba.args, **ba.kwargs), (12, 14, 13))
2033
Yury Selivanovda5fe4f2014-01-27 17:28:37 -05002034 def test_signature_on_partialmethod(self):
2035 from functools import partialmethod
2036
2037 class Spam:
2038 def test():
2039 pass
2040 ham = partialmethod(test)
2041
2042 with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
2043 inspect.signature(Spam.ham)
2044
2045 class Spam:
2046 def test(it, a, *, c) -> 'spam':
2047 pass
2048 ham = partialmethod(test, c=1)
2049
2050 self.assertEqual(self.signature(Spam.ham),
2051 ((('it', ..., ..., 'positional_or_keyword'),
2052 ('a', ..., ..., 'positional_or_keyword'),
2053 ('c', 1, ..., 'keyword_only')),
2054 'spam'))
2055
2056 self.assertEqual(self.signature(Spam().ham),
2057 ((('a', ..., ..., 'positional_or_keyword'),
2058 ('c', 1, ..., 'keyword_only')),
2059 'spam'))
2060
Yury Selivanov0486f812014-01-29 12:18:59 -05002061 def test_signature_on_fake_partialmethod(self):
2062 def foo(a): pass
2063 foo._partialmethod = 'spam'
2064 self.assertEqual(str(inspect.signature(foo)), '(a)')
2065
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002066 def test_signature_on_decorated(self):
2067 import functools
2068
2069 def decorator(func):
2070 @functools.wraps(func)
2071 def wrapper(*args, **kwargs) -> int:
2072 return func(*args, **kwargs)
2073 return wrapper
2074
2075 class Foo:
2076 @decorator
2077 def bar(self, a, b):
2078 pass
2079
2080 self.assertEqual(self.signature(Foo.bar),
2081 ((('self', ..., ..., "positional_or_keyword"),
2082 ('a', ..., ..., "positional_or_keyword"),
2083 ('b', ..., ..., "positional_or_keyword")),
2084 ...))
2085
2086 self.assertEqual(self.signature(Foo().bar),
2087 ((('a', ..., ..., "positional_or_keyword"),
2088 ('b', ..., ..., "positional_or_keyword")),
2089 ...))
2090
2091 # Test that we handle method wrappers correctly
2092 def decorator(func):
2093 @functools.wraps(func)
2094 def wrapper(*args, **kwargs) -> int:
2095 return func(42, *args, **kwargs)
2096 sig = inspect.signature(func)
2097 new_params = tuple(sig.parameters.values())[1:]
2098 wrapper.__signature__ = sig.replace(parameters=new_params)
2099 return wrapper
2100
2101 class Foo:
2102 @decorator
2103 def __call__(self, a, b):
2104 pass
2105
2106 self.assertEqual(self.signature(Foo.__call__),
2107 ((('a', ..., ..., "positional_or_keyword"),
2108 ('b', ..., ..., "positional_or_keyword")),
2109 ...))
2110
2111 self.assertEqual(self.signature(Foo().__call__),
2112 ((('b', ..., ..., "positional_or_keyword"),),
2113 ...))
2114
Nick Coghlane8c45d62013-07-28 20:00:01 +10002115 # Test we handle __signature__ partway down the wrapper stack
2116 def wrapped_foo_call():
2117 pass
2118 wrapped_foo_call.__wrapped__ = Foo.__call__
2119
2120 self.assertEqual(self.signature(wrapped_foo_call),
2121 ((('a', ..., ..., "positional_or_keyword"),
2122 ('b', ..., ..., "positional_or_keyword")),
2123 ...))
2124
2125
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002126 def test_signature_on_class(self):
2127 class C:
2128 def __init__(self, a):
2129 pass
2130
2131 self.assertEqual(self.signature(C),
2132 ((('a', ..., ..., "positional_or_keyword"),),
2133 ...))
2134
2135 class CM(type):
2136 def __call__(cls, a):
2137 pass
2138 class C(metaclass=CM):
2139 def __init__(self, b):
2140 pass
2141
2142 self.assertEqual(self.signature(C),
2143 ((('a', ..., ..., "positional_or_keyword"),),
2144 ...))
2145
2146 class CM(type):
2147 def __new__(mcls, name, bases, dct, *, foo=1):
2148 return super().__new__(mcls, name, bases, dct)
2149 class C(metaclass=CM):
2150 def __init__(self, b):
2151 pass
2152
2153 self.assertEqual(self.signature(C),
2154 ((('b', ..., ..., "positional_or_keyword"),),
2155 ...))
2156
2157 self.assertEqual(self.signature(CM),
2158 ((('name', ..., ..., "positional_or_keyword"),
2159 ('bases', ..., ..., "positional_or_keyword"),
2160 ('dct', ..., ..., "positional_or_keyword"),
2161 ('foo', 1, ..., "keyword_only")),
2162 ...))
2163
2164 class CMM(type):
2165 def __new__(mcls, name, bases, dct, *, foo=1):
2166 return super().__new__(mcls, name, bases, dct)
2167 def __call__(cls, nm, bs, dt):
2168 return type(nm, bs, dt)
2169 class CM(type, metaclass=CMM):
2170 def __new__(mcls, name, bases, dct, *, bar=2):
2171 return super().__new__(mcls, name, bases, dct)
2172 class C(metaclass=CM):
2173 def __init__(self, b):
2174 pass
2175
2176 self.assertEqual(self.signature(CMM),
2177 ((('name', ..., ..., "positional_or_keyword"),
2178 ('bases', ..., ..., "positional_or_keyword"),
2179 ('dct', ..., ..., "positional_or_keyword"),
2180 ('foo', 1, ..., "keyword_only")),
2181 ...))
2182
2183 self.assertEqual(self.signature(CM),
2184 ((('nm', ..., ..., "positional_or_keyword"),
2185 ('bs', ..., ..., "positional_or_keyword"),
2186 ('dt', ..., ..., "positional_or_keyword")),
2187 ...))
2188
2189 self.assertEqual(self.signature(C),
2190 ((('b', ..., ..., "positional_or_keyword"),),
2191 ...))
2192
2193 class CM(type):
2194 def __init__(cls, name, bases, dct, *, bar=2):
2195 return super().__init__(name, bases, dct)
2196 class C(metaclass=CM):
2197 def __init__(self, b):
2198 pass
2199
2200 self.assertEqual(self.signature(CM),
2201 ((('name', ..., ..., "positional_or_keyword"),
2202 ('bases', ..., ..., "positional_or_keyword"),
2203 ('dct', ..., ..., "positional_or_keyword"),
2204 ('bar', 2, ..., "keyword_only")),
2205 ...))
2206
Yury Selivanov145dff82014-02-01 13:49:29 -05002207 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2208 "Signature information for builtins requires docstrings")
2209 def test_signature_on_class_without_init(self):
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002210 # Test classes without user-defined __init__ or __new__
2211 class C: pass
2212 self.assertEqual(str(inspect.signature(C)), '()')
2213 class D(C): pass
2214 self.assertEqual(str(inspect.signature(D)), '()')
2215
2216 # Test meta-classes without user-defined __init__ or __new__
2217 class C(type): pass
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002218 class D(C): pass
Larry Hastings2623c8c2014-02-08 22:15:29 -08002219 with self.assertRaisesRegex(ValueError, "callable.*is not supported"):
2220 self.assertEqual(inspect.signature(C), None)
2221 with self.assertRaisesRegex(ValueError, "callable.*is not supported"):
2222 self.assertEqual(inspect.signature(D), None)
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002223
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002224 @unittest.skipIf(MISSING_C_DOCSTRINGS,
2225 "Signature information for builtins requires docstrings")
2226 def test_signature_on_builtin_class(self):
2227 self.assertEqual(str(inspect.signature(_pickle.Pickler)),
2228 '(file, protocol=None, fix_imports=True)')
2229
2230 class P(_pickle.Pickler): pass
2231 class EmptyTrait: pass
2232 class P2(EmptyTrait, P): pass
2233 self.assertEqual(str(inspect.signature(P)),
2234 '(file, protocol=None, fix_imports=True)')
2235 self.assertEqual(str(inspect.signature(P2)),
2236 '(file, protocol=None, fix_imports=True)')
2237
2238 class P3(P2):
2239 def __init__(self, spam):
2240 pass
2241 self.assertEqual(str(inspect.signature(P3)), '(spam)')
2242
2243 class MetaP(type):
2244 def __call__(cls, foo, bar):
2245 pass
2246 class P4(P2, metaclass=MetaP):
2247 pass
2248 self.assertEqual(str(inspect.signature(P4)), '(foo, bar)')
2249
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002250 def test_signature_on_callable_objects(self):
2251 class Foo:
2252 def __call__(self, a):
2253 pass
2254
2255 self.assertEqual(self.signature(Foo()),
2256 ((('a', ..., ..., "positional_or_keyword"),),
2257 ...))
2258
2259 class Spam:
2260 pass
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002261 with self.assertRaisesRegex(TypeError, "is not a callable object"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002262 inspect.signature(Spam())
2263
2264 class Bar(Spam, Foo):
2265 pass
2266
2267 self.assertEqual(self.signature(Bar()),
2268 ((('a', ..., ..., "positional_or_keyword"),),
2269 ...))
2270
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002271 class Wrapped:
2272 pass
2273 Wrapped.__wrapped__ = lambda a: None
2274 self.assertEqual(self.signature(Wrapped),
2275 ((('a', ..., ..., "positional_or_keyword"),),
2276 ...))
Nick Coghlane8c45d62013-07-28 20:00:01 +10002277 # wrapper loop:
2278 Wrapped.__wrapped__ = Wrapped
2279 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
2280 self.signature(Wrapped)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002281
2282 def test_signature_on_lambdas(self):
2283 self.assertEqual(self.signature((lambda a=10: a)),
2284 ((('a', 10, ..., "positional_or_keyword"),),
2285 ...))
2286
2287 def test_signature_equality(self):
2288 def foo(a, *, b:int) -> float: pass
2289 self.assertNotEqual(inspect.signature(foo), 42)
2290
2291 def bar(a, *, b:int) -> float: pass
2292 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
2293
2294 def bar(a, *, b:int) -> int: pass
2295 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
2296
2297 def bar(a, *, b:int): pass
2298 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
2299
2300 def bar(a, *, b:int=42) -> float: pass
2301 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
2302
2303 def bar(a, *, c) -> float: pass
2304 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
2305
2306 def bar(a, b:int) -> float: pass
2307 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
2308 def spam(b:int, a) -> float: pass
2309 self.assertNotEqual(inspect.signature(spam), inspect.signature(bar))
2310
2311 def foo(*, a, b, c): pass
2312 def bar(*, c, b, a): pass
2313 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
2314
2315 def foo(*, a=1, b, c): pass
2316 def bar(*, c, b, a=1): pass
2317 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
2318
2319 def foo(pos, *, a=1, b, c): pass
2320 def bar(pos, *, c, b, a=1): pass
2321 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
2322
2323 def foo(pos, *, a, b, c): pass
2324 def bar(pos, *, c, b, a=1): pass
2325 self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
2326
2327 def foo(pos, *args, a=42, b, c, **kwargs:int): pass
2328 def bar(pos, *args, c, b, a=42, **kwargs:int): pass
2329 self.assertEqual(inspect.signature(foo), inspect.signature(bar))
2330
2331 def test_signature_unhashable(self):
2332 def foo(a): pass
2333 sig = inspect.signature(foo)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002334 with self.assertRaisesRegex(TypeError, 'unhashable type'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002335 hash(sig)
2336
2337 def test_signature_str(self):
2338 def foo(a:int=1, *, b, c=None, **kwargs) -> 42:
2339 pass
2340 self.assertEqual(str(inspect.signature(foo)),
2341 '(a:int=1, *, b, c=None, **kwargs) -> 42')
2342
2343 def foo(a:int=1, *args, b, c=None, **kwargs) -> 42:
2344 pass
2345 self.assertEqual(str(inspect.signature(foo)),
2346 '(a:int=1, *args, b, c=None, **kwargs) -> 42')
2347
2348 def foo():
2349 pass
2350 self.assertEqual(str(inspect.signature(foo)), '()')
2351
2352 def test_signature_str_positional_only(self):
2353 P = inspect.Parameter
Yury Selivanov2393dca2014-01-27 15:07:58 -05002354 S = inspect.Signature
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002355
2356 def test(a_po, *, b, **kwargs):
2357 return a_po, kwargs
2358
2359 sig = inspect.signature(test)
2360 new_params = list(sig.parameters.values())
2361 new_params[0] = new_params[0].replace(kind=P.POSITIONAL_ONLY)
2362 test.__signature__ = sig.replace(parameters=new_params)
2363
2364 self.assertEqual(str(inspect.signature(test)),
Yury Selivanov2393dca2014-01-27 15:07:58 -05002365 '(a_po, /, *, b, **kwargs)')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002366
Yury Selivanov2393dca2014-01-27 15:07:58 -05002367 self.assertEqual(str(S(parameters=[P('foo', P.POSITIONAL_ONLY)])),
2368 '(foo, /)')
2369
2370 self.assertEqual(str(S(parameters=[
2371 P('foo', P.POSITIONAL_ONLY),
2372 P('bar', P.VAR_KEYWORD)])),
2373 '(foo, /, **bar)')
2374
2375 self.assertEqual(str(S(parameters=[
2376 P('foo', P.POSITIONAL_ONLY),
2377 P('bar', P.VAR_POSITIONAL)])),
2378 '(foo, /, *bar)')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002379
2380 def test_signature_replace_anno(self):
2381 def test() -> 42:
2382 pass
2383
2384 sig = inspect.signature(test)
2385 sig = sig.replace(return_annotation=None)
2386 self.assertIs(sig.return_annotation, None)
2387 sig = sig.replace(return_annotation=sig.empty)
2388 self.assertIs(sig.return_annotation, sig.empty)
2389 sig = sig.replace(return_annotation=42)
2390 self.assertEqual(sig.return_annotation, 42)
2391 self.assertEqual(sig, inspect.signature(test))
2392
2393
2394class TestParameterObject(unittest.TestCase):
2395 def test_signature_parameter_kinds(self):
2396 P = inspect.Parameter
2397 self.assertTrue(P.POSITIONAL_ONLY < P.POSITIONAL_OR_KEYWORD < \
2398 P.VAR_POSITIONAL < P.KEYWORD_ONLY < P.VAR_KEYWORD)
2399
2400 self.assertEqual(str(P.POSITIONAL_ONLY), 'POSITIONAL_ONLY')
2401 self.assertTrue('POSITIONAL_ONLY' in repr(P.POSITIONAL_ONLY))
2402
2403 def test_signature_parameter_object(self):
2404 p = inspect.Parameter('foo', default=10,
2405 kind=inspect.Parameter.POSITIONAL_ONLY)
2406 self.assertEqual(p.name, 'foo')
2407 self.assertEqual(p.default, 10)
2408 self.assertIs(p.annotation, p.empty)
2409 self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY)
2410
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002411 with self.assertRaisesRegex(ValueError, 'invalid value'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002412 inspect.Parameter('foo', default=10, kind='123')
2413
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002414 with self.assertRaisesRegex(ValueError, 'not a valid parameter name'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002415 inspect.Parameter('1', kind=inspect.Parameter.VAR_KEYWORD)
2416
Yury Selivanov2393dca2014-01-27 15:07:58 -05002417 with self.assertRaisesRegex(TypeError, 'name must be a str'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002418 inspect.Parameter(None, kind=inspect.Parameter.VAR_KEYWORD)
2419
Yury Selivanov2393dca2014-01-27 15:07:58 -05002420 with self.assertRaisesRegex(ValueError,
2421 'is not a valid parameter name'):
2422 inspect.Parameter('$', kind=inspect.Parameter.VAR_KEYWORD)
2423
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002424 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002425 inspect.Parameter('a', default=42,
2426 kind=inspect.Parameter.VAR_KEYWORD)
2427
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002428 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002429 inspect.Parameter('a', default=42,
2430 kind=inspect.Parameter.VAR_POSITIONAL)
2431
2432 p = inspect.Parameter('a', default=42,
2433 kind=inspect.Parameter.POSITIONAL_OR_KEYWORD)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002434 with self.assertRaisesRegex(ValueError, 'cannot have default values'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002435 p.replace(kind=inspect.Parameter.VAR_POSITIONAL)
2436
2437 self.assertTrue(repr(p).startswith('<Parameter'))
2438
2439 def test_signature_parameter_equality(self):
2440 P = inspect.Parameter
2441 p = P('foo', default=42, kind=inspect.Parameter.KEYWORD_ONLY)
2442
2443 self.assertEqual(p, p)
2444 self.assertNotEqual(p, 42)
2445
2446 self.assertEqual(p, P('foo', default=42,
2447 kind=inspect.Parameter.KEYWORD_ONLY))
2448
2449 def test_signature_parameter_unhashable(self):
2450 p = inspect.Parameter('foo', default=42,
2451 kind=inspect.Parameter.KEYWORD_ONLY)
2452
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002453 with self.assertRaisesRegex(TypeError, 'unhashable type'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002454 hash(p)
2455
2456 def test_signature_parameter_replace(self):
2457 p = inspect.Parameter('foo', default=42,
2458 kind=inspect.Parameter.KEYWORD_ONLY)
2459
2460 self.assertIsNot(p, p.replace())
2461 self.assertEqual(p, p.replace())
2462
2463 p2 = p.replace(annotation=1)
2464 self.assertEqual(p2.annotation, 1)
2465 p2 = p2.replace(annotation=p2.empty)
2466 self.assertEqual(p, p2)
2467
2468 p2 = p2.replace(name='bar')
2469 self.assertEqual(p2.name, 'bar')
2470 self.assertNotEqual(p2, p)
2471
Yury Selivanov2393dca2014-01-27 15:07:58 -05002472 with self.assertRaisesRegex(ValueError,
2473 'name is a required attribute'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002474 p2 = p2.replace(name=p2.empty)
2475
2476 p2 = p2.replace(name='foo', default=None)
2477 self.assertIs(p2.default, None)
2478 self.assertNotEqual(p2, p)
2479
2480 p2 = p2.replace(name='foo', default=p2.empty)
2481 self.assertIs(p2.default, p2.empty)
2482
2483
2484 p2 = p2.replace(default=42, kind=p2.POSITIONAL_OR_KEYWORD)
2485 self.assertEqual(p2.kind, p2.POSITIONAL_OR_KEYWORD)
2486 self.assertNotEqual(p2, p)
2487
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002488 with self.assertRaisesRegex(ValueError, 'invalid value for'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002489 p2 = p2.replace(kind=p2.empty)
2490
2491 p2 = p2.replace(kind=p2.KEYWORD_ONLY)
2492 self.assertEqual(p2, p)
2493
2494 def test_signature_parameter_positional_only(self):
Yury Selivanov2393dca2014-01-27 15:07:58 -05002495 with self.assertRaisesRegex(TypeError, 'name must be a str'):
2496 inspect.Parameter(None, kind=inspect.Parameter.POSITIONAL_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002497
2498 def test_signature_parameter_immutability(self):
Yury Selivanov2393dca2014-01-27 15:07:58 -05002499 p = inspect.Parameter('spam', kind=inspect.Parameter.KEYWORD_ONLY)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002500
2501 with self.assertRaises(AttributeError):
2502 p.foo = 'bar'
2503
2504 with self.assertRaises(AttributeError):
2505 p.kind = 123
2506
2507
2508class TestSignatureBind(unittest.TestCase):
2509 @staticmethod
2510 def call(func, *args, **kwargs):
2511 sig = inspect.signature(func)
2512 ba = sig.bind(*args, **kwargs)
2513 return func(*ba.args, **ba.kwargs)
2514
2515 def test_signature_bind_empty(self):
2516 def test():
2517 return 42
2518
2519 self.assertEqual(self.call(test), 42)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002520 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002521 self.call(test, 1)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002522 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002523 self.call(test, 1, spam=10)
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002524 with self.assertRaisesRegex(TypeError, 'too many keyword arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002525 self.call(test, spam=1)
2526
2527 def test_signature_bind_var(self):
2528 def test(*args, **kwargs):
2529 return args, kwargs
2530
2531 self.assertEqual(self.call(test), ((), {}))
2532 self.assertEqual(self.call(test, 1), ((1,), {}))
2533 self.assertEqual(self.call(test, 1, 2), ((1, 2), {}))
2534 self.assertEqual(self.call(test, foo='bar'), ((), {'foo': 'bar'}))
2535 self.assertEqual(self.call(test, 1, foo='bar'), ((1,), {'foo': 'bar'}))
2536 self.assertEqual(self.call(test, args=10), ((), {'args': 10}))
2537 self.assertEqual(self.call(test, 1, 2, foo='bar'),
2538 ((1, 2), {'foo': 'bar'}))
2539
2540 def test_signature_bind_just_args(self):
2541 def test(a, b, c):
2542 return a, b, c
2543
2544 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
2545
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002546 with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002547 self.call(test, 1, 2, 3, 4)
2548
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002549 with self.assertRaisesRegex(TypeError, "'b' parameter lacking default"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002550 self.call(test, 1)
2551
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002552 with self.assertRaisesRegex(TypeError, "'a' parameter lacking default"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002553 self.call(test)
2554
2555 def test(a, b, c=10):
2556 return a, b, c
2557 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
2558 self.assertEqual(self.call(test, 1, 2), (1, 2, 10))
2559
2560 def test(a=1, b=2, c=3):
2561 return a, b, c
2562 self.assertEqual(self.call(test, a=10, c=13), (10, 2, 13))
2563 self.assertEqual(self.call(test, a=10), (10, 2, 3))
2564 self.assertEqual(self.call(test, b=10), (1, 10, 3))
2565
2566 def test_signature_bind_varargs_order(self):
2567 def test(*args):
2568 return args
2569
2570 self.assertEqual(self.call(test), ())
2571 self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
2572
2573 def test_signature_bind_args_and_varargs(self):
2574 def test(a, b, c=3, *args):
2575 return a, b, c, args
2576
2577 self.assertEqual(self.call(test, 1, 2, 3, 4, 5), (1, 2, 3, (4, 5)))
2578 self.assertEqual(self.call(test, 1, 2), (1, 2, 3, ()))
2579 self.assertEqual(self.call(test, b=1, a=2), (2, 1, 3, ()))
2580 self.assertEqual(self.call(test, 1, b=2), (1, 2, 3, ()))
2581
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002582 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002583 "multiple values for argument 'c'"):
2584 self.call(test, 1, 2, 3, c=4)
2585
2586 def test_signature_bind_just_kwargs(self):
2587 def test(**kwargs):
2588 return kwargs
2589
2590 self.assertEqual(self.call(test), {})
2591 self.assertEqual(self.call(test, foo='bar', spam='ham'),
2592 {'foo': 'bar', 'spam': 'ham'})
2593
2594 def test_signature_bind_args_and_kwargs(self):
2595 def test(a, b, c=3, **kwargs):
2596 return a, b, c, kwargs
2597
2598 self.assertEqual(self.call(test, 1, 2), (1, 2, 3, {}))
2599 self.assertEqual(self.call(test, 1, 2, foo='bar', spam='ham'),
2600 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
2601 self.assertEqual(self.call(test, b=2, a=1, foo='bar', spam='ham'),
2602 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
2603 self.assertEqual(self.call(test, a=1, b=2, foo='bar', spam='ham'),
2604 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
2605 self.assertEqual(self.call(test, 1, b=2, foo='bar', spam='ham'),
2606 (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
2607 self.assertEqual(self.call(test, 1, b=2, c=4, foo='bar', spam='ham'),
2608 (1, 2, 4, {'foo': 'bar', 'spam': 'ham'}))
2609 self.assertEqual(self.call(test, 1, 2, 4, foo='bar'),
2610 (1, 2, 4, {'foo': 'bar'}))
2611 self.assertEqual(self.call(test, c=5, a=4, b=3),
2612 (4, 3, 5, {}))
2613
2614 def test_signature_bind_kwonly(self):
2615 def test(*, foo):
2616 return foo
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002617 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002618 'too many positional arguments'):
2619 self.call(test, 1)
2620 self.assertEqual(self.call(test, foo=1), 1)
2621
2622 def test(a, *, foo=1, bar):
2623 return foo
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002624 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002625 "'bar' parameter lacking default value"):
2626 self.call(test, 1)
2627
2628 def test(foo, *, bar):
2629 return foo, bar
2630 self.assertEqual(self.call(test, 1, bar=2), (1, 2))
2631 self.assertEqual(self.call(test, bar=2, foo=1), (1, 2))
2632
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002633 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002634 'too many keyword arguments'):
2635 self.call(test, bar=2, foo=1, spam=10)
2636
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002637 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002638 'too many positional arguments'):
2639 self.call(test, 1, 2)
2640
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002641 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002642 'too many positional arguments'):
2643 self.call(test, 1, 2, bar=2)
2644
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002645 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002646 'too many keyword arguments'):
2647 self.call(test, 1, bar=2, spam='ham')
2648
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002649 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002650 "'bar' parameter lacking default value"):
2651 self.call(test, 1)
2652
2653 def test(foo, *, bar, **bin):
2654 return foo, bar, bin
2655 self.assertEqual(self.call(test, 1, bar=2), (1, 2, {}))
2656 self.assertEqual(self.call(test, foo=1, bar=2), (1, 2, {}))
2657 self.assertEqual(self.call(test, 1, bar=2, spam='ham'),
2658 (1, 2, {'spam': 'ham'}))
2659 self.assertEqual(self.call(test, spam='ham', foo=1, bar=2),
2660 (1, 2, {'spam': 'ham'}))
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002661 with self.assertRaisesRegex(TypeError,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002662 "'foo' parameter lacking default value"):
2663 self.call(test, spam='ham', bar=2)
2664 self.assertEqual(self.call(test, 1, bar=2, bin=1, spam=10),
2665 (1, 2, {'bin': 1, 'spam': 10}))
2666
2667 def test_signature_bind_arguments(self):
2668 def test(a, *args, b, z=100, **kwargs):
2669 pass
2670 sig = inspect.signature(test)
2671 ba = sig.bind(10, 20, b=30, c=40, args=50, kwargs=60)
2672 # we won't have 'z' argument in the bound arguments object, as we didn't
2673 # pass it to the 'bind'
2674 self.assertEqual(tuple(ba.arguments.items()),
2675 (('a', 10), ('args', (20,)), ('b', 30),
2676 ('kwargs', {'c': 40, 'args': 50, 'kwargs': 60})))
2677 self.assertEqual(ba.kwargs,
2678 {'b': 30, 'c': 40, 'args': 50, 'kwargs': 60})
2679 self.assertEqual(ba.args, (10, 20))
2680
2681 def test_signature_bind_positional_only(self):
2682 P = inspect.Parameter
2683
2684 def test(a_po, b_po, c_po=3, foo=42, *, bar=50, **kwargs):
2685 return a_po, b_po, c_po, foo, bar, kwargs
2686
2687 sig = inspect.signature(test)
2688 new_params = collections.OrderedDict(tuple(sig.parameters.items()))
2689 for name in ('a_po', 'b_po', 'c_po'):
2690 new_params[name] = new_params[name].replace(kind=P.POSITIONAL_ONLY)
2691 new_sig = sig.replace(parameters=new_params.values())
2692 test.__signature__ = new_sig
2693
2694 self.assertEqual(self.call(test, 1, 2, 4, 5, bar=6),
2695 (1, 2, 4, 5, 6, {}))
2696
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05002697 self.assertEqual(self.call(test, 1, 2),
2698 (1, 2, 3, 42, 50, {}))
2699
2700 self.assertEqual(self.call(test, 1, 2, foo=4, bar=5),
2701 (1, 2, 3, 4, 5, {}))
2702
2703 with self.assertRaisesRegex(TypeError, "but was passed as a keyword"):
2704 self.call(test, 1, 2, foo=4, bar=5, c_po=10)
2705
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002706 with self.assertRaisesRegex(TypeError, "parameter is positional only"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002707 self.call(test, 1, 2, c_po=4)
2708
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002709 with self.assertRaisesRegex(TypeError, "parameter is positional only"):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002710 self.call(test, a_po=1, b_po=2)
2711
Antoine Pitroubd41d1b2013-01-29 21:20:57 +01002712 def test_signature_bind_with_self_arg(self):
2713 # Issue #17071: one of the parameters is named "self
2714 def test(a, self, b):
2715 pass
2716 sig = inspect.signature(test)
2717 ba = sig.bind(1, 2, 3)
2718 self.assertEqual(ba.args, (1, 2, 3))
2719 ba = sig.bind(1, self=2, b=3)
2720 self.assertEqual(ba.args, (1, 2, 3))
2721
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05002722 def test_signature_bind_vararg_name(self):
2723 def test(a, *args):
2724 return a, args
2725 sig = inspect.signature(test)
2726
2727 with self.assertRaisesRegex(TypeError, "too many keyword arguments"):
2728 sig.bind(a=0, args=1)
2729
2730 def test(*args, **kwargs):
2731 return args, kwargs
2732 self.assertEqual(self.call(test, args=1), ((), {'args': 1}))
2733
2734 sig = inspect.signature(test)
2735 ba = sig.bind(args=1)
2736 self.assertEqual(ba.arguments, {'kwargs': {'args': 1}})
2737
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002738
2739class TestBoundArguments(unittest.TestCase):
2740 def test_signature_bound_arguments_unhashable(self):
2741 def foo(a): pass
2742 ba = inspect.signature(foo).bind(1)
2743
Antoine Pitrou46cb1ef2012-06-23 18:11:59 +02002744 with self.assertRaisesRegex(TypeError, 'unhashable type'):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002745 hash(ba)
2746
2747 def test_signature_bound_arguments_equality(self):
2748 def foo(a): pass
2749 ba = inspect.signature(foo).bind(1)
2750 self.assertEqual(ba, ba)
2751
2752 ba2 = inspect.signature(foo).bind(1)
2753 self.assertEqual(ba, ba2)
2754
2755 ba3 = inspect.signature(foo).bind(2)
2756 self.assertNotEqual(ba, ba3)
2757 ba3.arguments['a'] = 1
2758 self.assertEqual(ba, ba3)
2759
2760 def bar(b): pass
2761 ba4 = inspect.signature(bar).bind(1)
2762 self.assertNotEqual(ba, ba4)
2763
2764
Yury Selivanovd82eddc2014-01-29 11:24:39 -05002765class TestSignaturePrivateHelpers(unittest.TestCase):
2766 def test_signature_get_bound_param(self):
2767 getter = inspect._signature_get_bound_param
2768
2769 self.assertEqual(getter('($self)'), 'self')
2770 self.assertEqual(getter('($self, obj)'), 'self')
2771 self.assertEqual(getter('($cls, /, obj)'), 'cls')
2772
Larry Hastings2623c8c2014-02-08 22:15:29 -08002773 def _strip_non_python_syntax(self, input,
2774 clean_signature, self_parameter, last_positional_only):
2775 computed_clean_signature, \
2776 computed_self_parameter, \
2777 computed_last_positional_only = \
2778 inspect._signature_strip_non_python_syntax(input)
2779 self.assertEqual(computed_clean_signature, clean_signature)
2780 self.assertEqual(computed_self_parameter, self_parameter)
2781 self.assertEqual(computed_last_positional_only, last_positional_only)
2782
2783 def test_signature_strip_non_python_syntax(self):
2784 self._strip_non_python_syntax(
2785 "($module, /, path, mode, *, dir_fd=None, " +
2786 "effective_ids=False,\n follow_symlinks=True)",
2787 "(module, path, mode, *, dir_fd=None, " +
2788 "effective_ids=False, follow_symlinks=True)",
2789 0,
2790 0)
2791
2792 self._strip_non_python_syntax(
2793 "($module, word, salt, /)",
2794 "(module, word, salt)",
2795 0,
2796 2)
2797
2798 self._strip_non_python_syntax(
2799 "(x, y=None, z=None, /)",
2800 "(x, y=None, z=None)",
2801 None,
2802 2)
2803
2804 self._strip_non_python_syntax(
2805 "(x, y=None, z=None)",
2806 "(x, y=None, z=None)",
2807 None,
2808 None)
2809
2810 self._strip_non_python_syntax(
2811 "(x,\n y=None,\n z = None )",
2812 "(x, y=None, z=None)",
2813 None,
2814 None)
2815
2816 self._strip_non_python_syntax(
2817 "",
2818 "",
2819 None,
2820 None)
2821
2822 self._strip_non_python_syntax(
2823 None,
2824 None,
2825 None,
2826 None)
2827
Yury Selivanovd82eddc2014-01-29 11:24:39 -05002828
Nick Coghlane8c45d62013-07-28 20:00:01 +10002829class TestUnwrap(unittest.TestCase):
2830
2831 def test_unwrap_one(self):
2832 def func(a, b):
2833 return a + b
2834 wrapper = functools.lru_cache(maxsize=20)(func)
2835 self.assertIs(inspect.unwrap(wrapper), func)
2836
2837 def test_unwrap_several(self):
2838 def func(a, b):
2839 return a + b
2840 wrapper = func
2841 for __ in range(10):
2842 @functools.wraps(wrapper)
2843 def wrapper():
2844 pass
2845 self.assertIsNot(wrapper.__wrapped__, func)
2846 self.assertIs(inspect.unwrap(wrapper), func)
2847
2848 def test_stop(self):
2849 def func1(a, b):
2850 return a + b
2851 @functools.wraps(func1)
2852 def func2():
2853 pass
2854 @functools.wraps(func2)
2855 def wrapper():
2856 pass
2857 func2.stop_here = 1
2858 unwrapped = inspect.unwrap(wrapper,
2859 stop=(lambda f: hasattr(f, "stop_here")))
2860 self.assertIs(unwrapped, func2)
2861
2862 def test_cycle(self):
2863 def func1(): pass
2864 func1.__wrapped__ = func1
2865 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
2866 inspect.unwrap(func1)
2867
2868 def func2(): pass
2869 func2.__wrapped__ = func1
2870 func1.__wrapped__ = func2
2871 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
2872 inspect.unwrap(func1)
2873 with self.assertRaisesRegex(ValueError, 'wrapper loop'):
2874 inspect.unwrap(func2)
2875
2876 def test_unhashable(self):
2877 def func(): pass
2878 func.__wrapped__ = None
2879 class C:
2880 __hash__ = None
2881 __wrapped__ = func
2882 self.assertIsNone(inspect.unwrap(C()))
2883
Nick Coghlanf94a16b2013-09-22 22:46:49 +10002884class TestMain(unittest.TestCase):
2885 def test_only_source(self):
2886 module = importlib.import_module('unittest')
2887 rc, out, err = assert_python_ok('-m', 'inspect',
2888 'unittest')
2889 lines = out.decode().splitlines()
2890 # ignore the final newline
2891 self.assertEqual(lines[:-1], inspect.getsource(module).splitlines())
2892 self.assertEqual(err, b'')
2893
Brett Cannon634a8fc2013-10-02 10:25:42 -04002894 @unittest.skipIf(ThreadPoolExecutor is None,
Brett Cannon0de3f012013-10-02 10:58:58 -04002895 'threads required to test __qualname__ for source files')
Nick Coghlanf94a16b2013-09-22 22:46:49 +10002896 def test_qualname_source(self):
Nick Coghlanf94a16b2013-09-22 22:46:49 +10002897 rc, out, err = assert_python_ok('-m', 'inspect',
2898 'concurrent.futures:ThreadPoolExecutor')
2899 lines = out.decode().splitlines()
2900 # ignore the final newline
2901 self.assertEqual(lines[:-1],
Brett Cannon634a8fc2013-10-02 10:25:42 -04002902 inspect.getsource(ThreadPoolExecutor).splitlines())
Nick Coghlanf94a16b2013-09-22 22:46:49 +10002903 self.assertEqual(err, b'')
2904
2905 def test_builtins(self):
2906 module = importlib.import_module('unittest')
2907 _, out, err = assert_python_failure('-m', 'inspect',
2908 'sys')
2909 lines = err.decode().splitlines()
2910 self.assertEqual(lines, ["Can't get info for builtin modules."])
2911
2912 def test_details(self):
2913 module = importlib.import_module('unittest')
2914 rc, out, err = assert_python_ok('-m', 'inspect',
2915 'unittest', '--details')
2916 output = out.decode()
2917 # Just a quick sanity check on the output
2918 self.assertIn(module.__name__, output)
2919 self.assertIn(module.__file__, output)
Serhiy Storchakab12cb6a2013-12-08 18:16:18 +02002920 if not sys.flags.optimize:
2921 self.assertIn(module.__cached__, output)
Nick Coghlanf94a16b2013-09-22 22:46:49 +10002922 self.assertEqual(err, b'')
2923
2924
2925
Nick Coghlane8c45d62013-07-28 20:00:01 +10002926
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00002927def test_main():
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00002928 run_unittest(
2929 TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBuggyCases,
2930 TestInterpreterStack, TestClassesAndFunctions, TestPredicates,
2931 TestGetcallargsFunctions, TestGetcallargsMethods,
Alexander Belopolskyf546e702010-12-02 00:10:11 +00002932 TestGetcallargsUnboundMethods, TestGetattrStatic, TestGetGeneratorState,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002933 TestNoEOL, TestSignatureObject, TestSignatureBind, TestParameterObject,
Yury Selivanovd82eddc2014-01-29 11:24:39 -05002934 TestBoundArguments, TestSignaturePrivateHelpers, TestGetClosureVars,
2935 TestUnwrap, TestMain
Michael Foord95fc51d2010-11-20 15:07:30 +00002936 )
Martin v. Löwis893ffa42003-10-31 15:35:53 +00002937
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00002938if __name__ == "__main__":
2939 test_main()