blob: 7a083b70dfbf18a7b22c24b7434903f8e0b43a66 [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
20else: raise TestFailed, 'expected AttributeError'
Barry Warsaw4a420a02001-01-15 20:30:15 +000021
Barry Warsaw033daa42001-08-14 18:28:28 +000022if b.__dict__ <> {}:
23 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
26if b.publish <> 1:
27 raise TestFailed, 'function attribute not set to expected value'
28
29docstring = 'its docstring'
30b.__doc__ = docstring
31if b.__doc__ <> docstring:
32 raise TestFailed, 'problem with setting __doc__ attribute'
33
34if 'publish' not in dir(b):
35 raise TestFailed, 'attribute not in dir()'
36
Barry Warsaw033daa42001-08-14 18:28:28 +000037try:
38 del b.__dict__
Guido van Rossumdb2a9022001-09-18 03:55:22 +000039except TypeError: pass
Barry Warsaw033daa42001-08-14 18:28:28 +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
Barry Warsaw033daa42001-08-14 18:28:28 +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
50if b.func_dict is not d:
51 raise TestFailed, 'func.__dict__ assignment to dictionary failed'
52if b.hello <> 'world':
53 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
61else: 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
66else: 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.
70try:
71 F.a.publish = 1
Guido van Rossumbd131492001-09-18 03:28:54 +000072except (AttributeError, TypeError): pass
73else: raise TestFailed, 'expected AttributeError or TypeError'
Barry Warsaw4a420a02001-01-15 20:30:15 +000074
Barry Warsawc1e100f2001-02-26 18:07:26 +000075# But setting it explicitly on the underlying function object is okay.
76F.a.im_func.publish = 1
77
Barry Warsaw4a420a02001-01-15 20:30:15 +000078if F.a.publish <> 1:
79 raise TestFailed, 'unbound method attribute not set to expected value'
80
81if f1.a.publish <> 1:
82 raise TestFailed, 'bound method attribute access did not work'
83
84if f2.a.publish <> 1:
85 raise TestFailed, 'bound method attribute access did not work'
86
87if 'publish' not in dir(F.a):
88 raise TestFailed, 'attribute not in dir()'
89
90try:
91 f1.a.publish = 0
Guido van Rossumbd131492001-09-18 03:28:54 +000092except (AttributeError, TypeError): pass
93else: raise TestFailed, 'expected AttributeError or TypeError'
Barry Warsaw4a420a02001-01-15 20:30:15 +000094
Barry Warsawc1e100f2001-02-26 18:07:26 +000095# See the comment above about the change in semantics for Python 2.1b1
96try:
97 F.a.myclass = F
Guido van Rossumbd131492001-09-18 03:28:54 +000098except (AttributeError, TypeError): pass
99else: raise TestFailed, 'expected AttributeError or TypeError'
Barry Warsawc1e100f2001-02-26 18:07:26 +0000100
101F.a.im_func.myclass = F
102
Barry Warsaw4a420a02001-01-15 20:30:15 +0000103f1.a.myclass
104f2.a.myclass
105f1.a.myclass
106F.a.myclass
107
108if f1.a.myclass is not f2.a.myclass or \
Barry Warsaw033daa42001-08-14 18:28:28 +0000109 f1.a.myclass is not F.a.myclass:
Barry Warsaw4a420a02001-01-15 20:30:15 +0000110 raise TestFailed, 'attributes were not the same'
111
112# try setting __dict__
113try:
114 F.a.__dict__ = (1, 2, 3)
Guido van Rossum56ff3872001-10-22 02:00:09 +0000115except (AttributeError, TypeError): pass
116else: raise TestFailed, 'expected TypeError or AttributeError'
Barry Warsaw4a420a02001-01-15 20:30:15 +0000117
Barry Warsawc1e100f2001-02-26 18:07:26 +0000118F.a.im_func.__dict__ = {'one': 11, 'two': 22, 'three': 33}
119
Barry Warsaw4a420a02001-01-15 20:30:15 +0000120if f1.a.two <> 22:
121 raise TestFailed, 'setting __dict__'
122
123from UserDict import UserDict
124d = UserDict({'four': 44, 'five': 55})
125
126try:
127 F.a.__dict__ = d
Guido van Rossum56ff3872001-10-22 02:00:09 +0000128except (AttributeError, TypeError): pass
Barry Warsaw033daa42001-08-14 18:28:28 +0000129else: raise TestFailed
Barry Warsaw4a420a02001-01-15 20:30:15 +0000130
131if f2.a.one <> f1.a.one <> F.a.one <> 11:
132 raise TestFailed
Barry Warsaw534c60f2001-01-15 21:00:02 +0000133
134# im_func may not be a Python method!
135import new
136F.id = new.instancemethod(id, None, F)
137
138eff = F()
139if eff.id() <> id(eff):
140 raise TestFailed
141
142try:
143 F.id.foo
144except AttributeError: pass
145else: raise TestFailed
146
147try:
148 F.id.foo = 12
Guido van Rossumbd131492001-09-18 03:28:54 +0000149except (AttributeError, TypeError): pass
Barry Warsaw534c60f2001-01-15 21:00:02 +0000150else: raise TestFailed
151
152try:
153 F.id.foo
154except AttributeError: pass
155else: raise TestFailed
156
157try:
158 eff.id.foo
159except AttributeError: pass
160else: raise TestFailed
161
162try:
163 eff.id.foo = 12
Guido van Rossumbd131492001-09-18 03:28:54 +0000164except (AttributeError, TypeError): pass
Barry Warsaw534c60f2001-01-15 21:00:02 +0000165else: raise TestFailed
166
167try:
168 eff.id.foo
169except AttributeError: pass
170else: raise TestFailed
Barry Warsaw2e9b3962001-01-19 19:55:12 +0000171
172# Regression test for a crash in pre-2.1a1
173def another():
174 pass
Barry Warsaw033daa42001-08-14 18:28:28 +0000175
176try:
177 del another.__dict__
Guido van Rossumdb2a9022001-09-18 03:55:22 +0000178except TypeError: pass
Barry Warsaw033daa42001-08-14 18:28:28 +0000179else: raise TestFailed
180
181try:
182 del another.func_dict
Guido van Rossumdb2a9022001-09-18 03:55:22 +0000183except TypeError: pass
Barry Warsaw033daa42001-08-14 18:28:28 +0000184else: raise TestFailed
185
186try:
187 another.func_dict = None
Guido van Rossumdb2a9022001-09-18 03:55:22 +0000188except TypeError: pass
Barry Warsaw033daa42001-08-14 18:28:28 +0000189else: raise TestFailed
Barry Warsaw2e9b3962001-01-19 19:55:12 +0000190
191try:
192 del another.bar
193except AttributeError: pass
194else: raise TestFailed
195
196# This isn't specifically related to function attributes, but it does test a
197# core dump regression in funcobject.c
198del another.func_defaults
Moshe Zadka497671e2001-01-29 06:21:17 +0000199
200def foo():
Tim Peters10fb3862001-02-09 20:17:14 +0000201 pass
Moshe Zadka497671e2001-01-29 06:21:17 +0000202
203def bar():
Tim Peters10fb3862001-02-09 20:17:14 +0000204 pass
Moshe Zadka497671e2001-01-29 06:21:17 +0000205
206def temp():
Tim Peters10fb3862001-02-09 20:17:14 +0000207 print 1
Moshe Zadka497671e2001-01-29 06:21:17 +0000208
Barry Warsaw033daa42001-08-14 18:28:28 +0000209if foo==bar:
210 raise TestFailed
Moshe Zadka497671e2001-01-29 06:21:17 +0000211
212d={}
213d[foo] = 1
214
215foo.func_code = temp.func_code
216
217d[foo]
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000218
219# Test all predefined function attributes systematically
220
Armin Rigo89a39462004-10-28 16:32:00 +0000221def cantset(obj, name, value, exception=(AttributeError, TypeError)):
Guido van Rossumbd131492001-09-18 03:28:54 +0000222 verify(hasattr(obj, name)) # Otherwise it's probably a typo
223 try:
224 setattr(obj, name, value)
Armin Rigo89a39462004-10-28 16:32:00 +0000225 except exception:
Guido van Rossumbd131492001-09-18 03:28:54 +0000226 pass
227 else:
228 raise TestFailed, "shouldn't be able to set %s to %r" % (name, value)
229 try:
230 delattr(obj, name)
Guido van Rossum56ff3872001-10-22 02:00:09 +0000231 except (AttributeError, TypeError):
Guido van Rossumbd131492001-09-18 03:28:54 +0000232 pass
233 else:
234 raise TestFailed, "shouldn't be able to del %s" % name
235
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000236def test_func_closure():
237 a = 12
238 def f(): print a
239 c = f.func_closure
240 verify(isinstance(c, tuple))
241 verify(len(c) == 1)
242 verify(c[0].__class__.__name__ == "cell") # don't have a type object handy
Guido van Rossumbd131492001-09-18 03:28:54 +0000243 cantset(f, "func_closure", c)
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000244
245def test_func_doc():
246 def f(): pass
247 verify(f.__doc__ is None)
248 verify(f.func_doc is None)
249 f.__doc__ = "hello"
250 verify(f.__doc__ == "hello")
251 verify(f.func_doc == "hello")
252 del f.__doc__
253 verify(f.__doc__ is None)
254 verify(f.func_doc is None)
255 f.func_doc = "world"
256 verify(f.__doc__ == "world")
257 verify(f.func_doc == "world")
258 del f.func_doc
259 verify(f.func_doc is None)
260 verify(f.__doc__ is None)
261
262def test_func_globals():
263 def f(): pass
264 verify(f.func_globals is globals())
Guido van Rossumbd131492001-09-18 03:28:54 +0000265 cantset(f, "func_globals", globals())
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000266
267def test_func_name():
268 def f(): pass
269 verify(f.__name__ == "f")
270 verify(f.func_name == "f")
Michael W. Hudson5e897952004-08-12 18:12:44 +0000271 f.__name__ = "g"
272 verify(f.__name__ == "g")
273 verify(f.func_name == "g")
274 f.func_name = "h"
275 verify(f.__name__ == "h")
276 verify(f.func_name == "h")
277 cantset(f, "func_globals", 1)
278 cantset(f, "__name__", 1)
Michael W. Hudsonee319f62005-02-17 10:37:21 +0000279 # test that you can access func.__name__ in restricted mode
280 s = """def f(): pass\nf.__name__"""
281 exec s in {'__builtins__':{}}
Tim Petersbf9ac4b2004-08-13 03:57:22 +0000282
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000283
284def test_func_code():
Armin Rigo89a39462004-10-28 16:32:00 +0000285 a = b = 24
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000286 def f(): pass
287 def g(): print 12
Armin Rigo89a39462004-10-28 16:32:00 +0000288 def f1(): print a
289 def g1(): print b
290 def f2(): print a, b
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000291 verify(type(f.func_code) is types.CodeType)
292 f.func_code = g.func_code
Guido van Rossumbd131492001-09-18 03:28:54 +0000293 cantset(f, "func_code", None)
Armin Rigo89a39462004-10-28 16:32:00 +0000294 # can't change the number of free vars
295 cantset(f, "func_code", f1.func_code, exception=ValueError)
296 cantset(f1, "func_code", f.func_code, exception=ValueError)
297 cantset(f1, "func_code", f2.func_code, exception=ValueError)
298 f1.func_code = g1.func_code
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000299
300def test_func_defaults():
301 def f(a, b): return (a, b)
302 verify(f.func_defaults is None)
303 f.func_defaults = (1, 2)
304 verify(f.func_defaults == (1, 2))
305 verify(f(10) == (10, 2))
306 def g(a=1, b=2): return (a, b)
307 verify(g.func_defaults == (1, 2))
308 del g.func_defaults
309 verify(g.func_defaults is None)
310 try:
311 g()
312 except TypeError:
313 pass
314 else:
315 raise TestFailed, "shouldn't be allowed to call g() w/o defaults"
316
317def test_func_dict():
318 def f(): pass
319 a = f.__dict__
320 b = f.func_dict
321 verify(a == {})
322 verify(a is b)
323 f.hello = 'world'
324 verify(a == {'hello': 'world'})
325 verify(f.func_dict is a is f.__dict__)
326 f.func_dict = {}
Guido van Rossumbd131492001-09-18 03:28:54 +0000327 verify(not hasattr(f, "hello"))
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000328 f.__dict__ = {'world': 'hello'}
329 verify(f.world == "hello")
330 verify(f.__dict__ is f.func_dict == {'world': 'hello'})
Guido van Rossumbd131492001-09-18 03:28:54 +0000331 cantset(f, "func_dict", None)
332 cantset(f, "__dict__", None)
333
334def test_im_class():
335 class C:
336 def foo(self): pass
337 verify(C.foo.im_class is C)
338 verify(C().foo.im_class is C)
339 cantset(C.foo, "im_class", C)
340 cantset(C().foo, "im_class", C)
341
342def test_im_func():
343 def foo(self): pass
344 class C:
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000345 pass
Guido van Rossumbd131492001-09-18 03:28:54 +0000346 C.foo = foo
347 verify(C.foo.im_func is foo)
348 verify(C().foo.im_func is foo)
349 cantset(C.foo, "im_func", foo)
350 cantset(C().foo, "im_func", foo)
351
352def test_im_self():
353 class C:
354 def foo(self): pass
355 verify(C.foo.im_self is None)
356 c = C()
357 verify(c.foo.im_self is c)
358 cantset(C.foo, "im_self", None)
359 cantset(c.foo, "im_self", c)
360
361def test_im_dict():
362 class C:
363 def foo(self): pass
364 foo.bar = 42
365 verify(C.foo.__dict__ == {'bar': 42})
366 verify(C().foo.__dict__ == {'bar': 42})
367 cantset(C.foo, "__dict__", C.foo.__dict__)
368 cantset(C().foo, "__dict__", C.foo.__dict__)
369
370def test_im_doc():
371 class C:
372 def foo(self): "hello"
373 verify(C.foo.__doc__ == "hello")
374 verify(C().foo.__doc__ == "hello")
375 cantset(C.foo, "__doc__", "hello")
376 cantset(C().foo, "__doc__", "hello")
377
378def test_im_name():
379 class C:
380 def foo(self): pass
381 verify(C.foo.__name__ == "foo")
382 verify(C().foo.__name__ == "foo")
383 cantset(C.foo, "__name__", "foo")
384 cantset(C().foo, "__name__", "foo")
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000385
386def testmore():
387 test_func_closure()
388 test_func_doc()
389 test_func_globals()
390 test_func_name()
391 test_func_code()
392 test_func_defaults()
393 test_func_dict()
Guido van Rossumbd131492001-09-18 03:28:54 +0000394 # Tests for instance method attributes
395 test_im_class()
396 test_im_func()
397 test_im_self()
398 test_im_dict()
399 test_im_doc()
400 test_im_name()
Guido van Rossumd9d1d4a2001-09-17 23:46:56 +0000401
402testmore()