blob: 746c91ee31497f4bff5bd1aab8c80eb3df64198c [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
Barry Warsaw033daa42001-08-14 18:28:28 +000014except AttributeError: pass
15else: raise TestFailed, 'expected AttributeError'
Barry Warsaw4a420a02001-01-15 20:30:15 +000016
Barry Warsaw033daa42001-08-14 18:28:28 +000017if b.__dict__ <> {}:
18 raise TestFailed, 'expected unassigned func.__dict__ to be {}'
Barry Warsawc1e100f2001-02-26 18:07:26 +000019
Barry Warsaw4a420a02001-01-15 20:30:15 +000020b.publish = 1
21if b.publish <> 1:
22 raise TestFailed, 'function attribute not set to expected value'
23
24docstring = 'its docstring'
25b.__doc__ = docstring
26if b.__doc__ <> docstring:
27 raise TestFailed, 'problem with setting __doc__ attribute'
28
29if 'publish' not in dir(b):
30 raise TestFailed, 'attribute not in dir()'
31
Barry Warsaw033daa42001-08-14 18:28:28 +000032try:
33 del b.__dict__
34except TypeError: pass
35else: raise TestFailed, 'del func.__dict__ expected TypeError'
Barry Warsawc1e100f2001-02-26 18:07:26 +000036
37b.publish = 1
Barry Warsaw033daa42001-08-14 18:28:28 +000038try:
39 b.__dict__ = None
40except TypeError: pass
41else: raise TestFailed, 'func.__dict__ = None expected TypeError'
Barry Warsawc1e100f2001-02-26 18:07:26 +000042
Barry Warsaw033daa42001-08-14 18:28:28 +000043d = {'hello': 'world'}
44b.__dict__ = d
45if b.func_dict is not d:
46 raise TestFailed, 'func.__dict__ assignment to dictionary failed'
47if b.hello <> 'world':
48 raise TestFailed, 'attribute after func.__dict__ assignment failed'
Barry Warsawc1e100f2001-02-26 18:07:26 +000049
Barry Warsaw4a420a02001-01-15 20:30:15 +000050f1 = F()
51f2 = F()
52
53try:
54 F.a.publish
Barry Warsaw033daa42001-08-14 18:28:28 +000055except AttributeError: pass
56else: raise TestFailed, 'expected AttributeError'
Barry Warsaw4a420a02001-01-15 20:30:15 +000057
58try:
59 f1.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
Barry Warsawc1e100f2001-02-26 18:07:26 +000063# In Python 2.1 beta 1, we disallowed setting attributes on unbound methods
64# (it was already disallowed on bound methods). See the PEP for details.
65try:
66 F.a.publish = 1
Barry Warsaw033daa42001-08-14 18:28:28 +000067except TypeError: pass
68else: 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
Barry Warsaw033daa42001-08-14 18:28:28 +000087except TypeError: pass
88else: raise TestFailed, 'expected TypeError'
Barry Warsaw4a420a02001-01-15 20:30:15 +000089
Barry Warsawc1e100f2001-02-26 18:07:26 +000090# See the comment above about the change in semantics for Python 2.1b1
91try:
92 F.a.myclass = F
Barry Warsaw033daa42001-08-14 18:28:28 +000093except TypeError: pass
94else: raise TestFailed, 'expected TypeError'
Barry Warsawc1e100f2001-02-26 18:07:26 +000095
96F.a.im_func.myclass = F
97
Barry Warsaw4a420a02001-01-15 20:30:15 +000098f1.a.myclass
99f2.a.myclass
100f1.a.myclass
101F.a.myclass
102
103if f1.a.myclass is not f2.a.myclass or \
Barry Warsaw033daa42001-08-14 18:28:28 +0000104 f1.a.myclass is not F.a.myclass:
Barry Warsaw4a420a02001-01-15 20:30:15 +0000105 raise TestFailed, 'attributes were not the same'
106
107# try setting __dict__
108try:
109 F.a.__dict__ = (1, 2, 3)
Barry Warsaw033daa42001-08-14 18:28:28 +0000110except TypeError: pass
111else: raise TestFailed, 'expected TypeError'
Barry Warsaw4a420a02001-01-15 20:30:15 +0000112
Barry Warsawc1e100f2001-02-26 18:07:26 +0000113F.a.im_func.__dict__ = {'one': 11, 'two': 22, 'three': 33}
114
Barry Warsaw4a420a02001-01-15 20:30:15 +0000115if f1.a.two <> 22:
116 raise TestFailed, 'setting __dict__'
117
118from UserDict import UserDict
119d = UserDict({'four': 44, 'five': 55})
120
121try:
122 F.a.__dict__ = d
Barry Warsaw033daa42001-08-14 18:28:28 +0000123except TypeError: pass
124else: raise TestFailed
Barry Warsaw4a420a02001-01-15 20:30:15 +0000125
126if f2.a.one <> f1.a.one <> F.a.one <> 11:
127 raise TestFailed
Barry Warsaw534c60f2001-01-15 21:00:02 +0000128
129# im_func may not be a Python method!
130import new
131F.id = new.instancemethod(id, None, F)
132
133eff = F()
134if eff.id() <> id(eff):
135 raise TestFailed
136
137try:
138 F.id.foo
139except AttributeError: pass
140else: raise TestFailed
141
142try:
143 F.id.foo = 12
144except TypeError: pass
145else: raise TestFailed
146
147try:
148 F.id.foo
149except AttributeError: pass
150else: raise TestFailed
151
152try:
153 eff.id.foo
154except AttributeError: pass
155else: raise TestFailed
156
157try:
158 eff.id.foo = 12
159except TypeError: pass
160else: raise TestFailed
161
162try:
163 eff.id.foo
164except AttributeError: pass
165else: raise TestFailed
Barry Warsaw2e9b3962001-01-19 19:55:12 +0000166
167# Regression test for a crash in pre-2.1a1
168def another():
169 pass
Barry Warsaw033daa42001-08-14 18:28:28 +0000170
171try:
172 del another.__dict__
173except TypeError: pass
174else: raise TestFailed
175
176try:
177 del another.func_dict
178except TypeError: pass
179else: raise TestFailed
180
181try:
182 another.func_dict = None
183except TypeError: pass
184else: raise TestFailed
Barry Warsaw2e9b3962001-01-19 19:55:12 +0000185
186try:
187 del another.bar
188except AttributeError: pass
189else: raise TestFailed
190
191# This isn't specifically related to function attributes, but it does test a
192# core dump regression in funcobject.c
193del another.func_defaults
Moshe Zadka497671e2001-01-29 06:21:17 +0000194
195def foo():
Tim Peters10fb3862001-02-09 20:17:14 +0000196 pass
Moshe Zadka497671e2001-01-29 06:21:17 +0000197
198def bar():
Tim Peters10fb3862001-02-09 20:17:14 +0000199 pass
Moshe Zadka497671e2001-01-29 06:21:17 +0000200
201def temp():
Tim Peters10fb3862001-02-09 20:17:14 +0000202 print 1
Moshe Zadka497671e2001-01-29 06:21:17 +0000203
Barry Warsaw033daa42001-08-14 18:28:28 +0000204if foo==bar:
205 raise TestFailed
Moshe Zadka497671e2001-01-29 06:21:17 +0000206
207d={}
208d[foo] = 1
209
210foo.func_code = temp.func_code
211
212d[foo]