blob: 802e1007f816b7fb5ab0441d2a54d4c299cdfef3 [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
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000044git = mod.StupidGit()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000045
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000046class IsTestBase(unittest.TestCase):
47 predicates = set([inspect.isbuiltin, inspect.isclass, inspect.iscode,
48 inspect.isframe, inspect.isfunction, inspect.ismethod,
Christian Heimes7131fd92008-02-19 14:21:46 +000049 inspect.ismodule, inspect.istraceback,
50 inspect.isgenerator, inspect.isgeneratorfunction])
Tim Peters5a9fb3c2005-01-07 16:01:32 +000051
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000052 def istest(self, predicate, exp):
53 obj = eval(exp)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000054 self.assertTrue(predicate(obj), '%s(%s)' % (predicate.__name__, exp))
Tim Peters5a9fb3c2005-01-07 16:01:32 +000055
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000056 for other in self.predicates - set([predicate]):
Christian Heimes7131fd92008-02-19 14:21:46 +000057 if predicate == inspect.isgeneratorfunction and\
58 other == inspect.isfunction:
59 continue
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000060 self.assertFalse(other(obj), 'not %s(%s)' % (other.__name__, exp))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000061
Christian Heimes7131fd92008-02-19 14:21:46 +000062def generator_function_example(self):
63 for i in range(2):
64 yield i
65
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000066class TestPredicates(IsTestBase):
Christian Heimes227c8002008-03-03 20:34:40 +000067 def test_sixteen(self):
Guido van Rossumc1f779c2007-07-03 08:25:58 +000068 count = len([x for x in dir(inspect) if x.startswith('is')])
Christian Heimes7131fd92008-02-19 14:21:46 +000069 # This test is here for remember you to update Doc/library/inspect.rst
Christian Heimes78644762008-03-04 23:39:23 +000070 # which claims there are 16 such functions
Christian Heimes227c8002008-03-03 20:34:40 +000071 expected = 16
Thomas Wouters0e3f5912006-08-11 14:57:12 +000072 err_msg = "There are %d (not %d) is* functions" % (count, expected)
73 self.assertEqual(count, expected, err_msg)
Tim Peters5a9fb3c2005-01-07 16:01:32 +000074
Christian Heimes7131fd92008-02-19 14:21:46 +000075
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000076 def test_excluding_predicates(self):
Antoine Pitroud5a1a212012-06-17 23:18:07 +020077 global tb
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000078 self.istest(inspect.isbuiltin, 'sys.exit')
79 self.istest(inspect.isbuiltin, '[].append')
Neal Norwitz221085d2007-02-25 20:55:47 +000080 self.istest(inspect.iscode, 'mod.spam.__code__')
Antoine Pitroud5a1a212012-06-17 23:18:07 +020081 try:
82 1/0
83 except:
84 tb = sys.exc_info()[2]
85 self.istest(inspect.isframe, 'tb.tb_frame')
86 self.istest(inspect.istraceback, 'tb')
87 if hasattr(types, 'GetSetDescriptorType'):
88 self.istest(inspect.isgetsetdescriptor,
89 'type(tb.tb_frame).f_locals')
90 else:
91 self.assertFalse(inspect.isgetsetdescriptor(type(tb.tb_frame).f_locals))
92 finally:
93 # Clear traceback and all the frames and local variables hanging to it.
94 tb = None
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000095 self.istest(inspect.isfunction, 'mod.spam')
Christian Heimes4a22b5d2007-11-25 09:39:14 +000096 self.istest(inspect.isfunction, 'mod.StupidGit.abuse')
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000097 self.istest(inspect.ismethod, 'git.argue')
98 self.istest(inspect.ismodule, 'mod')
Guido van Rossum813b0e52007-05-21 18:11:34 +000099 self.istest(inspect.isdatadescriptor, 'collections.defaultdict.default_factory')
Christian Heimes7131fd92008-02-19 14:21:46 +0000100 self.istest(inspect.isgenerator, '(x for x in range(2))')
101 self.istest(inspect.isgeneratorfunction, 'generator_function_example')
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000102 if hasattr(types, 'MemberDescriptorType'):
103 self.istest(inspect.ismemberdescriptor, 'datetime.timedelta.days')
104 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000105 self.assertFalse(inspect.ismemberdescriptor(datetime.timedelta.days))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000106
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000107 def test_isroutine(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000108 self.assertTrue(inspect.isroutine(mod.spam))
109 self.assertTrue(inspect.isroutine([].count))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000110
Benjamin Petersonc4656002009-01-17 22:41:18 +0000111 def test_isclass(self):
112 self.istest(inspect.isclass, 'mod.StupidGit')
113 self.assertTrue(inspect.isclass(list))
114
115 class CustomGetattr(object):
116 def __getattr__(self, attr):
117 return None
118 self.assertFalse(inspect.isclass(CustomGetattr()))
119
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000120 def test_get_slot_members(self):
121 class C(object):
122 __slots__ = ("a", "b")
123
124 x = C()
125 x.a = 42
126 members = dict(inspect.getmembers(x))
Benjamin Peterson577473f2010-01-19 00:09:57 +0000127 self.assertIn('a', members)
128 self.assertNotIn('b', members)
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000129
Benjamin Petersona0dfa822009-11-13 02:25:08 +0000130 def test_isabstract(self):
131 from abc import ABCMeta, abstractmethod
132
133 class AbstractClassExample(metaclass=ABCMeta):
134
135 @abstractmethod
136 def foo(self):
137 pass
138
139 class ClassExample(AbstractClassExample):
140 def foo(self):
141 pass
142
143 a = ClassExample()
144
145 # Test general behaviour.
146 self.assertTrue(inspect.isabstract(AbstractClassExample))
147 self.assertFalse(inspect.isabstract(ClassExample))
148 self.assertFalse(inspect.isabstract(a))
149 self.assertFalse(inspect.isabstract(int))
150 self.assertFalse(inspect.isabstract(5))
151
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000152
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000153class TestInterpreterStack(IsTestBase):
154 def __init__(self, *args, **kwargs):
155 unittest.TestCase.__init__(self, *args, **kwargs)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000156
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000157 git.abuse(7, 8, 9)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000158
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000159 def test_abuse_done(self):
160 self.istest(inspect.istraceback, 'git.ex[2]')
161 self.istest(inspect.isframe, 'mod.fr')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000162
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000163 def test_stack(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000164 self.assertTrue(len(mod.st) >= 5)
Christian Heimesa3538eb2007-11-06 11:44:48 +0000165 self.assertEqual(revise(*mod.st[0][1:]),
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000166 (modfile, 16, 'eggs', [' st = inspect.stack()\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000167 self.assertEqual(revise(*mod.st[1][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000168 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000169 self.assertEqual(revise(*mod.st[2][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000170 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000171 self.assertEqual(revise(*mod.st[3][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000172 (modfile, 39, 'abuse', [' self.argue(a, b, c)\n'], 0))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000173
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000174 def test_trace(self):
175 self.assertEqual(len(git.tr), 3)
Florent Xiclunac8575922010-03-24 17:37:49 +0000176 self.assertEqual(revise(*git.tr[0][1:]),
177 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
178 self.assertEqual(revise(*git.tr[1][1:]),
179 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
180 self.assertEqual(revise(*git.tr[2][1:]),
181 (modfile, 18, 'eggs', [' q = y / 0\n'], 0))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000182
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000183 def test_frame(self):
184 args, varargs, varkw, locals = inspect.getargvalues(mod.fr)
185 self.assertEqual(args, ['x', 'y'])
186 self.assertEqual(varargs, None)
187 self.assertEqual(varkw, None)
188 self.assertEqual(locals, {'x': 11, 'p': 11, 'y': 14})
189 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
190 '(x=11, y=14)')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000191
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000192 def test_previous_frame(self):
193 args, varargs, varkw, locals = inspect.getargvalues(mod.fr.f_back)
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000194 self.assertEqual(args, ['a', 'b', 'c', 'd', 'e', 'f'])
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000195 self.assertEqual(varargs, 'g')
196 self.assertEqual(varkw, 'h')
197 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000198 '(a=7, b=8, c=9, d=3, e=4, f=5, *g=(), **h={})')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000199
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000200class GetSourceBase(unittest.TestCase):
201 # Subclasses must override.
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000202 fodderModule = None
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000203
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000204 def __init__(self, *args, **kwargs):
205 unittest.TestCase.__init__(self, *args, **kwargs)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000206
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000207 with open(inspect.getsourcefile(self.fodderModule)) as fp:
Philip Jenveya27c5bd2009-05-28 06:09:08 +0000208 self.source = fp.read()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000209
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000210 def sourcerange(self, top, bottom):
211 lines = self.source.split("\n")
212 return "\n".join(lines[top-1:bottom]) + "\n"
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000213
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000214 def assertSourceEqual(self, obj, top, bottom):
215 self.assertEqual(inspect.getsource(obj),
216 self.sourcerange(top, bottom))
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000217
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000218class TestRetrievingSourceCode(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000219 fodderModule = mod
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000220
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000221 def test_getclasses(self):
222 classes = inspect.getmembers(mod, inspect.isclass)
223 self.assertEqual(classes,
224 [('FesteringGob', mod.FesteringGob),
225 ('MalodorousPervert', mod.MalodorousPervert),
226 ('ParrotDroppings', mod.ParrotDroppings),
227 ('StupidGit', mod.StupidGit)])
228 tree = inspect.getclasstree([cls[1] for cls in classes], 1)
229 self.assertEqual(tree,
Thomas Wouters725af872006-04-15 09:13:19 +0000230 [(object, ()),
231 [(mod.ParrotDroppings, (object,)),
232 (mod.StupidGit, (object,)),
233 [(mod.MalodorousPervert, (mod.StupidGit,)),
234 [(mod.FesteringGob, (mod.MalodorousPervert,
235 mod.ParrotDroppings))
236 ]
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000237 ]
238 ]
239 ])
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000240
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000241 def test_getfunctions(self):
242 functions = inspect.getmembers(mod, inspect.isfunction)
243 self.assertEqual(functions, [('eggs', mod.eggs),
244 ('spam', mod.spam)])
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000245
R. David Murray378c0cf2010-02-24 01:46:21 +0000246 @unittest.skipIf(sys.flags.optimize >= 2,
247 "Docstrings are omitted with -O2 and above")
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000248 def test_getdoc(self):
249 self.assertEqual(inspect.getdoc(mod), 'A module docstring.')
250 self.assertEqual(inspect.getdoc(mod.StupidGit),
251 'A longer,\n\nindented\n\ndocstring.')
252 self.assertEqual(inspect.getdoc(git.abuse),
253 'Another\n\ndocstring\n\ncontaining\n\ntabs')
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000254
Georg Brandl0c77a822008-06-10 16:37:50 +0000255 def test_cleandoc(self):
256 self.assertEqual(inspect.cleandoc('An\n indented\n docstring.'),
257 'An\nindented\ndocstring.')
258
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000259 def test_getcomments(self):
260 self.assertEqual(inspect.getcomments(mod), '# line 1\n')
261 self.assertEqual(inspect.getcomments(mod.StupidGit), '# line 20\n')
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000262
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000263 def test_getmodule(self):
Thomas Wouters89f507f2006-12-13 04:49:30 +0000264 # Check actual module
265 self.assertEqual(inspect.getmodule(mod), mod)
266 # Check class (uses __module__ attribute)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000267 self.assertEqual(inspect.getmodule(mod.StupidGit), mod)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000268 # Check a method (no __module__ attribute, falls back to filename)
269 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
270 # Do it again (check the caching isn't broken)
271 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
272 # Check a builtin
Georg Brandl1a3284e2007-12-02 09:40:06 +0000273 self.assertEqual(inspect.getmodule(str), sys.modules["builtins"])
Thomas Wouters89f507f2006-12-13 04:49:30 +0000274 # Check filename override
275 self.assertEqual(inspect.getmodule(None, modfile), mod)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000276
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000277 def test_getsource(self):
278 self.assertSourceEqual(git.abuse, 29, 39)
279 self.assertSourceEqual(mod.StupidGit, 21, 46)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000280
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000281 def test_getsourcefile(self):
Christian Heimesa3538eb2007-11-06 11:44:48 +0000282 self.assertEqual(normcase(inspect.getsourcefile(mod.spam)), modfile)
283 self.assertEqual(normcase(inspect.getsourcefile(git.abuse)), modfile)
R. David Murraya1b37402010-06-17 02:04:29 +0000284 fn = "_non_existing_filename_used_for_sourcefile_test.py"
285 co = compile("None", fn, "exec")
R. David Murray4155f972010-06-17 13:23:18 +0000286 self.assertEqual(inspect.getsourcefile(co), None)
R. David Murraya1b37402010-06-17 02:04:29 +0000287 linecache.cache[co.co_filename] = (1, None, "None", co.co_filename)
288 self.assertEqual(normcase(inspect.getsourcefile(co)), fn)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000289
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000290 def test_getfile(self):
291 self.assertEqual(inspect.getfile(mod.StupidGit), mod.__file__)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000292
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000293 def test_getmodule_recursion(self):
Christian Heimes45f9af32007-11-27 21:50:00 +0000294 from types import ModuleType
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000295 name = '__inspect_dummy'
Christian Heimes45f9af32007-11-27 21:50:00 +0000296 m = sys.modules[name] = ModuleType(name)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000297 m.__file__ = "<string>" # hopefully not a real filename...
298 m.__loader__ = "dummy" # pretend the filename is understood by a loader
Georg Brandl7cae87c2006-09-06 06:51:57 +0000299 exec("def x(): pass", m.__dict__)
Neal Norwitz221085d2007-02-25 20:55:47 +0000300 self.assertEqual(inspect.getsourcefile(m.x.__code__), '<string>')
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000301 del sys.modules[name]
302 inspect.getmodule(compile('a=10','','single'))
303
Benjamin Peterson9620cc02011-06-11 15:53:11 -0500304 def test_proceed_with_fake_filename(self):
305 '''doctest monkeypatches linecache to enable inspection'''
306 fn, source = '<test>', 'def x(): pass\n'
307 getlines = linecache.getlines
308 def monkey(filename, module_globals=None):
309 if filename == fn:
Ezio Melottid8b509b2011-09-28 17:37:55 +0300310 return source.splitlines(keepends=True)
Benjamin Peterson9620cc02011-06-11 15:53:11 -0500311 else:
312 return getlines(filename, module_globals)
313 linecache.getlines = monkey
314 try:
315 ns = {}
316 exec(compile(source, fn, 'single'), ns)
317 inspect.getsource(ns["x"])
318 finally:
319 linecache.getlines = getlines
320
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000321class TestDecorators(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000322 fodderModule = mod2
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000323
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000324 def test_wrapped_decorator(self):
Christian Heimes09aaa882008-02-23 15:01:06 +0000325 self.assertSourceEqual(mod2.wrapped, 14, 17)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000326
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000327 def test_replacing_decorator(self):
328 self.assertSourceEqual(mod2.gone, 9, 10)
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000329
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000330class TestOneliners(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000331 fodderModule = mod2
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000332 def test_oneline_lambda(self):
333 # Test inspect.getsource with a one-line lambda function.
334 self.assertSourceEqual(mod2.oll, 25, 25)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000335
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000336 def test_threeline_lambda(self):
337 # Test inspect.getsource with a three-line lambda function,
338 # where the second and third lines are _not_ indented.
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000339 self.assertSourceEqual(mod2.tll, 28, 30)
340
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000341 def test_twoline_indented_lambda(self):
342 # Test inspect.getsource with a two-line lambda function,
343 # where the second line _is_ indented.
344 self.assertSourceEqual(mod2.tlli, 33, 34)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000345
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000346 def test_onelinefunc(self):
347 # Test inspect.getsource with a regular one-line function.
348 self.assertSourceEqual(mod2.onelinefunc, 37, 37)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000349
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000350 def test_manyargs(self):
351 # Test inspect.getsource with a regular function where
352 # the arguments are on two lines and _not_ indented and
353 # the body on the second line with the last arguments.
354 self.assertSourceEqual(mod2.manyargs, 40, 41)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000355
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000356 def test_twolinefunc(self):
357 # Test inspect.getsource with a regular function where
358 # the body is on two lines, following the argument list and
359 # continued on the next line by a \\.
360 self.assertSourceEqual(mod2.twolinefunc, 44, 45)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000361
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000362 def test_lambda_in_list(self):
363 # Test inspect.getsource with a one-line lambda function
364 # defined in a list, indented.
365 self.assertSourceEqual(mod2.a[1], 49, 49)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000366
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000367 def test_anonymous(self):
368 # Test inspect.getsource with a lambda function defined
369 # as argument to another function.
370 self.assertSourceEqual(mod2.anonymous, 55, 55)
371
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000372class TestBuggyCases(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000373 fodderModule = mod2
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000374
375 def test_with_comment(self):
376 self.assertSourceEqual(mod2.with_comment, 58, 59)
377
378 def test_multiline_sig(self):
379 self.assertSourceEqual(mod2.multiline_sig[0], 63, 64)
380
Armin Rigodd5c0232005-09-25 11:45:45 +0000381 def test_nested_class(self):
382 self.assertSourceEqual(mod2.func69().func71, 71, 72)
383
384 def test_one_liner_followed_by_non_name(self):
385 self.assertSourceEqual(mod2.func77, 77, 77)
386
387 def test_one_liner_dedent_non_name(self):
388 self.assertSourceEqual(mod2.cls82.func83, 83, 83)
389
390 def test_with_comment_instead_of_docstring(self):
391 self.assertSourceEqual(mod2.func88, 88, 90)
392
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000393 def test_method_in_dynamic_class(self):
394 self.assertSourceEqual(mod2.method_in_dynamic_class, 95, 97)
395
R. David Murrayb5655772009-05-14 16:17:50 +0000396 @unittest.skipIf(
397 not hasattr(unicodedata, '__file__') or
398 unicodedata.__file__[-4:] in (".pyc", ".pyo"),
399 "unicodedata is not an external binary module")
R. David Murray74b89242009-05-13 17:33:03 +0000400 def test_findsource_binary(self):
R. David Murrayb5655772009-05-14 16:17:50 +0000401 self.assertRaises(IOError, inspect.getsource, unicodedata)
402 self.assertRaises(IOError, inspect.findsource, unicodedata)
R. David Murray74b89242009-05-13 17:33:03 +0000403
R. David Murraya1b37402010-06-17 02:04:29 +0000404 def test_findsource_code_in_linecache(self):
405 lines = ["x=1"]
406 co = compile(lines[0], "_dynamically_created_file", "exec")
407 self.assertRaises(IOError, inspect.findsource, co)
408 self.assertRaises(IOError, inspect.getsource, co)
409 linecache.cache[co.co_filename] = (1, None, lines, co.co_filename)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000410 self.assertEqual(inspect.findsource(co), (lines,0))
411 self.assertEqual(inspect.getsource(co), lines[0])
R. David Murraya1b37402010-06-17 02:04:29 +0000412
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000413class TestNoEOL(GetSourceBase):
414 def __init__(self, *args, **kwargs):
415 self.tempdir = TESTFN + '_dir'
416 os.mkdir(self.tempdir)
417 with open(os.path.join(self.tempdir,
418 'inspect_fodder3%spy' % os.extsep), 'w') as f:
419 f.write("class X:\n pass # No EOL")
420 with DirsOnSysPath(self.tempdir):
421 import inspect_fodder3 as mod3
422 self.fodderModule = mod3
423 GetSourceBase.__init__(self, *args, **kwargs)
424
425 def tearDown(self):
426 shutil.rmtree(self.tempdir)
427
428 def test_class(self):
429 self.assertSourceEqual(self.fodderModule.X, 1, 2)
430
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100431
432class _BrokenDataDescriptor(object):
433 """
434 A broken data descriptor. See bug #1785.
435 """
436 def __get__(*args):
437 raise AssertionError("should not __get__ data descriptors")
438
439 def __set__(*args):
440 raise RuntimeError
441
442 def __getattr__(*args):
443 raise AssertionError("should not __getattr__ data descriptors")
444
445
446class _BrokenMethodDescriptor(object):
447 """
448 A broken method descriptor. See bug #1785.
449 """
450 def __get__(*args):
451 raise AssertionError("should not __get__ method descriptors")
452
453 def __getattr__(*args):
454 raise AssertionError("should not __getattr__ method descriptors")
455
456
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000457# Helper for testing classify_class_attrs.
Tim Peters13b49d32001-09-23 02:00:29 +0000458def attrs_wo_objs(cls):
459 return [t[:3] for t in inspect.classify_class_attrs(cls)]
460
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100461
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000462class TestClassesAndFunctions(unittest.TestCase):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000463 def test_newstyle_mro(self):
464 # The same w/ new-class MRO.
465 class A(object): pass
466 class B(A): pass
467 class C(A): pass
468 class D(B, C): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000469
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000470 expected = (D, B, C, A, object)
471 got = inspect.getmro(D)
472 self.assertEqual(expected, got)
Tim Peters13b49d32001-09-23 02:00:29 +0000473
Christian Heimes3795b532007-11-08 13:48:53 +0000474 def assertArgSpecEquals(self, routine, args_e, varargs_e=None,
475 varkw_e=None, defaults_e=None, formatted=None):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000476 args, varargs, varkw, defaults = inspect.getargspec(routine)
477 self.assertEqual(args, args_e)
478 self.assertEqual(varargs, varargs_e)
479 self.assertEqual(varkw, varkw_e)
480 self.assertEqual(defaults, defaults_e)
481 if formatted is not None:
482 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults),
483 formatted)
Tim Peters13b49d32001-09-23 02:00:29 +0000484
Christian Heimes3795b532007-11-08 13:48:53 +0000485 def assertFullArgSpecEquals(self, routine, args_e, varargs_e=None,
486 varkw_e=None, defaults_e=None,
487 kwonlyargs_e=[], kwonlydefaults_e=None,
488 ann_e={}, formatted=None):
489 args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \
490 inspect.getfullargspec(routine)
491 self.assertEqual(args, args_e)
492 self.assertEqual(varargs, varargs_e)
493 self.assertEqual(varkw, varkw_e)
494 self.assertEqual(defaults, defaults_e)
495 self.assertEqual(kwonlyargs, kwonlyargs_e)
496 self.assertEqual(kwonlydefaults, kwonlydefaults_e)
497 self.assertEqual(ann, ann_e)
498 if formatted is not None:
499 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults,
500 kwonlyargs, kwonlydefaults, ann),
501 formatted)
502
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000503 def test_getargspec(self):
Christian Heimes3795b532007-11-08 13:48:53 +0000504 self.assertArgSpecEquals(mod.eggs, ['x', 'y'], formatted='(x, y)')
Tim Peters13b49d32001-09-23 02:00:29 +0000505
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000506 self.assertArgSpecEquals(mod.spam,
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000507 ['a', 'b', 'c', 'd', 'e', 'f'],
508 'g', 'h', (3, 4, 5),
509 '(a, b, c, d=3, e=4, f=5, *g, **h)')
Tim Peters13b49d32001-09-23 02:00:29 +0000510
Christian Heimes3795b532007-11-08 13:48:53 +0000511 self.assertRaises(ValueError, self.assertArgSpecEquals,
512 mod2.keyworded, [])
513
514 self.assertRaises(ValueError, self.assertArgSpecEquals,
515 mod2.annotated, [])
Benjamin Peterson9953a8d2009-01-17 04:15:01 +0000516 self.assertRaises(ValueError, self.assertArgSpecEquals,
517 mod2.keyword_only_arg, [])
518
Christian Heimes3795b532007-11-08 13:48:53 +0000519
520 def test_getfullargspec(self):
521 self.assertFullArgSpecEquals(mod2.keyworded, [], varargs_e='arg1',
522 kwonlyargs_e=['arg2'],
523 kwonlydefaults_e={'arg2':1},
524 formatted='(*arg1, arg2=1)')
525
526 self.assertFullArgSpecEquals(mod2.annotated, ['arg1'],
Christian Heimesc9543e42007-11-28 08:28:28 +0000527 ann_e={'arg1' : list},
Christian Heimes3795b532007-11-08 13:48:53 +0000528 formatted='(arg1: list)')
Benjamin Peterson9953a8d2009-01-17 04:15:01 +0000529 self.assertFullArgSpecEquals(mod2.keyword_only_arg, [],
530 kwonlyargs_e=['arg'],
531 formatted='(*, arg)')
532
Christian Heimes3795b532007-11-08 13:48:53 +0000533
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000534 def test_getargspec_method(self):
535 class A(object):
536 def m(self):
537 pass
538 self.assertArgSpecEquals(A.m, ['self'])
Tim Peters13b49d32001-09-23 02:00:29 +0000539
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000540 def test_classify_newstyle(self):
541 class A(object):
Tim Peters13b49d32001-09-23 02:00:29 +0000542
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000543 def s(): pass
544 s = staticmethod(s)
Tim Peters13b49d32001-09-23 02:00:29 +0000545
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000546 def c(cls): pass
547 c = classmethod(c)
Tim Peters13b49d32001-09-23 02:00:29 +0000548
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000549 def getp(self): pass
550 p = property(getp)
Tim Peters13b49d32001-09-23 02:00:29 +0000551
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000552 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000553
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000554 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000555
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000556 datablob = '1'
Tim Peters13b49d32001-09-23 02:00:29 +0000557
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100558 dd = _BrokenDataDescriptor()
559 md = _BrokenMethodDescriptor()
560
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000561 attrs = attrs_wo_objs(A)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000562 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
563 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
564 self.assertIn(('p', 'property', A), attrs, 'missing property')
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000565 self.assertIn(('m', 'method', A), attrs,
566 'missing plain method: %r' % attrs)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000567 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
568 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100569 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
570 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000571
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000572 class B(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000573
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000574 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000575
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000576 attrs = attrs_wo_objs(B)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000577 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
578 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
579 self.assertIn(('p', 'property', A), attrs, 'missing property')
580 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
581 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
582 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100583 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
584 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000585
586
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000587 class C(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000588
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000589 def m(self): pass
590 def c(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000591
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000592 attrs = attrs_wo_objs(C)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000593 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
594 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
595 self.assertIn(('p', 'property', A), attrs, 'missing property')
596 self.assertIn(('m', 'method', C), attrs, 'missing plain method')
597 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
598 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100599 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
600 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
Tim Peters13b49d32001-09-23 02:00:29 +0000601
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000602 class D(B, C):
Tim Peters13b49d32001-09-23 02:00:29 +0000603
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000604 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000605
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000606 attrs = attrs_wo_objs(D)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000607 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
608 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
609 self.assertIn(('p', 'property', A), attrs, 'missing property')
610 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
611 self.assertIn(('m1', 'method', D), attrs, 'missing plain method')
612 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100613 self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
614 self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
615
616 def test_classify_builtin_types(self):
617 # Simple sanity check that all built-in types can have their
618 # attributes classified.
619 for name in dir(__builtins__):
620 builtin = getattr(__builtins__, name)
621 if isinstance(builtin, type):
622 inspect.classify_class_attrs(builtin)
623
624 def test_getmembers_descriptors(self):
625 class A(object):
626 dd = _BrokenDataDescriptor()
627 md = _BrokenMethodDescriptor()
628
629 def pred_wrapper(pred):
630 # A quick'n'dirty way to discard standard attributes of new-style
631 # classes.
632 class Empty(object):
633 pass
634 def wrapped(x):
635 if '__name__' in dir(x) and hasattr(Empty, x.__name__):
636 return False
637 return pred(x)
638 return wrapped
639
640 ismethoddescriptor = pred_wrapper(inspect.ismethoddescriptor)
641 isdatadescriptor = pred_wrapper(inspect.isdatadescriptor)
642
643 self.assertEqual(inspect.getmembers(A, ismethoddescriptor),
644 [('md', A.__dict__['md'])])
645 self.assertEqual(inspect.getmembers(A, isdatadescriptor),
646 [('dd', A.__dict__['dd'])])
647
648 class B(A):
649 pass
650
651 self.assertEqual(inspect.getmembers(B, ismethoddescriptor),
652 [('md', A.__dict__['md'])])
653 self.assertEqual(inspect.getmembers(B, isdatadescriptor),
654 [('dd', A.__dict__['dd'])])
655
Antoine Pitrou0c603812012-01-18 17:40:18 +0100656 def test_getmembers_method(self):
657 class B:
658 def f(self):
659 pass
660
661 self.assertIn(('f', B.f), inspect.getmembers(B))
662 self.assertNotIn(('f', B.f), inspect.getmembers(B, inspect.ismethod))
663 b = B()
664 self.assertIn(('f', b.f), inspect.getmembers(b))
665 self.assertIn(('f', b.f), inspect.getmembers(b, inspect.ismethod))
666
Jeremy Hyltonc4bf5ed2003-06-27 18:43:12 +0000667
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000668class TestGetcallargsFunctions(unittest.TestCase):
669
670 def assertEqualCallArgs(self, func, call_params_string, locs=None):
671 locs = dict(locs or {}, func=func)
672 r1 = eval('func(%s)' % call_params_string, None, locs)
673 r2 = eval('inspect.getcallargs(func, %s)' % call_params_string, None,
674 locs)
675 self.assertEqual(r1, r2)
676
677 def assertEqualException(self, func, call_param_string, locs=None):
678 locs = dict(locs or {}, func=func)
679 try:
680 eval('func(%s)' % call_param_string, None, locs)
681 except Exception as e:
682 ex1 = e
683 else:
684 self.fail('Exception not raised')
685 try:
686 eval('inspect.getcallargs(func, %s)' % call_param_string, None,
687 locs)
688 except Exception as e:
689 ex2 = e
690 else:
691 self.fail('Exception not raised')
692 self.assertIs(type(ex1), type(ex2))
693 self.assertEqual(str(ex1), str(ex2))
694 del ex1, ex2
695
696 def makeCallable(self, signature):
697 """Create a function that returns its locals()"""
698 code = "lambda %s: locals()"
699 return eval(code % signature)
700
701 def test_plain(self):
702 f = self.makeCallable('a, b=1')
703 self.assertEqualCallArgs(f, '2')
704 self.assertEqualCallArgs(f, '2, 3')
705 self.assertEqualCallArgs(f, 'a=2')
706 self.assertEqualCallArgs(f, 'b=3, a=2')
707 self.assertEqualCallArgs(f, '2, b=3')
708 # expand *iterable / **mapping
709 self.assertEqualCallArgs(f, '*(2,)')
710 self.assertEqualCallArgs(f, '*[2]')
711 self.assertEqualCallArgs(f, '*(2, 3)')
712 self.assertEqualCallArgs(f, '*[2, 3]')
713 self.assertEqualCallArgs(f, '**{"a":2}')
714 self.assertEqualCallArgs(f, 'b=3, **{"a":2}')
715 self.assertEqualCallArgs(f, '2, **{"b":3}')
716 self.assertEqualCallArgs(f, '**{"b":3, "a":2}')
717 # expand UserList / UserDict
718 self.assertEqualCallArgs(f, '*collections.UserList([2])')
719 self.assertEqualCallArgs(f, '*collections.UserList([2, 3])')
720 self.assertEqualCallArgs(f, '**collections.UserDict(a=2)')
721 self.assertEqualCallArgs(f, '2, **collections.UserDict(b=3)')
722 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3)')
723
724 def test_varargs(self):
725 f = self.makeCallable('a, b=1, *c')
726 self.assertEqualCallArgs(f, '2')
727 self.assertEqualCallArgs(f, '2, 3')
728 self.assertEqualCallArgs(f, '2, 3, 4')
729 self.assertEqualCallArgs(f, '*(2,3,4)')
730 self.assertEqualCallArgs(f, '2, *[3,4]')
731 self.assertEqualCallArgs(f, '2, 3, *collections.UserList([4])')
732
733 def test_varkw(self):
734 f = self.makeCallable('a, b=1, **c')
735 self.assertEqualCallArgs(f, 'a=2')
736 self.assertEqualCallArgs(f, '2, b=3, c=4')
737 self.assertEqualCallArgs(f, 'b=3, a=2, c=4')
738 self.assertEqualCallArgs(f, 'c=4, **{"a":2, "b":3}')
739 self.assertEqualCallArgs(f, '2, c=4, **{"b":3}')
740 self.assertEqualCallArgs(f, 'b=2, **{"a":3, "c":4}')
741 self.assertEqualCallArgs(f, '**collections.UserDict(a=2, b=3, c=4)')
742 self.assertEqualCallArgs(f, '2, c=4, **collections.UserDict(b=3)')
743 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3, c=4)')
744
Benjamin Peterson6a2638b2011-03-28 17:32:31 -0500745 def test_varkw_only(self):
746 # issue11256:
747 f = self.makeCallable('**c')
748 self.assertEqualCallArgs(f, '')
749 self.assertEqualCallArgs(f, 'a=1')
750 self.assertEqualCallArgs(f, 'a=1, b=2')
751 self.assertEqualCallArgs(f, 'c=3, **{"a": 1, "b": 2}')
752 self.assertEqualCallArgs(f, '**collections.UserDict(a=1, b=2)')
753 self.assertEqualCallArgs(f, 'c=3, **collections.UserDict(a=1, b=2)')
754
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000755 def test_keyword_only(self):
756 f = self.makeCallable('a=3, *, c, d=2')
757 self.assertEqualCallArgs(f, 'c=3')
758 self.assertEqualCallArgs(f, 'c=3, a=3')
759 self.assertEqualCallArgs(f, 'a=2, c=4')
760 self.assertEqualCallArgs(f, '4, c=4')
761 self.assertEqualException(f, '')
762 self.assertEqualException(f, '3')
763 self.assertEqualException(f, 'a=3')
764 self.assertEqualException(f, 'd=4')
765
Benjamin Peterson6a2638b2011-03-28 17:32:31 -0500766 f = self.makeCallable('*, c, d=2')
767 self.assertEqualCallArgs(f, 'c=3')
768 self.assertEqualCallArgs(f, 'c=3, d=4')
769 self.assertEqualCallArgs(f, 'd=4, c=3')
770
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000771 def test_multiple_features(self):
772 f = self.makeCallable('a, b=2, *f, **g')
773 self.assertEqualCallArgs(f, '2, 3, 7')
774 self.assertEqualCallArgs(f, '2, 3, x=8')
775 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
776 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9')
777 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9')
778 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
779 '[2, 3, (4,[5,6])]), **{"y":9, "z":10}')
780 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
781 '(4,[5,6])]), **collections.UserDict('
782 'y=9, z=10)')
783
Benjamin Peterson6a2638b2011-03-28 17:32:31 -0500784 f = self.makeCallable('a, b=2, *f, x, y=99, **g')
785 self.assertEqualCallArgs(f, '2, 3, x=8')
786 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
787 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9, z=10')
788 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9, z=10')
789 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
790 '[2, 3, (4,[5,6])]), q=0, **{"y":9, "z":10}')
791 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
792 '(4,[5,6])]), q=0, **collections.UserDict('
793 'y=9, z=10)')
794
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000795 def test_errors(self):
796 f0 = self.makeCallable('')
797 f1 = self.makeCallable('a, b')
798 f2 = self.makeCallable('a, b=1')
799 # f0 takes no arguments
800 self.assertEqualException(f0, '1')
801 self.assertEqualException(f0, 'x=1')
802 self.assertEqualException(f0, '1,x=1')
803 # f1 takes exactly 2 arguments
804 self.assertEqualException(f1, '')
805 self.assertEqualException(f1, '1')
806 self.assertEqualException(f1, 'a=2')
807 self.assertEqualException(f1, 'b=3')
808 # f2 takes at least 1 argument
809 self.assertEqualException(f2, '')
810 self.assertEqualException(f2, 'b=3')
811 for f in f1, f2:
812 # f1/f2 takes exactly/at most 2 arguments
813 self.assertEqualException(f, '2, 3, 4')
814 self.assertEqualException(f, '1, 2, 3, a=1')
815 self.assertEqualException(f, '2, 3, 4, c=5')
Georg Brandl178e5ea2012-02-21 00:32:36 +0100816 # XXX: success of this one depends on dict order
817 ## self.assertEqualException(f, '2, 3, 4, a=1, c=5')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000818 # f got an unexpected keyword argument
819 self.assertEqualException(f, 'c=2')
820 self.assertEqualException(f, '2, c=3')
821 self.assertEqualException(f, '2, 3, c=4')
822 self.assertEqualException(f, '2, c=4, b=3')
823 self.assertEqualException(f, '**{u"\u03c0\u03b9": 4}')
824 # f got multiple values for keyword argument
825 self.assertEqualException(f, '1, a=2')
826 self.assertEqualException(f, '1, **{"a":2}')
827 self.assertEqualException(f, '1, 2, b=3')
828 # XXX: Python inconsistency
829 # - for functions and bound methods: unexpected keyword 'c'
830 # - for unbound methods: multiple values for keyword 'a'
831 #self.assertEqualException(f, '1, c=3, a=2')
Benjamin Peterson6a2638b2011-03-28 17:32:31 -0500832 # issue11256:
833 f3 = self.makeCallable('**c')
834 self.assertEqualException(f3, '1, 2')
835 self.assertEqualException(f3, '1, 2, a=1, b=2')
836 f4 = self.makeCallable('*, a, b=0')
837 self.assertEqualException(f3, '1, 2')
838 self.assertEqualException(f3, '1, 2, a=1, b=2')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000839
840class TestGetcallargsMethods(TestGetcallargsFunctions):
841
842 def setUp(self):
843 class Foo(object):
844 pass
845 self.cls = Foo
846 self.inst = Foo()
847
848 def makeCallable(self, signature):
849 assert 'self' not in signature
850 mk = super(TestGetcallargsMethods, self).makeCallable
851 self.cls.method = mk('self, ' + signature)
852 return self.inst.method
853
854class TestGetcallargsUnboundMethods(TestGetcallargsMethods):
855
856 def makeCallable(self, signature):
857 super(TestGetcallargsUnboundMethods, self).makeCallable(signature)
858 return self.cls.method
859
860 def assertEqualCallArgs(self, func, call_params_string, locs=None):
861 return super(TestGetcallargsUnboundMethods, self).assertEqualCallArgs(
862 *self._getAssertEqualParams(func, call_params_string, locs))
863
864 def assertEqualException(self, func, call_params_string, locs=None):
865 return super(TestGetcallargsUnboundMethods, self).assertEqualException(
866 *self._getAssertEqualParams(func, call_params_string, locs))
867
868 def _getAssertEqualParams(self, func, call_params_string, locs=None):
869 assert 'inst' not in call_params_string
870 locs = dict(locs or {}, inst=self.inst)
871 return (func, 'inst,' + call_params_string, locs)
872
Michael Foord95fc51d2010-11-20 15:07:30 +0000873
874class TestGetattrStatic(unittest.TestCase):
875
876 def test_basic(self):
877 class Thing(object):
878 x = object()
879
880 thing = Thing()
881 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
882 self.assertEqual(inspect.getattr_static(thing, 'x', None), Thing.x)
883 with self.assertRaises(AttributeError):
884 inspect.getattr_static(thing, 'y')
885
886 self.assertEqual(inspect.getattr_static(thing, 'y', 3), 3)
887
888 def test_inherited(self):
889 class Thing(object):
890 x = object()
891 class OtherThing(Thing):
892 pass
893
894 something = OtherThing()
895 self.assertEqual(inspect.getattr_static(something, 'x'), Thing.x)
896
897 def test_instance_attr(self):
898 class Thing(object):
899 x = 2
900 def __init__(self, x):
901 self.x = x
902 thing = Thing(3)
903 self.assertEqual(inspect.getattr_static(thing, 'x'), 3)
904 del thing.x
905 self.assertEqual(inspect.getattr_static(thing, 'x'), 2)
906
907 def test_property(self):
908 class Thing(object):
909 @property
910 def x(self):
911 raise AttributeError("I'm pretending not to exist")
912 thing = Thing()
913 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
914
Ezio Melotti75cbd732011-04-28 00:59:29 +0300915 def test_descriptor_raises_AttributeError(self):
Michael Foord95fc51d2010-11-20 15:07:30 +0000916 class descriptor(object):
917 def __get__(*_):
918 raise AttributeError("I'm pretending not to exist")
919 desc = descriptor()
920 class Thing(object):
921 x = desc
922 thing = Thing()
923 self.assertEqual(inspect.getattr_static(thing, 'x'), desc)
924
925 def test_classAttribute(self):
926 class Thing(object):
927 x = object()
928
929 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.x)
930
931 def test_inherited_classattribute(self):
932 class Thing(object):
933 x = object()
934 class OtherThing(Thing):
935 pass
936
937 self.assertEqual(inspect.getattr_static(OtherThing, 'x'), Thing.x)
938
939 def test_slots(self):
940 class Thing(object):
941 y = 'bar'
942 __slots__ = ['x']
943 def __init__(self):
944 self.x = 'foo'
945 thing = Thing()
946 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
947 self.assertEqual(inspect.getattr_static(thing, 'y'), 'bar')
948
949 del thing.x
950 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
951
952 def test_metaclass(self):
953 class meta(type):
954 attr = 'foo'
955 class Thing(object, metaclass=meta):
956 pass
957 self.assertEqual(inspect.getattr_static(Thing, 'attr'), 'foo')
958
959 class sub(meta):
960 pass
961 class OtherThing(object, metaclass=sub):
962 x = 3
963 self.assertEqual(inspect.getattr_static(OtherThing, 'attr'), 'foo')
964
965 class OtherOtherThing(OtherThing):
966 pass
967 # this test is odd, but it was added as it exposed a bug
968 self.assertEqual(inspect.getattr_static(OtherOtherThing, 'x'), 3)
969
970 def test_no_dict_no_slots(self):
971 self.assertEqual(inspect.getattr_static(1, 'foo', None), None)
972 self.assertNotEqual(inspect.getattr_static('foo', 'lower'), None)
973
974 def test_no_dict_no_slots_instance_member(self):
975 # returns descriptor
976 with open(__file__) as handle:
977 self.assertEqual(inspect.getattr_static(handle, 'name'), type(handle).name)
978
979 def test_inherited_slots(self):
980 # returns descriptor
981 class Thing(object):
982 __slots__ = ['x']
983 def __init__(self):
984 self.x = 'foo'
985
986 class OtherThing(Thing):
987 pass
988 # it would be nice if this worked...
989 # we get the descriptor instead of the instance attribute
990 self.assertEqual(inspect.getattr_static(OtherThing(), 'x'), Thing.x)
991
992 def test_descriptor(self):
993 class descriptor(object):
994 def __get__(self, instance, owner):
995 return 3
996 class Foo(object):
997 d = descriptor()
998
999 foo = Foo()
1000
1001 # for a non data descriptor we return the instance attribute
1002 foo.__dict__['d'] = 1
1003 self.assertEqual(inspect.getattr_static(foo, 'd'), 1)
1004
1005 # if the descriptor is a data-desciptor we should return the
1006 # descriptor
1007 descriptor.__set__ = lambda s, i, v: None
1008 self.assertEqual(inspect.getattr_static(foo, 'd'), Foo.__dict__['d'])
1009
1010
1011 def test_metaclass_with_descriptor(self):
1012 class descriptor(object):
1013 def __get__(self, instance, owner):
1014 return 3
1015 class meta(type):
1016 d = descriptor()
1017 class Thing(object, metaclass=meta):
1018 pass
1019 self.assertEqual(inspect.getattr_static(Thing, 'd'), meta.__dict__['d'])
1020
1021
Michael Foordcc7ebb82010-11-20 16:20:16 +00001022 def test_class_as_property(self):
1023 class Base(object):
1024 foo = 3
1025
1026 class Something(Base):
Michael Foord35184ed2010-11-20 16:58:30 +00001027 executed = False
Michael Foordcc7ebb82010-11-20 16:20:16 +00001028 @property
1029 def __class__(self):
Michael Foord35184ed2010-11-20 16:58:30 +00001030 self.executed = True
Michael Foordcc7ebb82010-11-20 16:20:16 +00001031 return object
1032
Michael Foord35184ed2010-11-20 16:58:30 +00001033 instance = Something()
1034 self.assertEqual(inspect.getattr_static(instance, 'foo'), 3)
1035 self.assertFalse(instance.executed)
Michael Foordcc7ebb82010-11-20 16:20:16 +00001036 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1037
Michael Foorde5162652010-11-20 16:40:44 +00001038 def test_mro_as_property(self):
1039 class Meta(type):
1040 @property
1041 def __mro__(self):
1042 return (object,)
1043
1044 class Base(object):
1045 foo = 3
1046
1047 class Something(Base, metaclass=Meta):
1048 pass
1049
1050 self.assertEqual(inspect.getattr_static(Something(), 'foo'), 3)
1051 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1052
Michael Foorddcebe0f2011-03-15 19:20:44 -04001053 def test_dict_as_property(self):
1054 test = self
1055 test.called = False
1056
1057 class Foo(dict):
1058 a = 3
1059 @property
1060 def __dict__(self):
1061 test.called = True
1062 return {}
1063
1064 foo = Foo()
1065 foo.a = 4
1066 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1067 self.assertFalse(test.called)
1068
1069 def test_custom_object_dict(self):
1070 test = self
1071 test.called = False
1072
1073 class Custom(dict):
1074 def get(self, key, default=None):
1075 test.called = True
1076 super().get(key, default)
1077
1078 class Foo(object):
1079 a = 3
1080 foo = Foo()
1081 foo.__dict__ = Custom()
1082 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1083 self.assertFalse(test.called)
1084
1085 def test_metaclass_dict_as_property(self):
1086 class Meta(type):
1087 @property
1088 def __dict__(self):
1089 self.executed = True
1090
1091 class Thing(metaclass=Meta):
1092 executed = False
1093
1094 def __init__(self):
1095 self.spam = 42
1096
1097 instance = Thing()
1098 self.assertEqual(inspect.getattr_static(instance, "spam"), 42)
1099 self.assertFalse(Thing.executed)
Michael Foorde5162652010-11-20 16:40:44 +00001100
Michael Foorda51623b2011-12-18 22:01:40 +00001101 def test_module(self):
1102 sentinel = object()
1103 self.assertIsNot(inspect.getattr_static(sys, "version", sentinel),
1104 sentinel)
1105
Michael Foord3ba95f82011-12-22 01:13:37 +00001106 def test_metaclass_with_metaclass_with_dict_as_property(self):
1107 class MetaMeta(type):
1108 @property
1109 def __dict__(self):
1110 self.executed = True
1111 return dict(spam=42)
1112
1113 class Meta(type, metaclass=MetaMeta):
1114 executed = False
1115
1116 class Thing(metaclass=Meta):
1117 pass
1118
1119 with self.assertRaises(AttributeError):
1120 inspect.getattr_static(Thing, "spam")
1121 self.assertFalse(Thing.executed)
1122
Nick Coghlane0f04652010-11-21 03:44:04 +00001123class TestGetGeneratorState(unittest.TestCase):
1124
1125 def setUp(self):
1126 def number_generator():
1127 for number in range(5):
1128 yield number
1129 self.generator = number_generator()
1130
1131 def _generatorstate(self):
1132 return inspect.getgeneratorstate(self.generator)
1133
1134 def test_created(self):
1135 self.assertEqual(self._generatorstate(), inspect.GEN_CREATED)
1136
1137 def test_suspended(self):
1138 next(self.generator)
1139 self.assertEqual(self._generatorstate(), inspect.GEN_SUSPENDED)
1140
1141 def test_closed_after_exhaustion(self):
1142 for i in self.generator:
1143 pass
1144 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1145
1146 def test_closed_after_immediate_exception(self):
1147 with self.assertRaises(RuntimeError):
1148 self.generator.throw(RuntimeError)
1149 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1150
1151 def test_running(self):
1152 # As mentioned on issue #10220, checking for the RUNNING state only
1153 # makes sense inside the generator itself.
1154 # The following generator checks for this by using the closure's
1155 # reference to self and the generator state checking helper method
1156 def running_check_generator():
1157 for number in range(5):
1158 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1159 yield number
1160 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1161 self.generator = running_check_generator()
1162 # Running up to the first yield
1163 next(self.generator)
1164 # Running after the first yield
1165 next(self.generator)
1166
Nick Coghlan7921b9f2010-11-30 06:36:04 +00001167 def test_easy_debugging(self):
1168 # repr() and str() of a generator state should contain the state name
1169 names = 'GEN_CREATED GEN_RUNNING GEN_SUSPENDED GEN_CLOSED'.split()
1170 for name in names:
1171 state = getattr(inspect, name)
1172 self.assertIn(name, repr(state))
1173 self.assertIn(name, str(state))
1174
Nick Coghlane0f04652010-11-21 03:44:04 +00001175
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001176def test_main():
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001177 run_unittest(
1178 TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBuggyCases,
1179 TestInterpreterStack, TestClassesAndFunctions, TestPredicates,
1180 TestGetcallargsFunctions, TestGetcallargsMethods,
Alexander Belopolskyf546e702010-12-02 00:10:11 +00001181 TestGetcallargsUnboundMethods, TestGetattrStatic, TestGetGeneratorState,
1182 TestNoEOL
Michael Foord95fc51d2010-11-20 15:07:30 +00001183 )
Martin v. Löwis893ffa42003-10-31 15:35:53 +00001184
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001185if __name__ == "__main__":
1186 test_main()