blob: b322f7dbdb02698916f3fc439a59da359de5b274 [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
Christian Heimesa3538eb2007-11-06 11:44:48 +00009from os.path import normcase
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000010
Georg Brandl1b37e872010-03-14 10:45:50 +000011from test.support import run_unittest
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000012
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000013from test import inspect_fodder as mod
14from test import inspect_fodder2 as mod2
Alexander Belopolsky41e422a2010-12-01 20:05:49 +000015from test import inspect_fodder3 as mod3
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000016
R. David Murray74b89242009-05-13 17:33:03 +000017# C module for test_findsource_binary
R. David Murrayb5655772009-05-14 16:17:50 +000018import unicodedata
R. David Murray74b89242009-05-13 17:33:03 +000019
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000020# Functions tested in this suite:
21# ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode,
Christian Heimes7131fd92008-02-19 14:21:46 +000022# isbuiltin, isroutine, isgenerator, isgeneratorfunction, getmembers,
23# getdoc, getfile, getmodule, getsourcefile, getcomments, getsource,
24# getclasstree, getargspec, getargvalues, formatargspec, formatargvalues,
25# currentframe, stack, trace, isdatadescriptor
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000026
Nick Coghlanf088e5e2008-12-14 11:50:48 +000027# NOTE: There are some additional tests relating to interaction with
28# zipimport in the test_zipimport_support test module.
29
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000030modfile = mod.__file__
Thomas Wouters0e3f5912006-08-11 14:57:12 +000031if modfile.endswith(('c', 'o')):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000032 modfile = modfile[:-1]
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000033
Christian Heimesa3538eb2007-11-06 11:44:48 +000034# Normalize file names: on Windows, the case of file names of compiled
35# modules depends on the path used to start the python executable.
36modfile = normcase(modfile)
37
38def revise(filename, *args):
39 return (normcase(filename),) + args
40
Georg Brandl1a3284e2007-12-02 09:40:06 +000041import builtins
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000042
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000043try:
44 1/0
45except:
Guido van Rossume7ba4952007-06-06 23:52:48 +000046 tb = sys.exc_info()[2]
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000047
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000048git = mod.StupidGit()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000049
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000050class IsTestBase(unittest.TestCase):
51 predicates = set([inspect.isbuiltin, inspect.isclass, inspect.iscode,
52 inspect.isframe, inspect.isfunction, inspect.ismethod,
Christian Heimes7131fd92008-02-19 14:21:46 +000053 inspect.ismodule, inspect.istraceback,
54 inspect.isgenerator, inspect.isgeneratorfunction])
Tim Peters5a9fb3c2005-01-07 16:01:32 +000055
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000056 def istest(self, predicate, exp):
57 obj = eval(exp)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000058 self.assertTrue(predicate(obj), '%s(%s)' % (predicate.__name__, exp))
Tim Peters5a9fb3c2005-01-07 16:01:32 +000059
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000060 for other in self.predicates - set([predicate]):
Christian Heimes7131fd92008-02-19 14:21:46 +000061 if predicate == inspect.isgeneratorfunction and\
62 other == inspect.isfunction:
63 continue
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000064 self.assertFalse(other(obj), 'not %s(%s)' % (other.__name__, exp))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000065
Christian Heimes7131fd92008-02-19 14:21:46 +000066def generator_function_example(self):
67 for i in range(2):
68 yield i
69
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000070class TestPredicates(IsTestBase):
Christian Heimes227c8002008-03-03 20:34:40 +000071 def test_sixteen(self):
Guido van Rossumc1f779c2007-07-03 08:25:58 +000072 count = len([x for x in dir(inspect) if x.startswith('is')])
Christian Heimes7131fd92008-02-19 14:21:46 +000073 # This test is here for remember you to update Doc/library/inspect.rst
Christian Heimes78644762008-03-04 23:39:23 +000074 # which claims there are 16 such functions
Christian Heimes227c8002008-03-03 20:34:40 +000075 expected = 16
Thomas Wouters0e3f5912006-08-11 14:57:12 +000076 err_msg = "There are %d (not %d) is* functions" % (count, expected)
77 self.assertEqual(count, expected, err_msg)
Tim Peters5a9fb3c2005-01-07 16:01:32 +000078
Christian Heimes7131fd92008-02-19 14:21:46 +000079
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000080 def test_excluding_predicates(self):
81 self.istest(inspect.isbuiltin, 'sys.exit')
82 self.istest(inspect.isbuiltin, '[].append')
Neal Norwitz221085d2007-02-25 20:55:47 +000083 self.istest(inspect.iscode, 'mod.spam.__code__')
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000084 self.istest(inspect.isframe, 'tb.tb_frame')
85 self.istest(inspect.isfunction, 'mod.spam')
Christian Heimes4a22b5d2007-11-25 09:39:14 +000086 self.istest(inspect.isfunction, 'mod.StupidGit.abuse')
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000087 self.istest(inspect.ismethod, 'git.argue')
88 self.istest(inspect.ismodule, 'mod')
89 self.istest(inspect.istraceback, 'tb')
Guido van Rossum813b0e52007-05-21 18:11:34 +000090 self.istest(inspect.isdatadescriptor, 'collections.defaultdict.default_factory')
Christian Heimes7131fd92008-02-19 14:21:46 +000091 self.istest(inspect.isgenerator, '(x for x in range(2))')
92 self.istest(inspect.isgeneratorfunction, 'generator_function_example')
Thomas Wouters0e3f5912006-08-11 14:57:12 +000093 if hasattr(types, 'GetSetDescriptorType'):
94 self.istest(inspect.isgetsetdescriptor,
95 'type(tb.tb_frame).f_locals')
96 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000097 self.assertFalse(inspect.isgetsetdescriptor(type(tb.tb_frame).f_locals))
Thomas Wouters0e3f5912006-08-11 14:57:12 +000098 if hasattr(types, 'MemberDescriptorType'):
99 self.istest(inspect.ismemberdescriptor, 'datetime.timedelta.days')
100 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000101 self.assertFalse(inspect.ismemberdescriptor(datetime.timedelta.days))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000102
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000103 def test_isroutine(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000104 self.assertTrue(inspect.isroutine(mod.spam))
105 self.assertTrue(inspect.isroutine([].count))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000106
Benjamin Petersonc4656002009-01-17 22:41:18 +0000107 def test_isclass(self):
108 self.istest(inspect.isclass, 'mod.StupidGit')
109 self.assertTrue(inspect.isclass(list))
110
111 class CustomGetattr(object):
112 def __getattr__(self, attr):
113 return None
114 self.assertFalse(inspect.isclass(CustomGetattr()))
115
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000116 def test_get_slot_members(self):
117 class C(object):
118 __slots__ = ("a", "b")
119
120 x = C()
121 x.a = 42
122 members = dict(inspect.getmembers(x))
Benjamin Peterson577473f2010-01-19 00:09:57 +0000123 self.assertIn('a', members)
124 self.assertNotIn('b', members)
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000125
Benjamin Petersona0dfa822009-11-13 02:25:08 +0000126 def test_isabstract(self):
127 from abc import ABCMeta, abstractmethod
128
129 class AbstractClassExample(metaclass=ABCMeta):
130
131 @abstractmethod
132 def foo(self):
133 pass
134
135 class ClassExample(AbstractClassExample):
136 def foo(self):
137 pass
138
139 a = ClassExample()
140
141 # Test general behaviour.
142 self.assertTrue(inspect.isabstract(AbstractClassExample))
143 self.assertFalse(inspect.isabstract(ClassExample))
144 self.assertFalse(inspect.isabstract(a))
145 self.assertFalse(inspect.isabstract(int))
146 self.assertFalse(inspect.isabstract(5))
147
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000148
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000149class TestInterpreterStack(IsTestBase):
150 def __init__(self, *args, **kwargs):
151 unittest.TestCase.__init__(self, *args, **kwargs)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000152
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000153 git.abuse(7, 8, 9)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000154
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000155 def test_abuse_done(self):
156 self.istest(inspect.istraceback, 'git.ex[2]')
157 self.istest(inspect.isframe, 'mod.fr')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000158
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000159 def test_stack(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000160 self.assertTrue(len(mod.st) >= 5)
Christian Heimesa3538eb2007-11-06 11:44:48 +0000161 self.assertEqual(revise(*mod.st[0][1:]),
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000162 (modfile, 16, 'eggs', [' st = inspect.stack()\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000163 self.assertEqual(revise(*mod.st[1][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000164 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000165 self.assertEqual(revise(*mod.st[2][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000166 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000167 self.assertEqual(revise(*mod.st[3][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000168 (modfile, 39, 'abuse', [' self.argue(a, b, c)\n'], 0))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000169
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000170 def test_trace(self):
171 self.assertEqual(len(git.tr), 3)
Florent Xiclunac8575922010-03-24 17:37:49 +0000172 self.assertEqual(revise(*git.tr[0][1:]),
173 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
174 self.assertEqual(revise(*git.tr[1][1:]),
175 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
176 self.assertEqual(revise(*git.tr[2][1:]),
177 (modfile, 18, 'eggs', [' q = y / 0\n'], 0))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000178
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000179 def test_frame(self):
180 args, varargs, varkw, locals = inspect.getargvalues(mod.fr)
181 self.assertEqual(args, ['x', 'y'])
182 self.assertEqual(varargs, None)
183 self.assertEqual(varkw, None)
184 self.assertEqual(locals, {'x': 11, 'p': 11, 'y': 14})
185 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
186 '(x=11, y=14)')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000187
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000188 def test_previous_frame(self):
189 args, varargs, varkw, locals = inspect.getargvalues(mod.fr.f_back)
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000190 self.assertEqual(args, ['a', 'b', 'c', 'd', 'e', 'f'])
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000191 self.assertEqual(varargs, 'g')
192 self.assertEqual(varkw, 'h')
193 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000194 '(a=7, b=8, c=9, d=3, e=4, f=5, *g=(), **h={})')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000195
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000196class GetSourceBase(unittest.TestCase):
197 # Subclasses must override.
198 fodderFile = None
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000199
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000200 def __init__(self, *args, **kwargs):
201 unittest.TestCase.__init__(self, *args, **kwargs)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000202
Philip Jenveya27c5bd2009-05-28 06:09:08 +0000203 with open(inspect.getsourcefile(self.fodderFile)) as fp:
204 self.source = fp.read()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000205
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000206 def sourcerange(self, top, bottom):
207 lines = self.source.split("\n")
208 return "\n".join(lines[top-1:bottom]) + "\n"
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000209
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000210 def assertSourceEqual(self, obj, top, bottom):
211 self.assertEqual(inspect.getsource(obj),
212 self.sourcerange(top, bottom))
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000213
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000214class TestRetrievingSourceCode(GetSourceBase):
215 fodderFile = mod
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000216
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000217 def test_getclasses(self):
218 classes = inspect.getmembers(mod, inspect.isclass)
219 self.assertEqual(classes,
220 [('FesteringGob', mod.FesteringGob),
221 ('MalodorousPervert', mod.MalodorousPervert),
222 ('ParrotDroppings', mod.ParrotDroppings),
223 ('StupidGit', mod.StupidGit)])
224 tree = inspect.getclasstree([cls[1] for cls in classes], 1)
225 self.assertEqual(tree,
Thomas Wouters725af872006-04-15 09:13:19 +0000226 [(object, ()),
227 [(mod.ParrotDroppings, (object,)),
228 (mod.StupidGit, (object,)),
229 [(mod.MalodorousPervert, (mod.StupidGit,)),
230 [(mod.FesteringGob, (mod.MalodorousPervert,
231 mod.ParrotDroppings))
232 ]
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000233 ]
234 ]
235 ])
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000236
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000237 def test_getfunctions(self):
238 functions = inspect.getmembers(mod, inspect.isfunction)
239 self.assertEqual(functions, [('eggs', mod.eggs),
240 ('spam', mod.spam)])
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000241
R. David Murray378c0cf2010-02-24 01:46:21 +0000242 @unittest.skipIf(sys.flags.optimize >= 2,
243 "Docstrings are omitted with -O2 and above")
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000244 def test_getdoc(self):
245 self.assertEqual(inspect.getdoc(mod), 'A module docstring.')
246 self.assertEqual(inspect.getdoc(mod.StupidGit),
247 'A longer,\n\nindented\n\ndocstring.')
248 self.assertEqual(inspect.getdoc(git.abuse),
249 'Another\n\ndocstring\n\ncontaining\n\ntabs')
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000250
Georg Brandl0c77a822008-06-10 16:37:50 +0000251 def test_cleandoc(self):
252 self.assertEqual(inspect.cleandoc('An\n indented\n docstring.'),
253 'An\nindented\ndocstring.')
254
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000255 def test_getcomments(self):
256 self.assertEqual(inspect.getcomments(mod), '# line 1\n')
257 self.assertEqual(inspect.getcomments(mod.StupidGit), '# line 20\n')
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000258
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000259 def test_getmodule(self):
Thomas Wouters89f507f2006-12-13 04:49:30 +0000260 # Check actual module
261 self.assertEqual(inspect.getmodule(mod), mod)
262 # Check class (uses __module__ attribute)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000263 self.assertEqual(inspect.getmodule(mod.StupidGit), mod)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000264 # Check a method (no __module__ attribute, falls back to filename)
265 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
266 # Do it again (check the caching isn't broken)
267 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
268 # Check a builtin
Georg Brandl1a3284e2007-12-02 09:40:06 +0000269 self.assertEqual(inspect.getmodule(str), sys.modules["builtins"])
Thomas Wouters89f507f2006-12-13 04:49:30 +0000270 # Check filename override
271 self.assertEqual(inspect.getmodule(None, modfile), mod)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000272
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000273 def test_getsource(self):
274 self.assertSourceEqual(git.abuse, 29, 39)
275 self.assertSourceEqual(mod.StupidGit, 21, 46)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000276
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000277 def test_getsourcefile(self):
Christian Heimesa3538eb2007-11-06 11:44:48 +0000278 self.assertEqual(normcase(inspect.getsourcefile(mod.spam)), modfile)
279 self.assertEqual(normcase(inspect.getsourcefile(git.abuse)), modfile)
R. David Murraya1b37402010-06-17 02:04:29 +0000280 fn = "_non_existing_filename_used_for_sourcefile_test.py"
281 co = compile("None", fn, "exec")
R. David Murray4155f972010-06-17 13:23:18 +0000282 self.assertEqual(inspect.getsourcefile(co), None)
R. David Murraya1b37402010-06-17 02:04:29 +0000283 linecache.cache[co.co_filename] = (1, None, "None", co.co_filename)
284 self.assertEqual(normcase(inspect.getsourcefile(co)), fn)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000285
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000286 def test_getfile(self):
287 self.assertEqual(inspect.getfile(mod.StupidGit), mod.__file__)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000288
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000289 def test_getmodule_recursion(self):
Christian Heimes45f9af32007-11-27 21:50:00 +0000290 from types import ModuleType
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000291 name = '__inspect_dummy'
Christian Heimes45f9af32007-11-27 21:50:00 +0000292 m = sys.modules[name] = ModuleType(name)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000293 m.__file__ = "<string>" # hopefully not a real filename...
294 m.__loader__ = "dummy" # pretend the filename is understood by a loader
Georg Brandl7cae87c2006-09-06 06:51:57 +0000295 exec("def x(): pass", m.__dict__)
Neal Norwitz221085d2007-02-25 20:55:47 +0000296 self.assertEqual(inspect.getsourcefile(m.x.__code__), '<string>')
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000297 del sys.modules[name]
298 inspect.getmodule(compile('a=10','','single'))
299
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000300class TestDecorators(GetSourceBase):
301 fodderFile = mod2
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000302
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000303 def test_wrapped_decorator(self):
Christian Heimes09aaa882008-02-23 15:01:06 +0000304 self.assertSourceEqual(mod2.wrapped, 14, 17)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000305
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000306 def test_replacing_decorator(self):
307 self.assertSourceEqual(mod2.gone, 9, 10)
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000308
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000309class TestOneliners(GetSourceBase):
310 fodderFile = mod2
311 def test_oneline_lambda(self):
312 # Test inspect.getsource with a one-line lambda function.
313 self.assertSourceEqual(mod2.oll, 25, 25)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000314
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000315 def test_threeline_lambda(self):
316 # Test inspect.getsource with a three-line lambda function,
317 # where the second and third lines are _not_ indented.
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000318 self.assertSourceEqual(mod2.tll, 28, 30)
319
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000320 def test_twoline_indented_lambda(self):
321 # Test inspect.getsource with a two-line lambda function,
322 # where the second line _is_ indented.
323 self.assertSourceEqual(mod2.tlli, 33, 34)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000324
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000325 def test_onelinefunc(self):
326 # Test inspect.getsource with a regular one-line function.
327 self.assertSourceEqual(mod2.onelinefunc, 37, 37)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000328
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000329 def test_manyargs(self):
330 # Test inspect.getsource with a regular function where
331 # the arguments are on two lines and _not_ indented and
332 # the body on the second line with the last arguments.
333 self.assertSourceEqual(mod2.manyargs, 40, 41)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000334
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000335 def test_twolinefunc(self):
336 # Test inspect.getsource with a regular function where
337 # the body is on two lines, following the argument list and
338 # continued on the next line by a \\.
339 self.assertSourceEqual(mod2.twolinefunc, 44, 45)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000340
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000341 def test_lambda_in_list(self):
342 # Test inspect.getsource with a one-line lambda function
343 # defined in a list, indented.
344 self.assertSourceEqual(mod2.a[1], 49, 49)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000345
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000346 def test_anonymous(self):
347 # Test inspect.getsource with a lambda function defined
348 # as argument to another function.
349 self.assertSourceEqual(mod2.anonymous, 55, 55)
350
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000351class TestBuggyCases(GetSourceBase):
352 fodderFile = mod2
353
354 def test_with_comment(self):
355 self.assertSourceEqual(mod2.with_comment, 58, 59)
356
357 def test_multiline_sig(self):
358 self.assertSourceEqual(mod2.multiline_sig[0], 63, 64)
359
Armin Rigodd5c0232005-09-25 11:45:45 +0000360 def test_nested_class(self):
361 self.assertSourceEqual(mod2.func69().func71, 71, 72)
362
363 def test_one_liner_followed_by_non_name(self):
364 self.assertSourceEqual(mod2.func77, 77, 77)
365
366 def test_one_liner_dedent_non_name(self):
367 self.assertSourceEqual(mod2.cls82.func83, 83, 83)
368
369 def test_with_comment_instead_of_docstring(self):
370 self.assertSourceEqual(mod2.func88, 88, 90)
371
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000372 def test_method_in_dynamic_class(self):
373 self.assertSourceEqual(mod2.method_in_dynamic_class, 95, 97)
374
R. David Murrayb5655772009-05-14 16:17:50 +0000375 @unittest.skipIf(
376 not hasattr(unicodedata, '__file__') or
377 unicodedata.__file__[-4:] in (".pyc", ".pyo"),
378 "unicodedata is not an external binary module")
R. David Murray74b89242009-05-13 17:33:03 +0000379 def test_findsource_binary(self):
R. David Murrayb5655772009-05-14 16:17:50 +0000380 self.assertRaises(IOError, inspect.getsource, unicodedata)
381 self.assertRaises(IOError, inspect.findsource, unicodedata)
R. David Murray74b89242009-05-13 17:33:03 +0000382
R. David Murraya1b37402010-06-17 02:04:29 +0000383 def test_findsource_code_in_linecache(self):
384 lines = ["x=1"]
385 co = compile(lines[0], "_dynamically_created_file", "exec")
386 self.assertRaises(IOError, inspect.findsource, co)
387 self.assertRaises(IOError, inspect.getsource, co)
388 linecache.cache[co.co_filename] = (1, None, lines, co.co_filename)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000389 self.assertEqual(inspect.findsource(co), (lines,0))
390 self.assertEqual(inspect.getsource(co), lines[0])
R. David Murraya1b37402010-06-17 02:04:29 +0000391
Alexander Belopolsky41e422a2010-12-01 20:05:49 +0000392class TestNoEOF(GetSourceBase):
393 fodderFile = mod3
394
395 def test_class(self):
396 self.assertSourceEqual(mod3.X, 1, 2)
397
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000398# Helper for testing classify_class_attrs.
Tim Peters13b49d32001-09-23 02:00:29 +0000399def attrs_wo_objs(cls):
400 return [t[:3] for t in inspect.classify_class_attrs(cls)]
401
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000402class TestClassesAndFunctions(unittest.TestCase):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000403 def test_newstyle_mro(self):
404 # The same w/ new-class MRO.
405 class A(object): pass
406 class B(A): pass
407 class C(A): pass
408 class D(B, C): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000409
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000410 expected = (D, B, C, A, object)
411 got = inspect.getmro(D)
412 self.assertEqual(expected, got)
Tim Peters13b49d32001-09-23 02:00:29 +0000413
Christian Heimes3795b532007-11-08 13:48:53 +0000414 def assertArgSpecEquals(self, routine, args_e, varargs_e=None,
415 varkw_e=None, defaults_e=None, formatted=None):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000416 args, varargs, varkw, defaults = inspect.getargspec(routine)
417 self.assertEqual(args, args_e)
418 self.assertEqual(varargs, varargs_e)
419 self.assertEqual(varkw, varkw_e)
420 self.assertEqual(defaults, defaults_e)
421 if formatted is not None:
422 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults),
423 formatted)
Tim Peters13b49d32001-09-23 02:00:29 +0000424
Christian Heimes3795b532007-11-08 13:48:53 +0000425 def assertFullArgSpecEquals(self, routine, args_e, varargs_e=None,
426 varkw_e=None, defaults_e=None,
427 kwonlyargs_e=[], kwonlydefaults_e=None,
428 ann_e={}, formatted=None):
429 args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \
430 inspect.getfullargspec(routine)
431 self.assertEqual(args, args_e)
432 self.assertEqual(varargs, varargs_e)
433 self.assertEqual(varkw, varkw_e)
434 self.assertEqual(defaults, defaults_e)
435 self.assertEqual(kwonlyargs, kwonlyargs_e)
436 self.assertEqual(kwonlydefaults, kwonlydefaults_e)
437 self.assertEqual(ann, ann_e)
438 if formatted is not None:
439 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults,
440 kwonlyargs, kwonlydefaults, ann),
441 formatted)
442
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000443 def test_getargspec(self):
Christian Heimes3795b532007-11-08 13:48:53 +0000444 self.assertArgSpecEquals(mod.eggs, ['x', 'y'], formatted='(x, y)')
Tim Peters13b49d32001-09-23 02:00:29 +0000445
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000446 self.assertArgSpecEquals(mod.spam,
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000447 ['a', 'b', 'c', 'd', 'e', 'f'],
448 'g', 'h', (3, 4, 5),
449 '(a, b, c, d=3, e=4, f=5, *g, **h)')
Tim Peters13b49d32001-09-23 02:00:29 +0000450
Christian Heimes3795b532007-11-08 13:48:53 +0000451 self.assertRaises(ValueError, self.assertArgSpecEquals,
452 mod2.keyworded, [])
453
454 self.assertRaises(ValueError, self.assertArgSpecEquals,
455 mod2.annotated, [])
Benjamin Peterson9953a8d2009-01-17 04:15:01 +0000456 self.assertRaises(ValueError, self.assertArgSpecEquals,
457 mod2.keyword_only_arg, [])
458
Christian Heimes3795b532007-11-08 13:48:53 +0000459
460 def test_getfullargspec(self):
461 self.assertFullArgSpecEquals(mod2.keyworded, [], varargs_e='arg1',
462 kwonlyargs_e=['arg2'],
463 kwonlydefaults_e={'arg2':1},
464 formatted='(*arg1, arg2=1)')
465
466 self.assertFullArgSpecEquals(mod2.annotated, ['arg1'],
Christian Heimesc9543e42007-11-28 08:28:28 +0000467 ann_e={'arg1' : list},
Christian Heimes3795b532007-11-08 13:48:53 +0000468 formatted='(arg1: list)')
Benjamin Peterson9953a8d2009-01-17 04:15:01 +0000469 self.assertFullArgSpecEquals(mod2.keyword_only_arg, [],
470 kwonlyargs_e=['arg'],
471 formatted='(*, arg)')
472
Christian Heimes3795b532007-11-08 13:48:53 +0000473
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000474 def test_getargspec_method(self):
475 class A(object):
476 def m(self):
477 pass
478 self.assertArgSpecEquals(A.m, ['self'])
Tim Peters13b49d32001-09-23 02:00:29 +0000479
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000480 def test_classify_newstyle(self):
481 class A(object):
Tim Peters13b49d32001-09-23 02:00:29 +0000482
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000483 def s(): pass
484 s = staticmethod(s)
Tim Peters13b49d32001-09-23 02:00:29 +0000485
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000486 def c(cls): pass
487 c = classmethod(c)
Tim Peters13b49d32001-09-23 02:00:29 +0000488
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000489 def getp(self): pass
490 p = property(getp)
Tim Peters13b49d32001-09-23 02:00:29 +0000491
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000492 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000493
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000494 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000495
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000496 datablob = '1'
Tim Peters13b49d32001-09-23 02:00:29 +0000497
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000498 attrs = attrs_wo_objs(A)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000499 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
500 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
501 self.assertIn(('p', 'property', A), attrs, 'missing property')
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000502 self.assertIn(('m', 'method', A), attrs,
503 'missing plain method: %r' % attrs)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000504 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
505 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Tim Peters13b49d32001-09-23 02:00:29 +0000506
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000507 class B(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000508
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000509 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000510
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000511 attrs = attrs_wo_objs(B)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000512 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
513 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
514 self.assertIn(('p', 'property', A), attrs, 'missing property')
515 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
516 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
517 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Tim Peters13b49d32001-09-23 02:00:29 +0000518
519
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000520 class C(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000521
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000522 def m(self): pass
523 def c(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000524
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000525 attrs = attrs_wo_objs(C)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000526 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
527 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
528 self.assertIn(('p', 'property', A), attrs, 'missing property')
529 self.assertIn(('m', 'method', C), attrs, 'missing plain method')
530 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
531 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Tim Peters13b49d32001-09-23 02:00:29 +0000532
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000533 class D(B, C):
Tim Peters13b49d32001-09-23 02:00:29 +0000534
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000535 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000536
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000537 attrs = attrs_wo_objs(D)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000538 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
539 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
540 self.assertIn(('p', 'property', A), attrs, 'missing property')
541 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
542 self.assertIn(('m1', 'method', D), attrs, 'missing plain method')
543 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Jeremy Hyltonc4bf5ed2003-06-27 18:43:12 +0000544
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000545class TestGetcallargsFunctions(unittest.TestCase):
546
547 def assertEqualCallArgs(self, func, call_params_string, locs=None):
548 locs = dict(locs or {}, func=func)
549 r1 = eval('func(%s)' % call_params_string, None, locs)
550 r2 = eval('inspect.getcallargs(func, %s)' % call_params_string, None,
551 locs)
552 self.assertEqual(r1, r2)
553
554 def assertEqualException(self, func, call_param_string, locs=None):
555 locs = dict(locs or {}, func=func)
556 try:
557 eval('func(%s)' % call_param_string, None, locs)
558 except Exception as e:
559 ex1 = e
560 else:
561 self.fail('Exception not raised')
562 try:
563 eval('inspect.getcallargs(func, %s)' % call_param_string, None,
564 locs)
565 except Exception as e:
566 ex2 = e
567 else:
568 self.fail('Exception not raised')
569 self.assertIs(type(ex1), type(ex2))
570 self.assertEqual(str(ex1), str(ex2))
571 del ex1, ex2
572
573 def makeCallable(self, signature):
574 """Create a function that returns its locals()"""
575 code = "lambda %s: locals()"
576 return eval(code % signature)
577
578 def test_plain(self):
579 f = self.makeCallable('a, b=1')
580 self.assertEqualCallArgs(f, '2')
581 self.assertEqualCallArgs(f, '2, 3')
582 self.assertEqualCallArgs(f, 'a=2')
583 self.assertEqualCallArgs(f, 'b=3, a=2')
584 self.assertEqualCallArgs(f, '2, b=3')
585 # expand *iterable / **mapping
586 self.assertEqualCallArgs(f, '*(2,)')
587 self.assertEqualCallArgs(f, '*[2]')
588 self.assertEqualCallArgs(f, '*(2, 3)')
589 self.assertEqualCallArgs(f, '*[2, 3]')
590 self.assertEqualCallArgs(f, '**{"a":2}')
591 self.assertEqualCallArgs(f, 'b=3, **{"a":2}')
592 self.assertEqualCallArgs(f, '2, **{"b":3}')
593 self.assertEqualCallArgs(f, '**{"b":3, "a":2}')
594 # expand UserList / UserDict
595 self.assertEqualCallArgs(f, '*collections.UserList([2])')
596 self.assertEqualCallArgs(f, '*collections.UserList([2, 3])')
597 self.assertEqualCallArgs(f, '**collections.UserDict(a=2)')
598 self.assertEqualCallArgs(f, '2, **collections.UserDict(b=3)')
599 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3)')
600
601 def test_varargs(self):
602 f = self.makeCallable('a, b=1, *c')
603 self.assertEqualCallArgs(f, '2')
604 self.assertEqualCallArgs(f, '2, 3')
605 self.assertEqualCallArgs(f, '2, 3, 4')
606 self.assertEqualCallArgs(f, '*(2,3,4)')
607 self.assertEqualCallArgs(f, '2, *[3,4]')
608 self.assertEqualCallArgs(f, '2, 3, *collections.UserList([4])')
609
610 def test_varkw(self):
611 f = self.makeCallable('a, b=1, **c')
612 self.assertEqualCallArgs(f, 'a=2')
613 self.assertEqualCallArgs(f, '2, b=3, c=4')
614 self.assertEqualCallArgs(f, 'b=3, a=2, c=4')
615 self.assertEqualCallArgs(f, 'c=4, **{"a":2, "b":3}')
616 self.assertEqualCallArgs(f, '2, c=4, **{"b":3}')
617 self.assertEqualCallArgs(f, 'b=2, **{"a":3, "c":4}')
618 self.assertEqualCallArgs(f, '**collections.UserDict(a=2, b=3, c=4)')
619 self.assertEqualCallArgs(f, '2, c=4, **collections.UserDict(b=3)')
620 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3, c=4)')
621
622 def test_keyword_only(self):
623 f = self.makeCallable('a=3, *, c, d=2')
624 self.assertEqualCallArgs(f, 'c=3')
625 self.assertEqualCallArgs(f, 'c=3, a=3')
626 self.assertEqualCallArgs(f, 'a=2, c=4')
627 self.assertEqualCallArgs(f, '4, c=4')
628 self.assertEqualException(f, '')
629 self.assertEqualException(f, '3')
630 self.assertEqualException(f, 'a=3')
631 self.assertEqualException(f, 'd=4')
632
633 def test_multiple_features(self):
634 f = self.makeCallable('a, b=2, *f, **g')
635 self.assertEqualCallArgs(f, '2, 3, 7')
636 self.assertEqualCallArgs(f, '2, 3, x=8')
637 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
638 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9')
639 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9')
640 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
641 '[2, 3, (4,[5,6])]), **{"y":9, "z":10}')
642 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
643 '(4,[5,6])]), **collections.UserDict('
644 'y=9, z=10)')
645
646 def test_errors(self):
647 f0 = self.makeCallable('')
648 f1 = self.makeCallable('a, b')
649 f2 = self.makeCallable('a, b=1')
650 # f0 takes no arguments
651 self.assertEqualException(f0, '1')
652 self.assertEqualException(f0, 'x=1')
653 self.assertEqualException(f0, '1,x=1')
654 # f1 takes exactly 2 arguments
655 self.assertEqualException(f1, '')
656 self.assertEqualException(f1, '1')
657 self.assertEqualException(f1, 'a=2')
658 self.assertEqualException(f1, 'b=3')
659 # f2 takes at least 1 argument
660 self.assertEqualException(f2, '')
661 self.assertEqualException(f2, 'b=3')
662 for f in f1, f2:
663 # f1/f2 takes exactly/at most 2 arguments
664 self.assertEqualException(f, '2, 3, 4')
665 self.assertEqualException(f, '1, 2, 3, a=1')
666 self.assertEqualException(f, '2, 3, 4, c=5')
667 self.assertEqualException(f, '2, 3, 4, a=1, c=5')
668 # f got an unexpected keyword argument
669 self.assertEqualException(f, 'c=2')
670 self.assertEqualException(f, '2, c=3')
671 self.assertEqualException(f, '2, 3, c=4')
672 self.assertEqualException(f, '2, c=4, b=3')
673 self.assertEqualException(f, '**{u"\u03c0\u03b9": 4}')
674 # f got multiple values for keyword argument
675 self.assertEqualException(f, '1, a=2')
676 self.assertEqualException(f, '1, **{"a":2}')
677 self.assertEqualException(f, '1, 2, b=3')
678 # XXX: Python inconsistency
679 # - for functions and bound methods: unexpected keyword 'c'
680 # - for unbound methods: multiple values for keyword 'a'
681 #self.assertEqualException(f, '1, c=3, a=2')
682
683class TestGetcallargsMethods(TestGetcallargsFunctions):
684
685 def setUp(self):
686 class Foo(object):
687 pass
688 self.cls = Foo
689 self.inst = Foo()
690
691 def makeCallable(self, signature):
692 assert 'self' not in signature
693 mk = super(TestGetcallargsMethods, self).makeCallable
694 self.cls.method = mk('self, ' + signature)
695 return self.inst.method
696
697class TestGetcallargsUnboundMethods(TestGetcallargsMethods):
698
699 def makeCallable(self, signature):
700 super(TestGetcallargsUnboundMethods, self).makeCallable(signature)
701 return self.cls.method
702
703 def assertEqualCallArgs(self, func, call_params_string, locs=None):
704 return super(TestGetcallargsUnboundMethods, self).assertEqualCallArgs(
705 *self._getAssertEqualParams(func, call_params_string, locs))
706
707 def assertEqualException(self, func, call_params_string, locs=None):
708 return super(TestGetcallargsUnboundMethods, self).assertEqualException(
709 *self._getAssertEqualParams(func, call_params_string, locs))
710
711 def _getAssertEqualParams(self, func, call_params_string, locs=None):
712 assert 'inst' not in call_params_string
713 locs = dict(locs or {}, inst=self.inst)
714 return (func, 'inst,' + call_params_string, locs)
715
Michael Foord95fc51d2010-11-20 15:07:30 +0000716
717class TestGetattrStatic(unittest.TestCase):
718
719 def test_basic(self):
720 class Thing(object):
721 x = object()
722
723 thing = Thing()
724 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
725 self.assertEqual(inspect.getattr_static(thing, 'x', None), Thing.x)
726 with self.assertRaises(AttributeError):
727 inspect.getattr_static(thing, 'y')
728
729 self.assertEqual(inspect.getattr_static(thing, 'y', 3), 3)
730
731 def test_inherited(self):
732 class Thing(object):
733 x = object()
734 class OtherThing(Thing):
735 pass
736
737 something = OtherThing()
738 self.assertEqual(inspect.getattr_static(something, 'x'), Thing.x)
739
740 def test_instance_attr(self):
741 class Thing(object):
742 x = 2
743 def __init__(self, x):
744 self.x = x
745 thing = Thing(3)
746 self.assertEqual(inspect.getattr_static(thing, 'x'), 3)
747 del thing.x
748 self.assertEqual(inspect.getattr_static(thing, 'x'), 2)
749
750 def test_property(self):
751 class Thing(object):
752 @property
753 def x(self):
754 raise AttributeError("I'm pretending not to exist")
755 thing = Thing()
756 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
757
758 def test_descriptor(self):
759 class descriptor(object):
760 def __get__(*_):
761 raise AttributeError("I'm pretending not to exist")
762 desc = descriptor()
763 class Thing(object):
764 x = desc
765 thing = Thing()
766 self.assertEqual(inspect.getattr_static(thing, 'x'), desc)
767
768 def test_classAttribute(self):
769 class Thing(object):
770 x = object()
771
772 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.x)
773
774 def test_inherited_classattribute(self):
775 class Thing(object):
776 x = object()
777 class OtherThing(Thing):
778 pass
779
780 self.assertEqual(inspect.getattr_static(OtherThing, 'x'), Thing.x)
781
782 def test_slots(self):
783 class Thing(object):
784 y = 'bar'
785 __slots__ = ['x']
786 def __init__(self):
787 self.x = 'foo'
788 thing = Thing()
789 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
790 self.assertEqual(inspect.getattr_static(thing, 'y'), 'bar')
791
792 del thing.x
793 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
794
795 def test_metaclass(self):
796 class meta(type):
797 attr = 'foo'
798 class Thing(object, metaclass=meta):
799 pass
800 self.assertEqual(inspect.getattr_static(Thing, 'attr'), 'foo')
801
802 class sub(meta):
803 pass
804 class OtherThing(object, metaclass=sub):
805 x = 3
806 self.assertEqual(inspect.getattr_static(OtherThing, 'attr'), 'foo')
807
808 class OtherOtherThing(OtherThing):
809 pass
810 # this test is odd, but it was added as it exposed a bug
811 self.assertEqual(inspect.getattr_static(OtherOtherThing, 'x'), 3)
812
813 def test_no_dict_no_slots(self):
814 self.assertEqual(inspect.getattr_static(1, 'foo', None), None)
815 self.assertNotEqual(inspect.getattr_static('foo', 'lower'), None)
816
817 def test_no_dict_no_slots_instance_member(self):
818 # returns descriptor
819 with open(__file__) as handle:
820 self.assertEqual(inspect.getattr_static(handle, 'name'), type(handle).name)
821
822 def test_inherited_slots(self):
823 # returns descriptor
824 class Thing(object):
825 __slots__ = ['x']
826 def __init__(self):
827 self.x = 'foo'
828
829 class OtherThing(Thing):
830 pass
831 # it would be nice if this worked...
832 # we get the descriptor instead of the instance attribute
833 self.assertEqual(inspect.getattr_static(OtherThing(), 'x'), Thing.x)
834
835 def test_descriptor(self):
836 class descriptor(object):
837 def __get__(self, instance, owner):
838 return 3
839 class Foo(object):
840 d = descriptor()
841
842 foo = Foo()
843
844 # for a non data descriptor we return the instance attribute
845 foo.__dict__['d'] = 1
846 self.assertEqual(inspect.getattr_static(foo, 'd'), 1)
847
848 # if the descriptor is a data-desciptor we should return the
849 # descriptor
850 descriptor.__set__ = lambda s, i, v: None
851 self.assertEqual(inspect.getattr_static(foo, 'd'), Foo.__dict__['d'])
852
853
854 def test_metaclass_with_descriptor(self):
855 class descriptor(object):
856 def __get__(self, instance, owner):
857 return 3
858 class meta(type):
859 d = descriptor()
860 class Thing(object, metaclass=meta):
861 pass
862 self.assertEqual(inspect.getattr_static(Thing, 'd'), meta.__dict__['d'])
863
864
Michael Foordcc7ebb82010-11-20 16:20:16 +0000865 def test_class_as_property(self):
866 class Base(object):
867 foo = 3
868
869 class Something(Base):
Michael Foord35184ed2010-11-20 16:58:30 +0000870 executed = False
Michael Foordcc7ebb82010-11-20 16:20:16 +0000871 @property
872 def __class__(self):
Michael Foord35184ed2010-11-20 16:58:30 +0000873 self.executed = True
Michael Foordcc7ebb82010-11-20 16:20:16 +0000874 return object
875
Michael Foord35184ed2010-11-20 16:58:30 +0000876 instance = Something()
877 self.assertEqual(inspect.getattr_static(instance, 'foo'), 3)
878 self.assertFalse(instance.executed)
Michael Foordcc7ebb82010-11-20 16:20:16 +0000879 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
880
Michael Foorde5162652010-11-20 16:40:44 +0000881 def test_mro_as_property(self):
882 class Meta(type):
883 @property
884 def __mro__(self):
885 return (object,)
886
887 class Base(object):
888 foo = 3
889
890 class Something(Base, metaclass=Meta):
891 pass
892
893 self.assertEqual(inspect.getattr_static(Something(), 'foo'), 3)
894 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
895
896
Nick Coghlane0f04652010-11-21 03:44:04 +0000897class TestGetGeneratorState(unittest.TestCase):
898
899 def setUp(self):
900 def number_generator():
901 for number in range(5):
902 yield number
903 self.generator = number_generator()
904
905 def _generatorstate(self):
906 return inspect.getgeneratorstate(self.generator)
907
908 def test_created(self):
909 self.assertEqual(self._generatorstate(), inspect.GEN_CREATED)
910
911 def test_suspended(self):
912 next(self.generator)
913 self.assertEqual(self._generatorstate(), inspect.GEN_SUSPENDED)
914
915 def test_closed_after_exhaustion(self):
916 for i in self.generator:
917 pass
918 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
919
920 def test_closed_after_immediate_exception(self):
921 with self.assertRaises(RuntimeError):
922 self.generator.throw(RuntimeError)
923 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
924
925 def test_running(self):
926 # As mentioned on issue #10220, checking for the RUNNING state only
927 # makes sense inside the generator itself.
928 # The following generator checks for this by using the closure's
929 # reference to self and the generator state checking helper method
930 def running_check_generator():
931 for number in range(5):
932 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
933 yield number
934 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
935 self.generator = running_check_generator()
936 # Running up to the first yield
937 next(self.generator)
938 # Running after the first yield
939 next(self.generator)
940
Nick Coghlan7921b9f2010-11-30 06:36:04 +0000941 def test_easy_debugging(self):
942 # repr() and str() of a generator state should contain the state name
943 names = 'GEN_CREATED GEN_RUNNING GEN_SUSPENDED GEN_CLOSED'.split()
944 for name in names:
945 state = getattr(inspect, name)
946 self.assertIn(name, repr(state))
947 self.assertIn(name, str(state))
948
Nick Coghlane0f04652010-11-21 03:44:04 +0000949
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000950def test_main():
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000951 run_unittest(
952 TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBuggyCases,
953 TestInterpreterStack, TestClassesAndFunctions, TestPredicates,
954 TestGetcallargsFunctions, TestGetcallargsMethods,
Nick Coghlane0f04652010-11-21 03:44:04 +0000955 TestGetcallargsUnboundMethods, TestGetattrStatic, TestGetGeneratorState
Michael Foord95fc51d2010-11-20 15:07:30 +0000956 )
Martin v. Löwis893ffa42003-10-31 15:35:53 +0000957
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000958if __name__ == "__main__":
959 test_main()