blob: d840bbe244af5b7a10bc617eced4ecfbb82a904b [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:
Ezio Melottid8b509b2011-09-28 17:37:55 +0300307 return source.splitlines(keepends=True)
Benjamin Peterson9620cc02011-06-11 15:53:11 -0500308 else:
309 return getlines(filename, module_globals)
310 linecache.getlines = monkey
311 try:
312 ns = {}
313 exec(compile(source, fn, 'single'), ns)
314 inspect.getsource(ns["x"])
315 finally:
316 linecache.getlines = getlines
317
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000318class TestDecorators(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000319 fodderModule = mod2
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000320
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000321 def test_wrapped_decorator(self):
Christian Heimes09aaa882008-02-23 15:01:06 +0000322 self.assertSourceEqual(mod2.wrapped, 14, 17)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000323
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000324 def test_replacing_decorator(self):
325 self.assertSourceEqual(mod2.gone, 9, 10)
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000326
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000327class TestOneliners(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000328 fodderModule = mod2
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000329 def test_oneline_lambda(self):
330 # Test inspect.getsource with a one-line lambda function.
331 self.assertSourceEqual(mod2.oll, 25, 25)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000332
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000333 def test_threeline_lambda(self):
334 # Test inspect.getsource with a three-line lambda function,
335 # where the second and third lines are _not_ indented.
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000336 self.assertSourceEqual(mod2.tll, 28, 30)
337
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000338 def test_twoline_indented_lambda(self):
339 # Test inspect.getsource with a two-line lambda function,
340 # where the second line _is_ indented.
341 self.assertSourceEqual(mod2.tlli, 33, 34)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000342
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000343 def test_onelinefunc(self):
344 # Test inspect.getsource with a regular one-line function.
345 self.assertSourceEqual(mod2.onelinefunc, 37, 37)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000346
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000347 def test_manyargs(self):
348 # Test inspect.getsource with a regular function where
349 # the arguments are on two lines and _not_ indented and
350 # the body on the second line with the last arguments.
351 self.assertSourceEqual(mod2.manyargs, 40, 41)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000352
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000353 def test_twolinefunc(self):
354 # Test inspect.getsource with a regular function where
355 # the body is on two lines, following the argument list and
356 # continued on the next line by a \\.
357 self.assertSourceEqual(mod2.twolinefunc, 44, 45)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000358
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000359 def test_lambda_in_list(self):
360 # Test inspect.getsource with a one-line lambda function
361 # defined in a list, indented.
362 self.assertSourceEqual(mod2.a[1], 49, 49)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000363
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000364 def test_anonymous(self):
365 # Test inspect.getsource with a lambda function defined
366 # as argument to another function.
367 self.assertSourceEqual(mod2.anonymous, 55, 55)
368
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000369class TestBuggyCases(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000370 fodderModule = mod2
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000371
372 def test_with_comment(self):
373 self.assertSourceEqual(mod2.with_comment, 58, 59)
374
375 def test_multiline_sig(self):
376 self.assertSourceEqual(mod2.multiline_sig[0], 63, 64)
377
Armin Rigodd5c0232005-09-25 11:45:45 +0000378 def test_nested_class(self):
379 self.assertSourceEqual(mod2.func69().func71, 71, 72)
380
381 def test_one_liner_followed_by_non_name(self):
382 self.assertSourceEqual(mod2.func77, 77, 77)
383
384 def test_one_liner_dedent_non_name(self):
385 self.assertSourceEqual(mod2.cls82.func83, 83, 83)
386
387 def test_with_comment_instead_of_docstring(self):
388 self.assertSourceEqual(mod2.func88, 88, 90)
389
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000390 def test_method_in_dynamic_class(self):
391 self.assertSourceEqual(mod2.method_in_dynamic_class, 95, 97)
392
R. David Murrayb5655772009-05-14 16:17:50 +0000393 @unittest.skipIf(
394 not hasattr(unicodedata, '__file__') or
395 unicodedata.__file__[-4:] in (".pyc", ".pyo"),
396 "unicodedata is not an external binary module")
R. David Murray74b89242009-05-13 17:33:03 +0000397 def test_findsource_binary(self):
R. David Murrayb5655772009-05-14 16:17:50 +0000398 self.assertRaises(IOError, inspect.getsource, unicodedata)
399 self.assertRaises(IOError, inspect.findsource, unicodedata)
R. David Murray74b89242009-05-13 17:33:03 +0000400
R. David Murraya1b37402010-06-17 02:04:29 +0000401 def test_findsource_code_in_linecache(self):
402 lines = ["x=1"]
403 co = compile(lines[0], "_dynamically_created_file", "exec")
404 self.assertRaises(IOError, inspect.findsource, co)
405 self.assertRaises(IOError, inspect.getsource, co)
406 linecache.cache[co.co_filename] = (1, None, lines, co.co_filename)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000407 self.assertEqual(inspect.findsource(co), (lines,0))
408 self.assertEqual(inspect.getsource(co), lines[0])
R. David Murraya1b37402010-06-17 02:04:29 +0000409
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000410class TestNoEOL(GetSourceBase):
411 def __init__(self, *args, **kwargs):
412 self.tempdir = TESTFN + '_dir'
413 os.mkdir(self.tempdir)
414 with open(os.path.join(self.tempdir,
415 'inspect_fodder3%spy' % os.extsep), 'w') as f:
416 f.write("class X:\n pass # No EOL")
417 with DirsOnSysPath(self.tempdir):
418 import inspect_fodder3 as mod3
419 self.fodderModule = mod3
420 GetSourceBase.__init__(self, *args, **kwargs)
421
422 def tearDown(self):
423 shutil.rmtree(self.tempdir)
424
425 def test_class(self):
426 self.assertSourceEqual(self.fodderModule.X, 1, 2)
427
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100428
429class _BrokenDataDescriptor(object):
430 """
431 A broken data descriptor. See bug #1785.
432 """
433 def __get__(*args):
434 raise AssertionError("should not __get__ data descriptors")
435
436 def __set__(*args):
437 raise RuntimeError
438
439 def __getattr__(*args):
440 raise AssertionError("should not __getattr__ data descriptors")
441
442
443class _BrokenMethodDescriptor(object):
444 """
445 A broken method descriptor. See bug #1785.
446 """
447 def __get__(*args):
448 raise AssertionError("should not __get__ method descriptors")
449
450 def __getattr__(*args):
451 raise AssertionError("should not __getattr__ method descriptors")
452
453
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000454# Helper for testing classify_class_attrs.
Tim Peters13b49d32001-09-23 02:00:29 +0000455def attrs_wo_objs(cls):
456 return [t[:3] for t in inspect.classify_class_attrs(cls)]
457
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100458
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000459class TestClassesAndFunctions(unittest.TestCase):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000460 def test_newstyle_mro(self):
461 # The same w/ new-class MRO.
462 class A(object): pass
463 class B(A): pass
464 class C(A): pass
465 class D(B, C): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000466
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000467 expected = (D, B, C, A, object)
468 got = inspect.getmro(D)
469 self.assertEqual(expected, got)
Tim Peters13b49d32001-09-23 02:00:29 +0000470
Christian Heimes3795b532007-11-08 13:48:53 +0000471 def assertArgSpecEquals(self, routine, args_e, varargs_e=None,
472 varkw_e=None, defaults_e=None, formatted=None):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000473 args, varargs, varkw, defaults = inspect.getargspec(routine)
474 self.assertEqual(args, args_e)
475 self.assertEqual(varargs, varargs_e)
476 self.assertEqual(varkw, varkw_e)
477 self.assertEqual(defaults, defaults_e)
478 if formatted is not None:
479 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults),
480 formatted)
Tim Peters13b49d32001-09-23 02:00:29 +0000481
Christian Heimes3795b532007-11-08 13:48:53 +0000482 def assertFullArgSpecEquals(self, routine, args_e, varargs_e=None,
483 varkw_e=None, defaults_e=None,
484 kwonlyargs_e=[], kwonlydefaults_e=None,
485 ann_e={}, formatted=None):
486 args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \
487 inspect.getfullargspec(routine)
488 self.assertEqual(args, args_e)
489 self.assertEqual(varargs, varargs_e)
490 self.assertEqual(varkw, varkw_e)
491 self.assertEqual(defaults, defaults_e)
492 self.assertEqual(kwonlyargs, kwonlyargs_e)
493 self.assertEqual(kwonlydefaults, kwonlydefaults_e)
494 self.assertEqual(ann, ann_e)
495 if formatted is not None:
496 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults,
497 kwonlyargs, kwonlydefaults, ann),
498 formatted)
499
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000500 def test_getargspec(self):
Christian Heimes3795b532007-11-08 13:48:53 +0000501 self.assertArgSpecEquals(mod.eggs, ['x', 'y'], formatted='(x, y)')
Tim Peters13b49d32001-09-23 02:00:29 +0000502
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000503 self.assertArgSpecEquals(mod.spam,
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000504 ['a', 'b', 'c', 'd', 'e', 'f'],
505 'g', 'h', (3, 4, 5),
506 '(a, b, c, d=3, e=4, f=5, *g, **h)')
Tim Peters13b49d32001-09-23 02:00:29 +0000507
Christian Heimes3795b532007-11-08 13:48:53 +0000508 self.assertRaises(ValueError, self.assertArgSpecEquals,
509 mod2.keyworded, [])
510
511 self.assertRaises(ValueError, self.assertArgSpecEquals,
512 mod2.annotated, [])
Benjamin Peterson9953a8d2009-01-17 04:15:01 +0000513 self.assertRaises(ValueError, self.assertArgSpecEquals,
514 mod2.keyword_only_arg, [])
515
Christian Heimes3795b532007-11-08 13:48:53 +0000516
517 def test_getfullargspec(self):
518 self.assertFullArgSpecEquals(mod2.keyworded, [], varargs_e='arg1',
519 kwonlyargs_e=['arg2'],
520 kwonlydefaults_e={'arg2':1},
521 formatted='(*arg1, arg2=1)')
522
523 self.assertFullArgSpecEquals(mod2.annotated, ['arg1'],
Christian Heimesc9543e42007-11-28 08:28:28 +0000524 ann_e={'arg1' : list},
Christian Heimes3795b532007-11-08 13:48:53 +0000525 formatted='(arg1: list)')
Benjamin Peterson9953a8d2009-01-17 04:15:01 +0000526 self.assertFullArgSpecEquals(mod2.keyword_only_arg, [],
527 kwonlyargs_e=['arg'],
528 formatted='(*, arg)')
529
Christian Heimes3795b532007-11-08 13:48:53 +0000530
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000531 def test_getargspec_method(self):
532 class A(object):
533 def m(self):
534 pass
535 self.assertArgSpecEquals(A.m, ['self'])
Tim Peters13b49d32001-09-23 02:00:29 +0000536
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000537 def test_classify_newstyle(self):
538 class A(object):
Tim Peters13b49d32001-09-23 02:00:29 +0000539
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000540 def s(): pass
541 s = staticmethod(s)
Tim Peters13b49d32001-09-23 02:00:29 +0000542
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000543 def c(cls): pass
544 c = classmethod(c)
Tim Peters13b49d32001-09-23 02:00:29 +0000545
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000546 def getp(self): pass
547 p = property(getp)
Tim Peters13b49d32001-09-23 02:00:29 +0000548
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000549 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000550
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000551 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000552
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000553 datablob = '1'
Tim Peters13b49d32001-09-23 02:00:29 +0000554
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100555 dd = _BrokenDataDescriptor()
556 md = _BrokenMethodDescriptor()
557
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000558 attrs = attrs_wo_objs(A)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000559 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
560 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
561 self.assertIn(('p', 'property', A), attrs, 'missing property')
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000562 self.assertIn(('m', 'method', A), attrs,
563 'missing plain method: %r' % attrs)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000564 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
565 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100566 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
567 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000568
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000569 class B(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000570
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000571 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000572
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000573 attrs = attrs_wo_objs(B)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000574 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
575 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
576 self.assertIn(('p', 'property', A), attrs, 'missing property')
577 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
578 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
579 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100580 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
581 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000582
583
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000584 class C(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000585
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000586 def m(self): pass
587 def c(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000588
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000589 attrs = attrs_wo_objs(C)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000590 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
591 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
592 self.assertIn(('p', 'property', A), attrs, 'missing property')
593 self.assertIn(('m', 'method', C), attrs, 'missing plain method')
594 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
595 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100596 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
597 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000598
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000599 class D(B, C):
Tim Peters13b49d32001-09-23 02:00:29 +0000600
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000601 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000602
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000603 attrs = attrs_wo_objs(D)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000604 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
605 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
606 self.assertIn(('p', 'property', A), attrs, 'missing property')
607 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
608 self.assertIn(('m1', 'method', D), attrs, 'missing plain method')
609 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100610 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
611 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
612
613 def test_classify_builtin_types(self):
614 # Simple sanity check that all built-in types can have their
615 # attributes classified.
616 for name in dir(__builtins__):
617 builtin = getattr(__builtins__, name)
618 if isinstance(builtin, type):
619 inspect.classify_class_attrs(builtin)
620
621 def test_getmembers_descriptors(self):
622 class A(object):
623 dd = _BrokenDataDescriptor()
624 md = _BrokenMethodDescriptor()
625
626 def pred_wrapper(pred):
627 # A quick'n'dirty way to discard standard attributes of new-style
628 # classes.
629 class Empty(object):
630 pass
631 def wrapped(x):
632 if '__name__' in dir(x) and hasattr(Empty, x.__name__):
633 return False
634 return pred(x)
635 return wrapped
636
637 ismethoddescriptor = pred_wrapper(inspect.ismethoddescriptor)
638 isdatadescriptor = pred_wrapper(inspect.isdatadescriptor)
639
640 self.assertEqual(inspect.getmembers(A, ismethoddescriptor),
641 [('md', A.__dict__['md'])])
642 self.assertEqual(inspect.getmembers(A, isdatadescriptor),
643 [('dd', A.__dict__['dd'])])
644
645 class B(A):
646 pass
647
648 self.assertEqual(inspect.getmembers(B, ismethoddescriptor),
649 [('md', A.__dict__['md'])])
650 self.assertEqual(inspect.getmembers(B, isdatadescriptor),
651 [('dd', A.__dict__['dd'])])
652
Antoine Pitrou0c603812012-01-18 17:40:18 +0100653 def test_getmembers_method(self):
654 class B:
655 def f(self):
656 pass
657
658 self.assertIn(('f', B.f), inspect.getmembers(B))
659 self.assertNotIn(('f', B.f), inspect.getmembers(B, inspect.ismethod))
660 b = B()
661 self.assertIn(('f', b.f), inspect.getmembers(b))
662 self.assertIn(('f', b.f), inspect.getmembers(b, inspect.ismethod))
663
Jeremy Hyltonc4bf5ed2003-06-27 18:43:12 +0000664
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000665class TestGetcallargsFunctions(unittest.TestCase):
666
667 def assertEqualCallArgs(self, func, call_params_string, locs=None):
668 locs = dict(locs or {}, func=func)
669 r1 = eval('func(%s)' % call_params_string, None, locs)
670 r2 = eval('inspect.getcallargs(func, %s)' % call_params_string, None,
671 locs)
672 self.assertEqual(r1, r2)
673
674 def assertEqualException(self, func, call_param_string, locs=None):
675 locs = dict(locs or {}, func=func)
676 try:
677 eval('func(%s)' % call_param_string, None, locs)
678 except Exception as e:
679 ex1 = e
680 else:
681 self.fail('Exception not raised')
682 try:
683 eval('inspect.getcallargs(func, %s)' % call_param_string, None,
684 locs)
685 except Exception as e:
686 ex2 = e
687 else:
688 self.fail('Exception not raised')
689 self.assertIs(type(ex1), type(ex2))
690 self.assertEqual(str(ex1), str(ex2))
691 del ex1, ex2
692
693 def makeCallable(self, signature):
694 """Create a function that returns its locals()"""
695 code = "lambda %s: locals()"
696 return eval(code % signature)
697
698 def test_plain(self):
699 f = self.makeCallable('a, b=1')
700 self.assertEqualCallArgs(f, '2')
701 self.assertEqualCallArgs(f, '2, 3')
702 self.assertEqualCallArgs(f, 'a=2')
703 self.assertEqualCallArgs(f, 'b=3, a=2')
704 self.assertEqualCallArgs(f, '2, b=3')
705 # expand *iterable / **mapping
706 self.assertEqualCallArgs(f, '*(2,)')
707 self.assertEqualCallArgs(f, '*[2]')
708 self.assertEqualCallArgs(f, '*(2, 3)')
709 self.assertEqualCallArgs(f, '*[2, 3]')
710 self.assertEqualCallArgs(f, '**{"a":2}')
711 self.assertEqualCallArgs(f, 'b=3, **{"a":2}')
712 self.assertEqualCallArgs(f, '2, **{"b":3}')
713 self.assertEqualCallArgs(f, '**{"b":3, "a":2}')
714 # expand UserList / UserDict
715 self.assertEqualCallArgs(f, '*collections.UserList([2])')
716 self.assertEqualCallArgs(f, '*collections.UserList([2, 3])')
717 self.assertEqualCallArgs(f, '**collections.UserDict(a=2)')
718 self.assertEqualCallArgs(f, '2, **collections.UserDict(b=3)')
719 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3)')
720
721 def test_varargs(self):
722 f = self.makeCallable('a, b=1, *c')
723 self.assertEqualCallArgs(f, '2')
724 self.assertEqualCallArgs(f, '2, 3')
725 self.assertEqualCallArgs(f, '2, 3, 4')
726 self.assertEqualCallArgs(f, '*(2,3,4)')
727 self.assertEqualCallArgs(f, '2, *[3,4]')
728 self.assertEqualCallArgs(f, '2, 3, *collections.UserList([4])')
729
730 def test_varkw(self):
731 f = self.makeCallable('a, b=1, **c')
732 self.assertEqualCallArgs(f, 'a=2')
733 self.assertEqualCallArgs(f, '2, b=3, c=4')
734 self.assertEqualCallArgs(f, 'b=3, a=2, c=4')
735 self.assertEqualCallArgs(f, 'c=4, **{"a":2, "b":3}')
736 self.assertEqualCallArgs(f, '2, c=4, **{"b":3}')
737 self.assertEqualCallArgs(f, 'b=2, **{"a":3, "c":4}')
738 self.assertEqualCallArgs(f, '**collections.UserDict(a=2, b=3, c=4)')
739 self.assertEqualCallArgs(f, '2, c=4, **collections.UserDict(b=3)')
740 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3, c=4)')
741
Benjamin Peterson6a2638b2011-03-28 17:32:31 -0500742 def test_varkw_only(self):
743 # issue11256:
744 f = self.makeCallable('**c')
745 self.assertEqualCallArgs(f, '')
746 self.assertEqualCallArgs(f, 'a=1')
747 self.assertEqualCallArgs(f, 'a=1, b=2')
748 self.assertEqualCallArgs(f, 'c=3, **{"a": 1, "b": 2}')
749 self.assertEqualCallArgs(f, '**collections.UserDict(a=1, b=2)')
750 self.assertEqualCallArgs(f, 'c=3, **collections.UserDict(a=1, b=2)')
751
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000752 def test_keyword_only(self):
753 f = self.makeCallable('a=3, *, c, d=2')
754 self.assertEqualCallArgs(f, 'c=3')
755 self.assertEqualCallArgs(f, 'c=3, a=3')
756 self.assertEqualCallArgs(f, 'a=2, c=4')
757 self.assertEqualCallArgs(f, '4, c=4')
758 self.assertEqualException(f, '')
759 self.assertEqualException(f, '3')
760 self.assertEqualException(f, 'a=3')
761 self.assertEqualException(f, 'd=4')
762
Benjamin Peterson6a2638b2011-03-28 17:32:31 -0500763 f = self.makeCallable('*, c, d=2')
764 self.assertEqualCallArgs(f, 'c=3')
765 self.assertEqualCallArgs(f, 'c=3, d=4')
766 self.assertEqualCallArgs(f, 'd=4, c=3')
767
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000768 def test_multiple_features(self):
769 f = self.makeCallable('a, b=2, *f, **g')
770 self.assertEqualCallArgs(f, '2, 3, 7')
771 self.assertEqualCallArgs(f, '2, 3, x=8')
772 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
773 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9')
774 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9')
775 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
776 '[2, 3, (4,[5,6])]), **{"y":9, "z":10}')
777 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
778 '(4,[5,6])]), **collections.UserDict('
779 'y=9, z=10)')
780
Benjamin Peterson6a2638b2011-03-28 17:32:31 -0500781 f = self.makeCallable('a, b=2, *f, x, y=99, **g')
782 self.assertEqualCallArgs(f, '2, 3, x=8')
783 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
784 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9, z=10')
785 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9, z=10')
786 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
787 '[2, 3, (4,[5,6])]), q=0, **{"y":9, "z":10}')
788 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
789 '(4,[5,6])]), q=0, **collections.UserDict('
790 'y=9, z=10)')
791
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000792 def test_errors(self):
793 f0 = self.makeCallable('')
794 f1 = self.makeCallable('a, b')
795 f2 = self.makeCallable('a, b=1')
796 # f0 takes no arguments
797 self.assertEqualException(f0, '1')
798 self.assertEqualException(f0, 'x=1')
799 self.assertEqualException(f0, '1,x=1')
800 # f1 takes exactly 2 arguments
801 self.assertEqualException(f1, '')
802 self.assertEqualException(f1, '1')
803 self.assertEqualException(f1, 'a=2')
804 self.assertEqualException(f1, 'b=3')
805 # f2 takes at least 1 argument
806 self.assertEqualException(f2, '')
807 self.assertEqualException(f2, 'b=3')
808 for f in f1, f2:
809 # f1/f2 takes exactly/at most 2 arguments
810 self.assertEqualException(f, '2, 3, 4')
811 self.assertEqualException(f, '1, 2, 3, a=1')
812 self.assertEqualException(f, '2, 3, 4, c=5')
Georg Brandl178e5ea2012-02-21 00:32:36 +0100813 # XXX: success of this one depends on dict order
814 ## self.assertEqualException(f, '2, 3, 4, a=1, c=5')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000815 # f got an unexpected keyword argument
816 self.assertEqualException(f, 'c=2')
817 self.assertEqualException(f, '2, c=3')
818 self.assertEqualException(f, '2, 3, c=4')
819 self.assertEqualException(f, '2, c=4, b=3')
820 self.assertEqualException(f, '**{u"\u03c0\u03b9": 4}')
821 # f got multiple values for keyword argument
822 self.assertEqualException(f, '1, a=2')
823 self.assertEqualException(f, '1, **{"a":2}')
824 self.assertEqualException(f, '1, 2, b=3')
825 # XXX: Python inconsistency
826 # - for functions and bound methods: unexpected keyword 'c'
827 # - for unbound methods: multiple values for keyword 'a'
828 #self.assertEqualException(f, '1, c=3, a=2')
Benjamin Peterson6a2638b2011-03-28 17:32:31 -0500829 # issue11256:
830 f3 = self.makeCallable('**c')
831 self.assertEqualException(f3, '1, 2')
832 self.assertEqualException(f3, '1, 2, a=1, b=2')
833 f4 = self.makeCallable('*, a, b=0')
834 self.assertEqualException(f3, '1, 2')
835 self.assertEqualException(f3, '1, 2, a=1, b=2')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000836
837class TestGetcallargsMethods(TestGetcallargsFunctions):
838
839 def setUp(self):
840 class Foo(object):
841 pass
842 self.cls = Foo
843 self.inst = Foo()
844
845 def makeCallable(self, signature):
846 assert 'self' not in signature
847 mk = super(TestGetcallargsMethods, self).makeCallable
848 self.cls.method = mk('self, ' + signature)
849 return self.inst.method
850
851class TestGetcallargsUnboundMethods(TestGetcallargsMethods):
852
853 def makeCallable(self, signature):
854 super(TestGetcallargsUnboundMethods, self).makeCallable(signature)
855 return self.cls.method
856
857 def assertEqualCallArgs(self, func, call_params_string, locs=None):
858 return super(TestGetcallargsUnboundMethods, self).assertEqualCallArgs(
859 *self._getAssertEqualParams(func, call_params_string, locs))
860
861 def assertEqualException(self, func, call_params_string, locs=None):
862 return super(TestGetcallargsUnboundMethods, self).assertEqualException(
863 *self._getAssertEqualParams(func, call_params_string, locs))
864
865 def _getAssertEqualParams(self, func, call_params_string, locs=None):
866 assert 'inst' not in call_params_string
867 locs = dict(locs or {}, inst=self.inst)
868 return (func, 'inst,' + call_params_string, locs)
869
Michael Foord95fc51d2010-11-20 15:07:30 +0000870
871class TestGetattrStatic(unittest.TestCase):
872
873 def test_basic(self):
874 class Thing(object):
875 x = object()
876
877 thing = Thing()
878 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
879 self.assertEqual(inspect.getattr_static(thing, 'x', None), Thing.x)
880 with self.assertRaises(AttributeError):
881 inspect.getattr_static(thing, 'y')
882
883 self.assertEqual(inspect.getattr_static(thing, 'y', 3), 3)
884
885 def test_inherited(self):
886 class Thing(object):
887 x = object()
888 class OtherThing(Thing):
889 pass
890
891 something = OtherThing()
892 self.assertEqual(inspect.getattr_static(something, 'x'), Thing.x)
893
894 def test_instance_attr(self):
895 class Thing(object):
896 x = 2
897 def __init__(self, x):
898 self.x = x
899 thing = Thing(3)
900 self.assertEqual(inspect.getattr_static(thing, 'x'), 3)
901 del thing.x
902 self.assertEqual(inspect.getattr_static(thing, 'x'), 2)
903
904 def test_property(self):
905 class Thing(object):
906 @property
907 def x(self):
908 raise AttributeError("I'm pretending not to exist")
909 thing = Thing()
910 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
911
Ezio Melotti75cbd732011-04-28 00:59:29 +0300912 def test_descriptor_raises_AttributeError(self):
Michael Foord95fc51d2010-11-20 15:07:30 +0000913 class descriptor(object):
914 def __get__(*_):
915 raise AttributeError("I'm pretending not to exist")
916 desc = descriptor()
917 class Thing(object):
918 x = desc
919 thing = Thing()
920 self.assertEqual(inspect.getattr_static(thing, 'x'), desc)
921
922 def test_classAttribute(self):
923 class Thing(object):
924 x = object()
925
926 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.x)
927
928 def test_inherited_classattribute(self):
929 class Thing(object):
930 x = object()
931 class OtherThing(Thing):
932 pass
933
934 self.assertEqual(inspect.getattr_static(OtherThing, 'x'), Thing.x)
935
936 def test_slots(self):
937 class Thing(object):
938 y = 'bar'
939 __slots__ = ['x']
940 def __init__(self):
941 self.x = 'foo'
942 thing = Thing()
943 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
944 self.assertEqual(inspect.getattr_static(thing, 'y'), 'bar')
945
946 del thing.x
947 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
948
949 def test_metaclass(self):
950 class meta(type):
951 attr = 'foo'
952 class Thing(object, metaclass=meta):
953 pass
954 self.assertEqual(inspect.getattr_static(Thing, 'attr'), 'foo')
955
956 class sub(meta):
957 pass
958 class OtherThing(object, metaclass=sub):
959 x = 3
960 self.assertEqual(inspect.getattr_static(OtherThing, 'attr'), 'foo')
961
962 class OtherOtherThing(OtherThing):
963 pass
964 # this test is odd, but it was added as it exposed a bug
965 self.assertEqual(inspect.getattr_static(OtherOtherThing, 'x'), 3)
966
967 def test_no_dict_no_slots(self):
968 self.assertEqual(inspect.getattr_static(1, 'foo', None), None)
969 self.assertNotEqual(inspect.getattr_static('foo', 'lower'), None)
970
971 def test_no_dict_no_slots_instance_member(self):
972 # returns descriptor
973 with open(__file__) as handle:
974 self.assertEqual(inspect.getattr_static(handle, 'name'), type(handle).name)
975
976 def test_inherited_slots(self):
977 # returns descriptor
978 class Thing(object):
979 __slots__ = ['x']
980 def __init__(self):
981 self.x = 'foo'
982
983 class OtherThing(Thing):
984 pass
985 # it would be nice if this worked...
986 # we get the descriptor instead of the instance attribute
987 self.assertEqual(inspect.getattr_static(OtherThing(), 'x'), Thing.x)
988
989 def test_descriptor(self):
990 class descriptor(object):
991 def __get__(self, instance, owner):
992 return 3
993 class Foo(object):
994 d = descriptor()
995
996 foo = Foo()
997
998 # for a non data descriptor we return the instance attribute
999 foo.__dict__['d'] = 1
1000 self.assertEqual(inspect.getattr_static(foo, 'd'), 1)
1001
1002 # if the descriptor is a data-desciptor we should return the
1003 # descriptor
1004 descriptor.__set__ = lambda s, i, v: None
1005 self.assertEqual(inspect.getattr_static(foo, 'd'), Foo.__dict__['d'])
1006
1007
1008 def test_metaclass_with_descriptor(self):
1009 class descriptor(object):
1010 def __get__(self, instance, owner):
1011 return 3
1012 class meta(type):
1013 d = descriptor()
1014 class Thing(object, metaclass=meta):
1015 pass
1016 self.assertEqual(inspect.getattr_static(Thing, 'd'), meta.__dict__['d'])
1017
1018
Michael Foordcc7ebb82010-11-20 16:20:16 +00001019 def test_class_as_property(self):
1020 class Base(object):
1021 foo = 3
1022
1023 class Something(Base):
Michael Foord35184ed2010-11-20 16:58:30 +00001024 executed = False
Michael Foordcc7ebb82010-11-20 16:20:16 +00001025 @property
1026 def __class__(self):
Michael Foord35184ed2010-11-20 16:58:30 +00001027 self.executed = True
Michael Foordcc7ebb82010-11-20 16:20:16 +00001028 return object
1029
Michael Foord35184ed2010-11-20 16:58:30 +00001030 instance = Something()
1031 self.assertEqual(inspect.getattr_static(instance, 'foo'), 3)
1032 self.assertFalse(instance.executed)
Michael Foordcc7ebb82010-11-20 16:20:16 +00001033 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1034
Michael Foorde5162652010-11-20 16:40:44 +00001035 def test_mro_as_property(self):
1036 class Meta(type):
1037 @property
1038 def __mro__(self):
1039 return (object,)
1040
1041 class Base(object):
1042 foo = 3
1043
1044 class Something(Base, metaclass=Meta):
1045 pass
1046
1047 self.assertEqual(inspect.getattr_static(Something(), 'foo'), 3)
1048 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1049
Michael Foorddcebe0f2011-03-15 19:20:44 -04001050 def test_dict_as_property(self):
1051 test = self
1052 test.called = False
1053
1054 class Foo(dict):
1055 a = 3
1056 @property
1057 def __dict__(self):
1058 test.called = True
1059 return {}
1060
1061 foo = Foo()
1062 foo.a = 4
1063 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1064 self.assertFalse(test.called)
1065
1066 def test_custom_object_dict(self):
1067 test = self
1068 test.called = False
1069
1070 class Custom(dict):
1071 def get(self, key, default=None):
1072 test.called = True
1073 super().get(key, default)
1074
1075 class Foo(object):
1076 a = 3
1077 foo = Foo()
1078 foo.__dict__ = Custom()
1079 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1080 self.assertFalse(test.called)
1081
1082 def test_metaclass_dict_as_property(self):
1083 class Meta(type):
1084 @property
1085 def __dict__(self):
1086 self.executed = True
1087
1088 class Thing(metaclass=Meta):
1089 executed = False
1090
1091 def __init__(self):
1092 self.spam = 42
1093
1094 instance = Thing()
1095 self.assertEqual(inspect.getattr_static(instance, "spam"), 42)
1096 self.assertFalse(Thing.executed)
Michael Foorde5162652010-11-20 16:40:44 +00001097
Michael Foorda51623b2011-12-18 22:01:40 +00001098 def test_module(self):
1099 sentinel = object()
1100 self.assertIsNot(inspect.getattr_static(sys, "version", sentinel),
1101 sentinel)
1102
Michael Foord3ba95f82011-12-22 01:13:37 +00001103 def test_metaclass_with_metaclass_with_dict_as_property(self):
1104 class MetaMeta(type):
1105 @property
1106 def __dict__(self):
1107 self.executed = True
1108 return dict(spam=42)
1109
1110 class Meta(type, metaclass=MetaMeta):
1111 executed = False
1112
1113 class Thing(metaclass=Meta):
1114 pass
1115
1116 with self.assertRaises(AttributeError):
1117 inspect.getattr_static(Thing, "spam")
1118 self.assertFalse(Thing.executed)
1119
Nick Coghlane0f04652010-11-21 03:44:04 +00001120class TestGetGeneratorState(unittest.TestCase):
1121
1122 def setUp(self):
1123 def number_generator():
1124 for number in range(5):
1125 yield number
1126 self.generator = number_generator()
1127
1128 def _generatorstate(self):
1129 return inspect.getgeneratorstate(self.generator)
1130
1131 def test_created(self):
1132 self.assertEqual(self._generatorstate(), inspect.GEN_CREATED)
1133
1134 def test_suspended(self):
1135 next(self.generator)
1136 self.assertEqual(self._generatorstate(), inspect.GEN_SUSPENDED)
1137
1138 def test_closed_after_exhaustion(self):
1139 for i in self.generator:
1140 pass
1141 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1142
1143 def test_closed_after_immediate_exception(self):
1144 with self.assertRaises(RuntimeError):
1145 self.generator.throw(RuntimeError)
1146 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1147
1148 def test_running(self):
1149 # As mentioned on issue #10220, checking for the RUNNING state only
1150 # makes sense inside the generator itself.
1151 # The following generator checks for this by using the closure's
1152 # reference to self and the generator state checking helper method
1153 def running_check_generator():
1154 for number in range(5):
1155 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1156 yield number
1157 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1158 self.generator = running_check_generator()
1159 # Running up to the first yield
1160 next(self.generator)
1161 # Running after the first yield
1162 next(self.generator)
1163
Nick Coghlan7921b9f2010-11-30 06:36:04 +00001164 def test_easy_debugging(self):
1165 # repr() and str() of a generator state should contain the state name
1166 names = 'GEN_CREATED GEN_RUNNING GEN_SUSPENDED GEN_CLOSED'.split()
1167 for name in names:
1168 state = getattr(inspect, name)
1169 self.assertIn(name, repr(state))
1170 self.assertIn(name, str(state))
1171
Nick Coghlane0f04652010-11-21 03:44:04 +00001172
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001173def test_main():
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001174 run_unittest(
1175 TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBuggyCases,
1176 TestInterpreterStack, TestClassesAndFunctions, TestPredicates,
1177 TestGetcallargsFunctions, TestGetcallargsMethods,
Alexander Belopolskyf546e702010-12-02 00:10:11 +00001178 TestGetcallargsUnboundMethods, TestGetattrStatic, TestGetGeneratorState,
1179 TestNoEOL
Michael Foord95fc51d2010-11-20 15:07:30 +00001180 )
Martin v. Löwis893ffa42003-10-31 15:35:53 +00001181
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001182if __name__ == "__main__":
1183 test_main()