blob: f5dff1e54393bd5f27e8d497d4674df22bfc4e3c [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
Benjamin Peterson6a2638b2011-03-28 17:32:31 -0500635 def test_varkw_only(self):
636 # issue11256:
637 f = self.makeCallable('**c')
638 self.assertEqualCallArgs(f, '')
639 self.assertEqualCallArgs(f, 'a=1')
640 self.assertEqualCallArgs(f, 'a=1, b=2')
641 self.assertEqualCallArgs(f, 'c=3, **{"a": 1, "b": 2}')
642 self.assertEqualCallArgs(f, '**collections.UserDict(a=1, b=2)')
643 self.assertEqualCallArgs(f, 'c=3, **collections.UserDict(a=1, b=2)')
644
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000645 def test_keyword_only(self):
646 f = self.makeCallable('a=3, *, c, d=2')
647 self.assertEqualCallArgs(f, 'c=3')
648 self.assertEqualCallArgs(f, 'c=3, a=3')
649 self.assertEqualCallArgs(f, 'a=2, c=4')
650 self.assertEqualCallArgs(f, '4, c=4')
651 self.assertEqualException(f, '')
652 self.assertEqualException(f, '3')
653 self.assertEqualException(f, 'a=3')
654 self.assertEqualException(f, 'd=4')
655
Benjamin Peterson6a2638b2011-03-28 17:32:31 -0500656 f = self.makeCallable('*, c, d=2')
657 self.assertEqualCallArgs(f, 'c=3')
658 self.assertEqualCallArgs(f, 'c=3, d=4')
659 self.assertEqualCallArgs(f, 'd=4, c=3')
660
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000661 def test_multiple_features(self):
662 f = self.makeCallable('a, b=2, *f, **g')
663 self.assertEqualCallArgs(f, '2, 3, 7')
664 self.assertEqualCallArgs(f, '2, 3, x=8')
665 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
666 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9')
667 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9')
668 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
669 '[2, 3, (4,[5,6])]), **{"y":9, "z":10}')
670 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
671 '(4,[5,6])]), **collections.UserDict('
672 'y=9, z=10)')
673
Benjamin Peterson6a2638b2011-03-28 17:32:31 -0500674 f = self.makeCallable('a, b=2, *f, x, y=99, **g')
675 self.assertEqualCallArgs(f, '2, 3, x=8')
676 self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
677 self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9, z=10')
678 self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9, z=10')
679 self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
680 '[2, 3, (4,[5,6])]), q=0, **{"y":9, "z":10}')
681 self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
682 '(4,[5,6])]), q=0, **collections.UserDict('
683 'y=9, z=10)')
684
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000685 def test_errors(self):
686 f0 = self.makeCallable('')
687 f1 = self.makeCallable('a, b')
688 f2 = self.makeCallable('a, b=1')
689 # f0 takes no arguments
690 self.assertEqualException(f0, '1')
691 self.assertEqualException(f0, 'x=1')
692 self.assertEqualException(f0, '1,x=1')
693 # f1 takes exactly 2 arguments
694 self.assertEqualException(f1, '')
695 self.assertEqualException(f1, '1')
696 self.assertEqualException(f1, 'a=2')
697 self.assertEqualException(f1, 'b=3')
698 # f2 takes at least 1 argument
699 self.assertEqualException(f2, '')
700 self.assertEqualException(f2, 'b=3')
701 for f in f1, f2:
702 # f1/f2 takes exactly/at most 2 arguments
703 self.assertEqualException(f, '2, 3, 4')
704 self.assertEqualException(f, '1, 2, 3, a=1')
705 self.assertEqualException(f, '2, 3, 4, c=5')
706 self.assertEqualException(f, '2, 3, 4, a=1, c=5')
707 # f got an unexpected keyword argument
708 self.assertEqualException(f, 'c=2')
709 self.assertEqualException(f, '2, c=3')
710 self.assertEqualException(f, '2, 3, c=4')
711 self.assertEqualException(f, '2, c=4, b=3')
712 self.assertEqualException(f, '**{u"\u03c0\u03b9": 4}')
713 # f got multiple values for keyword argument
714 self.assertEqualException(f, '1, a=2')
715 self.assertEqualException(f, '1, **{"a":2}')
716 self.assertEqualException(f, '1, 2, b=3')
717 # XXX: Python inconsistency
718 # - for functions and bound methods: unexpected keyword 'c'
719 # - for unbound methods: multiple values for keyword 'a'
720 #self.assertEqualException(f, '1, c=3, a=2')
Benjamin Peterson6a2638b2011-03-28 17:32:31 -0500721 # issue11256:
722 f3 = self.makeCallable('**c')
723 self.assertEqualException(f3, '1, 2')
724 self.assertEqualException(f3, '1, 2, a=1, b=2')
725 f4 = self.makeCallable('*, a, b=0')
726 self.assertEqualException(f3, '1, 2')
727 self.assertEqualException(f3, '1, 2, a=1, b=2')
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +0000728
729class TestGetcallargsMethods(TestGetcallargsFunctions):
730
731 def setUp(self):
732 class Foo(object):
733 pass
734 self.cls = Foo
735 self.inst = Foo()
736
737 def makeCallable(self, signature):
738 assert 'self' not in signature
739 mk = super(TestGetcallargsMethods, self).makeCallable
740 self.cls.method = mk('self, ' + signature)
741 return self.inst.method
742
743class TestGetcallargsUnboundMethods(TestGetcallargsMethods):
744
745 def makeCallable(self, signature):
746 super(TestGetcallargsUnboundMethods, self).makeCallable(signature)
747 return self.cls.method
748
749 def assertEqualCallArgs(self, func, call_params_string, locs=None):
750 return super(TestGetcallargsUnboundMethods, self).assertEqualCallArgs(
751 *self._getAssertEqualParams(func, call_params_string, locs))
752
753 def assertEqualException(self, func, call_params_string, locs=None):
754 return super(TestGetcallargsUnboundMethods, self).assertEqualException(
755 *self._getAssertEqualParams(func, call_params_string, locs))
756
757 def _getAssertEqualParams(self, func, call_params_string, locs=None):
758 assert 'inst' not in call_params_string
759 locs = dict(locs or {}, inst=self.inst)
760 return (func, 'inst,' + call_params_string, locs)
761
Michael Foord95fc51d2010-11-20 15:07:30 +0000762
763class TestGetattrStatic(unittest.TestCase):
764
765 def test_basic(self):
766 class Thing(object):
767 x = object()
768
769 thing = Thing()
770 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
771 self.assertEqual(inspect.getattr_static(thing, 'x', None), Thing.x)
772 with self.assertRaises(AttributeError):
773 inspect.getattr_static(thing, 'y')
774
775 self.assertEqual(inspect.getattr_static(thing, 'y', 3), 3)
776
777 def test_inherited(self):
778 class Thing(object):
779 x = object()
780 class OtherThing(Thing):
781 pass
782
783 something = OtherThing()
784 self.assertEqual(inspect.getattr_static(something, 'x'), Thing.x)
785
786 def test_instance_attr(self):
787 class Thing(object):
788 x = 2
789 def __init__(self, x):
790 self.x = x
791 thing = Thing(3)
792 self.assertEqual(inspect.getattr_static(thing, 'x'), 3)
793 del thing.x
794 self.assertEqual(inspect.getattr_static(thing, 'x'), 2)
795
796 def test_property(self):
797 class Thing(object):
798 @property
799 def x(self):
800 raise AttributeError("I'm pretending not to exist")
801 thing = Thing()
802 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
803
Ezio Melotti75cbd732011-04-28 00:59:29 +0300804 def test_descriptor_raises_AttributeError(self):
Michael Foord95fc51d2010-11-20 15:07:30 +0000805 class descriptor(object):
806 def __get__(*_):
807 raise AttributeError("I'm pretending not to exist")
808 desc = descriptor()
809 class Thing(object):
810 x = desc
811 thing = Thing()
812 self.assertEqual(inspect.getattr_static(thing, 'x'), desc)
813
814 def test_classAttribute(self):
815 class Thing(object):
816 x = object()
817
818 self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.x)
819
820 def test_inherited_classattribute(self):
821 class Thing(object):
822 x = object()
823 class OtherThing(Thing):
824 pass
825
826 self.assertEqual(inspect.getattr_static(OtherThing, 'x'), Thing.x)
827
828 def test_slots(self):
829 class Thing(object):
830 y = 'bar'
831 __slots__ = ['x']
832 def __init__(self):
833 self.x = 'foo'
834 thing = Thing()
835 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
836 self.assertEqual(inspect.getattr_static(thing, 'y'), 'bar')
837
838 del thing.x
839 self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
840
841 def test_metaclass(self):
842 class meta(type):
843 attr = 'foo'
844 class Thing(object, metaclass=meta):
845 pass
846 self.assertEqual(inspect.getattr_static(Thing, 'attr'), 'foo')
847
848 class sub(meta):
849 pass
850 class OtherThing(object, metaclass=sub):
851 x = 3
852 self.assertEqual(inspect.getattr_static(OtherThing, 'attr'), 'foo')
853
854 class OtherOtherThing(OtherThing):
855 pass
856 # this test is odd, but it was added as it exposed a bug
857 self.assertEqual(inspect.getattr_static(OtherOtherThing, 'x'), 3)
858
859 def test_no_dict_no_slots(self):
860 self.assertEqual(inspect.getattr_static(1, 'foo', None), None)
861 self.assertNotEqual(inspect.getattr_static('foo', 'lower'), None)
862
863 def test_no_dict_no_slots_instance_member(self):
864 # returns descriptor
865 with open(__file__) as handle:
866 self.assertEqual(inspect.getattr_static(handle, 'name'), type(handle).name)
867
868 def test_inherited_slots(self):
869 # returns descriptor
870 class Thing(object):
871 __slots__ = ['x']
872 def __init__(self):
873 self.x = 'foo'
874
875 class OtherThing(Thing):
876 pass
877 # it would be nice if this worked...
878 # we get the descriptor instead of the instance attribute
879 self.assertEqual(inspect.getattr_static(OtherThing(), 'x'), Thing.x)
880
881 def test_descriptor(self):
882 class descriptor(object):
883 def __get__(self, instance, owner):
884 return 3
885 class Foo(object):
886 d = descriptor()
887
888 foo = Foo()
889
890 # for a non data descriptor we return the instance attribute
891 foo.__dict__['d'] = 1
892 self.assertEqual(inspect.getattr_static(foo, 'd'), 1)
893
894 # if the descriptor is a data-desciptor we should return the
895 # descriptor
896 descriptor.__set__ = lambda s, i, v: None
897 self.assertEqual(inspect.getattr_static(foo, 'd'), Foo.__dict__['d'])
898
899
900 def test_metaclass_with_descriptor(self):
901 class descriptor(object):
902 def __get__(self, instance, owner):
903 return 3
904 class meta(type):
905 d = descriptor()
906 class Thing(object, metaclass=meta):
907 pass
908 self.assertEqual(inspect.getattr_static(Thing, 'd'), meta.__dict__['d'])
909
910
Michael Foordcc7ebb82010-11-20 16:20:16 +0000911 def test_class_as_property(self):
912 class Base(object):
913 foo = 3
914
915 class Something(Base):
Michael Foord35184ed2010-11-20 16:58:30 +0000916 executed = False
Michael Foordcc7ebb82010-11-20 16:20:16 +0000917 @property
918 def __class__(self):
Michael Foord35184ed2010-11-20 16:58:30 +0000919 self.executed = True
Michael Foordcc7ebb82010-11-20 16:20:16 +0000920 return object
921
Michael Foord35184ed2010-11-20 16:58:30 +0000922 instance = Something()
923 self.assertEqual(inspect.getattr_static(instance, 'foo'), 3)
924 self.assertFalse(instance.executed)
Michael Foordcc7ebb82010-11-20 16:20:16 +0000925 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
926
Michael Foorde5162652010-11-20 16:40:44 +0000927 def test_mro_as_property(self):
928 class Meta(type):
929 @property
930 def __mro__(self):
931 return (object,)
932
933 class Base(object):
934 foo = 3
935
936 class Something(Base, metaclass=Meta):
937 pass
938
939 self.assertEqual(inspect.getattr_static(Something(), 'foo'), 3)
940 self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
941
Michael Foorddcebe0f2011-03-15 19:20:44 -0400942 def test_dict_as_property(self):
943 test = self
944 test.called = False
945
946 class Foo(dict):
947 a = 3
948 @property
949 def __dict__(self):
950 test.called = True
951 return {}
952
953 foo = Foo()
954 foo.a = 4
955 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
956 self.assertFalse(test.called)
957
958 def test_custom_object_dict(self):
959 test = self
960 test.called = False
961
962 class Custom(dict):
963 def get(self, key, default=None):
964 test.called = True
965 super().get(key, default)
966
967 class Foo(object):
968 a = 3
969 foo = Foo()
970 foo.__dict__ = Custom()
971 self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
972 self.assertFalse(test.called)
973
974 def test_metaclass_dict_as_property(self):
975 class Meta(type):
976 @property
977 def __dict__(self):
978 self.executed = True
979
980 class Thing(metaclass=Meta):
981 executed = False
982
983 def __init__(self):
984 self.spam = 42
985
986 instance = Thing()
987 self.assertEqual(inspect.getattr_static(instance, "spam"), 42)
988 self.assertFalse(Thing.executed)
Michael Foorde5162652010-11-20 16:40:44 +0000989
Nick Coghlane0f04652010-11-21 03:44:04 +0000990class TestGetGeneratorState(unittest.TestCase):
991
992 def setUp(self):
993 def number_generator():
994 for number in range(5):
995 yield number
996 self.generator = number_generator()
997
998 def _generatorstate(self):
999 return inspect.getgeneratorstate(self.generator)
1000
1001 def test_created(self):
1002 self.assertEqual(self._generatorstate(), inspect.GEN_CREATED)
1003
1004 def test_suspended(self):
1005 next(self.generator)
1006 self.assertEqual(self._generatorstate(), inspect.GEN_SUSPENDED)
1007
1008 def test_closed_after_exhaustion(self):
1009 for i in self.generator:
1010 pass
1011 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1012
1013 def test_closed_after_immediate_exception(self):
1014 with self.assertRaises(RuntimeError):
1015 self.generator.throw(RuntimeError)
1016 self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1017
1018 def test_running(self):
1019 # As mentioned on issue #10220, checking for the RUNNING state only
1020 # makes sense inside the generator itself.
1021 # The following generator checks for this by using the closure's
1022 # reference to self and the generator state checking helper method
1023 def running_check_generator():
1024 for number in range(5):
1025 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1026 yield number
1027 self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1028 self.generator = running_check_generator()
1029 # Running up to the first yield
1030 next(self.generator)
1031 # Running after the first yield
1032 next(self.generator)
1033
Nick Coghlan7921b9f2010-11-30 06:36:04 +00001034 def test_easy_debugging(self):
1035 # repr() and str() of a generator state should contain the state name
1036 names = 'GEN_CREATED GEN_RUNNING GEN_SUSPENDED GEN_CLOSED'.split()
1037 for name in names:
1038 state = getattr(inspect, name)
1039 self.assertIn(name, repr(state))
1040 self.assertIn(name, str(state))
1041
Nick Coghlane0f04652010-11-21 03:44:04 +00001042
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001043def test_main():
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001044 run_unittest(
1045 TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBuggyCases,
1046 TestInterpreterStack, TestClassesAndFunctions, TestPredicates,
1047 TestGetcallargsFunctions, TestGetcallargsMethods,
Alexander Belopolskyf546e702010-12-02 00:10:11 +00001048 TestGetcallargsUnboundMethods, TestGetattrStatic, TestGetGeneratorState,
1049 TestNoEOL
Michael Foord95fc51d2010-11-20 15:07:30 +00001050 )
Martin v. Löwis893ffa42003-10-31 15:35:53 +00001051
Johannes Gijsberscb9015d2004-12-12 16:20:22 +00001052if __name__ == "__main__":
1053 test_main()