blob: 34895338adce4ebdce8fcdb013d194d2c2cb5ed9 [file] [log] [blame]
Barry Warsaw4a420a02001-01-15 20:30:15 +00001from test_support import verbose, TestFailed
2
3class F:
4 def a(self):
5 pass
6
7def b():
8 'my docstring'
9 pass
10
11# setting attributes on functions
12try:
13 b.publish
14except AttributeError:
15 pass
16else:
17 raise TestFailed, 'expected AttributeError'
18
Barry Warsawc1e100f2001-02-26 18:07:26 +000019if b.__dict__ <> None:
20 raise TestFailed, 'expected unassigned func.__dict__ to be None'
21
Barry Warsaw4a420a02001-01-15 20:30:15 +000022b.publish = 1
23if b.publish <> 1:
24 raise TestFailed, 'function attribute not set to expected value'
25
26docstring = 'its docstring'
27b.__doc__ = docstring
28if b.__doc__ <> docstring:
29 raise TestFailed, 'problem with setting __doc__ attribute'
30
31if 'publish' not in dir(b):
32 raise TestFailed, 'attribute not in dir()'
33
Barry Warsawc1e100f2001-02-26 18:07:26 +000034del b.__dict__
35if b.__dict__ <> None:
36 raise TestFailed, 'del func.__dict__ did not result in __dict__ == None'
37
38b.publish = 1
39b.__dict__ = None
40if b.__dict__ <> None:
41 raise TestFailed, 'func.__dict__ = None did not result in __dict__ == None'
42
43
Barry Warsaw4a420a02001-01-15 20:30:15 +000044f1 = F()
45f2 = F()
46
47try:
48 F.a.publish
49except AttributeError:
50 pass
51else:
52 raise TestFailed, 'expected AttributeError'
53
54try:
55 f1.a.publish
56except AttributeError:
57 pass
58else:
59 raise TestFailed, 'expected AttributeError'
60
Barry Warsawc1e100f2001-02-26 18:07:26 +000061# In Python 2.1 beta 1, we disallowed setting attributes on unbound methods
62# (it was already disallowed on bound methods). See the PEP for details.
63try:
64 F.a.publish = 1
65except TypeError:
66 pass
67else:
68 raise TestFailed, 'expected TypeError'
Barry Warsaw4a420a02001-01-15 20:30:15 +000069
Barry Warsawc1e100f2001-02-26 18:07:26 +000070# But setting it explicitly on the underlying function object is okay.
71F.a.im_func.publish = 1
72
Barry Warsaw4a420a02001-01-15 20:30:15 +000073if F.a.publish <> 1:
74 raise TestFailed, 'unbound method attribute not set to expected value'
75
76if f1.a.publish <> 1:
77 raise TestFailed, 'bound method attribute access did not work'
78
79if f2.a.publish <> 1:
80 raise TestFailed, 'bound method attribute access did not work'
81
82if 'publish' not in dir(F.a):
83 raise TestFailed, 'attribute not in dir()'
84
85try:
86 f1.a.publish = 0
87except TypeError:
88 pass
89else:
90 raise TestFailed, 'expected TypeError'
91
Barry Warsawc1e100f2001-02-26 18:07:26 +000092# See the comment above about the change in semantics for Python 2.1b1
93try:
94 F.a.myclass = F
95except TypeError:
96 pass
97else:
98 raise TestFailed, 'expected TypeError'
99
100F.a.im_func.myclass = F
101
Barry Warsaw4a420a02001-01-15 20:30:15 +0000102f1.a.myclass
103f2.a.myclass
104f1.a.myclass
105F.a.myclass
106
107if f1.a.myclass is not f2.a.myclass or \
108 f1.a.myclass is not F.a.myclass:
109 raise TestFailed, 'attributes were not the same'
110
111# try setting __dict__
112try:
113 F.a.__dict__ = (1, 2, 3)
114except TypeError:
115 pass
116else:
117 raise TestFailed, 'expected TypeError'
118
Barry Warsawc1e100f2001-02-26 18:07:26 +0000119F.a.im_func.__dict__ = {'one': 11, 'two': 22, 'three': 33}
120
Barry Warsaw4a420a02001-01-15 20:30:15 +0000121if f1.a.two <> 22:
122 raise TestFailed, 'setting __dict__'
123
124from UserDict import UserDict
125d = UserDict({'four': 44, 'five': 55})
126
127try:
128 F.a.__dict__ = d
129except TypeError:
130 pass
131else:
132 raise TestFailed
133
134if f2.a.one <> f1.a.one <> F.a.one <> 11:
135 raise TestFailed
Barry Warsaw534c60f2001-01-15 21:00:02 +0000136
137# im_func may not be a Python method!
138import new
139F.id = new.instancemethod(id, None, F)
140
141eff = F()
142if eff.id() <> id(eff):
143 raise TestFailed
144
145try:
146 F.id.foo
147except AttributeError: pass
148else: raise TestFailed
149
150try:
151 F.id.foo = 12
152except TypeError: pass
153else: raise TestFailed
154
155try:
156 F.id.foo
157except AttributeError: pass
158else: raise TestFailed
159
160try:
161 eff.id.foo
162except AttributeError: pass
163else: raise TestFailed
164
165try:
166 eff.id.foo = 12
167except TypeError: pass
168else: raise TestFailed
169
170try:
171 eff.id.foo
172except AttributeError: pass
173else: raise TestFailed
Barry Warsaw2e9b3962001-01-19 19:55:12 +0000174
175# Regression test for a crash in pre-2.1a1
176def another():
177 pass
178del another.__dict__
179del another.func_dict
180another.func_dict = None
181
182try:
183 del another.bar
184except AttributeError: pass
185else: raise TestFailed
186
187# This isn't specifically related to function attributes, but it does test a
188# core dump regression in funcobject.c
189del another.func_defaults
Moshe Zadka497671e2001-01-29 06:21:17 +0000190
191def foo():
Tim Peters10fb3862001-02-09 20:17:14 +0000192 pass
Moshe Zadka497671e2001-01-29 06:21:17 +0000193
194def bar():
Tim Peters10fb3862001-02-09 20:17:14 +0000195 pass
Moshe Zadka497671e2001-01-29 06:21:17 +0000196
197def temp():
Tim Peters10fb3862001-02-09 20:17:14 +0000198 print 1
Moshe Zadka497671e2001-01-29 06:21:17 +0000199
200if foo==bar: raise TestFailed
201
202d={}
203d[foo] = 1
204
205foo.func_code = temp.func_code
206
207d[foo]