blob: f5318e178b370a183dd3d466a281635b18238c37 [file] [log] [blame]
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001import re
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00002import sys
Thomas Wouters0e3f5912006-08-11 14:57:12 +00003import types
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00004import unittest
5import inspect
R. David Murraya1b37402010-06-17 02:04:29 +00006import linecache
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007import datetime
Guido van Rossum813b0e52007-05-21 18:11:34 +00008import collections
Alexander Belopolskyf546e702010-12-02 00:10:11 +00009import os
10import shutil
Christian Heimesa3538eb2007-11-06 11:44:48 +000011from os.path import normcase
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000012
Alexander Belopolskyf546e702010-12-02 00:10:11 +000013from test.support import run_unittest, TESTFN, DirsOnSysPath
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000014
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000015from test import inspect_fodder as mod
16from test import inspect_fodder2 as mod2
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000017
R. David Murray74b89242009-05-13 17:33:03 +000018# C module for test_findsource_binary
R. David Murrayb5655772009-05-14 16:17:50 +000019import unicodedata
R. David Murray74b89242009-05-13 17:33:03 +000020
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000021# Functions tested in this suite:
22# ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode,
Christian Heimes7131fd92008-02-19 14:21:46 +000023# isbuiltin, isroutine, isgenerator, isgeneratorfunction, getmembers,
24# getdoc, getfile, getmodule, getsourcefile, getcomments, getsource,
25# getclasstree, getargspec, getargvalues, formatargspec, formatargvalues,
26# currentframe, stack, trace, isdatadescriptor
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000027
Nick Coghlanf088e5e2008-12-14 11:50:48 +000028# NOTE: There are some additional tests relating to interaction with
29# zipimport in the test_zipimport_support test module.
30
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000031modfile = mod.__file__
Thomas Wouters0e3f5912006-08-11 14:57:12 +000032if modfile.endswith(('c', 'o')):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000033 modfile = modfile[:-1]
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000034
Christian Heimesa3538eb2007-11-06 11:44:48 +000035# Normalize file names: on Windows, the case of file names of compiled
36# modules depends on the path used to start the python executable.
37modfile = normcase(modfile)
38
39def revise(filename, *args):
40 return (normcase(filename),) + args
41
Georg Brandl1a3284e2007-12-02 09:40:06 +000042import builtins
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000043
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000044try:
45 1/0
46except:
Guido van Rossume7ba4952007-06-06 23:52:48 +000047 tb = sys.exc_info()[2]
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000048
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000049git = mod.StupidGit()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000050
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000051class IsTestBase(unittest.TestCase):
52 predicates = set([inspect.isbuiltin, inspect.isclass, inspect.iscode,
53 inspect.isframe, inspect.isfunction, inspect.ismethod,
Christian Heimes7131fd92008-02-19 14:21:46 +000054 inspect.ismodule, inspect.istraceback,
55 inspect.isgenerator, inspect.isgeneratorfunction])
Tim Peters5a9fb3c2005-01-07 16:01:32 +000056
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000057 def istest(self, predicate, exp):
58 obj = eval(exp)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000059 self.assertTrue(predicate(obj), '%s(%s)' % (predicate.__name__, exp))
Tim Peters5a9fb3c2005-01-07 16:01:32 +000060
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000061 for other in self.predicates - set([predicate]):
Christian Heimes7131fd92008-02-19 14:21:46 +000062 if predicate == inspect.isgeneratorfunction and\
63 other == inspect.isfunction:
64 continue
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000065 self.assertFalse(other(obj), 'not %s(%s)' % (other.__name__, exp))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000066
Christian Heimes7131fd92008-02-19 14:21:46 +000067def generator_function_example(self):
68 for i in range(2):
69 yield i
70
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000071class TestPredicates(IsTestBase):
Christian Heimes227c8002008-03-03 20:34:40 +000072 def test_sixteen(self):
Guido van Rossumc1f779c2007-07-03 08:25:58 +000073 count = len([x for x in dir(inspect) if x.startswith('is')])
Christian Heimes7131fd92008-02-19 14:21:46 +000074 # This test is here for remember you to update Doc/library/inspect.rst
Christian Heimes78644762008-03-04 23:39:23 +000075 # which claims there are 16 such functions
Christian Heimes227c8002008-03-03 20:34:40 +000076 expected = 16
Thomas Wouters0e3f5912006-08-11 14:57:12 +000077 err_msg = "There are %d (not %d) is* functions" % (count, expected)
78 self.assertEqual(count, expected, err_msg)
Tim Peters5a9fb3c2005-01-07 16:01:32 +000079
Christian Heimes7131fd92008-02-19 14:21:46 +000080
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000081 def test_excluding_predicates(self):
82 self.istest(inspect.isbuiltin, 'sys.exit')
83 self.istest(inspect.isbuiltin, '[].append')
Neal Norwitz221085d2007-02-25 20:55:47 +000084 self.istest(inspect.iscode, 'mod.spam.__code__')
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000085 self.istest(inspect.isframe, 'tb.tb_frame')
86 self.istest(inspect.isfunction, 'mod.spam')
Christian Heimes4a22b5d2007-11-25 09:39:14 +000087 self.istest(inspect.isfunction, 'mod.StupidGit.abuse')
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000088 self.istest(inspect.ismethod, 'git.argue')
89 self.istest(inspect.ismodule, 'mod')
90 self.istest(inspect.istraceback, 'tb')
Guido van Rossum813b0e52007-05-21 18:11:34 +000091 self.istest(inspect.isdatadescriptor, 'collections.defaultdict.default_factory')
Christian Heimes7131fd92008-02-19 14:21:46 +000092 self.istest(inspect.isgenerator, '(x for x in range(2))')
93 self.istest(inspect.isgeneratorfunction, 'generator_function_example')
Thomas Wouters0e3f5912006-08-11 14:57:12 +000094 if hasattr(types, 'GetSetDescriptorType'):
95 self.istest(inspect.isgetsetdescriptor,
96 'type(tb.tb_frame).f_locals')
97 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000098 self.assertFalse(inspect.isgetsetdescriptor(type(tb.tb_frame).f_locals))
Thomas Wouters0e3f5912006-08-11 14:57:12 +000099 if hasattr(types, 'MemberDescriptorType'):
100 self.istest(inspect.ismemberdescriptor, 'datetime.timedelta.days')
101 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000102 self.assertFalse(inspect.ismemberdescriptor(datetime.timedelta.days))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000103
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000104 def test_isroutine(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000105 self.assertTrue(inspect.isroutine(mod.spam))
106 self.assertTrue(inspect.isroutine([].count))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000107
Benjamin Petersonc4656002009-01-17 22:41:18 +0000108 def test_isclass(self):
109 self.istest(inspect.isclass, 'mod.StupidGit')
110 self.assertTrue(inspect.isclass(list))
111
112 class CustomGetattr(object):
113 def __getattr__(self, attr):
114 return None
115 self.assertFalse(inspect.isclass(CustomGetattr()))
116
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000117 def test_get_slot_members(self):
118 class C(object):
119 __slots__ = ("a", "b")
120
121 x = C()
122 x.a = 42
123 members = dict(inspect.getmembers(x))
Benjamin Peterson577473f2010-01-19 00:09:57 +0000124 self.assertIn('a', members)
125 self.assertNotIn('b', members)
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000126
Benjamin Petersona0dfa822009-11-13 02:25:08 +0000127 def test_isabstract(self):
128 from abc import ABCMeta, abstractmethod
129
130 class AbstractClassExample(metaclass=ABCMeta):
131
132 @abstractmethod
133 def foo(self):
134 pass
135
136 class ClassExample(AbstractClassExample):
137 def foo(self):
138 pass
139
140 a = ClassExample()
141
142 # Test general behaviour.
143 self.assertTrue(inspect.isabstract(AbstractClassExample))
144 self.assertFalse(inspect.isabstract(ClassExample))
145 self.assertFalse(inspect.isabstract(a))
146 self.assertFalse(inspect.isabstract(int))
147 self.assertFalse(inspect.isabstract(5))
148
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000149
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000150class TestInterpreterStack(IsTestBase):
151 def __init__(self, *args, **kwargs):
152 unittest.TestCase.__init__(self, *args, **kwargs)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000153
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000154 git.abuse(7, 8, 9)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000155
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000156 def test_abuse_done(self):
157 self.istest(inspect.istraceback, 'git.ex[2]')
158 self.istest(inspect.isframe, 'mod.fr')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000159
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000160 def test_stack(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000161 self.assertTrue(len(mod.st) >= 5)
Christian Heimesa3538eb2007-11-06 11:44:48 +0000162 self.assertEqual(revise(*mod.st[0][1:]),
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000163 (modfile, 16, 'eggs', [' st = inspect.stack()\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000164 self.assertEqual(revise(*mod.st[1][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000165 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000166 self.assertEqual(revise(*mod.st[2][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000167 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000168 self.assertEqual(revise(*mod.st[3][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000169 (modfile, 39, 'abuse', [' self.argue(a, b, c)\n'], 0))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000170
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000171 def test_trace(self):
172 self.assertEqual(len(git.tr), 3)
Florent Xiclunac8575922010-03-24 17:37:49 +0000173 self.assertEqual(revise(*git.tr[0][1:]),
174 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
175 self.assertEqual(revise(*git.tr[1][1:]),
176 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
177 self.assertEqual(revise(*git.tr[2][1:]),
178 (modfile, 18, 'eggs', [' q = y / 0\n'], 0))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000179
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000180 def test_frame(self):
181 args, varargs, varkw, locals = inspect.getargvalues(mod.fr)
182 self.assertEqual(args, ['x', 'y'])
183 self.assertEqual(varargs, None)
184 self.assertEqual(varkw, None)
185 self.assertEqual(locals, {'x': 11, 'p': 11, 'y': 14})
186 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
187 '(x=11, y=14)')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000188
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000189 def test_previous_frame(self):
190 args, varargs, varkw, locals = inspect.getargvalues(mod.fr.f_back)
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000191 self.assertEqual(args, ['a', 'b', 'c', 'd', 'e', 'f'])
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000192 self.assertEqual(varargs, 'g')
193 self.assertEqual(varkw, 'h')
194 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000195 '(a=7, b=8, c=9, d=3, e=4, f=5, *g=(), **h={})')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000196
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000197class GetSourceBase(unittest.TestCase):
198 # Subclasses must override.
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000199 fodderModule = None
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000200
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000201 def __init__(self, *args, **kwargs):
202 unittest.TestCase.__init__(self, *args, **kwargs)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000203
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000204 with open(inspect.getsourcefile(self.fodderModule)) as fp:
Philip Jenveya27c5bd2009-05-28 06:09:08 +0000205 self.source = fp.read()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000206
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000207 def sourcerange(self, top, bottom):
208 lines = self.source.split("\n")
209 return "\n".join(lines[top-1:bottom]) + "\n"
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000210
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000211 def assertSourceEqual(self, obj, top, bottom):
212 self.assertEqual(inspect.getsource(obj),
213 self.sourcerange(top, bottom))
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000214
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000215class TestRetrievingSourceCode(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000216 fodderModule = mod
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000217
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000218 def test_getclasses(self):
219 classes = inspect.getmembers(mod, inspect.isclass)
220 self.assertEqual(classes,
221 [('FesteringGob', mod.FesteringGob),
222 ('MalodorousPervert', mod.MalodorousPervert),
223 ('ParrotDroppings', mod.ParrotDroppings),
224 ('StupidGit', mod.StupidGit)])
225 tree = inspect.getclasstree([cls[1] for cls in classes], 1)
226 self.assertEqual(tree,
Thomas Wouters725af872006-04-15 09:13:19 +0000227 [(object, ()),
228 [(mod.ParrotDroppings, (object,)),
229 (mod.StupidGit, (object,)),
230 [(mod.MalodorousPervert, (mod.StupidGit,)),
231 [(mod.FesteringGob, (mod.MalodorousPervert,
232 mod.ParrotDroppings))
233 ]
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000234 ]
235 ]
236 ])
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000237
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000238 def test_getfunctions(self):
239 functions = inspect.getmembers(mod, inspect.isfunction)
240 self.assertEqual(functions, [('eggs', mod.eggs),
241 ('spam', mod.spam)])
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000242
R. David Murray378c0cf2010-02-24 01:46:21 +0000243 @unittest.skipIf(sys.flags.optimize >= 2,
244 "Docstrings are omitted with -O2 and above")
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000245 def test_getdoc(self):
246 self.assertEqual(inspect.getdoc(mod), 'A module docstring.')
247 self.assertEqual(inspect.getdoc(mod.StupidGit),
248 'A longer,\n\nindented\n\ndocstring.')
249 self.assertEqual(inspect.getdoc(git.abuse),
250 'Another\n\ndocstring\n\ncontaining\n\ntabs')
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000251
Georg Brandl0c77a822008-06-10 16:37:50 +0000252 def test_cleandoc(self):
253 self.assertEqual(inspect.cleandoc('An\n indented\n docstring.'),
254 'An\nindented\ndocstring.')
255
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000256 def test_getcomments(self):
257 self.assertEqual(inspect.getcomments(mod), '# line 1\n')
258 self.assertEqual(inspect.getcomments(mod.StupidGit), '# line 20\n')
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000259
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000260 def test_getmodule(self):
Thomas Wouters89f507f2006-12-13 04:49:30 +0000261 # Check actual module
262 self.assertEqual(inspect.getmodule(mod), mod)
263 # Check class (uses __module__ attribute)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000264 self.assertEqual(inspect.getmodule(mod.StupidGit), mod)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000265 # Check a method (no __module__ attribute, falls back to filename)
266 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
267 # Do it again (check the caching isn't broken)
268 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
269 # Check a builtin
Georg Brandl1a3284e2007-12-02 09:40:06 +0000270 self.assertEqual(inspect.getmodule(str), sys.modules["builtins"])
Thomas Wouters89f507f2006-12-13 04:49:30 +0000271 # Check filename override
272 self.assertEqual(inspect.getmodule(None, modfile), mod)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000273
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000274 def test_getsource(self):
275 self.assertSourceEqual(git.abuse, 29, 39)
276 self.assertSourceEqual(mod.StupidGit, 21, 46)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000277
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000278 def test_getsourcefile(self):
Christian Heimesa3538eb2007-11-06 11:44:48 +0000279 self.assertEqual(normcase(inspect.getsourcefile(mod.spam)), modfile)
280 self.assertEqual(normcase(inspect.getsourcefile(git.abuse)), modfile)
R. David Murraya1b37402010-06-17 02:04:29 +0000281 fn = "_non_existing_filename_used_for_sourcefile_test.py"
282 co = compile("None", fn, "exec")
R. David Murray4155f972010-06-17 13:23:18 +0000283 self.assertEqual(inspect.getsourcefile(co), None)
R. David Murraya1b37402010-06-17 02:04:29 +0000284 linecache.cache[co.co_filename] = (1, None, "None", co.co_filename)
285 self.assertEqual(normcase(inspect.getsourcefile(co)), fn)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000286
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000287 def test_getfile(self):
288 self.assertEqual(inspect.getfile(mod.StupidGit), mod.__file__)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000289
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000290 def test_getmodule_recursion(self):
Christian Heimes45f9af32007-11-27 21:50:00 +0000291 from types import ModuleType
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000292 name = '__inspect_dummy'
Christian Heimes45f9af32007-11-27 21:50:00 +0000293 m = sys.modules[name] = ModuleType(name)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000294 m.__file__ = "<string>" # hopefully not a real filename...
295 m.__loader__ = "dummy" # pretend the filename is understood by a loader
Georg Brandl7cae87c2006-09-06 06:51:57 +0000296 exec("def x(): pass", m.__dict__)
Neal Norwitz221085d2007-02-25 20:55:47 +0000297 self.assertEqual(inspect.getsourcefile(m.x.__code__), '<string>')
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000298 del sys.modules[name]
299 inspect.getmodule(compile('a=10','','single'))
300
Benjamin Peterson9620cc02011-06-11 15:53:11 -0500301 def test_proceed_with_fake_filename(self):
302 '''doctest monkeypatches linecache to enable inspection'''
303 fn, source = '<test>', 'def x(): pass\n'
304 getlines = linecache.getlines
305 def monkey(filename, module_globals=None):
306 if filename == fn:
307 return source.splitlines(True)
308 else:
309 return getlines(filename, module_globals)
310 linecache.getlines = monkey
311 try:
312 ns = {}
313 exec(compile(source, fn, 'single'), ns)
314 inspect.getsource(ns["x"])
315 finally:
316 linecache.getlines = getlines
317
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000318class TestDecorators(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000319 fodderModule = mod2
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000320
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000321 def test_wrapped_decorator(self):
Christian Heimes09aaa882008-02-23 15:01:06 +0000322 self.assertSourceEqual(mod2.wrapped, 14, 17)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000323
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000324 def test_replacing_decorator(self):
325 self.assertSourceEqual(mod2.gone, 9, 10)
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000326
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000327class TestOneliners(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000328 fodderModule = mod2
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000329 def test_oneline_lambda(self):
330 # Test inspect.getsource with a one-line lambda function.
331 self.assertSourceEqual(mod2.oll, 25, 25)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000332
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000333 def test_threeline_lambda(self):
334 # Test inspect.getsource with a three-line lambda function,
335 # where the second and third lines are _not_ indented.
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000336 self.assertSourceEqual(mod2.tll, 28, 30)
337
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000338 def test_twoline_indented_lambda(self):
339 # Test inspect.getsource with a two-line lambda function,
340 # where the second line _is_ indented.
341 self.assertSourceEqual(mod2.tlli, 33, 34)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000342
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000343 def test_onelinefunc(self):
344 # Test inspect.getsource with a regular one-line function.
345 self.assertSourceEqual(mod2.onelinefunc, 37, 37)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000346
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000347 def test_manyargs(self):
348 # Test inspect.getsource with a regular function where
349 # the arguments are on two lines and _not_ indented and
350 # the body on the second line with the last arguments.
351 self.assertSourceEqual(mod2.manyargs, 40, 41)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000352
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000353 def test_twolinefunc(self):
354 # Test inspect.getsource with a regular function where
355 # the body is on two lines, following the argument list and
356 # continued on the next line by a \\.
357 self.assertSourceEqual(mod2.twolinefunc, 44, 45)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000358
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000359 def test_lambda_in_list(self):
360 # Test inspect.getsource with a one-line lambda function
361 # defined in a list, indented.
362 self.assertSourceEqual(mod2.a[1], 49, 49)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000363
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000364 def test_anonymous(self):
365 # Test inspect.getsource with a lambda function defined
366 # as argument to another function.
367 self.assertSourceEqual(mod2.anonymous, 55, 55)
368
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000369class TestBuggyCases(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000370 fodderModule = mod2
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000371
372 def test_with_comment(self):
373 self.assertSourceEqual(mod2.with_comment, 58, 59)
374
375 def test_multiline_sig(self):
376 self.assertSourceEqual(mod2.multiline_sig[0], 63, 64)
377
Armin Rigodd5c0232005-09-25 11:45:45 +0000378 def test_nested_class(self):
379 self.assertSourceEqual(mod2.func69().func71, 71, 72)
380
381 def test_one_liner_followed_by_non_name(self):
382 self.assertSourceEqual(mod2.func77, 77, 77)
383
384 def test_one_liner_dedent_non_name(self):
385 self.assertSourceEqual(mod2.cls82.func83, 83, 83)
386
387 def test_with_comment_instead_of_docstring(self):
388 self.assertSourceEqual(mod2.func88, 88, 90)
389
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000390 def test_method_in_dynamic_class(self):
391 self.assertSourceEqual(mod2.method_in_dynamic_class, 95, 97)
392
R. David Murrayb5655772009-05-14 16:17:50 +0000393 @unittest.skipIf(
394 not hasattr(unicodedata, '__file__') or
395 unicodedata.__file__[-4:] in (".pyc", ".pyo"),
396 "unicodedata is not an external binary module")
R. David Murray74b89242009-05-13 17:33:03 +0000397 def test_findsource_binary(self):
R. David Murrayb5655772009-05-14 16:17:50 +0000398 self.assertRaises(IOError, inspect.getsource, unicodedata)
399 self.assertRaises(IOError, inspect.findsource, unicodedata)
R. David Murray74b89242009-05-13 17:33:03 +0000400
R. David Murraya1b37402010-06-17 02:04:29 +0000401 def test_findsource_code_in_linecache(self):
402 lines = ["x=1"]
403 co = compile(lines[0], "_dynamically_created_file", "exec")
404 self.assertRaises(IOError, inspect.findsource, co)
405 self.assertRaises(IOError, inspect.getsource, co)
406 linecache.cache[co.co_filename] = (1, None, lines, co.co_filename)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000407 self.assertEqual(inspect.findsource(co), (lines,0))
408 self.assertEqual(inspect.getsource(co), lines[0])
R. David Murraya1b37402010-06-17 02:04:29 +0000409
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000410class TestNoEOL(GetSourceBase):
411 def __init__(self, *args, **kwargs):
412 self.tempdir = TESTFN + '_dir'
413 os.mkdir(self.tempdir)
414 with open(os.path.join(self.tempdir,
415 'inspect_fodder3%spy' % os.extsep), 'w') as f:
416 f.write("class X:\n pass # No EOL")
417 with DirsOnSysPath(self.tempdir):
418 import inspect_fodder3 as mod3
419 self.fodderModule = mod3
420 GetSourceBase.__init__(self, *args, **kwargs)
421
422 def tearDown(self):
423 shutil.rmtree(self.tempdir)
424
425 def test_class(self):
426 self.assertSourceEqual(self.fodderModule.X, 1, 2)
427
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100428
429class _BrokenDataDescriptor(object):
430 """
431 A broken data descriptor. See bug #1785.
432 """
433 def __get__(*args):
434 raise AssertionError("should not __get__ data descriptors")
435
436 def __set__(*args):
437 raise RuntimeError
438
439 def __getattr__(*args):
440 raise AssertionError("should not __getattr__ data descriptors")
441
442
443class _BrokenMethodDescriptor(object):
444 """
445 A broken method descriptor. See bug #1785.
446 """
447 def __get__(*args):
448 raise AssertionError("should not __get__ method descriptors")
449
450 def __getattr__(*args):
451 raise AssertionError("should not __getattr__ method descriptors")
452
453
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000454# Helper for testing classify_class_attrs.
Tim Peters13b49d32001-09-23 02:00:29 +0000455def attrs_wo_objs(cls):
456 return [t[:3] for t in inspect.classify_class_attrs(cls)]
457
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100458
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000459class TestClassesAndFunctions(unittest.TestCase):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000460 def test_newstyle_mro(self):
461 # The same w/ new-class MRO.
462 class A(object): pass
463 class B(A): pass
464 class C(A): pass
465 class D(B, C): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000466
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000467 expected = (D, B, C, A, object)
468 got = inspect.getmro(D)
469 self.assertEqual(expected, got)
Tim Peters13b49d32001-09-23 02:00:29 +0000470
Christian Heimes3795b532007-11-08 13:48:53 +0000471 def assertArgSpecEquals(self, routine, args_e, varargs_e=None,
472 varkw_e=None, defaults_e=None, formatted=None):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000473 args, varargs, varkw, defaults = inspect.getargspec(routine)
474 self.assertEqual(args, args_e)
475 self.assertEqual(varargs, varargs_e)
476 self.assertEqual(varkw, varkw_e)
477 self.assertEqual(defaults, defaults_e)
478 if formatted is not None:
479 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults),
480 formatted)
Tim Peters13b49d32001-09-23 02:00:29 +0000481
Christian Heimes3795b532007-11-08 13:48:53 +0000482 def assertFullArgSpecEquals(self, routine, args_e, varargs_e=None,
483 varkw_e=None, defaults_e=None,
484 kwonlyargs_e=[], kwonlydefaults_e=None,
485 ann_e={}, formatted=None):
486 args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \
487 inspect.getfullargspec(routine)
488 self.assertEqual(args, args_e)
489 self.assertEqual(varargs, varargs_e)
490 self.assertEqual(varkw, varkw_e)
491 self.assertEqual(defaults, defaults_e)
492 self.assertEqual(kwonlyargs, kwonlyargs_e)
493 self.assertEqual(kwonlydefaults, kwonlydefaults_e)
494 self.assertEqual(ann, ann_e)
495 if formatted is not None:
496 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults,
497 kwonlyargs, kwonlydefaults, ann),
498 formatted)
499
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000500 def test_getargspec(self):
Christian Heimes3795b532007-11-08 13:48:53 +0000501 self.assertArgSpecEquals(mod.eggs, ['x', 'y'], formatted='(x, y)')
Tim Peters13b49d32001-09-23 02:00:29 +0000502
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000503 self.assertArgSpecEquals(mod.spam,
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000504 ['a', 'b', 'c', 'd', 'e', 'f'],
505 'g', 'h', (3, 4, 5),
506 '(a, b, c, d=3, e=4, f=5, *g, **h)')
Tim Peters13b49d32001-09-23 02:00:29 +0000507
Christian Heimes3795b532007-11-08 13:48:53 +0000508 self.assertRaises(ValueError, self.assertArgSpecEquals,
509 mod2.keyworded, [])
510
511 self.assertRaises(ValueError, self.assertArgSpecEquals,
512 mod2.annotated, [])
Benjamin Peterson9953a8d2009-01-17 04:15:01 +0000513 self.assertRaises(ValueError, self.assertArgSpecEquals,
514 mod2.keyword_only_arg, [])
515
Christian Heimes3795b532007-11-08 13:48:53 +0000516
517 def test_getfullargspec(self):
518 self.assertFullArgSpecEquals(mod2.keyworded, [], varargs_e='arg1',
519 kwonlyargs_e=['arg2'],
520 kwonlydefaults_e={'arg2':1},
521 formatted='(*arg1, arg2=1)')
522
523 self.assertFullArgSpecEquals(mod2.annotated, ['arg1'],
Christian Heimesc9543e42007-11-28 08:28:28 +0000524 ann_e={'arg1' : list},
Christian Heimes3795b532007-11-08 13:48:53 +0000525 formatted='(arg1: list)')
Benjamin Peterson9953a8d2009-01-17 04:15:01 +0000526 self.assertFullArgSpecEquals(mod2.keyword_only_arg, [],
527 kwonlyargs_e=['arg'],
528 formatted='(*, arg)')
529
Christian Heimes3795b532007-11-08 13:48:53 +0000530
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000531 def test_getargspec_method(self):
532 class A(object):
533 def m(self):
534 pass
535 self.assertArgSpecEquals(A.m, ['self'])
Tim Peters13b49d32001-09-23 02:00:29 +0000536
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000537 def test_classify_newstyle(self):
538 class A(object):
Tim Peters13b49d32001-09-23 02:00:29 +0000539
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000540 def s(): pass
541 s = staticmethod(s)
Tim Peters13b49d32001-09-23 02:00:29 +0000542
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000543 def c(cls): pass
544 c = classmethod(c)
Tim Peters13b49d32001-09-23 02:00:29 +0000545
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000546 def getp(self): pass
547 p = property(getp)
Tim Peters13b49d32001-09-23 02:00:29 +0000548
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000549 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000550
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000551 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000552
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000553 datablob = '1'
Tim Peters13b49d32001-09-23 02:00:29 +0000554
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100555 dd = _BrokenDataDescriptor()
556 md = _BrokenMethodDescriptor()
557
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000558 attrs = attrs_wo_objs(A)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000559 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
560 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
561 self.assertIn(('p', 'property', A), attrs, 'missing property')
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000562 self.assertIn(('m', 'method', A), attrs,
563 'missing plain method: %r' % attrs)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000564 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
565 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100566 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
567 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000568
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000569 class B(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000570
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000571 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000572
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000573 attrs = attrs_wo_objs(B)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000574 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
575 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
576 self.assertIn(('p', 'property', A), attrs, 'missing property')
577 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
578 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
579 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100580 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
581 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000582
583
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000584 class C(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000585
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000586 def m(self): pass
587 def c(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000588
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000589 attrs = attrs_wo_objs(C)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000590 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
591 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
592 self.assertIn(('p', 'property', A), attrs, 'missing property')
593 self.assertIn(('m', 'method', C), attrs, 'missing plain method')
594 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
595 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100596 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
597 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000598
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000599 class D(B, C):
Tim Peters13b49d32001-09-23 02:00:29 +0000600
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000601 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000602
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000603 attrs = attrs_wo_objs(D)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000604 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
605 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
606 self.assertIn(('p', 'property', A), attrs, 'missing property')
607 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
608 self.assertIn(('m1', 'method', D), attrs, 'missing plain method')
609 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100610 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
611 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
612
613 def test_classify_builtin_types(self):
614 # Simple sanity check that all built-in types can have their
615 # attributes classified.
616 for name in dir(__builtins__):
617 builtin = getattr(__builtins__, name)
618 if isinstance(builtin, type):
619 inspect.classify_class_attrs(builtin)
620
621 def test_getmembers_descriptors(self):
622 class A(object):
623 dd = _BrokenDataDescriptor()
624 md = _BrokenMethodDescriptor()
625
626 def pred_wrapper(pred):
627 # A quick'n'dirty way to discard standard attributes of new-style
628 # classes.
629 class Empty(object):
630 pass
631 def wrapped(x):
632 if '__name__' in dir(x) and hasattr(Empty, x.__name__):
633 return False
634 return pred(x)
635 return wrapped
636
637 ismethoddescriptor = pred_wrapper(inspect.ismethoddescriptor)
638 isdatadescriptor = pred_wrapper(inspect.isdatadescriptor)
639
640 self.assertEqual(inspect.getmembers(A, ismethoddescriptor),
641 [('md', A.__dict__['md'])])
642 self.assertEqual(inspect.getmembers(A, isdatadescriptor),
643 [('dd', A.__dict__['dd'])])
644
645 class B(A):
646 pass
647
648 self.assertEqual(inspect.getmembers(B, ismethoddescriptor),
649 [('md', A.__dict__['md'])])
650 self.assertEqual(inspect.getmembers(B, isdatadescriptor),
651 [('dd', A.__dict__['dd'])])
652
Antoine Pitrou0c603812012-01-18 17:40:18 +0100653 def test_getmembers_method(self):
654 class B:
655 def f(self):
656 pass
657
658 self.assertIn(('f', B.f), inspect.getmembers(B))
659 self.assertNotIn(('f', B.f), inspect.getmembers(B, inspect.ismethod))
660 b = B()
661 self.assertIn(('f', b.f), inspect.getmembers(b))
662 self.assertIn(('f', b.f), inspect.getmembers(b, inspect.ismethod))
663
Jeremy Hyltonc4bf5ed2003-06-27 18:43:12 +0000664
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000665class TestGetcallargsFunctions(unittest.TestCase):
666
667 def assertEqualCallArgs(self, func, call_params_string, locs=None):
668 locs = dict(locs or {}, func=func)
669 r1 = eval('func(%s)' % call_params_string, None, locs)
670 r2 = eval('inspect.getcallargs(func, %s)' % call_params_string, None,
671 locs)
672 self.assertEqual(r1, r2)
673
674 def assertEqualException(self, func, call_param_string, locs=None):
675 locs = dict(locs or {}, func=func)
676 try:
677 eval('func(%s)' % call_param_string, None, locs)
678 except Exception as e:
679 ex1 = e
680 else:
681 self.fail('Exception not raised')
682 try:
683 eval('inspect.getcallargs(func, %s)' % call_param_string, None,
684 locs)
685 except Exception as e:
686 ex2 = e
687 else:
688 self.fail('Exception not raised')
689 self.assertIs(type(ex1), type(ex2))
690 self.assertEqual(str(ex1), str(ex2))
691 del ex1, ex2
692
693 def makeCallable(self, signature):
694 """Create a function that returns its locals()"""
695 code = "lambda %s: locals()"
696 return eval(code % signature)
697
698 def test_plain(self):
699 f = self.makeCallable('a, b=1')
700 self.assertEqualCallArgs(f, '2')
701 self.assertEqualCallArgs(f, '2, 3')
702 self.assertEqualCallArgs(f, 'a=2')
703 self.assertEqualCallArgs(f, 'b=3, a=2')
704 self.assertEqualCallArgs(f, '2, b=3')
705 # expand *iterable / **mapping
706 self.assertEqualCallArgs(f, '*(2,)')
707 self.assertEqualCallArgs(f, '*[2]')
708 self.assertEqualCallArgs(f, '*(2, 3)')
709 self.assertEqualCallArgs(f, '*[2, 3]')
710 self.assertEqualCallArgs(f, '**{"a":2}')
711 self.assertEqualCallArgs(f, 'b=3, **{"a":2}')
712 self.assertEqualCallArgs(f, '2, **{"b":3}')
713 self.assertEqualCallArgs(f, '**{"b":3, "a":2}')
714 # expand UserList / UserDict
715 self.assertEqualCallArgs(f, '*collections.UserList([2])')
716 self.assertEqualCallArgs(f, '*collections.UserList([2, 3])')
717 self.assertEqualCallArgs(f, '**collections.UserDict(a=2)')
718 self.assertEqualCallArgs(f, '2, **collections.UserDict(b=3)')
719 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3)')
720
721 def test_varargs(self):
722 f = self.makeCallable('a, b=1, *c')
723 self.assertEqualCallArgs(f, '2')
724 self.assertEqualCallArgs(f, '2, 3')
725 self.assertEqualCallArgs(f, '2, 3, 4')
726 self.assertEqualCallArgs(f, '*(2,3,4)')
727 self.assertEqualCallArgs(f, '2, *[3,4]')
728 self.assertEqualCallArgs(f, '2, 3, *collections.UserList([4])')
729
730 def test_varkw(self):
731 f = self.makeCallable('a, b=1, **c')
732 self.assertEqualCallArgs(f, 'a=2')
733 self.assertEqualCallArgs(f, '2, b=3, c=4')
734 self.assertEqualCallArgs(f, 'b=3, a=2, c=4')
735 self.assertEqualCallArgs(f, 'c=4, **{"a":2, "b":3}')
736 self.assertEqualCallArgs(f, '2, c=4, **{"b":3}')
737 self.assertEqualCallArgs(f, 'b=2, **{"a":3, "c":4}')
738 self.assertEqualCallArgs(f, '**collections.UserDict(a=2, b=3, c=4)')
739 self.assertEqualCallArgs(f, '2, c=4, **collections.UserDict(b=3)')
740 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3, c=4)')
741
Benjamin Peterson6a2638b2011-03-28 17:32:31 -0500742 def test_varkw_only(self):
743 # issue11256:
744 f = self.makeCallable('**c')
745 self.assertEqualCallArgs(f, '')
746 self.assertEqualCallArgs(f, 'a=1')
747 self.assertEqualCallArgs(f, 'a=1, b=2')
748 self.assertEqualCallArgs(f, 'c=3, **{"a": 1, "b": 2}')
749 self.assertEqualCallArgs(f, '**collections.UserDict(a=1, b=2)')
750 self.assertEqualCallArgs(f, 'c=3, **collections.UserDict(a=1, b=2)')
751
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000752 def test_keyword_only(self):
753 f = self.makeCallable('a=3, *, c, d=2')
754 self.assertEqualCallArgs(f, 'c=3')
755 self.assertEqualCallArgs(f, 'c=3, a=3')
756 self.assertEqualCallArgs(f, 'a=2, c=4')
757 self.assertEqualCallArgs(f, '4, c=4')
758 self.assertEqualException(f, '')
759 self.assertEqualException(f, '3')
760 self.assertEqualException(f, 'a=3')
761 self.assertEqualException(f, 'd=4')
762
Benjamin Peterson6a2638b2011-03-28 17:32:31 -0500763 f = self.makeCallable('*, c, d=2')
764 self.assertEqualCallArgs(f, 'c=3')
765 self.assertEqualCallArgs(f, 'c=3, d=4')
766 self.assertEqualCallArgs(f, 'd=4, c=3')
767
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000768 def test_multiple_features(self):
769 f = self.makeCallable('a, b=2, *f, **g')
770 self.assertEqualCallArgs(f, '2, 3, 7')
771 self.assertEqualCallArgs(f, '2, 3, x=8')
772 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
773 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9')
774 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9')
775 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
776 '[2, 3, (4,[5,6])]), **{"y":9, "z":10}')
777 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
778 '(4,[5,6])]), **collections.UserDict('
779 'y=9, z=10)')
780
Benjamin Peterson6a2638b2011-03-28 17:32:31 -0500781 f = self.makeCallable('a, b=2, *f, x, y=99, **g')
782 self.assertEqualCallArgs(f, '2, 3, x=8')
783 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
784 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9, z=10')
785 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9, z=10')
786 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
787 '[2, 3, (4,[5,6])]), q=0, **{"y":9, "z":10}')
788 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
789 '(4,[5,6])]), q=0, **collections.UserDict('
790 'y=9, z=10)')
791
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000792 def test_errors(self):
793 f0 = self.makeCallable('')
794 f1 = self.makeCallable('a, b')
795 f2 = self.makeCallable('a, b=1')
796 # f0 takes no arguments
797 self.assertEqualException(f0, '1')
798 self.assertEqualException(f0, 'x=1')
799 self.assertEqualException(f0, '1,x=1')
800 # f1 takes exactly 2 arguments
801 self.assertEqualException(f1, '')
802 self.assertEqualException(f1, '1')
803 self.assertEqualException(f1, 'a=2')
804 self.assertEqualException(f1, 'b=3')
805 # f2 takes at least 1 argument
806 self.assertEqualException(f2, '')
807 self.assertEqualException(f2, 'b=3')
808 for f in f1, f2:
809 # f1/f2 takes exactly/at most 2 arguments
810 self.assertEqualException(f, '2, 3, 4')
811 self.assertEqualException(f, '1, 2, 3, a=1')
812 self.assertEqualException(f, '2, 3, 4, c=5')
813 self.assertEqualException(f, '2, 3, 4, a=1, c=5')
814 # f got an unexpected keyword argument
815 self.assertEqualException(f, 'c=2')
816 self.assertEqualException(f, '2, c=3')
817 self.assertEqualException(f, '2, 3, c=4')
818 self.assertEqualException(f, '2, c=4, b=3')
819 self.assertEqualException(f, '**{u"\u03c0\u03b9": 4}')
820 # f got multiple values for keyword argument
821 self.assertEqualException(f, '1, a=2')
822 self.assertEqualException(f, '1, **{"a":2}')
823 self.assertEqualException(f, '1, 2, b=3')
824 # XXX: Python inconsistency
825 # - for functions and bound methods: unexpected keyword 'c'
826 # - for unbound methods: multiple values for keyword 'a'
827 #self.assertEqualException(f, '1, c=3, a=2')
Benjamin Peterson6a2638b2011-03-28 17:32:31 -0500828 # issue11256:
829 f3 = self.makeCallable('**c')
830 self.assertEqualException(f3, '1, 2')
831 self.assertEqualException(f3, '1, 2, a=1, b=2')
832 f4 = self.makeCallable('*, a, b=0')
833 self.assertEqualException(f3, '1, 2')
834 self.assertEqualException(f3, '1, 2, a=1, b=2')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000835
836class TestGetcallargsMethods(TestGetcallargsFunctions):
837
838 def setUp(self):
839 class Foo(object):
840 pass
841 self.cls = Foo
842 self.inst = Foo()
843
844 def makeCallable(self, signature):
845 assert 'self' not in signature
846 mk = super(TestGetcallargsMethods, self).makeCallable
847 self.cls.method = mk('self, ' + signature)
848 return self.inst.method
849
850class TestGetcallargsUnboundMethods(TestGetcallargsMethods):
851
852 def makeCallable(self, signature):
853 super(TestGetcallargsUnboundMethods, self).makeCallable(signature)
854 return self.cls.method
855
856 def assertEqualCallArgs(self, func, call_params_string, locs=None):
857 return super(TestGetcallargsUnboundMethods, self).assertEqualCallArgs(
858 *self._getAssertEqualParams(func, call_params_string, locs))
859
860 def assertEqualException(self, func, call_params_string, locs=None):
861 return super(TestGetcallargsUnboundMethods, self).assertEqualException(
862 *self._getAssertEqualParams(func, call_params_string, locs))
863
864 def _getAssertEqualParams(self, func, call_params_string, locs=None):
865 assert 'inst' not in call_params_string
866 locs = dict(locs or {}, inst=self.inst)
867 return (func, 'inst,' + call_params_string, locs)
868
Michael Foord95fc51d2010-11-20 15:07:30 +0000869
870class TestGetattrStatic(unittest.TestCase):
871
872 def test_basic(self):
873 class Thing(object):
874 x = object()
875
876 thing = Thing()
877 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
878 self.assertEqual(inspect.getattr_static(thing, 'x', None), Thing.x)
879 with self.assertRaises(AttributeError):
880 inspect.getattr_static(thing, 'y')
881
882 self.assertEqual(inspect.getattr_static(thing, 'y', 3), 3)
883
884 def test_inherited(self):
885 class Thing(object):
886 x = object()
887 class OtherThing(Thing):
888 pass
889
890 something = OtherThing()
891 self.assertEqual(inspect.getattr_static(something, 'x'), Thing.x)
892
893 def test_instance_attr(self):
894 class Thing(object):
895 x = 2
896 def __init__(self, x):
897 self.x = x
898 thing = Thing(3)
899 self.assertEqual(inspect.getattr_static(thing, 'x'), 3)
900 del thing.x
901 self.assertEqual(inspect.getattr_static(thing, 'x'), 2)
902
903 def test_property(self):
904 class Thing(object):
905 @property
906 def x(self):
907 raise AttributeError("I'm pretending not to exist")
908 thing = Thing()
909 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
910
Ezio Melotti75cbd732011-04-28 00:59:29 +0300911 def test_descriptor_raises_AttributeError(self):
Michael Foord95fc51d2010-11-20 15:07:30 +0000912 class descriptor(object):
913 def __get__(*_):
914 raise AttributeError("I'm pretending not to exist")
915 desc = descriptor()
916 class Thing(object):
917 x = desc
918 thing = Thing()
919 self.assertEqual(inspect.getattr_static(thing, 'x'), desc)
920
921 def test_classAttribute(self):
922 class Thing(object):
923 x = object()
924
925 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.x)
926
927 def test_inherited_classattribute(self):
928 class Thing(object):
929 x = object()
930 class OtherThing(Thing):
931 pass
932
933 self.assertEqual(inspect.getattr_static(OtherThing, 'x'), Thing.x)
934
935 def test_slots(self):
936 class Thing(object):
937 y = 'bar'
938 __slots__ = ['x']
939 def __init__(self):
940 self.x = 'foo'
941 thing = Thing()
942 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
943 self.assertEqual(inspect.getattr_static(thing, 'y'), 'bar')
944
945 del thing.x
946 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
947
948 def test_metaclass(self):
949 class meta(type):
950 attr = 'foo'
951 class Thing(object, metaclass=meta):
952 pass
953 self.assertEqual(inspect.getattr_static(Thing, 'attr'), 'foo')
954
955 class sub(meta):
956 pass
957 class OtherThing(object, metaclass=sub):
958 x = 3
959 self.assertEqual(inspect.getattr_static(OtherThing, 'attr'), 'foo')
960
961 class OtherOtherThing(OtherThing):
962 pass
963 # this test is odd, but it was added as it exposed a bug
964 self.assertEqual(inspect.getattr_static(OtherOtherThing, 'x'), 3)
965
966 def test_no_dict_no_slots(self):
967 self.assertEqual(inspect.getattr_static(1, 'foo', None), None)
968 self.assertNotEqual(inspect.getattr_static('foo', 'lower'), None)
969
970 def test_no_dict_no_slots_instance_member(self):
971 # returns descriptor
972 with open(__file__) as handle:
973 self.assertEqual(inspect.getattr_static(handle, 'name'), type(handle).name)
974
975 def test_inherited_slots(self):
976 # returns descriptor
977 class Thing(object):
978 __slots__ = ['x']
979 def __init__(self):
980 self.x = 'foo'
981
982 class OtherThing(Thing):
983 pass
984 # it would be nice if this worked...
985 # we get the descriptor instead of the instance attribute
986 self.assertEqual(inspect.getattr_static(OtherThing(), 'x'), Thing.x)
987
988 def test_descriptor(self):
989 class descriptor(object):
990 def __get__(self, instance, owner):
991 return 3
992 class Foo(object):
993 d = descriptor()
994
995 foo = Foo()
996
997 # for a non data descriptor we return the instance attribute
998 foo.__dict__['d'] = 1
999 self.assertEqual(inspect.getattr_static(foo, 'd'), 1)
1000
1001 # if the descriptor is a data-desciptor we should return the
1002 # descriptor
1003 descriptor.__set__ = lambda s, i, v: None
1004 self.assertEqual(inspect.getattr_static(foo, 'd'), Foo.__dict__['d'])
1005
1006
1007 def test_metaclass_with_descriptor(self):
1008 class descriptor(object):
1009 def __get__(self, instance, owner):
1010 return 3
1011 class meta(type):
1012 d = descriptor()
1013 class Thing(object, metaclass=meta):
1014 pass
1015 self.assertEqual(inspect.getattr_static(Thing, 'd'), meta.__dict__['d'])
1016
1017
Michael Foordcc7ebb82010-11-20 16:20:16 +00001018 def test_class_as_property(self):
1019 class Base(object):
1020 foo = 3
1021
1022 class Something(Base):
Michael Foord35184ed2010-11-20 16:58:30 +00001023 executed = False
Michael Foordcc7ebb82010-11-20 16:20:16 +00001024 @property
1025 def __class__(self):
Michael Foord35184ed2010-11-20 16:58:30 +00001026 self.executed = True
Michael Foordcc7ebb82010-11-20 16:20:16 +00001027 return object
1028
Michael Foord35184ed2010-11-20 16:58:30 +00001029 instance = Something()
1030 self.assertEqual(inspect.getattr_static(instance, 'foo'), 3)
1031 self.assertFalse(instance.executed)
Michael Foordcc7ebb82010-11-20 16:20:16 +00001032 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1033
Michael Foorde5162652010-11-20 16:40:44 +00001034 def test_mro_as_property(self):
1035 class Meta(type):
1036 @property
1037 def __mro__(self):
1038 return (object,)
1039
1040 class Base(object):
1041 foo = 3
1042
1043 class Something(Base, metaclass=Meta):
1044 pass
1045
1046 self.assertEqual(inspect.getattr_static(Something(), 'foo'), 3)
1047 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1048
Michael Foorddcebe0f2011-03-15 19:20:44 -04001049 def test_dict_as_property(self):
1050 test = self
1051 test.called = False
1052
1053 class Foo(dict):
1054 a = 3
1055 @property
1056 def __dict__(self):
1057 test.called = True
1058 return {}
1059
1060 foo = Foo()
1061 foo.a = 4
1062 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1063 self.assertFalse(test.called)
1064
1065 def test_custom_object_dict(self):
1066 test = self
1067 test.called = False
1068
1069 class Custom(dict):
1070 def get(self, key, default=None):
1071 test.called = True
1072 super().get(key, default)
1073
1074 class Foo(object):
1075 a = 3
1076 foo = Foo()
1077 foo.__dict__ = Custom()
1078 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1079 self.assertFalse(test.called)
1080
1081 def test_metaclass_dict_as_property(self):
1082 class Meta(type):
1083 @property
1084 def __dict__(self):
1085 self.executed = True
1086
1087 class Thing(metaclass=Meta):
1088 executed = False
1089
1090 def __init__(self):
1091 self.spam = 42
1092
1093 instance = Thing()
1094 self.assertEqual(inspect.getattr_static(instance, "spam"), 42)
1095 self.assertFalse(Thing.executed)
Michael Foorde5162652010-11-20 16:40:44 +00001096
Michael Foorda51623b2011-12-18 22:01:40 +00001097 def test_module(self):
1098 sentinel = object()
1099 self.assertIsNot(inspect.getattr_static(sys, "version", sentinel),
1100 sentinel)
1101
Michael Foord3ba95f82011-12-22 01:13:37 +00001102 def test_metaclass_with_metaclass_with_dict_as_property(self):
1103 class MetaMeta(type):
1104 @property
1105 def __dict__(self):
1106 self.executed = True
1107 return dict(spam=42)
1108
1109 class Meta(type, metaclass=MetaMeta):
1110 executed = False
1111
1112 class Thing(metaclass=Meta):
1113 pass
1114
1115 with self.assertRaises(AttributeError):
1116 inspect.getattr_static(Thing, "spam")
1117 self.assertFalse(Thing.executed)
1118
Nick Coghlane0f04652010-11-21 03:44:04 +00001119class TestGetGeneratorState(unittest.TestCase):
1120
1121 def setUp(self):
1122 def number_generator():
1123 for number in range(5):
1124 yield number
1125 self.generator = number_generator()
1126
1127 def _generatorstate(self):
1128 return inspect.getgeneratorstate(self.generator)
1129
1130 def test_created(self):
1131 self.assertEqual(self._generatorstate(), inspect.GEN_CREATED)
1132
1133 def test_suspended(self):
1134 next(self.generator)
1135 self.assertEqual(self._generatorstate(), inspect.GEN_SUSPENDED)
1136
1137 def test_closed_after_exhaustion(self):
1138 for i in self.generator:
1139 pass
1140 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1141
1142 def test_closed_after_immediate_exception(self):
1143 with self.assertRaises(RuntimeError):
1144 self.generator.throw(RuntimeError)
1145 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1146
1147 def test_running(self):
1148 # As mentioned on issue #10220, checking for the RUNNING state only
1149 # makes sense inside the generator itself.
1150 # The following generator checks for this by using the closure's
1151 # reference to self and the generator state checking helper method
1152 def running_check_generator():
1153 for number in range(5):
1154 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1155 yield number
1156 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1157 self.generator = running_check_generator()
1158 # Running up to the first yield
1159 next(self.generator)
1160 # Running after the first yield
1161 next(self.generator)
1162
Nick Coghlan7921b9f2010-11-30 06:36:04 +00001163 def test_easy_debugging(self):
1164 # repr() and str() of a generator state should contain the state name
1165 names = 'GEN_CREATED GEN_RUNNING GEN_SUSPENDED GEN_CLOSED'.split()
1166 for name in names:
1167 state = getattr(inspect, name)
1168 self.assertIn(name, repr(state))
1169 self.assertIn(name, str(state))
1170
Nick Coghlane0f04652010-11-21 03:44:04 +00001171
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001172def test_main():
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001173 run_unittest(
1174 TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBuggyCases,
1175 TestInterpreterStack, TestClassesAndFunctions, TestPredicates,
1176 TestGetcallargsFunctions, TestGetcallargsMethods,
Alexander Belopolskyf546e702010-12-02 00:10:11 +00001177 TestGetcallargsUnboundMethods, TestGetattrStatic, TestGetGeneratorState,
1178 TestNoEOL
Michael Foord95fc51d2010-11-20 15:07:30 +00001179 )
Martin v. Löwis893ffa42003-10-31 15:35:53 +00001180
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001181if __name__ == "__main__":
1182 test_main()