blob: bd9caffd6f0f7c106f858eea217e8fff5aa6cedd [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
107# im_func may not be a Python method!
108import new
109F.id = new.instancemethod(id, None, F)
110
111eff = F()
Guido van Rossumb053cd82006-08-24 03:53:23 +0000112if eff.id() != id(eff):
Barry Warsaw534c60f2001-01-15 21:00:02 +0000113 raise TestFailed
114
115try:
116 F.id.foo
117except AttributeError: pass
118else: raise TestFailed
119
120try:
121 F.id.foo = 12
Guido van Rossumbd131492001-09-18 03:28:54 +0000122except (AttributeError, TypeError): pass
Barry Warsaw534c60f2001-01-15 21:00:02 +0000123else: raise TestFailed
124
125try:
126 F.id.foo
127except AttributeError: pass
128else: raise TestFailed
129
130try:
131 eff.id.foo
132except AttributeError: pass
133else: raise TestFailed
134
135try:
136 eff.id.foo = 12
Guido van Rossumbd131492001-09-18 03:28:54 +0000137except (AttributeError, TypeError): pass
Barry Warsaw534c60f2001-01-15 21:00:02 +0000138else: raise TestFailed
139
140try:
141 eff.id.foo
142except AttributeError: pass
143else: raise TestFailed
Barry Warsaw2e9b3962001-01-19 19:55:12 +0000144
145# Regression test for a crash in pre-2.1a1
146def another():
147 pass
Barry Warsaw033daa42001-08-14 18:28:28 +0000148
149try:
150 del another.__dict__
Guido van Rossumdb2a9022001-09-18 03:55:22 +0000151except TypeError: pass
Barry Warsaw033daa42001-08-14 18:28:28 +0000152else: raise TestFailed
153
154try:
Neal Norwitz221085d2007-02-25 20:55:47 +0000155 del another.__dict__
Guido van Rossumdb2a9022001-09-18 03:55:22 +0000156except TypeError: pass
Barry Warsaw033daa42001-08-14 18:28:28 +0000157else: raise TestFailed
158
159try:
Neal Norwitz221085d2007-02-25 20:55:47 +0000160 another.__dict__ = None
Guido van Rossumdb2a9022001-09-18 03:55:22 +0000161except TypeError: pass
Barry Warsaw033daa42001-08-14 18:28:28 +0000162else: raise TestFailed
Barry Warsaw2e9b3962001-01-19 19:55:12 +0000163
164try:
165 del another.bar
166except AttributeError: pass
167else: raise TestFailed
168
169# This isn't specifically related to function attributes, but it does test a
170# core dump regression in funcobject.c
Neal Norwitz221085d2007-02-25 20:55:47 +0000171del another.__defaults__
Moshe Zadka497671e2001-01-29 06:21:17 +0000172
173def foo():
Tim Peters10fb3862001-02-09 20:17:14 +0000174 pass
Moshe Zadka497671e2001-01-29 06:21:17 +0000175
176def bar():
Tim Peters10fb3862001-02-09 20:17:14 +0000177 pass
Moshe Zadka497671e2001-01-29 06:21:17 +0000178
179def temp():
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000180 print(1)
Moshe Zadka497671e2001-01-29 06:21:17 +0000181
Barry Warsaw033daa42001-08-14 18:28:28 +0000182if foo==bar:
183 raise TestFailed
Moshe Zadka497671e2001-01-29 06:21:17 +0000184
185d={}
186d[foo] = 1
187
Neal Norwitz221085d2007-02-25 20:55:47 +0000188foo.__code__ = temp.__code__
Moshe Zadka497671e2001-01-29 06:21:17 +0000189
190d[foo]
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000191
192# Test all predefined function attributes systematically
193
Armin Rigo89a39462004-10-28 16:32:00 +0000194def cantset(obj, name, value, exception=(AttributeError, TypeError)):
Guido van Rossumbd131492001-09-18 03:28:54 +0000195 verify(hasattr(obj, name)) # Otherwise it's probably a typo
196 try:
197 setattr(obj, name, value)
Armin Rigo89a39462004-10-28 16:32:00 +0000198 except exception:
Guido van Rossumbd131492001-09-18 03:28:54 +0000199 pass
200 else:
Collin Winter3add4d72007-08-29 23:37:32 +0000201 raise TestFailed("shouldn't be able to set %s to %r" % (name, value))
Guido van Rossumbd131492001-09-18 03:28:54 +0000202 try:
203 delattr(obj, name)
Guido van Rossum56ff3872001-10-22 02:00:09 +0000204 except (AttributeError, TypeError):
Guido van Rossumbd131492001-09-18 03:28:54 +0000205 pass
206 else:
Collin Winter3add4d72007-08-29 23:37:32 +0000207 raise TestFailed("shouldn't be able to del %s" % name)
Guido van Rossumbd131492001-09-18 03:28:54 +0000208
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000209def test_func_closure():
210 a = 12
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000211 def f(): print(a)
Neal Norwitz221085d2007-02-25 20:55:47 +0000212 c = f.__closure__
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000213 verify(isinstance(c, tuple))
214 verify(len(c) == 1)
215 verify(c[0].__class__.__name__ == "cell") # don't have a type object handy
Neal Norwitz221085d2007-02-25 20:55:47 +0000216 cantset(f, "__closure__", c)
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000217
218def test_func_doc():
219 def f(): pass
220 verify(f.__doc__ is None)
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000221 f.__doc__ = "hello"
222 verify(f.__doc__ == "hello")
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000223 del f.__doc__
224 verify(f.__doc__ is None)
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000225
226def test_func_globals():
227 def f(): pass
Neal Norwitz221085d2007-02-25 20:55:47 +0000228 verify(f.__globals__ is globals())
229 cantset(f, "__globals__", globals())
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000230
231def test_func_name():
232 def f(): pass
233 verify(f.__name__ == "f")
Neal Norwitz7e95bef2007-08-26 03:56:04 +0000234 f.__name__ = "g"
235 verify(f.__name__ == "g")
Neal Norwitz221085d2007-02-25 20:55:47 +0000236 cantset(f, "__globals__", 1)
Michael W. Hudson5e897952004-08-12 18:12:44 +0000237 cantset(f, "__name__", 1)
Michael W. Hudsonee319f62005-02-17 10:37:21 +0000238 # test that you can access func.__name__ in restricted mode
239 s = """def f(): pass\nf.__name__"""
Georg Brandl7cae87c2006-09-06 06:51:57 +0000240 exec(s, {'__builtins__':{}})
Tim Petersbf9ac4b2004-08-13 03:57:22 +0000241
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000242
243def test_func_code():
Armin Rigo89a39462004-10-28 16:32:00 +0000244 a = b = 24
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000245 def f(): pass
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000246 def g(): print(12)
247 def f1(): print(a)
248 def g1(): print(b)
249 def f2(): print(a, b)
Neal Norwitz221085d2007-02-25 20:55:47 +0000250 verify(type(f.__code__) is types.CodeType)
251 f.__code__ = g.__code__
252 cantset(f, "__code__", None)
Armin Rigo89a39462004-10-28 16:32:00 +0000253 # can't change the number of free vars
Neal Norwitz221085d2007-02-25 20:55:47 +0000254 cantset(f, "__code__", f1.__code__, exception=ValueError)
255 cantset(f1, "__code__", f.__code__, exception=ValueError)
256 cantset(f1, "__code__", f2.__code__, exception=ValueError)
257 f1.__code__ = g1.__code__
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000258
259def test_func_defaults():
260 def f(a, b): return (a, b)
Neal Norwitz221085d2007-02-25 20:55:47 +0000261 verify(f.__defaults__ is None)
262 f.__defaults__ = (1, 2)
263 verify(f.__defaults__ == (1, 2))
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000264 verify(f(10) == (10, 2))
265 def g(a=1, b=2): return (a, b)
Neal Norwitz221085d2007-02-25 20:55:47 +0000266 verify(g.__defaults__ == (1, 2))
267 del g.__defaults__
268 verify(g.__defaults__ is None)
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000269 try:
270 g()
271 except TypeError:
272 pass
273 else:
Collin Winter3add4d72007-08-29 23:37:32 +0000274 raise TestFailed("shouldn't be allowed to call g() w/o defaults")
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000275
276def test_func_dict():
277 def f(): pass
278 a = f.__dict__
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000279 verify(a == {})
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000280 f.hello = 'world'
281 verify(a == {'hello': 'world'})
Neal Norwitz221085d2007-02-25 20:55:47 +0000282 verify(a is f.__dict__)
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000283 f.__dict__ = {'world': 'hello'}
284 verify(f.world == "hello")
Neal Norwitz221085d2007-02-25 20:55:47 +0000285 verify(f.__dict__ == {'world': 'hello'})
Guido van Rossumbd131492001-09-18 03:28:54 +0000286 cantset(f, "__dict__", None)
287
288def test_im_class():
289 class C:
290 def foo(self): pass
Christian Heimes4a22b5d2007-11-25 09:39:14 +0000291 #verify(C.foo.im_class is C)
Guido van Rossumbd131492001-09-18 03:28:54 +0000292 verify(C().foo.im_class is C)
Christian Heimes4a22b5d2007-11-25 09:39:14 +0000293 #cantset(C.foo, "im_class", C)
Guido van Rossumbd131492001-09-18 03:28:54 +0000294 cantset(C().foo, "im_class", C)
295
296def test_im_func():
297 def foo(self): pass
298 class C:
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000299 pass
Guido van Rossumbd131492001-09-18 03:28:54 +0000300 C.foo = foo
Christian Heimes4a22b5d2007-11-25 09:39:14 +0000301 #verify(C.foo.im_func is foo)
Guido van Rossumbd131492001-09-18 03:28:54 +0000302 verify(C().foo.im_func is foo)
Christian Heimes4a22b5d2007-11-25 09:39:14 +0000303 #cantset(C.foo, "im_func", foo)
Guido van Rossumbd131492001-09-18 03:28:54 +0000304 cantset(C().foo, "im_func", foo)
305
306def test_im_self():
307 class C:
308 def foo(self): pass
Christian Heimes4a22b5d2007-11-25 09:39:14 +0000309 #verify(C.foo.im_self is None)
Guido van Rossumbd131492001-09-18 03:28:54 +0000310 c = C()
Christian Heimes4a22b5d2007-11-25 09:39:14 +0000311 #verify(c.foo.im_self is c)
312 #cantset(C.foo, "im_self", None)
313 #cantset(c.foo, "im_self", c)
Guido van Rossumbd131492001-09-18 03:28:54 +0000314
315def test_im_dict():
316 class C:
317 def foo(self): pass
318 foo.bar = 42
319 verify(C.foo.__dict__ == {'bar': 42})
320 verify(C().foo.__dict__ == {'bar': 42})
Christian Heimes4a22b5d2007-11-25 09:39:14 +0000321 #cantset(C.foo, "__dict__", C.foo.__dict__)
322 #cantset(C().foo, "__dict__", C.foo.__dict__)
Guido van Rossumbd131492001-09-18 03:28:54 +0000323
324def test_im_doc():
325 class C:
326 def foo(self): "hello"
327 verify(C.foo.__doc__ == "hello")
328 verify(C().foo.__doc__ == "hello")
Christian Heimes4a22b5d2007-11-25 09:39:14 +0000329 #cantset(C.foo, "__doc__", "hello")
330 #cantset(C().foo, "__doc__", "hello")
Guido van Rossumbd131492001-09-18 03:28:54 +0000331
332def test_im_name():
333 class C:
334 def foo(self): pass
335 verify(C.foo.__name__ == "foo")
336 verify(C().foo.__name__ == "foo")
Christian Heimes4a22b5d2007-11-25 09:39:14 +0000337 #cantset(C.foo, "__name__", "foo")
338 #cantset(C().foo, "__name__", "foo")
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000339
340def testmore():
341 test_func_closure()
342 test_func_doc()
343 test_func_globals()
344 test_func_name()
345 test_func_code()
346 test_func_defaults()
347 test_func_dict()
Guido van Rossumbd131492001-09-18 03:28:54 +0000348 # Tests for instance method attributes
349 test_im_class()
350 test_im_func()
351 test_im_self()
352 test_im_dict()
353 test_im_doc()
354 test_im_name()
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000355
356testmore()