blob: ccfcaba8baa330cff7146c1a37f43434175cff3a [file] [log] [blame]
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001import re
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00002import sys
Thomas Wouters0e3f5912006-08-11 14:57:12 +00003import types
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00004import unittest
5import inspect
R. David Murraya1b37402010-06-17 02:04:29 +00006import linecache
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007import datetime
Guido van Rossum813b0e52007-05-21 18:11:34 +00008import collections
Alexander Belopolskyf546e702010-12-02 00:10:11 +00009import os
10import shutil
Christian Heimesa3538eb2007-11-06 11:44:48 +000011from os.path import normcase
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000012
Alexander Belopolskyf546e702010-12-02 00:10:11 +000013from test.support import run_unittest, TESTFN, DirsOnSysPath
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000014
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000015from test import inspect_fodder as mod
16from test import inspect_fodder2 as mod2
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000017
R. David Murray74b89242009-05-13 17:33:03 +000018# C module for test_findsource_binary
R. David Murrayb5655772009-05-14 16:17:50 +000019import unicodedata
R. David Murray74b89242009-05-13 17:33:03 +000020
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000021# Functions tested in this suite:
22# ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode,
Christian Heimes7131fd92008-02-19 14:21:46 +000023# isbuiltin, isroutine, isgenerator, isgeneratorfunction, getmembers,
24# getdoc, getfile, getmodule, getsourcefile, getcomments, getsource,
25# getclasstree, getargspec, getargvalues, formatargspec, formatargvalues,
26# currentframe, stack, trace, isdatadescriptor
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000027
Nick Coghlanf088e5e2008-12-14 11:50:48 +000028# NOTE: There are some additional tests relating to interaction with
29# zipimport in the test_zipimport_support test module.
30
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000031modfile = mod.__file__
Thomas Wouters0e3f5912006-08-11 14:57:12 +000032if modfile.endswith(('c', 'o')):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000033 modfile = modfile[:-1]
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000034
Christian Heimesa3538eb2007-11-06 11:44:48 +000035# Normalize file names: on Windows, the case of file names of compiled
36# modules depends on the path used to start the python executable.
37modfile = normcase(modfile)
38
39def revise(filename, *args):
40 return (normcase(filename),) + args
41
Georg Brandl1a3284e2007-12-02 09:40:06 +000042import builtins
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000043
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000044try:
45 1/0
46except:
Guido van Rossume7ba4952007-06-06 23:52:48 +000047 tb = sys.exc_info()[2]
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000048
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000049git = mod.StupidGit()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000050
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000051class IsTestBase(unittest.TestCase):
52 predicates = set([inspect.isbuiltin, inspect.isclass, inspect.iscode,
53 inspect.isframe, inspect.isfunction, inspect.ismethod,
Christian Heimes7131fd92008-02-19 14:21:46 +000054 inspect.ismodule, inspect.istraceback,
55 inspect.isgenerator, inspect.isgeneratorfunction])
Tim Peters5a9fb3c2005-01-07 16:01:32 +000056
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000057 def istest(self, predicate, exp):
58 obj = eval(exp)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000059 self.assertTrue(predicate(obj), '%s(%s)' % (predicate.__name__, exp))
Tim Peters5a9fb3c2005-01-07 16:01:32 +000060
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000061 for other in self.predicates - set([predicate]):
Christian Heimes7131fd92008-02-19 14:21:46 +000062 if predicate == inspect.isgeneratorfunction and\
63 other == inspect.isfunction:
64 continue
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000065 self.assertFalse(other(obj), 'not %s(%s)' % (other.__name__, exp))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000066
Christian Heimes7131fd92008-02-19 14:21:46 +000067def generator_function_example(self):
68 for i in range(2):
69 yield i
70
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000071class TestPredicates(IsTestBase):
Christian Heimes227c8002008-03-03 20:34:40 +000072 def test_sixteen(self):
Guido van Rossumc1f779c2007-07-03 08:25:58 +000073 count = len([x for x in dir(inspect) if x.startswith('is')])
Christian Heimes7131fd92008-02-19 14:21:46 +000074 # This test is here for remember you to update Doc/library/inspect.rst
Christian Heimes78644762008-03-04 23:39:23 +000075 # which claims there are 16 such functions
Christian Heimes227c8002008-03-03 20:34:40 +000076 expected = 16
Thomas Wouters0e3f5912006-08-11 14:57:12 +000077 err_msg = "There are %d (not %d) is* functions" % (count, expected)
78 self.assertEqual(count, expected, err_msg)
Tim Peters5a9fb3c2005-01-07 16:01:32 +000079
Christian Heimes7131fd92008-02-19 14:21:46 +000080
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000081 def test_excluding_predicates(self):
82 self.istest(inspect.isbuiltin, 'sys.exit')
83 self.istest(inspect.isbuiltin, '[].append')
Neal Norwitz221085d2007-02-25 20:55:47 +000084 self.istest(inspect.iscode, 'mod.spam.__code__')
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000085 self.istest(inspect.isframe, 'tb.tb_frame')
86 self.istest(inspect.isfunction, 'mod.spam')
Christian Heimes4a22b5d2007-11-25 09:39:14 +000087 self.istest(inspect.isfunction, 'mod.StupidGit.abuse')
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000088 self.istest(inspect.ismethod, 'git.argue')
89 self.istest(inspect.ismodule, 'mod')
90 self.istest(inspect.istraceback, 'tb')
Guido van Rossum813b0e52007-05-21 18:11:34 +000091 self.istest(inspect.isdatadescriptor, 'collections.defaultdict.default_factory')
Christian Heimes7131fd92008-02-19 14:21:46 +000092 self.istest(inspect.isgenerator, '(x for x in range(2))')
93 self.istest(inspect.isgeneratorfunction, 'generator_function_example')
Thomas Wouters0e3f5912006-08-11 14:57:12 +000094 if hasattr(types, 'GetSetDescriptorType'):
95 self.istest(inspect.isgetsetdescriptor,
96 'type(tb.tb_frame).f_locals')
97 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000098 self.assertFalse(inspect.isgetsetdescriptor(type(tb.tb_frame).f_locals))
Thomas Wouters0e3f5912006-08-11 14:57:12 +000099 if hasattr(types, 'MemberDescriptorType'):
100 self.istest(inspect.ismemberdescriptor, 'datetime.timedelta.days')
101 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000102 self.assertFalse(inspect.ismemberdescriptor(datetime.timedelta.days))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000103
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000104 def test_isroutine(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000105 self.assertTrue(inspect.isroutine(mod.spam))
106 self.assertTrue(inspect.isroutine([].count))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000107
Benjamin Petersonc4656002009-01-17 22:41:18 +0000108 def test_isclass(self):
109 self.istest(inspect.isclass, 'mod.StupidGit')
110 self.assertTrue(inspect.isclass(list))
111
112 class CustomGetattr(object):
113 def __getattr__(self, attr):
114 return None
115 self.assertFalse(inspect.isclass(CustomGetattr()))
116
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000117 def test_get_slot_members(self):
118 class C(object):
119 __slots__ = ("a", "b")
120
121 x = C()
122 x.a = 42
123 members = dict(inspect.getmembers(x))
Benjamin Peterson577473f2010-01-19 00:09:57 +0000124 self.assertIn('a', members)
125 self.assertNotIn('b', members)
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000126
Benjamin Petersona0dfa822009-11-13 02:25:08 +0000127 def test_isabstract(self):
128 from abc import ABCMeta, abstractmethod
129
130 class AbstractClassExample(metaclass=ABCMeta):
131
132 @abstractmethod
133 def foo(self):
134 pass
135
136 class ClassExample(AbstractClassExample):
137 def foo(self):
138 pass
139
140 a = ClassExample()
141
142 # Test general behaviour.
143 self.assertTrue(inspect.isabstract(AbstractClassExample))
144 self.assertFalse(inspect.isabstract(ClassExample))
145 self.assertFalse(inspect.isabstract(a))
146 self.assertFalse(inspect.isabstract(int))
147 self.assertFalse(inspect.isabstract(5))
148
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000149
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000150class TestInterpreterStack(IsTestBase):
151 def __init__(self, *args, **kwargs):
152 unittest.TestCase.__init__(self, *args, **kwargs)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000153
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000154 git.abuse(7, 8, 9)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000155
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000156 def test_abuse_done(self):
157 self.istest(inspect.istraceback, 'git.ex[2]')
158 self.istest(inspect.isframe, 'mod.fr')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000159
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000160 def test_stack(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000161 self.assertTrue(len(mod.st) >= 5)
Christian Heimesa3538eb2007-11-06 11:44:48 +0000162 self.assertEqual(revise(*mod.st[0][1:]),
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000163 (modfile, 16, 'eggs', [' st = inspect.stack()\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000164 self.assertEqual(revise(*mod.st[1][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000165 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000166 self.assertEqual(revise(*mod.st[2][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000167 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000168 self.assertEqual(revise(*mod.st[3][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000169 (modfile, 39, 'abuse', [' self.argue(a, b, c)\n'], 0))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000170
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000171 def test_trace(self):
172 self.assertEqual(len(git.tr), 3)
Florent Xiclunac8575922010-03-24 17:37:49 +0000173 self.assertEqual(revise(*git.tr[0][1:]),
174 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
175 self.assertEqual(revise(*git.tr[1][1:]),
176 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
177 self.assertEqual(revise(*git.tr[2][1:]),
178 (modfile, 18, 'eggs', [' q = y / 0\n'], 0))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000179
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000180 def test_frame(self):
181 args, varargs, varkw, locals = inspect.getargvalues(mod.fr)
182 self.assertEqual(args, ['x', 'y'])
183 self.assertEqual(varargs, None)
184 self.assertEqual(varkw, None)
185 self.assertEqual(locals, {'x': 11, 'p': 11, 'y': 14})
186 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
187 '(x=11, y=14)')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000188
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000189 def test_previous_frame(self):
190 args, varargs, varkw, locals = inspect.getargvalues(mod.fr.f_back)
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000191 self.assertEqual(args, ['a', 'b', 'c', 'd', 'e', 'f'])
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000192 self.assertEqual(varargs, 'g')
193 self.assertEqual(varkw, 'h')
194 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000195 '(a=7, b=8, c=9, d=3, e=4, f=5, *g=(), **h={})')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000196
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000197class GetSourceBase(unittest.TestCase):
198 # Subclasses must override.
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000199 fodderModule = None
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000200
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000201 def __init__(self, *args, **kwargs):
202 unittest.TestCase.__init__(self, *args, **kwargs)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000203
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000204 with open(inspect.getsourcefile(self.fodderModule)) as fp:
Philip Jenveya27c5bd2009-05-28 06:09:08 +0000205 self.source = fp.read()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000206
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000207 def sourcerange(self, top, bottom):
208 lines = self.source.split("\n")
209 return "\n".join(lines[top-1:bottom]) + "\n"
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000210
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000211 def assertSourceEqual(self, obj, top, bottom):
212 self.assertEqual(inspect.getsource(obj),
213 self.sourcerange(top, bottom))
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000214
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000215class TestRetrievingSourceCode(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000216 fodderModule = mod
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000217
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000218 def test_getclasses(self):
219 classes = inspect.getmembers(mod, inspect.isclass)
220 self.assertEqual(classes,
221 [('FesteringGob', mod.FesteringGob),
222 ('MalodorousPervert', mod.MalodorousPervert),
223 ('ParrotDroppings', mod.ParrotDroppings),
224 ('StupidGit', mod.StupidGit)])
225 tree = inspect.getclasstree([cls[1] for cls in classes], 1)
226 self.assertEqual(tree,
Thomas Wouters725af872006-04-15 09:13:19 +0000227 [(object, ()),
228 [(mod.ParrotDroppings, (object,)),
229 (mod.StupidGit, (object,)),
230 [(mod.MalodorousPervert, (mod.StupidGit,)),
231 [(mod.FesteringGob, (mod.MalodorousPervert,
232 mod.ParrotDroppings))
233 ]
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000234 ]
235 ]
236 ])
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000237
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000238 def test_getfunctions(self):
239 functions = inspect.getmembers(mod, inspect.isfunction)
240 self.assertEqual(functions, [('eggs', mod.eggs),
241 ('spam', mod.spam)])
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000242
R. David Murray378c0cf2010-02-24 01:46:21 +0000243 @unittest.skipIf(sys.flags.optimize >= 2,
244 "Docstrings are omitted with -O2 and above")
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000245 def test_getdoc(self):
246 self.assertEqual(inspect.getdoc(mod), 'A module docstring.')
247 self.assertEqual(inspect.getdoc(mod.StupidGit),
248 'A longer,\n\nindented\n\ndocstring.')
249 self.assertEqual(inspect.getdoc(git.abuse),
250 'Another\n\ndocstring\n\ncontaining\n\ntabs')
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000251
Georg Brandl0c77a822008-06-10 16:37:50 +0000252 def test_cleandoc(self):
253 self.assertEqual(inspect.cleandoc('An\n indented\n docstring.'),
254 'An\nindented\ndocstring.')
255
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000256 def test_getcomments(self):
257 self.assertEqual(inspect.getcomments(mod), '# line 1\n')
258 self.assertEqual(inspect.getcomments(mod.StupidGit), '# line 20\n')
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000259
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000260 def test_getmodule(self):
Thomas Wouters89f507f2006-12-13 04:49:30 +0000261 # Check actual module
262 self.assertEqual(inspect.getmodule(mod), mod)
263 # Check class (uses __module__ attribute)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000264 self.assertEqual(inspect.getmodule(mod.StupidGit), mod)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000265 # Check a method (no __module__ attribute, falls back to filename)
266 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
267 # Do it again (check the caching isn't broken)
268 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
269 # Check a builtin
Georg Brandl1a3284e2007-12-02 09:40:06 +0000270 self.assertEqual(inspect.getmodule(str), sys.modules["builtins"])
Thomas Wouters89f507f2006-12-13 04:49:30 +0000271 # Check filename override
272 self.assertEqual(inspect.getmodule(None, modfile), mod)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000273
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000274 def test_getsource(self):
275 self.assertSourceEqual(git.abuse, 29, 39)
276 self.assertSourceEqual(mod.StupidGit, 21, 46)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000277
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000278 def test_getsourcefile(self):
Christian Heimesa3538eb2007-11-06 11:44:48 +0000279 self.assertEqual(normcase(inspect.getsourcefile(mod.spam)), modfile)
280 self.assertEqual(normcase(inspect.getsourcefile(git.abuse)), modfile)
R. David Murraya1b37402010-06-17 02:04:29 +0000281 fn = "_non_existing_filename_used_for_sourcefile_test.py"
282 co = compile("None", fn, "exec")
R. David Murray4155f972010-06-17 13:23:18 +0000283 self.assertEqual(inspect.getsourcefile(co), None)
R. David Murraya1b37402010-06-17 02:04:29 +0000284 linecache.cache[co.co_filename] = (1, None, "None", co.co_filename)
285 self.assertEqual(normcase(inspect.getsourcefile(co)), fn)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000286
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000287 def test_getfile(self):
288 self.assertEqual(inspect.getfile(mod.StupidGit), mod.__file__)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000289
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000290 def test_getmodule_recursion(self):
Christian Heimes45f9af32007-11-27 21:50:00 +0000291 from types import ModuleType
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000292 name = '__inspect_dummy'
Christian Heimes45f9af32007-11-27 21:50:00 +0000293 m = sys.modules[name] = ModuleType(name)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000294 m.__file__ = "<string>" # hopefully not a real filename...
295 m.__loader__ = "dummy" # pretend the filename is understood by a loader
Georg Brandl7cae87c2006-09-06 06:51:57 +0000296 exec("def x(): pass", m.__dict__)
Neal Norwitz221085d2007-02-25 20:55:47 +0000297 self.assertEqual(inspect.getsourcefile(m.x.__code__), '<string>')
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000298 del sys.modules[name]
299 inspect.getmodule(compile('a=10','','single'))
300
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000301class TestDecorators(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000302 fodderModule = mod2
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000303
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000304 def test_wrapped_decorator(self):
Christian Heimes09aaa882008-02-23 15:01:06 +0000305 self.assertSourceEqual(mod2.wrapped, 14, 17)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000306
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000307 def test_replacing_decorator(self):
308 self.assertSourceEqual(mod2.gone, 9, 10)
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000309
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000310class TestOneliners(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000311 fodderModule = mod2
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000312 def test_oneline_lambda(self):
313 # Test inspect.getsource with a one-line lambda function.
314 self.assertSourceEqual(mod2.oll, 25, 25)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000315
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000316 def test_threeline_lambda(self):
317 # Test inspect.getsource with a three-line lambda function,
318 # where the second and third lines are _not_ indented.
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000319 self.assertSourceEqual(mod2.tll, 28, 30)
320
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000321 def test_twoline_indented_lambda(self):
322 # Test inspect.getsource with a two-line lambda function,
323 # where the second line _is_ indented.
324 self.assertSourceEqual(mod2.tlli, 33, 34)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000325
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000326 def test_onelinefunc(self):
327 # Test inspect.getsource with a regular one-line function.
328 self.assertSourceEqual(mod2.onelinefunc, 37, 37)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000329
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000330 def test_manyargs(self):
331 # Test inspect.getsource with a regular function where
332 # the arguments are on two lines and _not_ indented and
333 # the body on the second line with the last arguments.
334 self.assertSourceEqual(mod2.manyargs, 40, 41)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000335
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000336 def test_twolinefunc(self):
337 # Test inspect.getsource with a regular function where
338 # the body is on two lines, following the argument list and
339 # continued on the next line by a \\.
340 self.assertSourceEqual(mod2.twolinefunc, 44, 45)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000341
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000342 def test_lambda_in_list(self):
343 # Test inspect.getsource with a one-line lambda function
344 # defined in a list, indented.
345 self.assertSourceEqual(mod2.a[1], 49, 49)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000346
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000347 def test_anonymous(self):
348 # Test inspect.getsource with a lambda function defined
349 # as argument to another function.
350 self.assertSourceEqual(mod2.anonymous, 55, 55)
351
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000352class TestBuggyCases(GetSourceBase):
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000353 fodderModule = mod2
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000354
355 def test_with_comment(self):
356 self.assertSourceEqual(mod2.with_comment, 58, 59)
357
358 def test_multiline_sig(self):
359 self.assertSourceEqual(mod2.multiline_sig[0], 63, 64)
360
Armin Rigodd5c0232005-09-25 11:45:45 +0000361 def test_nested_class(self):
362 self.assertSourceEqual(mod2.func69().func71, 71, 72)
363
364 def test_one_liner_followed_by_non_name(self):
365 self.assertSourceEqual(mod2.func77, 77, 77)
366
367 def test_one_liner_dedent_non_name(self):
368 self.assertSourceEqual(mod2.cls82.func83, 83, 83)
369
370 def test_with_comment_instead_of_docstring(self):
371 self.assertSourceEqual(mod2.func88, 88, 90)
372
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000373 def test_method_in_dynamic_class(self):
374 self.assertSourceEqual(mod2.method_in_dynamic_class, 95, 97)
375
R. David Murrayb5655772009-05-14 16:17:50 +0000376 @unittest.skipIf(
377 not hasattr(unicodedata, '__file__') or
378 unicodedata.__file__[-4:] in (".pyc", ".pyo"),
379 "unicodedata is not an external binary module")
R. David Murray74b89242009-05-13 17:33:03 +0000380 def test_findsource_binary(self):
R. David Murrayb5655772009-05-14 16:17:50 +0000381 self.assertRaises(IOError, inspect.getsource, unicodedata)
382 self.assertRaises(IOError, inspect.findsource, unicodedata)
R. David Murray74b89242009-05-13 17:33:03 +0000383
R. David Murraya1b37402010-06-17 02:04:29 +0000384 def test_findsource_code_in_linecache(self):
385 lines = ["x=1"]
386 co = compile(lines[0], "_dynamically_created_file", "exec")
387 self.assertRaises(IOError, inspect.findsource, co)
388 self.assertRaises(IOError, inspect.getsource, co)
389 linecache.cache[co.co_filename] = (1, None, lines, co.co_filename)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000390 self.assertEqual(inspect.findsource(co), (lines,0))
391 self.assertEqual(inspect.getsource(co), lines[0])
R. David Murraya1b37402010-06-17 02:04:29 +0000392
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000393class TestNoEOL(GetSourceBase):
394 def __init__(self, *args, **kwargs):
395 self.tempdir = TESTFN + '_dir'
396 os.mkdir(self.tempdir)
397 with open(os.path.join(self.tempdir,
398 'inspect_fodder3%spy' % os.extsep), 'w') as f:
399 f.write("class X:\n pass # No EOL")
400 with DirsOnSysPath(self.tempdir):
401 import inspect_fodder3 as mod3
402 self.fodderModule = mod3
403 GetSourceBase.__init__(self, *args, **kwargs)
404
405 def tearDown(self):
406 shutil.rmtree(self.tempdir)
407
408 def test_class(self):
409 self.assertSourceEqual(self.fodderModule.X, 1, 2)
410
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000411# Helper for testing classify_class_attrs.
Tim Peters13b49d32001-09-23 02:00:29 +0000412def attrs_wo_objs(cls):
413 return [t[:3] for t in inspect.classify_class_attrs(cls)]
414
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000415class TestClassesAndFunctions(unittest.TestCase):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000416 def test_newstyle_mro(self):
417 # The same w/ new-class MRO.
418 class A(object): pass
419 class B(A): pass
420 class C(A): pass
421 class D(B, C): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000422
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000423 expected = (D, B, C, A, object)
424 got = inspect.getmro(D)
425 self.assertEqual(expected, got)
Tim Peters13b49d32001-09-23 02:00:29 +0000426
Christian Heimes3795b532007-11-08 13:48:53 +0000427 def assertArgSpecEquals(self, routine, args_e, varargs_e=None,
428 varkw_e=None, defaults_e=None, formatted=None):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000429 args, varargs, varkw, defaults = inspect.getargspec(routine)
430 self.assertEqual(args, args_e)
431 self.assertEqual(varargs, varargs_e)
432 self.assertEqual(varkw, varkw_e)
433 self.assertEqual(defaults, defaults_e)
434 if formatted is not None:
435 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults),
436 formatted)
Tim Peters13b49d32001-09-23 02:00:29 +0000437
Christian Heimes3795b532007-11-08 13:48:53 +0000438 def assertFullArgSpecEquals(self, routine, args_e, varargs_e=None,
439 varkw_e=None, defaults_e=None,
440 kwonlyargs_e=[], kwonlydefaults_e=None,
441 ann_e={}, formatted=None):
442 args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \
443 inspect.getfullargspec(routine)
444 self.assertEqual(args, args_e)
445 self.assertEqual(varargs, varargs_e)
446 self.assertEqual(varkw, varkw_e)
447 self.assertEqual(defaults, defaults_e)
448 self.assertEqual(kwonlyargs, kwonlyargs_e)
449 self.assertEqual(kwonlydefaults, kwonlydefaults_e)
450 self.assertEqual(ann, ann_e)
451 if formatted is not None:
452 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults,
453 kwonlyargs, kwonlydefaults, ann),
454 formatted)
455
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000456 def test_getargspec(self):
Christian Heimes3795b532007-11-08 13:48:53 +0000457 self.assertArgSpecEquals(mod.eggs, ['x', 'y'], formatted='(x, y)')
Tim Peters13b49d32001-09-23 02:00:29 +0000458
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000459 self.assertArgSpecEquals(mod.spam,
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000460 ['a', 'b', 'c', 'd', 'e', 'f'],
461 'g', 'h', (3, 4, 5),
462 '(a, b, c, d=3, e=4, f=5, *g, **h)')
Tim Peters13b49d32001-09-23 02:00:29 +0000463
Christian Heimes3795b532007-11-08 13:48:53 +0000464 self.assertRaises(ValueError, self.assertArgSpecEquals,
465 mod2.keyworded, [])
466
467 self.assertRaises(ValueError, self.assertArgSpecEquals,
468 mod2.annotated, [])
Benjamin Peterson9953a8d2009-01-17 04:15:01 +0000469 self.assertRaises(ValueError, self.assertArgSpecEquals,
470 mod2.keyword_only_arg, [])
471
Christian Heimes3795b532007-11-08 13:48:53 +0000472
473 def test_getfullargspec(self):
474 self.assertFullArgSpecEquals(mod2.keyworded, [], varargs_e='arg1',
475 kwonlyargs_e=['arg2'],
476 kwonlydefaults_e={'arg2':1},
477 formatted='(*arg1, arg2=1)')
478
479 self.assertFullArgSpecEquals(mod2.annotated, ['arg1'],
Christian Heimesc9543e42007-11-28 08:28:28 +0000480 ann_e={'arg1' : list},
Christian Heimes3795b532007-11-08 13:48:53 +0000481 formatted='(arg1: list)')
Benjamin Peterson9953a8d2009-01-17 04:15:01 +0000482 self.assertFullArgSpecEquals(mod2.keyword_only_arg, [],
483 kwonlyargs_e=['arg'],
484 formatted='(*, arg)')
485
Christian Heimes3795b532007-11-08 13:48:53 +0000486
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000487 def test_getargspec_method(self):
488 class A(object):
489 def m(self):
490 pass
491 self.assertArgSpecEquals(A.m, ['self'])
Tim Peters13b49d32001-09-23 02:00:29 +0000492
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000493 def test_classify_newstyle(self):
494 class A(object):
Tim Peters13b49d32001-09-23 02:00:29 +0000495
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000496 def s(): pass
497 s = staticmethod(s)
Tim Peters13b49d32001-09-23 02:00:29 +0000498
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000499 def c(cls): pass
500 c = classmethod(c)
Tim Peters13b49d32001-09-23 02:00:29 +0000501
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000502 def getp(self): pass
503 p = property(getp)
Tim Peters13b49d32001-09-23 02:00:29 +0000504
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000505 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000506
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000507 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000508
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000509 datablob = '1'
Tim Peters13b49d32001-09-23 02:00:29 +0000510
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000511 attrs = attrs_wo_objs(A)
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')
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000515 self.assertIn(('m', 'method', A), attrs,
516 'missing plain method: %r' % attrs)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000517 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
518 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Tim Peters13b49d32001-09-23 02:00:29 +0000519
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000520 class B(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000521
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000522 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000523
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000524 attrs = attrs_wo_objs(B)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000525 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
526 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
527 self.assertIn(('p', 'property', A), attrs, 'missing property')
528 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
529 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
530 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Tim Peters13b49d32001-09-23 02:00:29 +0000531
532
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000533 class C(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000534
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000535 def m(self): pass
536 def c(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000537
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000538 attrs = attrs_wo_objs(C)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000539 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
540 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
541 self.assertIn(('p', 'property', A), attrs, 'missing property')
542 self.assertIn(('m', 'method', C), attrs, 'missing plain method')
543 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
544 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Tim Peters13b49d32001-09-23 02:00:29 +0000545
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000546 class D(B, C):
Tim Peters13b49d32001-09-23 02:00:29 +0000547
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000548 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000549
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000550 attrs = attrs_wo_objs(D)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000551 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
552 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
553 self.assertIn(('p', 'property', A), attrs, 'missing property')
554 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
555 self.assertIn(('m1', 'method', D), attrs, 'missing plain method')
556 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Jeremy Hyltonc4bf5ed2003-06-27 18:43:12 +0000557
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000558class TestGetcallargsFunctions(unittest.TestCase):
559
560 def assertEqualCallArgs(self, func, call_params_string, locs=None):
561 locs = dict(locs or {}, func=func)
562 r1 = eval('func(%s)' % call_params_string, None, locs)
563 r2 = eval('inspect.getcallargs(func, %s)' % call_params_string, None,
564 locs)
565 self.assertEqual(r1, r2)
566
567 def assertEqualException(self, func, call_param_string, locs=None):
568 locs = dict(locs or {}, func=func)
569 try:
570 eval('func(%s)' % call_param_string, None, locs)
571 except Exception as e:
572 ex1 = e
573 else:
574 self.fail('Exception not raised')
575 try:
576 eval('inspect.getcallargs(func, %s)' % call_param_string, None,
577 locs)
578 except Exception as e:
579 ex2 = e
580 else:
581 self.fail('Exception not raised')
582 self.assertIs(type(ex1), type(ex2))
583 self.assertEqual(str(ex1), str(ex2))
584 del ex1, ex2
585
586 def makeCallable(self, signature):
587 """Create a function that returns its locals()"""
588 code = "lambda %s: locals()"
589 return eval(code % signature)
590
591 def test_plain(self):
592 f = self.makeCallable('a, b=1')
593 self.assertEqualCallArgs(f, '2')
594 self.assertEqualCallArgs(f, '2, 3')
595 self.assertEqualCallArgs(f, 'a=2')
596 self.assertEqualCallArgs(f, 'b=3, a=2')
597 self.assertEqualCallArgs(f, '2, b=3')
598 # expand *iterable / **mapping
599 self.assertEqualCallArgs(f, '*(2,)')
600 self.assertEqualCallArgs(f, '*[2]')
601 self.assertEqualCallArgs(f, '*(2, 3)')
602 self.assertEqualCallArgs(f, '*[2, 3]')
603 self.assertEqualCallArgs(f, '**{"a":2}')
604 self.assertEqualCallArgs(f, 'b=3, **{"a":2}')
605 self.assertEqualCallArgs(f, '2, **{"b":3}')
606 self.assertEqualCallArgs(f, '**{"b":3, "a":2}')
607 # expand UserList / UserDict
608 self.assertEqualCallArgs(f, '*collections.UserList([2])')
609 self.assertEqualCallArgs(f, '*collections.UserList([2, 3])')
610 self.assertEqualCallArgs(f, '**collections.UserDict(a=2)')
611 self.assertEqualCallArgs(f, '2, **collections.UserDict(b=3)')
612 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3)')
613
614 def test_varargs(self):
615 f = self.makeCallable('a, b=1, *c')
616 self.assertEqualCallArgs(f, '2')
617 self.assertEqualCallArgs(f, '2, 3')
618 self.assertEqualCallArgs(f, '2, 3, 4')
619 self.assertEqualCallArgs(f, '*(2,3,4)')
620 self.assertEqualCallArgs(f, '2, *[3,4]')
621 self.assertEqualCallArgs(f, '2, 3, *collections.UserList([4])')
622
623 def test_varkw(self):
624 f = self.makeCallable('a, b=1, **c')
625 self.assertEqualCallArgs(f, 'a=2')
626 self.assertEqualCallArgs(f, '2, b=3, c=4')
627 self.assertEqualCallArgs(f, 'b=3, a=2, c=4')
628 self.assertEqualCallArgs(f, 'c=4, **{"a":2, "b":3}')
629 self.assertEqualCallArgs(f, '2, c=4, **{"b":3}')
630 self.assertEqualCallArgs(f, 'b=2, **{"a":3, "c":4}')
631 self.assertEqualCallArgs(f, '**collections.UserDict(a=2, b=3, c=4)')
632 self.assertEqualCallArgs(f, '2, c=4, **collections.UserDict(b=3)')
633 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3, c=4)')
634
635 def test_keyword_only(self):
636 f = self.makeCallable('a=3, *, c, d=2')
637 self.assertEqualCallArgs(f, 'c=3')
638 self.assertEqualCallArgs(f, 'c=3, a=3')
639 self.assertEqualCallArgs(f, 'a=2, c=4')
640 self.assertEqualCallArgs(f, '4, c=4')
641 self.assertEqualException(f, '')
642 self.assertEqualException(f, '3')
643 self.assertEqualException(f, 'a=3')
644 self.assertEqualException(f, 'd=4')
645
646 def test_multiple_features(self):
647 f = self.makeCallable('a, b=2, *f, **g')
648 self.assertEqualCallArgs(f, '2, 3, 7')
649 self.assertEqualCallArgs(f, '2, 3, x=8')
650 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
651 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9')
652 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9')
653 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
654 '[2, 3, (4,[5,6])]), **{"y":9, "z":10}')
655 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
656 '(4,[5,6])]), **collections.UserDict('
657 'y=9, z=10)')
658
659 def test_errors(self):
660 f0 = self.makeCallable('')
661 f1 = self.makeCallable('a, b')
662 f2 = self.makeCallable('a, b=1')
663 # f0 takes no arguments
664 self.assertEqualException(f0, '1')
665 self.assertEqualException(f0, 'x=1')
666 self.assertEqualException(f0, '1,x=1')
667 # f1 takes exactly 2 arguments
668 self.assertEqualException(f1, '')
669 self.assertEqualException(f1, '1')
670 self.assertEqualException(f1, 'a=2')
671 self.assertEqualException(f1, 'b=3')
672 # f2 takes at least 1 argument
673 self.assertEqualException(f2, '')
674 self.assertEqualException(f2, 'b=3')
675 for f in f1, f2:
676 # f1/f2 takes exactly/at most 2 arguments
677 self.assertEqualException(f, '2, 3, 4')
678 self.assertEqualException(f, '1, 2, 3, a=1')
679 self.assertEqualException(f, '2, 3, 4, c=5')
680 self.assertEqualException(f, '2, 3, 4, a=1, c=5')
681 # f got an unexpected keyword argument
682 self.assertEqualException(f, 'c=2')
683 self.assertEqualException(f, '2, c=3')
684 self.assertEqualException(f, '2, 3, c=4')
685 self.assertEqualException(f, '2, c=4, b=3')
686 self.assertEqualException(f, '**{u"\u03c0\u03b9": 4}')
687 # f got multiple values for keyword argument
688 self.assertEqualException(f, '1, a=2')
689 self.assertEqualException(f, '1, **{"a":2}')
690 self.assertEqualException(f, '1, 2, b=3')
691 # XXX: Python inconsistency
692 # - for functions and bound methods: unexpected keyword 'c'
693 # - for unbound methods: multiple values for keyword 'a'
694 #self.assertEqualException(f, '1, c=3, a=2')
695
696class TestGetcallargsMethods(TestGetcallargsFunctions):
697
698 def setUp(self):
699 class Foo(object):
700 pass
701 self.cls = Foo
702 self.inst = Foo()
703
704 def makeCallable(self, signature):
705 assert 'self' not in signature
706 mk = super(TestGetcallargsMethods, self).makeCallable
707 self.cls.method = mk('self, ' + signature)
708 return self.inst.method
709
710class TestGetcallargsUnboundMethods(TestGetcallargsMethods):
711
712 def makeCallable(self, signature):
713 super(TestGetcallargsUnboundMethods, self).makeCallable(signature)
714 return self.cls.method
715
716 def assertEqualCallArgs(self, func, call_params_string, locs=None):
717 return super(TestGetcallargsUnboundMethods, self).assertEqualCallArgs(
718 *self._getAssertEqualParams(func, call_params_string, locs))
719
720 def assertEqualException(self, func, call_params_string, locs=None):
721 return super(TestGetcallargsUnboundMethods, self).assertEqualException(
722 *self._getAssertEqualParams(func, call_params_string, locs))
723
724 def _getAssertEqualParams(self, func, call_params_string, locs=None):
725 assert 'inst' not in call_params_string
726 locs = dict(locs or {}, inst=self.inst)
727 return (func, 'inst,' + call_params_string, locs)
728
Michael Foord95fc51d2010-11-20 15:07:30 +0000729
730class TestGetattrStatic(unittest.TestCase):
731
732 def test_basic(self):
733 class Thing(object):
734 x = object()
735
736 thing = Thing()
737 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
738 self.assertEqual(inspect.getattr_static(thing, 'x', None), Thing.x)
739 with self.assertRaises(AttributeError):
740 inspect.getattr_static(thing, 'y')
741
742 self.assertEqual(inspect.getattr_static(thing, 'y', 3), 3)
743
744 def test_inherited(self):
745 class Thing(object):
746 x = object()
747 class OtherThing(Thing):
748 pass
749
750 something = OtherThing()
751 self.assertEqual(inspect.getattr_static(something, 'x'), Thing.x)
752
753 def test_instance_attr(self):
754 class Thing(object):
755 x = 2
756 def __init__(self, x):
757 self.x = x
758 thing = Thing(3)
759 self.assertEqual(inspect.getattr_static(thing, 'x'), 3)
760 del thing.x
761 self.assertEqual(inspect.getattr_static(thing, 'x'), 2)
762
763 def test_property(self):
764 class Thing(object):
765 @property
766 def x(self):
767 raise AttributeError("I'm pretending not to exist")
768 thing = Thing()
769 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
770
771 def test_descriptor(self):
772 class descriptor(object):
773 def __get__(*_):
774 raise AttributeError("I'm pretending not to exist")
775 desc = descriptor()
776 class Thing(object):
777 x = desc
778 thing = Thing()
779 self.assertEqual(inspect.getattr_static(thing, 'x'), desc)
780
781 def test_classAttribute(self):
782 class Thing(object):
783 x = object()
784
785 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.x)
786
787 def test_inherited_classattribute(self):
788 class Thing(object):
789 x = object()
790 class OtherThing(Thing):
791 pass
792
793 self.assertEqual(inspect.getattr_static(OtherThing, 'x'), Thing.x)
794
795 def test_slots(self):
796 class Thing(object):
797 y = 'bar'
798 __slots__ = ['x']
799 def __init__(self):
800 self.x = 'foo'
801 thing = Thing()
802 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
803 self.assertEqual(inspect.getattr_static(thing, 'y'), 'bar')
804
805 del thing.x
806 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
807
808 def test_metaclass(self):
809 class meta(type):
810 attr = 'foo'
811 class Thing(object, metaclass=meta):
812 pass
813 self.assertEqual(inspect.getattr_static(Thing, 'attr'), 'foo')
814
815 class sub(meta):
816 pass
817 class OtherThing(object, metaclass=sub):
818 x = 3
819 self.assertEqual(inspect.getattr_static(OtherThing, 'attr'), 'foo')
820
821 class OtherOtherThing(OtherThing):
822 pass
823 # this test is odd, but it was added as it exposed a bug
824 self.assertEqual(inspect.getattr_static(OtherOtherThing, 'x'), 3)
825
826 def test_no_dict_no_slots(self):
827 self.assertEqual(inspect.getattr_static(1, 'foo', None), None)
828 self.assertNotEqual(inspect.getattr_static('foo', 'lower'), None)
829
830 def test_no_dict_no_slots_instance_member(self):
831 # returns descriptor
832 with open(__file__) as handle:
833 self.assertEqual(inspect.getattr_static(handle, 'name'), type(handle).name)
834
835 def test_inherited_slots(self):
836 # returns descriptor
837 class Thing(object):
838 __slots__ = ['x']
839 def __init__(self):
840 self.x = 'foo'
841
842 class OtherThing(Thing):
843 pass
844 # it would be nice if this worked...
845 # we get the descriptor instead of the instance attribute
846 self.assertEqual(inspect.getattr_static(OtherThing(), 'x'), Thing.x)
847
848 def test_descriptor(self):
849 class descriptor(object):
850 def __get__(self, instance, owner):
851 return 3
852 class Foo(object):
853 d = descriptor()
854
855 foo = Foo()
856
857 # for a non data descriptor we return the instance attribute
858 foo.__dict__['d'] = 1
859 self.assertEqual(inspect.getattr_static(foo, 'd'), 1)
860
861 # if the descriptor is a data-desciptor we should return the
862 # descriptor
863 descriptor.__set__ = lambda s, i, v: None
864 self.assertEqual(inspect.getattr_static(foo, 'd'), Foo.__dict__['d'])
865
866
867 def test_metaclass_with_descriptor(self):
868 class descriptor(object):
869 def __get__(self, instance, owner):
870 return 3
871 class meta(type):
872 d = descriptor()
873 class Thing(object, metaclass=meta):
874 pass
875 self.assertEqual(inspect.getattr_static(Thing, 'd'), meta.__dict__['d'])
876
877
Michael Foordcc7ebb82010-11-20 16:20:16 +0000878 def test_class_as_property(self):
879 class Base(object):
880 foo = 3
881
882 class Something(Base):
Michael Foord35184ed2010-11-20 16:58:30 +0000883 executed = False
Michael Foordcc7ebb82010-11-20 16:20:16 +0000884 @property
885 def __class__(self):
Michael Foord35184ed2010-11-20 16:58:30 +0000886 self.executed = True
Michael Foordcc7ebb82010-11-20 16:20:16 +0000887 return object
888
Michael Foord35184ed2010-11-20 16:58:30 +0000889 instance = Something()
890 self.assertEqual(inspect.getattr_static(instance, 'foo'), 3)
891 self.assertFalse(instance.executed)
Michael Foordcc7ebb82010-11-20 16:20:16 +0000892 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
893
Michael Foorde5162652010-11-20 16:40:44 +0000894 def test_mro_as_property(self):
895 class Meta(type):
896 @property
897 def __mro__(self):
898 return (object,)
899
900 class Base(object):
901 foo = 3
902
903 class Something(Base, metaclass=Meta):
904 pass
905
906 self.assertEqual(inspect.getattr_static(Something(), 'foo'), 3)
907 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
908
909
Nick Coghlane0f04652010-11-21 03:44:04 +0000910class TestGetGeneratorState(unittest.TestCase):
911
912 def setUp(self):
913 def number_generator():
914 for number in range(5):
915 yield number
916 self.generator = number_generator()
917
918 def _generatorstate(self):
919 return inspect.getgeneratorstate(self.generator)
920
921 def test_created(self):
922 self.assertEqual(self._generatorstate(), inspect.GEN_CREATED)
923
924 def test_suspended(self):
925 next(self.generator)
926 self.assertEqual(self._generatorstate(), inspect.GEN_SUSPENDED)
927
928 def test_closed_after_exhaustion(self):
929 for i in self.generator:
930 pass
931 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
932
933 def test_closed_after_immediate_exception(self):
934 with self.assertRaises(RuntimeError):
935 self.generator.throw(RuntimeError)
936 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
937
938 def test_running(self):
939 # As mentioned on issue #10220, checking for the RUNNING state only
940 # makes sense inside the generator itself.
941 # The following generator checks for this by using the closure's
942 # reference to self and the generator state checking helper method
943 def running_check_generator():
944 for number in range(5):
945 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
946 yield number
947 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
948 self.generator = running_check_generator()
949 # Running up to the first yield
950 next(self.generator)
951 # Running after the first yield
952 next(self.generator)
953
Nick Coghlan7921b9f2010-11-30 06:36:04 +0000954 def test_easy_debugging(self):
955 # repr() and str() of a generator state should contain the state name
956 names = 'GEN_CREATED GEN_RUNNING GEN_SUSPENDED GEN_CLOSED'.split()
957 for name in names:
958 state = getattr(inspect, name)
959 self.assertIn(name, repr(state))
960 self.assertIn(name, str(state))
961
Nick Coghlane0f04652010-11-21 03:44:04 +0000962
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000963def test_main():
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000964 run_unittest(
965 TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBuggyCases,
966 TestInterpreterStack, TestClassesAndFunctions, TestPredicates,
967 TestGetcallargsFunctions, TestGetcallargsMethods,
Alexander Belopolskyf546e702010-12-02 00:10:11 +0000968 TestGetcallargsUnboundMethods, TestGetattrStatic, TestGetGeneratorState,
969 TestNoEOL
Michael Foord95fc51d2010-11-20 15:07:30 +0000970 )
Martin v. Löwis893ffa42003-10-31 15:35:53 +0000971
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000972if __name__ == "__main__":
973 test_main()