blob: 7666fe43a7339b4904fe73461949fc4e4fd81f70 [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
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000428# Helper for testing classify_class_attrs.
Tim Peters13b49d32001-09-23 02:00:29 +0000429def attrs_wo_objs(cls):
430 return [t[:3] for t in inspect.classify_class_attrs(cls)]
431
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000432class TestClassesAndFunctions(unittest.TestCase):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000433 def test_newstyle_mro(self):
434 # The same w/ new-class MRO.
435 class A(object): pass
436 class B(A): pass
437 class C(A): pass
438 class D(B, C): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000439
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000440 expected = (D, B, C, A, object)
441 got = inspect.getmro(D)
442 self.assertEqual(expected, got)
Tim Peters13b49d32001-09-23 02:00:29 +0000443
Christian Heimes3795b532007-11-08 13:48:53 +0000444 def assertArgSpecEquals(self, routine, args_e, varargs_e=None,
445 varkw_e=None, defaults_e=None, formatted=None):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000446 args, varargs, varkw, defaults = inspect.getargspec(routine)
447 self.assertEqual(args, args_e)
448 self.assertEqual(varargs, varargs_e)
449 self.assertEqual(varkw, varkw_e)
450 self.assertEqual(defaults, defaults_e)
451 if formatted is not None:
452 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults),
453 formatted)
Tim Peters13b49d32001-09-23 02:00:29 +0000454
Christian Heimes3795b532007-11-08 13:48:53 +0000455 def assertFullArgSpecEquals(self, routine, args_e, varargs_e=None,
456 varkw_e=None, defaults_e=None,
457 kwonlyargs_e=[], kwonlydefaults_e=None,
458 ann_e={}, formatted=None):
459 args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \
460 inspect.getfullargspec(routine)
461 self.assertEqual(args, args_e)
462 self.assertEqual(varargs, varargs_e)
463 self.assertEqual(varkw, varkw_e)
464 self.assertEqual(defaults, defaults_e)
465 self.assertEqual(kwonlyargs, kwonlyargs_e)
466 self.assertEqual(kwonlydefaults, kwonlydefaults_e)
467 self.assertEqual(ann, ann_e)
468 if formatted is not None:
469 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults,
470 kwonlyargs, kwonlydefaults, ann),
471 formatted)
472
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000473 def test_getargspec(self):
Christian Heimes3795b532007-11-08 13:48:53 +0000474 self.assertArgSpecEquals(mod.eggs, ['x', 'y'], formatted='(x, y)')
Tim Peters13b49d32001-09-23 02:00:29 +0000475
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000476 self.assertArgSpecEquals(mod.spam,
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000477 ['a', 'b', 'c', 'd', 'e', 'f'],
478 'g', 'h', (3, 4, 5),
479 '(a, b, c, d=3, e=4, f=5, *g, **h)')
Tim Peters13b49d32001-09-23 02:00:29 +0000480
Christian Heimes3795b532007-11-08 13:48:53 +0000481 self.assertRaises(ValueError, self.assertArgSpecEquals,
482 mod2.keyworded, [])
483
484 self.assertRaises(ValueError, self.assertArgSpecEquals,
485 mod2.annotated, [])
Benjamin Peterson9953a8d2009-01-17 04:15:01 +0000486 self.assertRaises(ValueError, self.assertArgSpecEquals,
487 mod2.keyword_only_arg, [])
488
Christian Heimes3795b532007-11-08 13:48:53 +0000489
490 def test_getfullargspec(self):
491 self.assertFullArgSpecEquals(mod2.keyworded, [], varargs_e='arg1',
492 kwonlyargs_e=['arg2'],
493 kwonlydefaults_e={'arg2':1},
494 formatted='(*arg1, arg2=1)')
495
496 self.assertFullArgSpecEquals(mod2.annotated, ['arg1'],
Christian Heimesc9543e42007-11-28 08:28:28 +0000497 ann_e={'arg1' : list},
Christian Heimes3795b532007-11-08 13:48:53 +0000498 formatted='(arg1: list)')
Benjamin Peterson9953a8d2009-01-17 04:15:01 +0000499 self.assertFullArgSpecEquals(mod2.keyword_only_arg, [],
500 kwonlyargs_e=['arg'],
501 formatted='(*, arg)')
502
Christian Heimes3795b532007-11-08 13:48:53 +0000503
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000504 def test_getargspec_method(self):
505 class A(object):
506 def m(self):
507 pass
508 self.assertArgSpecEquals(A.m, ['self'])
Tim Peters13b49d32001-09-23 02:00:29 +0000509
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000510 def test_classify_newstyle(self):
511 class A(object):
Tim Peters13b49d32001-09-23 02:00:29 +0000512
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000513 def s(): pass
514 s = staticmethod(s)
Tim Peters13b49d32001-09-23 02:00:29 +0000515
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000516 def c(cls): pass
517 c = classmethod(c)
Tim Peters13b49d32001-09-23 02:00:29 +0000518
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000519 def getp(self): pass
520 p = property(getp)
Tim Peters13b49d32001-09-23 02:00:29 +0000521
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000522 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000523
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000524 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000525
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000526 datablob = '1'
Tim Peters13b49d32001-09-23 02:00:29 +0000527
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000528 attrs = attrs_wo_objs(A)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000529 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
530 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
531 self.assertIn(('p', 'property', A), attrs, 'missing property')
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000532 self.assertIn(('m', 'method', A), attrs,
533 'missing plain method: %r' % attrs)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000534 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
535 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Tim Peters13b49d32001-09-23 02:00:29 +0000536
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000537 class B(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000538
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000539 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000540
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000541 attrs = attrs_wo_objs(B)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000542 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
543 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
544 self.assertIn(('p', 'property', A), attrs, 'missing property')
545 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
546 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
547 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Tim Peters13b49d32001-09-23 02:00:29 +0000548
549
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000550 class C(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000551
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000552 def m(self): pass
553 def c(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000554
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000555 attrs = attrs_wo_objs(C)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000556 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
557 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
558 self.assertIn(('p', 'property', A), attrs, 'missing property')
559 self.assertIn(('m', 'method', C), attrs, 'missing plain method')
560 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
561 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Tim Peters13b49d32001-09-23 02:00:29 +0000562
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000563 class D(B, C):
Tim Peters13b49d32001-09-23 02:00:29 +0000564
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000565 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000566
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000567 attrs = attrs_wo_objs(D)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000568 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
569 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
570 self.assertIn(('p', 'property', A), attrs, 'missing property')
571 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
572 self.assertIn(('m1', 'method', D), attrs, 'missing plain method')
573 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Jeremy Hyltonc4bf5ed2003-06-27 18:43:12 +0000574
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000575class TestGetcallargsFunctions(unittest.TestCase):
576
577 def assertEqualCallArgs(self, func, call_params_string, locs=None):
578 locs = dict(locs or {}, func=func)
579 r1 = eval('func(%s)' % call_params_string, None, locs)
580 r2 = eval('inspect.getcallargs(func, %s)' % call_params_string, None,
581 locs)
582 self.assertEqual(r1, r2)
583
584 def assertEqualException(self, func, call_param_string, locs=None):
585 locs = dict(locs or {}, func=func)
586 try:
587 eval('func(%s)' % call_param_string, None, locs)
588 except Exception as e:
589 ex1 = e
590 else:
591 self.fail('Exception not raised')
592 try:
593 eval('inspect.getcallargs(func, %s)' % call_param_string, None,
594 locs)
595 except Exception as e:
596 ex2 = e
597 else:
598 self.fail('Exception not raised')
599 self.assertIs(type(ex1), type(ex2))
600 self.assertEqual(str(ex1), str(ex2))
601 del ex1, ex2
602
603 def makeCallable(self, signature):
604 """Create a function that returns its locals()"""
605 code = "lambda %s: locals()"
606 return eval(code % signature)
607
608 def test_plain(self):
609 f = self.makeCallable('a, b=1')
610 self.assertEqualCallArgs(f, '2')
611 self.assertEqualCallArgs(f, '2, 3')
612 self.assertEqualCallArgs(f, 'a=2')
613 self.assertEqualCallArgs(f, 'b=3, a=2')
614 self.assertEqualCallArgs(f, '2, b=3')
615 # expand *iterable / **mapping
616 self.assertEqualCallArgs(f, '*(2,)')
617 self.assertEqualCallArgs(f, '*[2]')
618 self.assertEqualCallArgs(f, '*(2, 3)')
619 self.assertEqualCallArgs(f, '*[2, 3]')
620 self.assertEqualCallArgs(f, '**{"a":2}')
621 self.assertEqualCallArgs(f, 'b=3, **{"a":2}')
622 self.assertEqualCallArgs(f, '2, **{"b":3}')
623 self.assertEqualCallArgs(f, '**{"b":3, "a":2}')
624 # expand UserList / UserDict
625 self.assertEqualCallArgs(f, '*collections.UserList([2])')
626 self.assertEqualCallArgs(f, '*collections.UserList([2, 3])')
627 self.assertEqualCallArgs(f, '**collections.UserDict(a=2)')
628 self.assertEqualCallArgs(f, '2, **collections.UserDict(b=3)')
629 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3)')
630
631 def test_varargs(self):
632 f = self.makeCallable('a, b=1, *c')
633 self.assertEqualCallArgs(f, '2')
634 self.assertEqualCallArgs(f, '2, 3')
635 self.assertEqualCallArgs(f, '2, 3, 4')
636 self.assertEqualCallArgs(f, '*(2,3,4)')
637 self.assertEqualCallArgs(f, '2, *[3,4]')
638 self.assertEqualCallArgs(f, '2, 3, *collections.UserList([4])')
639
640 def test_varkw(self):
641 f = self.makeCallable('a, b=1, **c')
642 self.assertEqualCallArgs(f, 'a=2')
643 self.assertEqualCallArgs(f, '2, b=3, c=4')
644 self.assertEqualCallArgs(f, 'b=3, a=2, c=4')
645 self.assertEqualCallArgs(f, 'c=4, **{"a":2, "b":3}')
646 self.assertEqualCallArgs(f, '2, c=4, **{"b":3}')
647 self.assertEqualCallArgs(f, 'b=2, **{"a":3, "c":4}')
648 self.assertEqualCallArgs(f, '**collections.UserDict(a=2, b=3, c=4)')
649 self.assertEqualCallArgs(f, '2, c=4, **collections.UserDict(b=3)')
650 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3, c=4)')
651
Benjamin Peterson6a2638b2011-03-28 17:32:31 -0500652 def test_varkw_only(self):
653 # issue11256:
654 f = self.makeCallable('**c')
655 self.assertEqualCallArgs(f, '')
656 self.assertEqualCallArgs(f, 'a=1')
657 self.assertEqualCallArgs(f, 'a=1, b=2')
658 self.assertEqualCallArgs(f, 'c=3, **{"a": 1, "b": 2}')
659 self.assertEqualCallArgs(f, '**collections.UserDict(a=1, b=2)')
660 self.assertEqualCallArgs(f, 'c=3, **collections.UserDict(a=1, b=2)')
661
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000662 def test_keyword_only(self):
663 f = self.makeCallable('a=3, *, c, d=2')
664 self.assertEqualCallArgs(f, 'c=3')
665 self.assertEqualCallArgs(f, 'c=3, a=3')
666 self.assertEqualCallArgs(f, 'a=2, c=4')
667 self.assertEqualCallArgs(f, '4, c=4')
668 self.assertEqualException(f, '')
669 self.assertEqualException(f, '3')
670 self.assertEqualException(f, 'a=3')
671 self.assertEqualException(f, 'd=4')
672
Benjamin Peterson6a2638b2011-03-28 17:32:31 -0500673 f = self.makeCallable('*, c, d=2')
674 self.assertEqualCallArgs(f, 'c=3')
675 self.assertEqualCallArgs(f, 'c=3, d=4')
676 self.assertEqualCallArgs(f, 'd=4, c=3')
677
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000678 def test_multiple_features(self):
679 f = self.makeCallable('a, b=2, *f, **g')
680 self.assertEqualCallArgs(f, '2, 3, 7')
681 self.assertEqualCallArgs(f, '2, 3, x=8')
682 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
683 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9')
684 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9')
685 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
686 '[2, 3, (4,[5,6])]), **{"y":9, "z":10}')
687 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
688 '(4,[5,6])]), **collections.UserDict('
689 'y=9, z=10)')
690
Benjamin Peterson6a2638b2011-03-28 17:32:31 -0500691 f = self.makeCallable('a, b=2, *f, x, y=99, **g')
692 self.assertEqualCallArgs(f, '2, 3, x=8')
693 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
694 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9, z=10')
695 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9, z=10')
696 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
697 '[2, 3, (4,[5,6])]), q=0, **{"y":9, "z":10}')
698 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
699 '(4,[5,6])]), q=0, **collections.UserDict('
700 'y=9, z=10)')
701
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000702 def test_errors(self):
703 f0 = self.makeCallable('')
704 f1 = self.makeCallable('a, b')
705 f2 = self.makeCallable('a, b=1')
706 # f0 takes no arguments
707 self.assertEqualException(f0, '1')
708 self.assertEqualException(f0, 'x=1')
709 self.assertEqualException(f0, '1,x=1')
710 # f1 takes exactly 2 arguments
711 self.assertEqualException(f1, '')
712 self.assertEqualException(f1, '1')
713 self.assertEqualException(f1, 'a=2')
714 self.assertEqualException(f1, 'b=3')
715 # f2 takes at least 1 argument
716 self.assertEqualException(f2, '')
717 self.assertEqualException(f2, 'b=3')
718 for f in f1, f2:
719 # f1/f2 takes exactly/at most 2 arguments
720 self.assertEqualException(f, '2, 3, 4')
721 self.assertEqualException(f, '1, 2, 3, a=1')
722 self.assertEqualException(f, '2, 3, 4, c=5')
723 self.assertEqualException(f, '2, 3, 4, a=1, c=5')
724 # f got an unexpected keyword argument
725 self.assertEqualException(f, 'c=2')
726 self.assertEqualException(f, '2, c=3')
727 self.assertEqualException(f, '2, 3, c=4')
728 self.assertEqualException(f, '2, c=4, b=3')
729 self.assertEqualException(f, '**{u"\u03c0\u03b9": 4}')
730 # f got multiple values for keyword argument
731 self.assertEqualException(f, '1, a=2')
732 self.assertEqualException(f, '1, **{"a":2}')
733 self.assertEqualException(f, '1, 2, b=3')
734 # XXX: Python inconsistency
735 # - for functions and bound methods: unexpected keyword 'c'
736 # - for unbound methods: multiple values for keyword 'a'
737 #self.assertEqualException(f, '1, c=3, a=2')
Benjamin Peterson6a2638b2011-03-28 17:32:31 -0500738 # issue11256:
739 f3 = self.makeCallable('**c')
740 self.assertEqualException(f3, '1, 2')
741 self.assertEqualException(f3, '1, 2, a=1, b=2')
742 f4 = self.makeCallable('*, a, b=0')
743 self.assertEqualException(f3, '1, 2')
744 self.assertEqualException(f3, '1, 2, a=1, b=2')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000745
746class TestGetcallargsMethods(TestGetcallargsFunctions):
747
748 def setUp(self):
749 class Foo(object):
750 pass
751 self.cls = Foo
752 self.inst = Foo()
753
754 def makeCallable(self, signature):
755 assert 'self' not in signature
756 mk = super(TestGetcallargsMethods, self).makeCallable
757 self.cls.method = mk('self, ' + signature)
758 return self.inst.method
759
760class TestGetcallargsUnboundMethods(TestGetcallargsMethods):
761
762 def makeCallable(self, signature):
763 super(TestGetcallargsUnboundMethods, self).makeCallable(signature)
764 return self.cls.method
765
766 def assertEqualCallArgs(self, func, call_params_string, locs=None):
767 return super(TestGetcallargsUnboundMethods, self).assertEqualCallArgs(
768 *self._getAssertEqualParams(func, call_params_string, locs))
769
770 def assertEqualException(self, func, call_params_string, locs=None):
771 return super(TestGetcallargsUnboundMethods, self).assertEqualException(
772 *self._getAssertEqualParams(func, call_params_string, locs))
773
774 def _getAssertEqualParams(self, func, call_params_string, locs=None):
775 assert 'inst' not in call_params_string
776 locs = dict(locs or {}, inst=self.inst)
777 return (func, 'inst,' + call_params_string, locs)
778
Michael Foord95fc51d2010-11-20 15:07:30 +0000779
780class TestGetattrStatic(unittest.TestCase):
781
782 def test_basic(self):
783 class Thing(object):
784 x = object()
785
786 thing = Thing()
787 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
788 self.assertEqual(inspect.getattr_static(thing, 'x', None), Thing.x)
789 with self.assertRaises(AttributeError):
790 inspect.getattr_static(thing, 'y')
791
792 self.assertEqual(inspect.getattr_static(thing, 'y', 3), 3)
793
794 def test_inherited(self):
795 class Thing(object):
796 x = object()
797 class OtherThing(Thing):
798 pass
799
800 something = OtherThing()
801 self.assertEqual(inspect.getattr_static(something, 'x'), Thing.x)
802
803 def test_instance_attr(self):
804 class Thing(object):
805 x = 2
806 def __init__(self, x):
807 self.x = x
808 thing = Thing(3)
809 self.assertEqual(inspect.getattr_static(thing, 'x'), 3)
810 del thing.x
811 self.assertEqual(inspect.getattr_static(thing, 'x'), 2)
812
813 def test_property(self):
814 class Thing(object):
815 @property
816 def x(self):
817 raise AttributeError("I'm pretending not to exist")
818 thing = Thing()
819 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
820
Ezio Melotti75cbd732011-04-28 00:59:29 +0300821 def test_descriptor_raises_AttributeError(self):
Michael Foord95fc51d2010-11-20 15:07:30 +0000822 class descriptor(object):
823 def __get__(*_):
824 raise AttributeError("I'm pretending not to exist")
825 desc = descriptor()
826 class Thing(object):
827 x = desc
828 thing = Thing()
829 self.assertEqual(inspect.getattr_static(thing, 'x'), desc)
830
831 def test_classAttribute(self):
832 class Thing(object):
833 x = object()
834
835 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.x)
836
837 def test_inherited_classattribute(self):
838 class Thing(object):
839 x = object()
840 class OtherThing(Thing):
841 pass
842
843 self.assertEqual(inspect.getattr_static(OtherThing, 'x'), Thing.x)
844
845 def test_slots(self):
846 class Thing(object):
847 y = 'bar'
848 __slots__ = ['x']
849 def __init__(self):
850 self.x = 'foo'
851 thing = Thing()
852 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
853 self.assertEqual(inspect.getattr_static(thing, 'y'), 'bar')
854
855 del thing.x
856 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
857
858 def test_metaclass(self):
859 class meta(type):
860 attr = 'foo'
861 class Thing(object, metaclass=meta):
862 pass
863 self.assertEqual(inspect.getattr_static(Thing, 'attr'), 'foo')
864
865 class sub(meta):
866 pass
867 class OtherThing(object, metaclass=sub):
868 x = 3
869 self.assertEqual(inspect.getattr_static(OtherThing, 'attr'), 'foo')
870
871 class OtherOtherThing(OtherThing):
872 pass
873 # this test is odd, but it was added as it exposed a bug
874 self.assertEqual(inspect.getattr_static(OtherOtherThing, 'x'), 3)
875
876 def test_no_dict_no_slots(self):
877 self.assertEqual(inspect.getattr_static(1, 'foo', None), None)
878 self.assertNotEqual(inspect.getattr_static('foo', 'lower'), None)
879
880 def test_no_dict_no_slots_instance_member(self):
881 # returns descriptor
882 with open(__file__) as handle:
883 self.assertEqual(inspect.getattr_static(handle, 'name'), type(handle).name)
884
885 def test_inherited_slots(self):
886 # returns descriptor
887 class Thing(object):
888 __slots__ = ['x']
889 def __init__(self):
890 self.x = 'foo'
891
892 class OtherThing(Thing):
893 pass
894 # it would be nice if this worked...
895 # we get the descriptor instead of the instance attribute
896 self.assertEqual(inspect.getattr_static(OtherThing(), 'x'), Thing.x)
897
898 def test_descriptor(self):
899 class descriptor(object):
900 def __get__(self, instance, owner):
901 return 3
902 class Foo(object):
903 d = descriptor()
904
905 foo = Foo()
906
907 # for a non data descriptor we return the instance attribute
908 foo.__dict__['d'] = 1
909 self.assertEqual(inspect.getattr_static(foo, 'd'), 1)
910
911 # if the descriptor is a data-desciptor we should return the
912 # descriptor
913 descriptor.__set__ = lambda s, i, v: None
914 self.assertEqual(inspect.getattr_static(foo, 'd'), Foo.__dict__['d'])
915
916
917 def test_metaclass_with_descriptor(self):
918 class descriptor(object):
919 def __get__(self, instance, owner):
920 return 3
921 class meta(type):
922 d = descriptor()
923 class Thing(object, metaclass=meta):
924 pass
925 self.assertEqual(inspect.getattr_static(Thing, 'd'), meta.__dict__['d'])
926
927
Michael Foordcc7ebb82010-11-20 16:20:16 +0000928 def test_class_as_property(self):
929 class Base(object):
930 foo = 3
931
932 class Something(Base):
Michael Foord35184ed2010-11-20 16:58:30 +0000933 executed = False
Michael Foordcc7ebb82010-11-20 16:20:16 +0000934 @property
935 def __class__(self):
Michael Foord35184ed2010-11-20 16:58:30 +0000936 self.executed = True
Michael Foordcc7ebb82010-11-20 16:20:16 +0000937 return object
938
Michael Foord35184ed2010-11-20 16:58:30 +0000939 instance = Something()
940 self.assertEqual(inspect.getattr_static(instance, 'foo'), 3)
941 self.assertFalse(instance.executed)
Michael Foordcc7ebb82010-11-20 16:20:16 +0000942 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
943
Michael Foorde5162652010-11-20 16:40:44 +0000944 def test_mro_as_property(self):
945 class Meta(type):
946 @property
947 def __mro__(self):
948 return (object,)
949
950 class Base(object):
951 foo = 3
952
953 class Something(Base, metaclass=Meta):
954 pass
955
956 self.assertEqual(inspect.getattr_static(Something(), 'foo'), 3)
957 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
958
Michael Foorddcebe0f2011-03-15 19:20:44 -0400959 def test_dict_as_property(self):
960 test = self
961 test.called = False
962
963 class Foo(dict):
964 a = 3
965 @property
966 def __dict__(self):
967 test.called = True
968 return {}
969
970 foo = Foo()
971 foo.a = 4
972 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
973 self.assertFalse(test.called)
974
975 def test_custom_object_dict(self):
976 test = self
977 test.called = False
978
979 class Custom(dict):
980 def get(self, key, default=None):
981 test.called = True
982 super().get(key, default)
983
984 class Foo(object):
985 a = 3
986 foo = Foo()
987 foo.__dict__ = Custom()
988 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
989 self.assertFalse(test.called)
990
991 def test_metaclass_dict_as_property(self):
992 class Meta(type):
993 @property
994 def __dict__(self):
995 self.executed = True
996
997 class Thing(metaclass=Meta):
998 executed = False
999
1000 def __init__(self):
1001 self.spam = 42
1002
1003 instance = Thing()
1004 self.assertEqual(inspect.getattr_static(instance, "spam"), 42)
1005 self.assertFalse(Thing.executed)
Michael Foorde5162652010-11-20 16:40:44 +00001006
Nick Coghlane0f04652010-11-21 03:44:04 +00001007class TestGetGeneratorState(unittest.TestCase):
1008
1009 def setUp(self):
1010 def number_generator():
1011 for number in range(5):
1012 yield number
1013 self.generator = number_generator()
1014
1015 def _generatorstate(self):
1016 return inspect.getgeneratorstate(self.generator)
1017
1018 def test_created(self):
1019 self.assertEqual(self._generatorstate(), inspect.GEN_CREATED)
1020
1021 def test_suspended(self):
1022 next(self.generator)
1023 self.assertEqual(self._generatorstate(), inspect.GEN_SUSPENDED)
1024
1025 def test_closed_after_exhaustion(self):
1026 for i in self.generator:
1027 pass
1028 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1029
1030 def test_closed_after_immediate_exception(self):
1031 with self.assertRaises(RuntimeError):
1032 self.generator.throw(RuntimeError)
1033 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1034
1035 def test_running(self):
1036 # As mentioned on issue #10220, checking for the RUNNING state only
1037 # makes sense inside the generator itself.
1038 # The following generator checks for this by using the closure's
1039 # reference to self and the generator state checking helper method
1040 def running_check_generator():
1041 for number in range(5):
1042 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1043 yield number
1044 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1045 self.generator = running_check_generator()
1046 # Running up to the first yield
1047 next(self.generator)
1048 # Running after the first yield
1049 next(self.generator)
1050
Nick Coghlan7921b9f2010-11-30 06:36:04 +00001051 def test_easy_debugging(self):
1052 # repr() and str() of a generator state should contain the state name
1053 names = 'GEN_CREATED GEN_RUNNING GEN_SUSPENDED GEN_CLOSED'.split()
1054 for name in names:
1055 state = getattr(inspect, name)
1056 self.assertIn(name, repr(state))
1057 self.assertIn(name, str(state))
1058
Nick Coghlane0f04652010-11-21 03:44:04 +00001059
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001060def test_main():
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001061 run_unittest(
1062 TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBuggyCases,
1063 TestInterpreterStack, TestClassesAndFunctions, TestPredicates,
1064 TestGetcallargsFunctions, TestGetcallargsMethods,
Alexander Belopolskyf546e702010-12-02 00:10:11 +00001065 TestGetcallargsUnboundMethods, TestGetattrStatic, TestGetGeneratorState,
1066 TestNoEOL
Michael Foord95fc51d2010-11-20 15:07:30 +00001067 )
Martin v. Löwis893ffa42003-10-31 15:35:53 +00001068
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001069if __name__ == "__main__":
1070 test_main()