blob: df480b8b9dd23060410179c3193b774a85c4f28d [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
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000015
R. David Murray74b89242009-05-13 17:33:03 +000016# C module for test_findsource_binary
R. David Murrayb5655772009-05-14 16:17:50 +000017import unicodedata
R. David Murray74b89242009-05-13 17:33:03 +000018
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000019# Functions tested in this suite:
20# ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode,
Christian Heimes7131fd92008-02-19 14:21:46 +000021# isbuiltin, isroutine, isgenerator, isgeneratorfunction, getmembers,
22# getdoc, getfile, getmodule, getsourcefile, getcomments, getsource,
23# getclasstree, getargspec, getargvalues, formatargspec, formatargvalues,
24# currentframe, stack, trace, isdatadescriptor
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000025
Nick Coghlanf088e5e2008-12-14 11:50:48 +000026# NOTE: There are some additional tests relating to interaction with
27# zipimport in the test_zipimport_support test module.
28
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000029modfile = mod.__file__
Thomas Wouters0e3f5912006-08-11 14:57:12 +000030if modfile.endswith(('c', 'o')):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000031 modfile = modfile[:-1]
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000032
Christian Heimesa3538eb2007-11-06 11:44:48 +000033# Normalize file names: on Windows, the case of file names of compiled
34# modules depends on the path used to start the python executable.
35modfile = normcase(modfile)
36
37def revise(filename, *args):
38 return (normcase(filename),) + args
39
Georg Brandl1a3284e2007-12-02 09:40:06 +000040import builtins
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000041
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000042try:
43 1/0
44except:
Guido van Rossume7ba4952007-06-06 23:52:48 +000045 tb = sys.exc_info()[2]
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000046
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000047git = mod.StupidGit()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000048
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000049class IsTestBase(unittest.TestCase):
50 predicates = set([inspect.isbuiltin, inspect.isclass, inspect.iscode,
51 inspect.isframe, inspect.isfunction, inspect.ismethod,
Christian Heimes7131fd92008-02-19 14:21:46 +000052 inspect.ismodule, inspect.istraceback,
53 inspect.isgenerator, inspect.isgeneratorfunction])
Tim Peters5a9fb3c2005-01-07 16:01:32 +000054
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000055 def istest(self, predicate, exp):
56 obj = eval(exp)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000057 self.assertTrue(predicate(obj), '%s(%s)' % (predicate.__name__, exp))
Tim Peters5a9fb3c2005-01-07 16:01:32 +000058
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000059 for other in self.predicates - set([predicate]):
Christian Heimes7131fd92008-02-19 14:21:46 +000060 if predicate == inspect.isgeneratorfunction and\
61 other == inspect.isfunction:
62 continue
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000063 self.assertFalse(other(obj), 'not %s(%s)' % (other.__name__, exp))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000064
Christian Heimes7131fd92008-02-19 14:21:46 +000065def generator_function_example(self):
66 for i in range(2):
67 yield i
68
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000069class TestPredicates(IsTestBase):
Christian Heimes227c8002008-03-03 20:34:40 +000070 def test_sixteen(self):
Guido van Rossumc1f779c2007-07-03 08:25:58 +000071 count = len([x for x in dir(inspect) if x.startswith('is')])
Christian Heimes7131fd92008-02-19 14:21:46 +000072 # This test is here for remember you to update Doc/library/inspect.rst
Christian Heimes78644762008-03-04 23:39:23 +000073 # which claims there are 16 such functions
Christian Heimes227c8002008-03-03 20:34:40 +000074 expected = 16
Thomas Wouters0e3f5912006-08-11 14:57:12 +000075 err_msg = "There are %d (not %d) is* functions" % (count, expected)
76 self.assertEqual(count, expected, err_msg)
Tim Peters5a9fb3c2005-01-07 16:01:32 +000077
Christian Heimes7131fd92008-02-19 14:21:46 +000078
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000079 def test_excluding_predicates(self):
80 self.istest(inspect.isbuiltin, 'sys.exit')
81 self.istest(inspect.isbuiltin, '[].append')
Neal Norwitz221085d2007-02-25 20:55:47 +000082 self.istest(inspect.iscode, 'mod.spam.__code__')
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000083 self.istest(inspect.isframe, 'tb.tb_frame')
84 self.istest(inspect.isfunction, 'mod.spam')
Christian Heimes4a22b5d2007-11-25 09:39:14 +000085 self.istest(inspect.isfunction, 'mod.StupidGit.abuse')
Johannes Gijsberscb9015d2004-12-12 16:20:22 +000086 self.istest(inspect.ismethod, 'git.argue')
87 self.istest(inspect.ismodule, 'mod')
88 self.istest(inspect.istraceback, 'tb')
Guido van Rossum813b0e52007-05-21 18:11:34 +000089 self.istest(inspect.isdatadescriptor, 'collections.defaultdict.default_factory')
Christian Heimes7131fd92008-02-19 14:21:46 +000090 self.istest(inspect.isgenerator, '(x for x in range(2))')
91 self.istest(inspect.isgeneratorfunction, 'generator_function_example')
Thomas Wouters0e3f5912006-08-11 14:57:12 +000092 if hasattr(types, 'GetSetDescriptorType'):
93 self.istest(inspect.isgetsetdescriptor,
94 'type(tb.tb_frame).f_locals')
95 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000096 self.assertFalse(inspect.isgetsetdescriptor(type(tb.tb_frame).f_locals))
Thomas Wouters0e3f5912006-08-11 14:57:12 +000097 if hasattr(types, 'MemberDescriptorType'):
98 self.istest(inspect.ismemberdescriptor, 'datetime.timedelta.days')
99 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000100 self.assertFalse(inspect.ismemberdescriptor(datetime.timedelta.days))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000101
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000102 def test_isroutine(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000103 self.assertTrue(inspect.isroutine(mod.spam))
104 self.assertTrue(inspect.isroutine([].count))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000105
Benjamin Petersonc4656002009-01-17 22:41:18 +0000106 def test_isclass(self):
107 self.istest(inspect.isclass, 'mod.StupidGit')
108 self.assertTrue(inspect.isclass(list))
109
110 class CustomGetattr(object):
111 def __getattr__(self, attr):
112 return None
113 self.assertFalse(inspect.isclass(CustomGetattr()))
114
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000115 def test_get_slot_members(self):
116 class C(object):
117 __slots__ = ("a", "b")
118
119 x = C()
120 x.a = 42
121 members = dict(inspect.getmembers(x))
Benjamin Peterson577473f2010-01-19 00:09:57 +0000122 self.assertIn('a', members)
123 self.assertNotIn('b', members)
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000124
Benjamin Petersona0dfa822009-11-13 02:25:08 +0000125 def test_isabstract(self):
126 from abc import ABCMeta, abstractmethod
127
128 class AbstractClassExample(metaclass=ABCMeta):
129
130 @abstractmethod
131 def foo(self):
132 pass
133
134 class ClassExample(AbstractClassExample):
135 def foo(self):
136 pass
137
138 a = ClassExample()
139
140 # Test general behaviour.
141 self.assertTrue(inspect.isabstract(AbstractClassExample))
142 self.assertFalse(inspect.isabstract(ClassExample))
143 self.assertFalse(inspect.isabstract(a))
144 self.assertFalse(inspect.isabstract(int))
145 self.assertFalse(inspect.isabstract(5))
146
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000147
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000148class TestInterpreterStack(IsTestBase):
149 def __init__(self, *args, **kwargs):
150 unittest.TestCase.__init__(self, *args, **kwargs)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000151
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000152 git.abuse(7, 8, 9)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000153
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000154 def test_abuse_done(self):
155 self.istest(inspect.istraceback, 'git.ex[2]')
156 self.istest(inspect.isframe, 'mod.fr')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000157
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000158 def test_stack(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000159 self.assertTrue(len(mod.st) >= 5)
Christian Heimesa3538eb2007-11-06 11:44:48 +0000160 self.assertEqual(revise(*mod.st[0][1:]),
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000161 (modfile, 16, 'eggs', [' st = inspect.stack()\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000162 self.assertEqual(revise(*mod.st[1][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000163 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000164 self.assertEqual(revise(*mod.st[2][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000165 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
Christian Heimesa3538eb2007-11-06 11:44:48 +0000166 self.assertEqual(revise(*mod.st[3][1:]),
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000167 (modfile, 39, 'abuse', [' self.argue(a, b, c)\n'], 0))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000168
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000169 def test_trace(self):
170 self.assertEqual(len(git.tr), 3)
Florent Xiclunac8575922010-03-24 17:37:49 +0000171 self.assertEqual(revise(*git.tr[0][1:]),
172 (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0))
173 self.assertEqual(revise(*git.tr[1][1:]),
174 (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0))
175 self.assertEqual(revise(*git.tr[2][1:]),
176 (modfile, 18, 'eggs', [' q = y / 0\n'], 0))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000177
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000178 def test_frame(self):
179 args, varargs, varkw, locals = inspect.getargvalues(mod.fr)
180 self.assertEqual(args, ['x', 'y'])
181 self.assertEqual(varargs, None)
182 self.assertEqual(varkw, None)
183 self.assertEqual(locals, {'x': 11, 'p': 11, 'y': 14})
184 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
185 '(x=11, y=14)')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000186
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000187 def test_previous_frame(self):
188 args, varargs, varkw, locals = inspect.getargvalues(mod.fr.f_back)
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000189 self.assertEqual(args, ['a', 'b', 'c', 'd', 'e', 'f'])
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000190 self.assertEqual(varargs, 'g')
191 self.assertEqual(varkw, 'h')
192 self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000193 '(a=7, b=8, c=9, d=3, e=4, f=5, *g=(), **h={})')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000194
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000195class GetSourceBase(unittest.TestCase):
196 # Subclasses must override.
197 fodderFile = None
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000198
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000199 def __init__(self, *args, **kwargs):
200 unittest.TestCase.__init__(self, *args, **kwargs)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000201
Philip Jenveya27c5bd2009-05-28 06:09:08 +0000202 with open(inspect.getsourcefile(self.fodderFile)) as fp:
203 self.source = fp.read()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000204
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000205 def sourcerange(self, top, bottom):
206 lines = self.source.split("\n")
207 return "\n".join(lines[top-1:bottom]) + "\n"
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000208
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000209 def assertSourceEqual(self, obj, top, bottom):
210 self.assertEqual(inspect.getsource(obj),
211 self.sourcerange(top, bottom))
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000212
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000213class TestRetrievingSourceCode(GetSourceBase):
214 fodderFile = mod
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000215
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000216 def test_getclasses(self):
217 classes = inspect.getmembers(mod, inspect.isclass)
218 self.assertEqual(classes,
219 [('FesteringGob', mod.FesteringGob),
220 ('MalodorousPervert', mod.MalodorousPervert),
221 ('ParrotDroppings', mod.ParrotDroppings),
222 ('StupidGit', mod.StupidGit)])
223 tree = inspect.getclasstree([cls[1] for cls in classes], 1)
224 self.assertEqual(tree,
Thomas Wouters725af872006-04-15 09:13:19 +0000225 [(object, ()),
226 [(mod.ParrotDroppings, (object,)),
227 (mod.StupidGit, (object,)),
228 [(mod.MalodorousPervert, (mod.StupidGit,)),
229 [(mod.FesteringGob, (mod.MalodorousPervert,
230 mod.ParrotDroppings))
231 ]
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000232 ]
233 ]
234 ])
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000235
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000236 def test_getfunctions(self):
237 functions = inspect.getmembers(mod, inspect.isfunction)
238 self.assertEqual(functions, [('eggs', mod.eggs),
239 ('spam', mod.spam)])
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000240
R. David Murray378c0cf2010-02-24 01:46:21 +0000241 @unittest.skipIf(sys.flags.optimize >= 2,
242 "Docstrings are omitted with -O2 and above")
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000243 def test_getdoc(self):
244 self.assertEqual(inspect.getdoc(mod), 'A module docstring.')
245 self.assertEqual(inspect.getdoc(mod.StupidGit),
246 'A longer,\n\nindented\n\ndocstring.')
247 self.assertEqual(inspect.getdoc(git.abuse),
248 'Another\n\ndocstring\n\ncontaining\n\ntabs')
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000249
Georg Brandl0c77a822008-06-10 16:37:50 +0000250 def test_cleandoc(self):
251 self.assertEqual(inspect.cleandoc('An\n indented\n docstring.'),
252 'An\nindented\ndocstring.')
253
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000254 def test_getcomments(self):
255 self.assertEqual(inspect.getcomments(mod), '# line 1\n')
256 self.assertEqual(inspect.getcomments(mod.StupidGit), '# line 20\n')
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000257
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000258 def test_getmodule(self):
Thomas Wouters89f507f2006-12-13 04:49:30 +0000259 # Check actual module
260 self.assertEqual(inspect.getmodule(mod), mod)
261 # Check class (uses __module__ attribute)
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000262 self.assertEqual(inspect.getmodule(mod.StupidGit), mod)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000263 # Check a method (no __module__ attribute, falls back to filename)
264 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
265 # Do it again (check the caching isn't broken)
266 self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
267 # Check a builtin
Georg Brandl1a3284e2007-12-02 09:40:06 +0000268 self.assertEqual(inspect.getmodule(str), sys.modules["builtins"])
Thomas Wouters89f507f2006-12-13 04:49:30 +0000269 # Check filename override
270 self.assertEqual(inspect.getmodule(None, modfile), mod)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000271
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000272 def test_getsource(self):
273 self.assertSourceEqual(git.abuse, 29, 39)
274 self.assertSourceEqual(mod.StupidGit, 21, 46)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000275
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000276 def test_getsourcefile(self):
Christian Heimesa3538eb2007-11-06 11:44:48 +0000277 self.assertEqual(normcase(inspect.getsourcefile(mod.spam)), modfile)
278 self.assertEqual(normcase(inspect.getsourcefile(git.abuse)), modfile)
R. David Murraya1b37402010-06-17 02:04:29 +0000279 fn = "_non_existing_filename_used_for_sourcefile_test.py"
280 co = compile("None", fn, "exec")
R. David Murray4155f972010-06-17 13:23:18 +0000281 self.assertEqual(inspect.getsourcefile(co), None)
R. David Murraya1b37402010-06-17 02:04:29 +0000282 linecache.cache[co.co_filename] = (1, None, "None", co.co_filename)
283 self.assertEqual(normcase(inspect.getsourcefile(co)), fn)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000284
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000285 def test_getfile(self):
286 self.assertEqual(inspect.getfile(mod.StupidGit), mod.__file__)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000287
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000288 def test_getmodule_recursion(self):
Christian Heimes45f9af32007-11-27 21:50:00 +0000289 from types import ModuleType
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000290 name = '__inspect_dummy'
Christian Heimes45f9af32007-11-27 21:50:00 +0000291 m = sys.modules[name] = ModuleType(name)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000292 m.__file__ = "<string>" # hopefully not a real filename...
293 m.__loader__ = "dummy" # pretend the filename is understood by a loader
Georg Brandl7cae87c2006-09-06 06:51:57 +0000294 exec("def x(): pass", m.__dict__)
Neal Norwitz221085d2007-02-25 20:55:47 +0000295 self.assertEqual(inspect.getsourcefile(m.x.__code__), '<string>')
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000296 del sys.modules[name]
297 inspect.getmodule(compile('a=10','','single'))
298
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000299class TestDecorators(GetSourceBase):
300 fodderFile = mod2
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000301
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000302 def test_wrapped_decorator(self):
Christian Heimes09aaa882008-02-23 15:01:06 +0000303 self.assertSourceEqual(mod2.wrapped, 14, 17)
Johannes Gijsbersc473c992004-08-18 12:40:31 +0000304
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000305 def test_replacing_decorator(self):
306 self.assertSourceEqual(mod2.gone, 9, 10)
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000307
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000308class TestOneliners(GetSourceBase):
309 fodderFile = mod2
310 def test_oneline_lambda(self):
311 # Test inspect.getsource with a one-line lambda function.
312 self.assertSourceEqual(mod2.oll, 25, 25)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000313
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000314 def test_threeline_lambda(self):
315 # Test inspect.getsource with a three-line lambda function,
316 # where the second and third lines are _not_ indented.
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000317 self.assertSourceEqual(mod2.tll, 28, 30)
318
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000319 def test_twoline_indented_lambda(self):
320 # Test inspect.getsource with a two-line lambda function,
321 # where the second line _is_ indented.
322 self.assertSourceEqual(mod2.tlli, 33, 34)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000323
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000324 def test_onelinefunc(self):
325 # Test inspect.getsource with a regular one-line function.
326 self.assertSourceEqual(mod2.onelinefunc, 37, 37)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000327
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000328 def test_manyargs(self):
329 # Test inspect.getsource with a regular function where
330 # the arguments are on two lines and _not_ indented and
331 # the body on the second line with the last arguments.
332 self.assertSourceEqual(mod2.manyargs, 40, 41)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000333
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000334 def test_twolinefunc(self):
335 # Test inspect.getsource with a regular function where
336 # the body is on two lines, following the argument list and
337 # continued on the next line by a \\.
338 self.assertSourceEqual(mod2.twolinefunc, 44, 45)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000339
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000340 def test_lambda_in_list(self):
341 # Test inspect.getsource with a one-line lambda function
342 # defined in a list, indented.
343 self.assertSourceEqual(mod2.a[1], 49, 49)
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000344
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000345 def test_anonymous(self):
346 # Test inspect.getsource with a lambda function defined
347 # as argument to another function.
348 self.assertSourceEqual(mod2.anonymous, 55, 55)
349
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000350class TestBuggyCases(GetSourceBase):
351 fodderFile = mod2
352
353 def test_with_comment(self):
354 self.assertSourceEqual(mod2.with_comment, 58, 59)
355
356 def test_multiline_sig(self):
357 self.assertSourceEqual(mod2.multiline_sig[0], 63, 64)
358
Armin Rigodd5c0232005-09-25 11:45:45 +0000359 def test_nested_class(self):
360 self.assertSourceEqual(mod2.func69().func71, 71, 72)
361
362 def test_one_liner_followed_by_non_name(self):
363 self.assertSourceEqual(mod2.func77, 77, 77)
364
365 def test_one_liner_dedent_non_name(self):
366 self.assertSourceEqual(mod2.cls82.func83, 83, 83)
367
368 def test_with_comment_instead_of_docstring(self):
369 self.assertSourceEqual(mod2.func88, 88, 90)
370
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000371 def test_method_in_dynamic_class(self):
372 self.assertSourceEqual(mod2.method_in_dynamic_class, 95, 97)
373
R. David Murrayb5655772009-05-14 16:17:50 +0000374 @unittest.skipIf(
375 not hasattr(unicodedata, '__file__') or
376 unicodedata.__file__[-4:] in (".pyc", ".pyo"),
377 "unicodedata is not an external binary module")
R. David Murray74b89242009-05-13 17:33:03 +0000378 def test_findsource_binary(self):
R. David Murrayb5655772009-05-14 16:17:50 +0000379 self.assertRaises(IOError, inspect.getsource, unicodedata)
380 self.assertRaises(IOError, inspect.findsource, unicodedata)
R. David Murray74b89242009-05-13 17:33:03 +0000381
R. David Murraya1b37402010-06-17 02:04:29 +0000382 def test_findsource_code_in_linecache(self):
383 lines = ["x=1"]
384 co = compile(lines[0], "_dynamically_created_file", "exec")
385 self.assertRaises(IOError, inspect.findsource, co)
386 self.assertRaises(IOError, inspect.getsource, co)
387 linecache.cache[co.co_filename] = (1, None, lines, co.co_filename)
388 self.assertEquals(inspect.findsource(co), (lines,0))
389 self.assertEquals(inspect.getsource(co), lines[0])
390
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000391# Helper for testing classify_class_attrs.
Tim Peters13b49d32001-09-23 02:00:29 +0000392def attrs_wo_objs(cls):
393 return [t[:3] for t in inspect.classify_class_attrs(cls)]
394
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000395class TestClassesAndFunctions(unittest.TestCase):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000396 def test_newstyle_mro(self):
397 # The same w/ new-class MRO.
398 class A(object): pass
399 class B(A): pass
400 class C(A): pass
401 class D(B, C): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000402
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000403 expected = (D, B, C, A, object)
404 got = inspect.getmro(D)
405 self.assertEqual(expected, got)
Tim Peters13b49d32001-09-23 02:00:29 +0000406
Christian Heimes3795b532007-11-08 13:48:53 +0000407 def assertArgSpecEquals(self, routine, args_e, varargs_e=None,
408 varkw_e=None, defaults_e=None, formatted=None):
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000409 args, varargs, varkw, defaults = inspect.getargspec(routine)
410 self.assertEqual(args, args_e)
411 self.assertEqual(varargs, varargs_e)
412 self.assertEqual(varkw, varkw_e)
413 self.assertEqual(defaults, defaults_e)
414 if formatted is not None:
415 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults),
416 formatted)
Tim Peters13b49d32001-09-23 02:00:29 +0000417
Christian Heimes3795b532007-11-08 13:48:53 +0000418 def assertFullArgSpecEquals(self, routine, args_e, varargs_e=None,
419 varkw_e=None, defaults_e=None,
420 kwonlyargs_e=[], kwonlydefaults_e=None,
421 ann_e={}, formatted=None):
422 args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \
423 inspect.getfullargspec(routine)
424 self.assertEqual(args, args_e)
425 self.assertEqual(varargs, varargs_e)
426 self.assertEqual(varkw, varkw_e)
427 self.assertEqual(defaults, defaults_e)
428 self.assertEqual(kwonlyargs, kwonlyargs_e)
429 self.assertEqual(kwonlydefaults, kwonlydefaults_e)
430 self.assertEqual(ann, ann_e)
431 if formatted is not None:
432 self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults,
433 kwonlyargs, kwonlydefaults, ann),
434 formatted)
435
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000436 def test_getargspec(self):
Christian Heimes3795b532007-11-08 13:48:53 +0000437 self.assertArgSpecEquals(mod.eggs, ['x', 'y'], formatted='(x, y)')
Tim Peters13b49d32001-09-23 02:00:29 +0000438
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000439 self.assertArgSpecEquals(mod.spam,
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000440 ['a', 'b', 'c', 'd', 'e', 'f'],
441 'g', 'h', (3, 4, 5),
442 '(a, b, c, d=3, e=4, f=5, *g, **h)')
Tim Peters13b49d32001-09-23 02:00:29 +0000443
Christian Heimes3795b532007-11-08 13:48:53 +0000444 self.assertRaises(ValueError, self.assertArgSpecEquals,
445 mod2.keyworded, [])
446
447 self.assertRaises(ValueError, self.assertArgSpecEquals,
448 mod2.annotated, [])
Benjamin Peterson9953a8d2009-01-17 04:15:01 +0000449 self.assertRaises(ValueError, self.assertArgSpecEquals,
450 mod2.keyword_only_arg, [])
451
Christian Heimes3795b532007-11-08 13:48:53 +0000452
453 def test_getfullargspec(self):
454 self.assertFullArgSpecEquals(mod2.keyworded, [], varargs_e='arg1',
455 kwonlyargs_e=['arg2'],
456 kwonlydefaults_e={'arg2':1},
457 formatted='(*arg1, arg2=1)')
458
459 self.assertFullArgSpecEquals(mod2.annotated, ['arg1'],
Christian Heimesc9543e42007-11-28 08:28:28 +0000460 ann_e={'arg1' : list},
Christian Heimes3795b532007-11-08 13:48:53 +0000461 formatted='(arg1: list)')
Benjamin Peterson9953a8d2009-01-17 04:15:01 +0000462 self.assertFullArgSpecEquals(mod2.keyword_only_arg, [],
463 kwonlyargs_e=['arg'],
464 formatted='(*, arg)')
465
Christian Heimes3795b532007-11-08 13:48:53 +0000466
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000467 def test_getargspec_method(self):
468 class A(object):
469 def m(self):
470 pass
471 self.assertArgSpecEquals(A.m, ['self'])
Tim Peters13b49d32001-09-23 02:00:29 +0000472
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000473 def test_classify_newstyle(self):
474 class A(object):
Tim Peters13b49d32001-09-23 02:00:29 +0000475
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000476 def s(): pass
477 s = staticmethod(s)
Tim Peters13b49d32001-09-23 02:00:29 +0000478
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000479 def c(cls): pass
480 c = classmethod(c)
Tim Peters13b49d32001-09-23 02:00:29 +0000481
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000482 def getp(self): pass
483 p = property(getp)
Tim Peters13b49d32001-09-23 02:00:29 +0000484
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000485 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000486
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000487 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000488
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000489 datablob = '1'
Tim Peters13b49d32001-09-23 02:00:29 +0000490
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000491 attrs = attrs_wo_objs(A)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000492 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
493 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
494 self.assertIn(('p', 'property', A), attrs, 'missing property')
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000495 self.assertIn(('m', 'method', A), attrs,
496 'missing plain method: %r' % attrs)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000497 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
498 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Tim Peters13b49d32001-09-23 02:00:29 +0000499
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000500 class B(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000501
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000502 def m(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000503
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000504 attrs = attrs_wo_objs(B)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000505 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
506 self.assertIn(('c', 'class method', A), attrs, 'missing class method')
507 self.assertIn(('p', 'property', A), attrs, 'missing property')
508 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
509 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
510 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Tim Peters13b49d32001-09-23 02:00:29 +0000511
512
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000513 class C(A):
Tim Peters13b49d32001-09-23 02:00:29 +0000514
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000515 def m(self): pass
516 def c(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000517
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000518 attrs = attrs_wo_objs(C)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000519 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
520 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
521 self.assertIn(('p', 'property', A), attrs, 'missing property')
522 self.assertIn(('m', 'method', C), attrs, 'missing plain method')
523 self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
524 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Tim Peters13b49d32001-09-23 02:00:29 +0000525
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000526 class D(B, C):
Tim Peters13b49d32001-09-23 02:00:29 +0000527
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000528 def m1(self): pass
Tim Peters13b49d32001-09-23 02:00:29 +0000529
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000530 attrs = attrs_wo_objs(D)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000531 self.assertIn(('s', 'static method', A), attrs, 'missing static method')
532 self.assertIn(('c', 'method', C), attrs, 'missing plain method')
533 self.assertIn(('p', 'property', A), attrs, 'missing property')
534 self.assertIn(('m', 'method', B), attrs, 'missing plain method')
535 self.assertIn(('m1', 'method', D), attrs, 'missing plain method')
536 self.assertIn(('datablob', 'data', A), attrs, 'missing data')
Jeremy Hyltonc4bf5ed2003-06-27 18:43:12 +0000537
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000538class TestGetcallargsFunctions(unittest.TestCase):
539
540 def assertEqualCallArgs(self, func, call_params_string, locs=None):
541 locs = dict(locs or {}, func=func)
542 r1 = eval('func(%s)' % call_params_string, None, locs)
543 r2 = eval('inspect.getcallargs(func, %s)' % call_params_string, None,
544 locs)
545 self.assertEqual(r1, r2)
546
547 def assertEqualException(self, func, call_param_string, locs=None):
548 locs = dict(locs or {}, func=func)
549 try:
550 eval('func(%s)' % call_param_string, None, locs)
551 except Exception as e:
552 ex1 = e
553 else:
554 self.fail('Exception not raised')
555 try:
556 eval('inspect.getcallargs(func, %s)' % call_param_string, None,
557 locs)
558 except Exception as e:
559 ex2 = e
560 else:
561 self.fail('Exception not raised')
562 self.assertIs(type(ex1), type(ex2))
563 self.assertEqual(str(ex1), str(ex2))
564 del ex1, ex2
565
566 def makeCallable(self, signature):
567 """Create a function that returns its locals()"""
568 code = "lambda %s: locals()"
569 return eval(code % signature)
570
571 def test_plain(self):
572 f = self.makeCallable('a, b=1')
573 self.assertEqualCallArgs(f, '2')
574 self.assertEqualCallArgs(f, '2, 3')
575 self.assertEqualCallArgs(f, 'a=2')
576 self.assertEqualCallArgs(f, 'b=3, a=2')
577 self.assertEqualCallArgs(f, '2, b=3')
578 # expand *iterable / **mapping
579 self.assertEqualCallArgs(f, '*(2,)')
580 self.assertEqualCallArgs(f, '*[2]')
581 self.assertEqualCallArgs(f, '*(2, 3)')
582 self.assertEqualCallArgs(f, '*[2, 3]')
583 self.assertEqualCallArgs(f, '**{"a":2}')
584 self.assertEqualCallArgs(f, 'b=3, **{"a":2}')
585 self.assertEqualCallArgs(f, '2, **{"b":3}')
586 self.assertEqualCallArgs(f, '**{"b":3, "a":2}')
587 # expand UserList / UserDict
588 self.assertEqualCallArgs(f, '*collections.UserList([2])')
589 self.assertEqualCallArgs(f, '*collections.UserList([2, 3])')
590 self.assertEqualCallArgs(f, '**collections.UserDict(a=2)')
591 self.assertEqualCallArgs(f, '2, **collections.UserDict(b=3)')
592 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3)')
593
594 def test_varargs(self):
595 f = self.makeCallable('a, b=1, *c')
596 self.assertEqualCallArgs(f, '2')
597 self.assertEqualCallArgs(f, '2, 3')
598 self.assertEqualCallArgs(f, '2, 3, 4')
599 self.assertEqualCallArgs(f, '*(2,3,4)')
600 self.assertEqualCallArgs(f, '2, *[3,4]')
601 self.assertEqualCallArgs(f, '2, 3, *collections.UserList([4])')
602
603 def test_varkw(self):
604 f = self.makeCallable('a, b=1, **c')
605 self.assertEqualCallArgs(f, 'a=2')
606 self.assertEqualCallArgs(f, '2, b=3, c=4')
607 self.assertEqualCallArgs(f, 'b=3, a=2, c=4')
608 self.assertEqualCallArgs(f, 'c=4, **{"a":2, "b":3}')
609 self.assertEqualCallArgs(f, '2, c=4, **{"b":3}')
610 self.assertEqualCallArgs(f, 'b=2, **{"a":3, "c":4}')
611 self.assertEqualCallArgs(f, '**collections.UserDict(a=2, b=3, c=4)')
612 self.assertEqualCallArgs(f, '2, c=4, **collections.UserDict(b=3)')
613 self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3, c=4)')
614
615 def test_keyword_only(self):
616 f = self.makeCallable('a=3, *, c, d=2')
617 self.assertEqualCallArgs(f, 'c=3')
618 self.assertEqualCallArgs(f, 'c=3, a=3')
619 self.assertEqualCallArgs(f, 'a=2, c=4')
620 self.assertEqualCallArgs(f, '4, c=4')
621 self.assertEqualException(f, '')
622 self.assertEqualException(f, '3')
623 self.assertEqualException(f, 'a=3')
624 self.assertEqualException(f, 'd=4')
625
626 def test_multiple_features(self):
627 f = self.makeCallable('a, b=2, *f, **g')
628 self.assertEqualCallArgs(f, '2, 3, 7')
629 self.assertEqualCallArgs(f, '2, 3, x=8')
630 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
631 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9')
632 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9')
633 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
634 '[2, 3, (4,[5,6])]), **{"y":9, "z":10}')
635 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
636 '(4,[5,6])]), **collections.UserDict('
637 'y=9, z=10)')
638
639 def test_errors(self):
640 f0 = self.makeCallable('')
641 f1 = self.makeCallable('a, b')
642 f2 = self.makeCallable('a, b=1')
643 # f0 takes no arguments
644 self.assertEqualException(f0, '1')
645 self.assertEqualException(f0, 'x=1')
646 self.assertEqualException(f0, '1,x=1')
647 # f1 takes exactly 2 arguments
648 self.assertEqualException(f1, '')
649 self.assertEqualException(f1, '1')
650 self.assertEqualException(f1, 'a=2')
651 self.assertEqualException(f1, 'b=3')
652 # f2 takes at least 1 argument
653 self.assertEqualException(f2, '')
654 self.assertEqualException(f2, 'b=3')
655 for f in f1, f2:
656 # f1/f2 takes exactly/at most 2 arguments
657 self.assertEqualException(f, '2, 3, 4')
658 self.assertEqualException(f, '1, 2, 3, a=1')
659 self.assertEqualException(f, '2, 3, 4, c=5')
660 self.assertEqualException(f, '2, 3, 4, a=1, c=5')
661 # f got an unexpected keyword argument
662 self.assertEqualException(f, 'c=2')
663 self.assertEqualException(f, '2, c=3')
664 self.assertEqualException(f, '2, 3, c=4')
665 self.assertEqualException(f, '2, c=4, b=3')
666 self.assertEqualException(f, '**{u"\u03c0\u03b9": 4}')
667 # f got multiple values for keyword argument
668 self.assertEqualException(f, '1, a=2')
669 self.assertEqualException(f, '1, **{"a":2}')
670 self.assertEqualException(f, '1, 2, b=3')
671 # XXX: Python inconsistency
672 # - for functions and bound methods: unexpected keyword 'c'
673 # - for unbound methods: multiple values for keyword 'a'
674 #self.assertEqualException(f, '1, c=3, a=2')
675
676class TestGetcallargsMethods(TestGetcallargsFunctions):
677
678 def setUp(self):
679 class Foo(object):
680 pass
681 self.cls = Foo
682 self.inst = Foo()
683
684 def makeCallable(self, signature):
685 assert 'self' not in signature
686 mk = super(TestGetcallargsMethods, self).makeCallable
687 self.cls.method = mk('self, ' + signature)
688 return self.inst.method
689
690class TestGetcallargsUnboundMethods(TestGetcallargsMethods):
691
692 def makeCallable(self, signature):
693 super(TestGetcallargsUnboundMethods, self).makeCallable(signature)
694 return self.cls.method
695
696 def assertEqualCallArgs(self, func, call_params_string, locs=None):
697 return super(TestGetcallargsUnboundMethods, self).assertEqualCallArgs(
698 *self._getAssertEqualParams(func, call_params_string, locs))
699
700 def assertEqualException(self, func, call_params_string, locs=None):
701 return super(TestGetcallargsUnboundMethods, self).assertEqualException(
702 *self._getAssertEqualParams(func, call_params_string, locs))
703
704 def _getAssertEqualParams(self, func, call_params_string, locs=None):
705 assert 'inst' not in call_params_string
706 locs = dict(locs or {}, inst=self.inst)
707 return (func, 'inst,' + call_params_string, locs)
708
Michael Foord95fc51d2010-11-20 15:07:30 +0000709
710class TestGetattrStatic(unittest.TestCase):
711
712 def test_basic(self):
713 class Thing(object):
714 x = object()
715
716 thing = Thing()
717 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
718 self.assertEqual(inspect.getattr_static(thing, 'x', None), Thing.x)
719 with self.assertRaises(AttributeError):
720 inspect.getattr_static(thing, 'y')
721
722 self.assertEqual(inspect.getattr_static(thing, 'y', 3), 3)
723
724 def test_inherited(self):
725 class Thing(object):
726 x = object()
727 class OtherThing(Thing):
728 pass
729
730 something = OtherThing()
731 self.assertEqual(inspect.getattr_static(something, 'x'), Thing.x)
732
733 def test_instance_attr(self):
734 class Thing(object):
735 x = 2
736 def __init__(self, x):
737 self.x = x
738 thing = Thing(3)
739 self.assertEqual(inspect.getattr_static(thing, 'x'), 3)
740 del thing.x
741 self.assertEqual(inspect.getattr_static(thing, 'x'), 2)
742
743 def test_property(self):
744 class Thing(object):
745 @property
746 def x(self):
747 raise AttributeError("I'm pretending not to exist")
748 thing = Thing()
749 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
750
751 def test_descriptor(self):
752 class descriptor(object):
753 def __get__(*_):
754 raise AttributeError("I'm pretending not to exist")
755 desc = descriptor()
756 class Thing(object):
757 x = desc
758 thing = Thing()
759 self.assertEqual(inspect.getattr_static(thing, 'x'), desc)
760
761 def test_classAttribute(self):
762 class Thing(object):
763 x = object()
764
765 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.x)
766
767 def test_inherited_classattribute(self):
768 class Thing(object):
769 x = object()
770 class OtherThing(Thing):
771 pass
772
773 self.assertEqual(inspect.getattr_static(OtherThing, 'x'), Thing.x)
774
775 def test_slots(self):
776 class Thing(object):
777 y = 'bar'
778 __slots__ = ['x']
779 def __init__(self):
780 self.x = 'foo'
781 thing = Thing()
782 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
783 self.assertEqual(inspect.getattr_static(thing, 'y'), 'bar')
784
785 del thing.x
786 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
787
788 def test_metaclass(self):
789 class meta(type):
790 attr = 'foo'
791 class Thing(object, metaclass=meta):
792 pass
793 self.assertEqual(inspect.getattr_static(Thing, 'attr'), 'foo')
794
795 class sub(meta):
796 pass
797 class OtherThing(object, metaclass=sub):
798 x = 3
799 self.assertEqual(inspect.getattr_static(OtherThing, 'attr'), 'foo')
800
801 class OtherOtherThing(OtherThing):
802 pass
803 # this test is odd, but it was added as it exposed a bug
804 self.assertEqual(inspect.getattr_static(OtherOtherThing, 'x'), 3)
805
806 def test_no_dict_no_slots(self):
807 self.assertEqual(inspect.getattr_static(1, 'foo', None), None)
808 self.assertNotEqual(inspect.getattr_static('foo', 'lower'), None)
809
810 def test_no_dict_no_slots_instance_member(self):
811 # returns descriptor
812 with open(__file__) as handle:
813 self.assertEqual(inspect.getattr_static(handle, 'name'), type(handle).name)
814
815 def test_inherited_slots(self):
816 # returns descriptor
817 class Thing(object):
818 __slots__ = ['x']
819 def __init__(self):
820 self.x = 'foo'
821
822 class OtherThing(Thing):
823 pass
824 # it would be nice if this worked...
825 # we get the descriptor instead of the instance attribute
826 self.assertEqual(inspect.getattr_static(OtherThing(), 'x'), Thing.x)
827
828 def test_descriptor(self):
829 class descriptor(object):
830 def __get__(self, instance, owner):
831 return 3
832 class Foo(object):
833 d = descriptor()
834
835 foo = Foo()
836
837 # for a non data descriptor we return the instance attribute
838 foo.__dict__['d'] = 1
839 self.assertEqual(inspect.getattr_static(foo, 'd'), 1)
840
841 # if the descriptor is a data-desciptor we should return the
842 # descriptor
843 descriptor.__set__ = lambda s, i, v: None
844 self.assertEqual(inspect.getattr_static(foo, 'd'), Foo.__dict__['d'])
845
846
847 def test_metaclass_with_descriptor(self):
848 class descriptor(object):
849 def __get__(self, instance, owner):
850 return 3
851 class meta(type):
852 d = descriptor()
853 class Thing(object, metaclass=meta):
854 pass
855 self.assertEqual(inspect.getattr_static(Thing, 'd'), meta.__dict__['d'])
856
857
Michael Foordcc7ebb82010-11-20 16:20:16 +0000858 def test_class_as_property(self):
859 class Base(object):
860 foo = 3
861
862 class Something(Base):
Michael Foord35184ed2010-11-20 16:58:30 +0000863 executed = False
Michael Foordcc7ebb82010-11-20 16:20:16 +0000864 @property
865 def __class__(self):
Michael Foord35184ed2010-11-20 16:58:30 +0000866 self.executed = True
Michael Foordcc7ebb82010-11-20 16:20:16 +0000867 return object
868
Michael Foord35184ed2010-11-20 16:58:30 +0000869 instance = Something()
870 self.assertEqual(inspect.getattr_static(instance, 'foo'), 3)
871 self.assertFalse(instance.executed)
Michael Foordcc7ebb82010-11-20 16:20:16 +0000872 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
873
Michael Foorde5162652010-11-20 16:40:44 +0000874 def test_mro_as_property(self):
875 class Meta(type):
876 @property
877 def __mro__(self):
878 return (object,)
879
880 class Base(object):
881 foo = 3
882
883 class Something(Base, metaclass=Meta):
884 pass
885
886 self.assertEqual(inspect.getattr_static(Something(), 'foo'), 3)
887 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
888
889
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000890def test_main():
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000891 run_unittest(
892 TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBuggyCases,
893 TestInterpreterStack, TestClassesAndFunctions, TestPredicates,
894 TestGetcallargsFunctions, TestGetcallargsMethods,
Michael Foord95fc51d2010-11-20 15:07:30 +0000895 TestGetcallargsUnboundMethods, TestGetattrStatic
896 )
Martin v. Löwis893ffa42003-10-31 15:35:53 +0000897
Johannes Gijsberscb9015d2004-12-12 16:20:22 +0000898if __name__ == "__main__":
899 test_main()