- Got rid of newmodule.c
[python/dscho.git] / Lib / test / test_funcattrs.py
blob293b911def434822daf347111dba5661a218b565
1 from test_support import verbose, TestFailed, verify
2 import types
4 class F:
5 def a(self):
6 pass
8 def b():
9 'my docstring'
10 pass
12 # setting attributes on functions
13 try:
14 b.publish
15 except AttributeError: pass
16 else: raise TestFailed, 'expected AttributeError'
18 if b.__dict__ <> {}:
19 raise TestFailed, 'expected unassigned func.__dict__ to be {}'
21 b.publish = 1
22 if b.publish <> 1:
23 raise TestFailed, 'function attribute not set to expected value'
25 docstring = 'its docstring'
26 b.__doc__ = docstring
27 if b.__doc__ <> docstring:
28 raise TestFailed, 'problem with setting __doc__ attribute'
30 if 'publish' not in dir(b):
31 raise TestFailed, 'attribute not in dir()'
33 try:
34 del b.__dict__
35 except TypeError: pass
36 else: raise TestFailed, 'del func.__dict__ expected TypeError'
38 b.publish = 1
39 try:
40 b.__dict__ = None
41 except TypeError: pass
42 else: raise TestFailed, 'func.__dict__ = None expected TypeError'
44 d = {'hello': 'world'}
45 b.__dict__ = d
46 if b.func_dict is not d:
47 raise TestFailed, 'func.__dict__ assignment to dictionary failed'
48 if b.hello <> 'world':
49 raise TestFailed, 'attribute after func.__dict__ assignment failed'
51 f1 = F()
52 f2 = F()
54 try:
55 F.a.publish
56 except AttributeError: pass
57 else: raise TestFailed, 'expected AttributeError'
59 try:
60 f1.a.publish
61 except AttributeError: pass
62 else: raise TestFailed, 'expected AttributeError'
64 # In Python 2.1 beta 1, we disallowed setting attributes on unbound methods
65 # (it was already disallowed on bound methods). See the PEP for details.
66 try:
67 F.a.publish = 1
68 except (AttributeError, TypeError): pass
69 else: raise TestFailed, 'expected AttributeError or TypeError'
71 # But setting it explicitly on the underlying function object is okay.
72 F.a.im_func.publish = 1
74 if F.a.publish <> 1:
75 raise TestFailed, 'unbound method attribute not set to expected value'
77 if f1.a.publish <> 1:
78 raise TestFailed, 'bound method attribute access did not work'
80 if f2.a.publish <> 1:
81 raise TestFailed, 'bound method attribute access did not work'
83 if 'publish' not in dir(F.a):
84 raise TestFailed, 'attribute not in dir()'
86 try:
87 f1.a.publish = 0
88 except (AttributeError, TypeError): pass
89 else: raise TestFailed, 'expected AttributeError or TypeError'
91 # See the comment above about the change in semantics for Python 2.1b1
92 try:
93 F.a.myclass = F
94 except (AttributeError, TypeError): pass
95 else: raise TestFailed, 'expected AttributeError or TypeError'
97 F.a.im_func.myclass = F
99 f1.a.myclass
100 f2.a.myclass
101 f1.a.myclass
102 F.a.myclass
104 if f1.a.myclass is not f2.a.myclass or \
105 f1.a.myclass is not F.a.myclass:
106 raise TestFailed, 'attributes were not the same'
108 # try setting __dict__
109 try:
110 F.a.__dict__ = (1, 2, 3)
111 except (AttributeError, TypeError): pass
112 else: raise TestFailed, 'expected TypeError or AttributeError'
114 F.a.im_func.__dict__ = {'one': 11, 'two': 22, 'three': 33}
116 if f1.a.two <> 22:
117 raise TestFailed, 'setting __dict__'
119 from UserDict import UserDict
120 d = UserDict({'four': 44, 'five': 55})
122 try:
123 F.a.__dict__ = d
124 except (AttributeError, TypeError): pass
125 else: raise TestFailed
127 if f2.a.one <> f1.a.one <> F.a.one <> 11:
128 raise TestFailed
130 # im_func may not be a Python method!
131 import new
132 F.id = new.instancemethod(id, None, F)
134 eff = F()
135 if eff.id() <> id(eff):
136 raise TestFailed
138 try:
139 F.id.foo
140 except AttributeError: pass
141 else: raise TestFailed
143 try:
144 F.id.foo = 12
145 except (AttributeError, TypeError): pass
146 else: raise TestFailed
148 try:
149 F.id.foo
150 except AttributeError: pass
151 else: raise TestFailed
153 try:
154 eff.id.foo
155 except AttributeError: pass
156 else: raise TestFailed
158 try:
159 eff.id.foo = 12
160 except (AttributeError, TypeError): pass
161 else: raise TestFailed
163 try:
164 eff.id.foo
165 except AttributeError: pass
166 else: raise TestFailed
168 # Regression test for a crash in pre-2.1a1
169 def another():
170 pass
172 try:
173 del another.__dict__
174 except TypeError: pass
175 else: raise TestFailed
177 try:
178 del another.func_dict
179 except TypeError: pass
180 else: raise TestFailed
182 try:
183 another.func_dict = None
184 except TypeError: pass
185 else: raise TestFailed
187 try:
188 del another.bar
189 except AttributeError: pass
190 else: raise TestFailed
192 # This isn't specifically related to function attributes, but it does test a
193 # core dump regression in funcobject.c
194 del another.func_defaults
196 def foo():
197 pass
199 def bar():
200 pass
202 def temp():
203 print 1
205 if foo==bar:
206 raise TestFailed
208 d={}
209 d[foo] = 1
211 foo.func_code = temp.func_code
213 d[foo]
215 # Test all predefined function attributes systematically
217 def cantset(obj, name, value):
218 verify(hasattr(obj, name)) # Otherwise it's probably a typo
219 try:
220 setattr(obj, name, value)
221 except (AttributeError, TypeError):
222 pass
223 else:
224 raise TestFailed, "shouldn't be able to set %s to %r" % (name, value)
225 try:
226 delattr(obj, name)
227 except (AttributeError, TypeError):
228 pass
229 else:
230 raise TestFailed, "shouldn't be able to del %s" % name
232 def test_func_closure():
233 a = 12
234 def f(): print a
235 c = f.func_closure
236 verify(isinstance(c, tuple))
237 verify(len(c) == 1)
238 verify(c[0].__class__.__name__ == "cell") # don't have a type object handy
239 cantset(f, "func_closure", c)
241 def test_func_doc():
242 def f(): pass
243 verify(f.__doc__ is None)
244 verify(f.func_doc is None)
245 f.__doc__ = "hello"
246 verify(f.__doc__ == "hello")
247 verify(f.func_doc == "hello")
248 del f.__doc__
249 verify(f.__doc__ is None)
250 verify(f.func_doc is None)
251 f.func_doc = "world"
252 verify(f.__doc__ == "world")
253 verify(f.func_doc == "world")
254 del f.func_doc
255 verify(f.func_doc is None)
256 verify(f.__doc__ is None)
258 def test_func_globals():
259 def f(): pass
260 verify(f.func_globals is globals())
261 cantset(f, "func_globals", globals())
263 def test_func_name():
264 def f(): pass
265 verify(f.__name__ == "f")
266 verify(f.func_name == "f")
267 cantset(f, "func_name", "f")
268 cantset(f, "__name__", "f")
270 def test_func_code():
271 def f(): pass
272 def g(): print 12
273 verify(type(f.func_code) is types.CodeType)
274 f.func_code = g.func_code
275 cantset(f, "func_code", None)
277 def test_func_defaults():
278 def f(a, b): return (a, b)
279 verify(f.func_defaults is None)
280 f.func_defaults = (1, 2)
281 verify(f.func_defaults == (1, 2))
282 verify(f(10) == (10, 2))
283 def g(a=1, b=2): return (a, b)
284 verify(g.func_defaults == (1, 2))
285 del g.func_defaults
286 verify(g.func_defaults is None)
287 try:
289 except TypeError:
290 pass
291 else:
292 raise TestFailed, "shouldn't be allowed to call g() w/o defaults"
294 def test_func_dict():
295 def f(): pass
296 a = f.__dict__
297 b = f.func_dict
298 verify(a == {})
299 verify(a is b)
300 f.hello = 'world'
301 verify(a == {'hello': 'world'})
302 verify(f.func_dict is a is f.__dict__)
303 f.func_dict = {}
304 verify(not hasattr(f, "hello"))
305 f.__dict__ = {'world': 'hello'}
306 verify(f.world == "hello")
307 verify(f.__dict__ is f.func_dict == {'world': 'hello'})
308 cantset(f, "func_dict", None)
309 cantset(f, "__dict__", None)
311 def test_im_class():
312 class C:
313 def foo(self): pass
314 verify(C.foo.im_class is C)
315 verify(C().foo.im_class is C)
316 cantset(C.foo, "im_class", C)
317 cantset(C().foo, "im_class", C)
319 def test_im_func():
320 def foo(self): pass
321 class C:
322 pass
323 C.foo = foo
324 verify(C.foo.im_func is foo)
325 verify(C().foo.im_func is foo)
326 cantset(C.foo, "im_func", foo)
327 cantset(C().foo, "im_func", foo)
329 def test_im_self():
330 class C:
331 def foo(self): pass
332 verify(C.foo.im_self is None)
333 c = C()
334 verify(c.foo.im_self is c)
335 cantset(C.foo, "im_self", None)
336 cantset(c.foo, "im_self", c)
338 def test_im_dict():
339 class C:
340 def foo(self): pass
341 foo.bar = 42
342 verify(C.foo.__dict__ == {'bar': 42})
343 verify(C().foo.__dict__ == {'bar': 42})
344 cantset(C.foo, "__dict__", C.foo.__dict__)
345 cantset(C().foo, "__dict__", C.foo.__dict__)
347 def test_im_doc():
348 class C:
349 def foo(self): "hello"
350 verify(C.foo.__doc__ == "hello")
351 verify(C().foo.__doc__ == "hello")
352 cantset(C.foo, "__doc__", "hello")
353 cantset(C().foo, "__doc__", "hello")
355 def test_im_name():
356 class C:
357 def foo(self): pass
358 verify(C.foo.__name__ == "foo")
359 verify(C().foo.__name__ == "foo")
360 cantset(C.foo, "__name__", "foo")
361 cantset(C().foo, "__name__", "foo")
363 def testmore():
364 test_func_closure()
365 test_func_doc()
366 test_func_globals()
367 test_func_name()
368 test_func_code()
369 test_func_defaults()
370 test_func_dict()
371 # Tests for instance method attributes
372 test_im_class()
373 test_im_func()
374 test_im_self()
375 test_im_dict()
376 test_im_doc()
377 test_im_name()
379 testmore()