blob: 3d0d4aa40e2b54f9b004624f7dfca1a456cf17df [file] [log] [blame]
Barry Warsaw408b6d32002-07-30 23:27:12 +00001from test.test_support import verbose, TestFailed, verify
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +00002import types
Barry Warsaw4a420a02001-01-15 20:30:15 +00003
4class F:
5 def a(self):
6 pass
7
8def b():
9 'my docstring'
10 pass
11
Jeremy Hylton4f0dcc92003-01-31 18:33:18 +000012# __module__ is a special attribute
13verify(b.__module__ == __name__)
14verify(verify.__module__ == "test.test_support")
15
Barry Warsaw4a420a02001-01-15 20:30:15 +000016# setting attributes on functions
17try:
18 b.publish
Barry Warsaw033daa42001-08-14 18:28:28 +000019except AttributeError: pass
Collin Winter3add4d72007-08-29 23:37:32 +000020else: raise TestFailed('expected AttributeError')
Barry Warsaw4a420a02001-01-15 20:30:15 +000021
Guido van Rossumb053cd82006-08-24 03:53:23 +000022if b.__dict__ != {}:
Collin Winter3add4d72007-08-29 23:37:32 +000023 raise TestFailed('expected unassigned func.__dict__ to be {}')
Barry Warsawc1e100f2001-02-26 18:07:26 +000024
Barry Warsaw4a420a02001-01-15 20:30:15 +000025b.publish = 1
Guido van Rossumb053cd82006-08-24 03:53:23 +000026if b.publish != 1:
Collin Winter3add4d72007-08-29 23:37:32 +000027 raise TestFailed('function attribute not set to expected value')
Barry Warsaw4a420a02001-01-15 20:30:15 +000028
29docstring = 'its docstring'
30b.__doc__ = docstring
Guido van Rossumb053cd82006-08-24 03:53:23 +000031if b.__doc__ != docstring:
Collin Winter3add4d72007-08-29 23:37:32 +000032 raise TestFailed('problem with setting __doc__ attribute')
Barry Warsaw4a420a02001-01-15 20:30:15 +000033
34if 'publish' not in dir(b):
Collin Winter3add4d72007-08-29 23:37:32 +000035 raise TestFailed('attribute not in dir()')
Barry Warsaw4a420a02001-01-15 20:30:15 +000036
Barry Warsaw033daa42001-08-14 18:28:28 +000037try:
38 del b.__dict__
Guido van Rossumdb2a9022001-09-18 03:55:22 +000039except TypeError: pass
Collin Winter3add4d72007-08-29 23:37:32 +000040else: raise TestFailed('del func.__dict__ expected TypeError')
Barry Warsawc1e100f2001-02-26 18:07:26 +000041
42b.publish = 1
Barry Warsaw033daa42001-08-14 18:28:28 +000043try:
44 b.__dict__ = None
Guido van Rossumdb2a9022001-09-18 03:55:22 +000045except TypeError: pass
Collin Winter3add4d72007-08-29 23:37:32 +000046else: raise TestFailed('func.__dict__ = None expected TypeError')
Barry Warsawc1e100f2001-02-26 18:07:26 +000047
Barry Warsaw033daa42001-08-14 18:28:28 +000048d = {'hello': 'world'}
49b.__dict__ = d
Neal Norwitz221085d2007-02-25 20:55:47 +000050if b.__dict__ is not d:
Collin Winter3add4d72007-08-29 23:37:32 +000051 raise TestFailed('func.__dict__ assignment to dictionary failed')
Guido van Rossumb053cd82006-08-24 03:53:23 +000052if b.hello != 'world':
Collin Winter3add4d72007-08-29 23:37:32 +000053 raise TestFailed('attribute after func.__dict__ assignment failed')
Barry Warsawc1e100f2001-02-26 18:07:26 +000054
Barry Warsaw4a420a02001-01-15 20:30:15 +000055f1 = F()
56f2 = F()
57
58try:
59 F.a.publish
Barry Warsaw033daa42001-08-14 18:28:28 +000060except AttributeError: pass
Collin Winter3add4d72007-08-29 23:37:32 +000061else: raise TestFailed('expected AttributeError')
Barry Warsaw4a420a02001-01-15 20:30:15 +000062
63try:
64 f1.a.publish
Barry Warsaw033daa42001-08-14 18:28:28 +000065except AttributeError: pass
Collin Winter3add4d72007-08-29 23:37:32 +000066else: raise TestFailed('expected AttributeError')
Barry Warsaw4a420a02001-01-15 20:30:15 +000067
Barry Warsawc1e100f2001-02-26 18:07:26 +000068# In Python 2.1 beta 1, we disallowed setting attributes on unbound methods
69# (it was already disallowed on bound methods). See the PEP for details.
Christian Heimes4a22b5d2007-11-25 09:39:14 +000070# In Python 3.0 unbound methods are gone.
71F.a.publish = 1
Barry Warsawc1e100f2001-02-26 18:07:26 +000072
Guido van Rossumb053cd82006-08-24 03:53:23 +000073if F.a.publish != 1:
Collin Winter3add4d72007-08-29 23:37:32 +000074 raise TestFailed('unbound method attribute not set to expected value')
Barry Warsaw4a420a02001-01-15 20:30:15 +000075
Guido van Rossumb053cd82006-08-24 03:53:23 +000076if f1.a.publish != 1:
Collin Winter3add4d72007-08-29 23:37:32 +000077 raise TestFailed('bound method attribute access did not work')
Barry Warsaw4a420a02001-01-15 20:30:15 +000078
Guido van Rossumb053cd82006-08-24 03:53:23 +000079if f2.a.publish != 1:
Collin Winter3add4d72007-08-29 23:37:32 +000080 raise TestFailed('bound method attribute access did not work')
Barry Warsaw4a420a02001-01-15 20:30:15 +000081
82if 'publish' not in dir(F.a):
Collin Winter3add4d72007-08-29 23:37:32 +000083 raise TestFailed('attribute not in dir()')
Barry Warsaw4a420a02001-01-15 20:30:15 +000084
85try:
86 f1.a.publish = 0
Guido van Rossumbd131492001-09-18 03:28:54 +000087except (AttributeError, TypeError): pass
Collin Winter3add4d72007-08-29 23:37:32 +000088else: raise TestFailed('expected AttributeError or TypeError')
Barry Warsaw4a420a02001-01-15 20:30:15 +000089
Barry Warsaw4a420a02001-01-15 20:30:15 +000090# try setting __dict__
Christian Heimes4a22b5d2007-11-25 09:39:14 +000091F.a.__dict__ = {'one': 11, 'two': 22, 'three': 33}
Barry Warsawc1e100f2001-02-26 18:07:26 +000092
Guido van Rossumb053cd82006-08-24 03:53:23 +000093if f1.a.two != 22:
Collin Winter3add4d72007-08-29 23:37:32 +000094 raise TestFailed('setting __dict__')
Barry Warsaw4a420a02001-01-15 20:30:15 +000095
96from UserDict import UserDict
97d = UserDict({'four': 44, 'five': 55})
98
99try:
100 F.a.__dict__ = d
Guido van Rossum56ff3872001-10-22 02:00:09 +0000101except (AttributeError, TypeError): pass
Barry Warsaw033daa42001-08-14 18:28:28 +0000102else: raise TestFailed
Barry Warsaw4a420a02001-01-15 20:30:15 +0000103
Guido van Rossumb053cd82006-08-24 03:53:23 +0000104if f2.a.one != f1.a.one != F.a.one != 11:
Barry Warsaw4a420a02001-01-15 20:30:15 +0000105 raise TestFailed
Barry Warsaw534c60f2001-01-15 21:00:02 +0000106
Christian Heimesff737952007-11-27 10:40:20 +0000107# __func__ may not be a Python method!
Barry Warsaw534c60f2001-01-15 21:00:02 +0000108import new
Christian Heimesff737952007-11-27 10:40:20 +0000109F.id = id
Barry Warsaw534c60f2001-01-15 21:00:02 +0000110
111eff = F()
Christian Heimesff737952007-11-27 10:40:20 +0000112eff.id = new.instancemethod(id, eff)
Guido van Rossumb053cd82006-08-24 03:53:23 +0000113if eff.id() != id(eff):
Barry Warsaw534c60f2001-01-15 21:00:02 +0000114 raise TestFailed
115
116try:
117 F.id.foo
118except AttributeError: pass
119else: raise TestFailed
120
121try:
122 F.id.foo = 12
Guido van Rossumbd131492001-09-18 03:28:54 +0000123except (AttributeError, TypeError): pass
Barry Warsaw534c60f2001-01-15 21:00:02 +0000124else: raise TestFailed
125
126try:
127 F.id.foo
128except AttributeError: pass
129else: raise TestFailed
130
131try:
132 eff.id.foo
133except AttributeError: pass
134else: raise TestFailed
135
136try:
137 eff.id.foo = 12
Guido van Rossumbd131492001-09-18 03:28:54 +0000138except (AttributeError, TypeError): pass
Barry Warsaw534c60f2001-01-15 21:00:02 +0000139else: raise TestFailed
140
141try:
142 eff.id.foo
143except AttributeError: pass
144else: raise TestFailed
Barry Warsaw2e9b3962001-01-19 19:55:12 +0000145
146# Regression test for a crash in pre-2.1a1
147def another():
148 pass
Barry Warsaw033daa42001-08-14 18:28:28 +0000149
150try:
151 del another.__dict__
Guido van Rossumdb2a9022001-09-18 03:55:22 +0000152except TypeError: pass
Barry Warsaw033daa42001-08-14 18:28:28 +0000153else: raise TestFailed
154
155try:
Neal Norwitz221085d2007-02-25 20:55:47 +0000156 del another.__dict__
Guido van Rossumdb2a9022001-09-18 03:55:22 +0000157except TypeError: pass
Barry Warsaw033daa42001-08-14 18:28:28 +0000158else: raise TestFailed
159
160try:
Neal Norwitz221085d2007-02-25 20:55:47 +0000161 another.__dict__ = None
Guido van Rossumdb2a9022001-09-18 03:55:22 +0000162except TypeError: pass
Barry Warsaw033daa42001-08-14 18:28:28 +0000163else: raise TestFailed
Barry Warsaw2e9b3962001-01-19 19:55:12 +0000164
165try:
166 del another.bar
167except AttributeError: pass
168else: raise TestFailed
169
170# This isn't specifically related to function attributes, but it does test a
171# core dump regression in funcobject.c
Neal Norwitz221085d2007-02-25 20:55:47 +0000172del another.__defaults__
Moshe Zadka497671e2001-01-29 06:21:17 +0000173
174def foo():
Tim Peters10fb3862001-02-09 20:17:14 +0000175 pass
Moshe Zadka497671e2001-01-29 06:21:17 +0000176
177def bar():
Tim Peters10fb3862001-02-09 20:17:14 +0000178 pass
Moshe Zadka497671e2001-01-29 06:21:17 +0000179
180def temp():
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000181 print(1)
Moshe Zadka497671e2001-01-29 06:21:17 +0000182
Barry Warsaw033daa42001-08-14 18:28:28 +0000183if foo==bar:
184 raise TestFailed
Moshe Zadka497671e2001-01-29 06:21:17 +0000185
186d={}
187d[foo] = 1
188
Neal Norwitz221085d2007-02-25 20:55:47 +0000189foo.__code__ = temp.__code__
Moshe Zadka497671e2001-01-29 06:21:17 +0000190
191d[foo]
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000192
193# Test all predefined function attributes systematically
194
Armin Rigo89a39462004-10-28 16:32:00 +0000195def cantset(obj, name, value, exception=(AttributeError, TypeError)):
Guido van Rossumbd131492001-09-18 03:28:54 +0000196 verify(hasattr(obj, name)) # Otherwise it's probably a typo
197 try:
198 setattr(obj, name, value)
Armin Rigo89a39462004-10-28 16:32:00 +0000199 except exception:
Guido van Rossumbd131492001-09-18 03:28:54 +0000200 pass
201 else:
Collin Winter3add4d72007-08-29 23:37:32 +0000202 raise TestFailed("shouldn't be able to set %s to %r" % (name, value))
Guido van Rossumbd131492001-09-18 03:28:54 +0000203 try:
204 delattr(obj, name)
Guido van Rossum56ff3872001-10-22 02:00:09 +0000205 except (AttributeError, TypeError):
Guido van Rossumbd131492001-09-18 03:28:54 +0000206 pass
207 else:
Collin Winter3add4d72007-08-29 23:37:32 +0000208 raise TestFailed("shouldn't be able to del %s" % name)
Guido van Rossumbd131492001-09-18 03:28:54 +0000209
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000210def test_func_closure():
211 a = 12
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000212 def f(): print(a)
Neal Norwitz221085d2007-02-25 20:55:47 +0000213 c = f.__closure__
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000214 verify(isinstance(c, tuple))
215 verify(len(c) == 1)
216 verify(c[0].__class__.__name__ == "cell") # don't have a type object handy
Neal Norwitz221085d2007-02-25 20:55:47 +0000217 cantset(f, "__closure__", c)
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000218
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +0000219def test_empty_cell():
220 def f(): print(a)
221 try:
222 f.__closure__[0].cell_contents
223 except ValueError:
224 pass
225 else:
226 raise TestFailed("shouldn't be able to read an empty cell")
227
228 a = 12
229
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000230def test_func_doc():
231 def f(): pass
232 verify(f.__doc__ is None)
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000233 f.__doc__ = "hello"
234 verify(f.__doc__ == "hello")
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000235 del f.__doc__
236 verify(f.__doc__ is None)
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000237
238def test_func_globals():
239 def f(): pass
Neal Norwitz221085d2007-02-25 20:55:47 +0000240 verify(f.__globals__ is globals())
241 cantset(f, "__globals__", globals())
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000242
243def test_func_name():
244 def f(): pass
245 verify(f.__name__ == "f")
Neal Norwitz7e95bef2007-08-26 03:56:04 +0000246 f.__name__ = "g"
247 verify(f.__name__ == "g")
Neal Norwitz221085d2007-02-25 20:55:47 +0000248 cantset(f, "__globals__", 1)
Michael W. Hudson5e897952004-08-12 18:12:44 +0000249 cantset(f, "__name__", 1)
Michael W. Hudsonee319f62005-02-17 10:37:21 +0000250 # test that you can access func.__name__ in restricted mode
251 s = """def f(): pass\nf.__name__"""
Georg Brandl7cae87c2006-09-06 06:51:57 +0000252 exec(s, {'__builtins__':{}})
Tim Petersbf9ac4b2004-08-13 03:57:22 +0000253
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000254
255def test_func_code():
Armin Rigo89a39462004-10-28 16:32:00 +0000256 a = b = 24
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000257 def f(): pass
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000258 def g(): print(12)
259 def f1(): print(a)
260 def g1(): print(b)
261 def f2(): print(a, b)
Neal Norwitz221085d2007-02-25 20:55:47 +0000262 verify(type(f.__code__) is types.CodeType)
263 f.__code__ = g.__code__
264 cantset(f, "__code__", None)
Armin Rigo89a39462004-10-28 16:32:00 +0000265 # can't change the number of free vars
Neal Norwitz221085d2007-02-25 20:55:47 +0000266 cantset(f, "__code__", f1.__code__, exception=ValueError)
267 cantset(f1, "__code__", f.__code__, exception=ValueError)
268 cantset(f1, "__code__", f2.__code__, exception=ValueError)
269 f1.__code__ = g1.__code__
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000270
271def test_func_defaults():
272 def f(a, b): return (a, b)
Neal Norwitz221085d2007-02-25 20:55:47 +0000273 verify(f.__defaults__ is None)
274 f.__defaults__ = (1, 2)
275 verify(f.__defaults__ == (1, 2))
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000276 verify(f(10) == (10, 2))
277 def g(a=1, b=2): return (a, b)
Neal Norwitz221085d2007-02-25 20:55:47 +0000278 verify(g.__defaults__ == (1, 2))
279 del g.__defaults__
280 verify(g.__defaults__ is None)
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000281 try:
282 g()
283 except TypeError:
284 pass
285 else:
Collin Winter3add4d72007-08-29 23:37:32 +0000286 raise TestFailed("shouldn't be allowed to call g() w/o defaults")
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000287
288def test_func_dict():
289 def f(): pass
290 a = f.__dict__
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000291 verify(a == {})
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000292 f.hello = 'world'
293 verify(a == {'hello': 'world'})
Neal Norwitz221085d2007-02-25 20:55:47 +0000294 verify(a is f.__dict__)
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000295 f.__dict__ = {'world': 'hello'}
296 verify(f.world == "hello")
Neal Norwitz221085d2007-02-25 20:55:47 +0000297 verify(f.__dict__ == {'world': 'hello'})
Guido van Rossumbd131492001-09-18 03:28:54 +0000298 cantset(f, "__dict__", None)
299
Christian Heimesff737952007-11-27 10:40:20 +0000300def test___self__():
Guido van Rossumbd131492001-09-18 03:28:54 +0000301 class C:
302 def foo(self): pass
Christian Heimesff737952007-11-27 10:40:20 +0000303 #verify(C.foo.__self__.__class__ is C)
304 verify(C().foo.__self__.__class__ is C)
305 #cantset(C.foo, "__self__.__class__", C)
306 cantset(C().foo, "__self__.__class__", C)
Guido van Rossumbd131492001-09-18 03:28:54 +0000307
Christian Heimesff737952007-11-27 10:40:20 +0000308def test___func__():
Guido van Rossumbd131492001-09-18 03:28:54 +0000309 def foo(self): pass
310 class C:
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000311 pass
Guido van Rossumbd131492001-09-18 03:28:54 +0000312 C.foo = foo
Christian Heimesff737952007-11-27 10:40:20 +0000313 #verify(C.foo.__func__ is foo)
314 verify(C().foo.__func__ is foo)
315 #cantset(C.foo, "__func__", foo)
316 cantset(C().foo, "__func__", foo)
Guido van Rossumbd131492001-09-18 03:28:54 +0000317
Christian Heimesff737952007-11-27 10:40:20 +0000318def test___self__():
Guido van Rossumbd131492001-09-18 03:28:54 +0000319 class C:
320 def foo(self): pass
Christian Heimesff737952007-11-27 10:40:20 +0000321 #verify(C.foo.__self__ is None)
Guido van Rossumbd131492001-09-18 03:28:54 +0000322 c = C()
Christian Heimesff737952007-11-27 10:40:20 +0000323 #verify(c.foo.__self__ is c)
324 #cantset(C.foo, "__self__", None)
325 #cantset(c.foo, "__self__", c)
Guido van Rossumbd131492001-09-18 03:28:54 +0000326
327def test_im_dict():
328 class C:
329 def foo(self): pass
330 foo.bar = 42
331 verify(C.foo.__dict__ == {'bar': 42})
332 verify(C().foo.__dict__ == {'bar': 42})
Christian Heimes4a22b5d2007-11-25 09:39:14 +0000333 #cantset(C.foo, "__dict__", C.foo.__dict__)
334 #cantset(C().foo, "__dict__", C.foo.__dict__)
Guido van Rossumbd131492001-09-18 03:28:54 +0000335
336def test_im_doc():
337 class C:
338 def foo(self): "hello"
339 verify(C.foo.__doc__ == "hello")
340 verify(C().foo.__doc__ == "hello")
Christian Heimes4a22b5d2007-11-25 09:39:14 +0000341 #cantset(C.foo, "__doc__", "hello")
342 #cantset(C().foo, "__doc__", "hello")
Guido van Rossumbd131492001-09-18 03:28:54 +0000343
344def test_im_name():
345 class C:
346 def foo(self): pass
347 verify(C.foo.__name__ == "foo")
348 verify(C().foo.__name__ == "foo")
Christian Heimes4a22b5d2007-11-25 09:39:14 +0000349 #cantset(C.foo, "__name__", "foo")
350 #cantset(C().foo, "__name__", "foo")
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000351
352def testmore():
353 test_func_closure()
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +0000354 test_empty_cell()
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000355 test_func_doc()
356 test_func_globals()
357 test_func_name()
358 test_func_code()
359 test_func_defaults()
360 test_func_dict()
Guido van Rossumbd131492001-09-18 03:28:54 +0000361 # Tests for instance method attributes
Christian Heimesff737952007-11-27 10:40:20 +0000362 test___self__()
363 test___func__()
364 test___self__()
Guido van Rossumbd131492001-09-18 03:28:54 +0000365 test_im_dict()
366 test_im_doc()
367 test_im_name()
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000368
369testmore()