blob: 56f9929770f8ce96d1684d084fec9ad181e32146 [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
Jeremy Hyltonc4bf5ed2003-06-27 18:43:12 +0000653
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000654class TestGetcallargsFunctions(unittest.TestCase):
655
656 def assertEqualCallArgs(self, func, call_params_string, locs=None):
657 locs = dict(locs or {}, func=func)
658 r1 = eval('func(%s)' % call_params_string, None, locs)
659 r2 = eval('inspect.getcallargs(func, %s)' % call_params_string, None,
660 locs)
661 self.assertEqual(r1, r2)
662
663 def assertEqualException(self, func, call_param_string, locs=None):
664 locs = dict(locs or {}, func=func)
665 try:
666 eval('func(%s)' % call_param_string, None, locs)
667 except Exception as e:
668 ex1 = e
669 else:
670 self.fail('Exception not raised')
671 try:
672 eval('inspect.getcallargs(func, %s)' % call_param_string, None,
673 locs)
674 except Exception as e:
675 ex2 = e
676 else:
677 self.fail('Exception not raised')
678 self.assertIs(type(ex1), type(ex2))
679 self.assertEqual(str(ex1), str(ex2))
680 del ex1, ex2
681
682 def makeCallable(self, signature):
683 """Create a function that returns its locals()"""
684 code = "lambda %s: locals()"
685 return eval(code % signature)
686
687 def test_plain(self):
688 f = self.makeCallable('a, b=1')
689 self.assertEqualCallArgs(f, '2')
690 self.assertEqualCallArgs(f, '2, 3')
691 self.assertEqualCallArgs(f, 'a=2')
692 self.assertEqualCallArgs(f, 'b=3, a=2')
693 self.assertEqualCallArgs(f, '2, b=3')
694 # expand *iterable / **mapping
695 self.assertEqualCallArgs(f, '*(2,)')
696 self.assertEqualCallArgs(f, '*[2]')
697 self.assertEqualCallArgs(f, '*(2, 3)')
698 self.assertEqualCallArgs(f, '*[2, 3]')
699 self.assertEqualCallArgs(f, '**{"a":2}')
700 self.assertEqualCallArgs(f, 'b=3, **{"a":2}')
701 self.assertEqualCallArgs(f, '2, **{"b":3}')
702 self.assertEqualCallArgs(f, '**{"b":3, "a":2}')
703 # expand UserList / UserDict
704 self.assertEqualCallArgs(f, '*collections.UserList([2])')
705 self.assertEqualCallArgs(f, '*collections.UserList([2, 3])')
706 self.assertEqualCallArgs(f, '**collections.UserDict(a=2)')
707 self.assertEqualCallArgs(f, '2, **collections.UserDict(b=3)')
708 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3)')
709
710 def test_varargs(self):
711 f = self.makeCallable('a, b=1, *c')
712 self.assertEqualCallArgs(f, '2')
713 self.assertEqualCallArgs(f, '2, 3')
714 self.assertEqualCallArgs(f, '2, 3, 4')
715 self.assertEqualCallArgs(f, '*(2,3,4)')
716 self.assertEqualCallArgs(f, '2, *[3,4]')
717 self.assertEqualCallArgs(f, '2, 3, *collections.UserList([4])')
718
719 def test_varkw(self):
720 f = self.makeCallable('a, b=1, **c')
721 self.assertEqualCallArgs(f, 'a=2')
722 self.assertEqualCallArgs(f, '2, b=3, c=4')
723 self.assertEqualCallArgs(f, 'b=3, a=2, c=4')
724 self.assertEqualCallArgs(f, 'c=4, **{"a":2, "b":3}')
725 self.assertEqualCallArgs(f, '2, c=4, **{"b":3}')
726 self.assertEqualCallArgs(f, 'b=2, **{"a":3, "c":4}')
727 self.assertEqualCallArgs(f, '**collections.UserDict(a=2, b=3, c=4)')
728 self.assertEqualCallArgs(f, '2, c=4, **collections.UserDict(b=3)')
729 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3, c=4)')
730
Benjamin Peterson6a2638b2011-03-28 17:32:31 -0500731 def test_varkw_only(self):
732 # issue11256:
733 f = self.makeCallable('**c')
734 self.assertEqualCallArgs(f, '')
735 self.assertEqualCallArgs(f, 'a=1')
736 self.assertEqualCallArgs(f, 'a=1, b=2')
737 self.assertEqualCallArgs(f, 'c=3, **{"a": 1, "b": 2}')
738 self.assertEqualCallArgs(f, '**collections.UserDict(a=1, b=2)')
739 self.assertEqualCallArgs(f, 'c=3, **collections.UserDict(a=1, b=2)')
740
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000741 def test_keyword_only(self):
742 f = self.makeCallable('a=3, *, c, d=2')
743 self.assertEqualCallArgs(f, 'c=3')
744 self.assertEqualCallArgs(f, 'c=3, a=3')
745 self.assertEqualCallArgs(f, 'a=2, c=4')
746 self.assertEqualCallArgs(f, '4, c=4')
747 self.assertEqualException(f, '')
748 self.assertEqualException(f, '3')
749 self.assertEqualException(f, 'a=3')
750 self.assertEqualException(f, 'd=4')
751
Benjamin Peterson6a2638b2011-03-28 17:32:31 -0500752 f = self.makeCallable('*, c, d=2')
753 self.assertEqualCallArgs(f, 'c=3')
754 self.assertEqualCallArgs(f, 'c=3, d=4')
755 self.assertEqualCallArgs(f, 'd=4, c=3')
756
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000757 def test_multiple_features(self):
758 f = self.makeCallable('a, b=2, *f, **g')
759 self.assertEqualCallArgs(f, '2, 3, 7')
760 self.assertEqualCallArgs(f, '2, 3, x=8')
761 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
762 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9')
763 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9')
764 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
765 '[2, 3, (4,[5,6])]), **{"y":9, "z":10}')
766 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
767 '(4,[5,6])]), **collections.UserDict('
768 'y=9, z=10)')
769
Benjamin Peterson6a2638b2011-03-28 17:32:31 -0500770 f = self.makeCallable('a, b=2, *f, x, y=99, **g')
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, z=10')
774 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9, z=10')
775 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
776 '[2, 3, (4,[5,6])]), q=0, **{"y":9, "z":10}')
777 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
778 '(4,[5,6])]), q=0, **collections.UserDict('
779 'y=9, z=10)')
780
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000781 def test_errors(self):
782 f0 = self.makeCallable('')
783 f1 = self.makeCallable('a, b')
784 f2 = self.makeCallable('a, b=1')
785 # f0 takes no arguments
786 self.assertEqualException(f0, '1')
787 self.assertEqualException(f0, 'x=1')
788 self.assertEqualException(f0, '1,x=1')
789 # f1 takes exactly 2 arguments
790 self.assertEqualException(f1, '')
791 self.assertEqualException(f1, '1')
792 self.assertEqualException(f1, 'a=2')
793 self.assertEqualException(f1, 'b=3')
794 # f2 takes at least 1 argument
795 self.assertEqualException(f2, '')
796 self.assertEqualException(f2, 'b=3')
797 for f in f1, f2:
798 # f1/f2 takes exactly/at most 2 arguments
799 self.assertEqualException(f, '2, 3, 4')
800 self.assertEqualException(f, '1, 2, 3, a=1')
801 self.assertEqualException(f, '2, 3, 4, c=5')
802 self.assertEqualException(f, '2, 3, 4, a=1, c=5')
803 # f got an unexpected keyword argument
804 self.assertEqualException(f, 'c=2')
805 self.assertEqualException(f, '2, c=3')
806 self.assertEqualException(f, '2, 3, c=4')
807 self.assertEqualException(f, '2, c=4, b=3')
808 self.assertEqualException(f, '**{u"\u03c0\u03b9": 4}')
809 # f got multiple values for keyword argument
810 self.assertEqualException(f, '1, a=2')
811 self.assertEqualException(f, '1, **{"a":2}')
812 self.assertEqualException(f, '1, 2, b=3')
813 # XXX: Python inconsistency
814 # - for functions and bound methods: unexpected keyword 'c'
815 # - for unbound methods: multiple values for keyword 'a'
816 #self.assertEqualException(f, '1, c=3, a=2')
Benjamin Peterson6a2638b2011-03-28 17:32:31 -0500817 # issue11256:
818 f3 = self.makeCallable('**c')
819 self.assertEqualException(f3, '1, 2')
820 self.assertEqualException(f3, '1, 2, a=1, b=2')
821 f4 = self.makeCallable('*, a, b=0')
822 self.assertEqualException(f3, '1, 2')
823 self.assertEqualException(f3, '1, 2, a=1, b=2')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000824
825class TestGetcallargsMethods(TestGetcallargsFunctions):
826
827 def setUp(self):
828 class Foo(object):
829 pass
830 self.cls = Foo
831 self.inst = Foo()
832
833 def makeCallable(self, signature):
834 assert 'self' not in signature
835 mk = super(TestGetcallargsMethods, self).makeCallable
836 self.cls.method = mk('self, ' + signature)
837 return self.inst.method
838
839class TestGetcallargsUnboundMethods(TestGetcallargsMethods):
840
841 def makeCallable(self, signature):
842 super(TestGetcallargsUnboundMethods, self).makeCallable(signature)
843 return self.cls.method
844
845 def assertEqualCallArgs(self, func, call_params_string, locs=None):
846 return super(TestGetcallargsUnboundMethods, self).assertEqualCallArgs(
847 *self._getAssertEqualParams(func, call_params_string, locs))
848
849 def assertEqualException(self, func, call_params_string, locs=None):
850 return super(TestGetcallargsUnboundMethods, self).assertEqualException(
851 *self._getAssertEqualParams(func, call_params_string, locs))
852
853 def _getAssertEqualParams(self, func, call_params_string, locs=None):
854 assert 'inst' not in call_params_string
855 locs = dict(locs or {}, inst=self.inst)
856 return (func, 'inst,' + call_params_string, locs)
857
Michael Foord95fc51d2010-11-20 15:07:30 +0000858
859class TestGetattrStatic(unittest.TestCase):
860
861 def test_basic(self):
862 class Thing(object):
863 x = object()
864
865 thing = Thing()
866 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
867 self.assertEqual(inspect.getattr_static(thing, 'x', None), Thing.x)
868 with self.assertRaises(AttributeError):
869 inspect.getattr_static(thing, 'y')
870
871 self.assertEqual(inspect.getattr_static(thing, 'y', 3), 3)
872
873 def test_inherited(self):
874 class Thing(object):
875 x = object()
876 class OtherThing(Thing):
877 pass
878
879 something = OtherThing()
880 self.assertEqual(inspect.getattr_static(something, 'x'), Thing.x)
881
882 def test_instance_attr(self):
883 class Thing(object):
884 x = 2
885 def __init__(self, x):
886 self.x = x
887 thing = Thing(3)
888 self.assertEqual(inspect.getattr_static(thing, 'x'), 3)
889 del thing.x
890 self.assertEqual(inspect.getattr_static(thing, 'x'), 2)
891
892 def test_property(self):
893 class Thing(object):
894 @property
895 def x(self):
896 raise AttributeError("I'm pretending not to exist")
897 thing = Thing()
898 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
899
Ezio Melotti75cbd732011-04-28 00:59:29 +0300900 def test_descriptor_raises_AttributeError(self):
Michael Foord95fc51d2010-11-20 15:07:30 +0000901 class descriptor(object):
902 def __get__(*_):
903 raise AttributeError("I'm pretending not to exist")
904 desc = descriptor()
905 class Thing(object):
906 x = desc
907 thing = Thing()
908 self.assertEqual(inspect.getattr_static(thing, 'x'), desc)
909
910 def test_classAttribute(self):
911 class Thing(object):
912 x = object()
913
914 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.x)
915
916 def test_inherited_classattribute(self):
917 class Thing(object):
918 x = object()
919 class OtherThing(Thing):
920 pass
921
922 self.assertEqual(inspect.getattr_static(OtherThing, 'x'), Thing.x)
923
924 def test_slots(self):
925 class Thing(object):
926 y = 'bar'
927 __slots__ = ['x']
928 def __init__(self):
929 self.x = 'foo'
930 thing = Thing()
931 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
932 self.assertEqual(inspect.getattr_static(thing, 'y'), 'bar')
933
934 del thing.x
935 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
936
937 def test_metaclass(self):
938 class meta(type):
939 attr = 'foo'
940 class Thing(object, metaclass=meta):
941 pass
942 self.assertEqual(inspect.getattr_static(Thing, 'attr'), 'foo')
943
944 class sub(meta):
945 pass
946 class OtherThing(object, metaclass=sub):
947 x = 3
948 self.assertEqual(inspect.getattr_static(OtherThing, 'attr'), 'foo')
949
950 class OtherOtherThing(OtherThing):
951 pass
952 # this test is odd, but it was added as it exposed a bug
953 self.assertEqual(inspect.getattr_static(OtherOtherThing, 'x'), 3)
954
955 def test_no_dict_no_slots(self):
956 self.assertEqual(inspect.getattr_static(1, 'foo', None), None)
957 self.assertNotEqual(inspect.getattr_static('foo', 'lower'), None)
958
959 def test_no_dict_no_slots_instance_member(self):
960 # returns descriptor
961 with open(__file__) as handle:
962 self.assertEqual(inspect.getattr_static(handle, 'name'), type(handle).name)
963
964 def test_inherited_slots(self):
965 # returns descriptor
966 class Thing(object):
967 __slots__ = ['x']
968 def __init__(self):
969 self.x = 'foo'
970
971 class OtherThing(Thing):
972 pass
973 # it would be nice if this worked...
974 # we get the descriptor instead of the instance attribute
975 self.assertEqual(inspect.getattr_static(OtherThing(), 'x'), Thing.x)
976
977 def test_descriptor(self):
978 class descriptor(object):
979 def __get__(self, instance, owner):
980 return 3
981 class Foo(object):
982 d = descriptor()
983
984 foo = Foo()
985
986 # for a non data descriptor we return the instance attribute
987 foo.__dict__['d'] = 1
988 self.assertEqual(inspect.getattr_static(foo, 'd'), 1)
989
990 # if the descriptor is a data-desciptor we should return the
991 # descriptor
992 descriptor.__set__ = lambda s, i, v: None
993 self.assertEqual(inspect.getattr_static(foo, 'd'), Foo.__dict__['d'])
994
995
996 def test_metaclass_with_descriptor(self):
997 class descriptor(object):
998 def __get__(self, instance, owner):
999 return 3
1000 class meta(type):
1001 d = descriptor()
1002 class Thing(object, metaclass=meta):
1003 pass
1004 self.assertEqual(inspect.getattr_static(Thing, 'd'), meta.__dict__['d'])
1005
1006
Michael Foordcc7ebb82010-11-20 16:20:16 +00001007 def test_class_as_property(self):
1008 class Base(object):
1009 foo = 3
1010
1011 class Something(Base):
Michael Foord35184ed2010-11-20 16:58:30 +00001012 executed = False
Michael Foordcc7ebb82010-11-20 16:20:16 +00001013 @property
1014 def __class__(self):
Michael Foord35184ed2010-11-20 16:58:30 +00001015 self.executed = True
Michael Foordcc7ebb82010-11-20 16:20:16 +00001016 return object
1017
Michael Foord35184ed2010-11-20 16:58:30 +00001018 instance = Something()
1019 self.assertEqual(inspect.getattr_static(instance, 'foo'), 3)
1020 self.assertFalse(instance.executed)
Michael Foordcc7ebb82010-11-20 16:20:16 +00001021 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1022
Michael Foorde5162652010-11-20 16:40:44 +00001023 def test_mro_as_property(self):
1024 class Meta(type):
1025 @property
1026 def __mro__(self):
1027 return (object,)
1028
1029 class Base(object):
1030 foo = 3
1031
1032 class Something(Base, metaclass=Meta):
1033 pass
1034
1035 self.assertEqual(inspect.getattr_static(Something(), 'foo'), 3)
1036 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1037
Michael Foorddcebe0f2011-03-15 19:20:44 -04001038 def test_dict_as_property(self):
1039 test = self
1040 test.called = False
1041
1042 class Foo(dict):
1043 a = 3
1044 @property
1045 def __dict__(self):
1046 test.called = True
1047 return {}
1048
1049 foo = Foo()
1050 foo.a = 4
1051 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1052 self.assertFalse(test.called)
1053
1054 def test_custom_object_dict(self):
1055 test = self
1056 test.called = False
1057
1058 class Custom(dict):
1059 def get(self, key, default=None):
1060 test.called = True
1061 super().get(key, default)
1062
1063 class Foo(object):
1064 a = 3
1065 foo = Foo()
1066 foo.__dict__ = Custom()
1067 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1068 self.assertFalse(test.called)
1069
1070 def test_metaclass_dict_as_property(self):
1071 class Meta(type):
1072 @property
1073 def __dict__(self):
1074 self.executed = True
1075
1076 class Thing(metaclass=Meta):
1077 executed = False
1078
1079 def __init__(self):
1080 self.spam = 42
1081
1082 instance = Thing()
1083 self.assertEqual(inspect.getattr_static(instance, "spam"), 42)
1084 self.assertFalse(Thing.executed)
Michael Foorde5162652010-11-20 16:40:44 +00001085
Michael Foorda51623b2011-12-18 22:01:40 +00001086 def test_module(self):
1087 sentinel = object()
1088 self.assertIsNot(inspect.getattr_static(sys, "version", sentinel),
1089 sentinel)
1090
Nick Coghlane0f04652010-11-21 03:44:04 +00001091class TestGetGeneratorState(unittest.TestCase):
1092
1093 def setUp(self):
1094 def number_generator():
1095 for number in range(5):
1096 yield number
1097 self.generator = number_generator()
1098
1099 def _generatorstate(self):
1100 return inspect.getgeneratorstate(self.generator)
1101
1102 def test_created(self):
1103 self.assertEqual(self._generatorstate(), inspect.GEN_CREATED)
1104
1105 def test_suspended(self):
1106 next(self.generator)
1107 self.assertEqual(self._generatorstate(), inspect.GEN_SUSPENDED)
1108
1109 def test_closed_after_exhaustion(self):
1110 for i in self.generator:
1111 pass
1112 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1113
1114 def test_closed_after_immediate_exception(self):
1115 with self.assertRaises(RuntimeError):
1116 self.generator.throw(RuntimeError)
1117 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1118
1119 def test_running(self):
1120 # As mentioned on issue #10220, checking for the RUNNING state only
1121 # makes sense inside the generator itself.
1122 # The following generator checks for this by using the closure's
1123 # reference to self and the generator state checking helper method
1124 def running_check_generator():
1125 for number in range(5):
1126 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1127 yield number
1128 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1129 self.generator = running_check_generator()
1130 # Running up to the first yield
1131 next(self.generator)
1132 # Running after the first yield
1133 next(self.generator)
1134
Nick Coghlan7921b9f2010-11-30 06:36:04 +00001135 def test_easy_debugging(self):
1136 # repr() and str() of a generator state should contain the state name
1137 names = 'GEN_CREATED GEN_RUNNING GEN_SUSPENDED GEN_CLOSED'.split()
1138 for name in names:
1139 state = getattr(inspect, name)
1140 self.assertIn(name, repr(state))
1141 self.assertIn(name, str(state))
1142
Nick Coghlane0f04652010-11-21 03:44:04 +00001143
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001144def test_main():
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001145 run_unittest(
1146 TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBuggyCases,
1147 TestInterpreterStack, TestClassesAndFunctions, TestPredicates,
1148 TestGetcallargsFunctions, TestGetcallargsMethods,
Alexander Belopolskyf546e702010-12-02 00:10:11 +00001149 TestGetcallargsUnboundMethods, TestGetattrStatic, TestGetGeneratorState,
1150 TestNoEOL
Michael Foord95fc51d2010-11-20 15:07:30 +00001151 )
Martin v. Löwis893ffa42003-10-31 15:35:53 +00001152
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001153if __name__ == "__main__":
1154 test_main()