Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit bd13149

Browse files
committed
- Some tests that check that assignments are not allowed expect this
to raise TypeError. In practice, a disallowed attribute assignment can raise either TypeError or AttributeError (and it's unclear which is better). So allow either. (Yes, this is in anticipation of a code change that switches the exception raised. :-) - Add a utility function, cantset(), which verifies that setting a particular attribute to a given value is disallowed, and also that deleting that same attribute is disallowed. Use this in the test_func_*() tests. - Add a new set of tests that test conformance of various instance method attributes. (Also in anticipation of code that changes their implementation.)
1 parent 427ce80 commit bd13149

1 file changed

Lines changed: 95 additions & 85 deletions

File tree

Lib/test/test_funcattrs.py

Lines changed: 95 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,13 @@ def b():
3232

3333
try:
3434
del b.__dict__
35-
except TypeError: pass
35+
except (AttributeError, TypeError): pass
3636
else: raise TestFailed, 'del func.__dict__ expected TypeError'
3737

3838
b.publish = 1
3939
try:
4040
b.__dict__ = None
41-
except TypeError: pass
41+
except (AttributeError, TypeError): pass
4242
else: raise TestFailed, 'func.__dict__ = None expected TypeError'
4343

4444
d = {'hello': 'world'}
@@ -65,8 +65,8 @@ def b():
6565
# (it was already disallowed on bound methods). See the PEP for details.
6666
try:
6767
F.a.publish = 1
68-
except TypeError: pass
69-
else: raise TestFailed, 'expected TypeError'
68+
except (AttributeError, TypeError): pass
69+
else: raise TestFailed, 'expected AttributeError or TypeError'
7070

7171
# But setting it explicitly on the underlying function object is okay.
7272
F.a.im_func.publish = 1
@@ -85,14 +85,14 @@ def b():
8585

8686
try:
8787
f1.a.publish = 0
88-
except TypeError: pass
89-
else: raise TestFailed, 'expected TypeError'
88+
except (AttributeError, TypeError): pass
89+
else: raise TestFailed, 'expected AttributeError or TypeError'
9090

9191
# See the comment above about the change in semantics for Python 2.1b1
9292
try:
9393
F.a.myclass = F
94-
except TypeError: pass
95-
else: raise TestFailed, 'expected TypeError'
94+
except (AttributeError, TypeError): pass
95+
else: raise TestFailed, 'expected AttributeError or TypeError'
9696

9797
F.a.im_func.myclass = F
9898

@@ -108,7 +108,7 @@ def b():
108108
# try setting __dict__
109109
try:
110110
F.a.__dict__ = (1, 2, 3)
111-
except TypeError: pass
111+
except (AttributeError, TypeError): pass
112112
else: raise TestFailed, 'expected TypeError'
113113

114114
F.a.im_func.__dict__ = {'one': 11, 'two': 22, 'three': 33}
@@ -121,7 +121,7 @@ def b():
121121

122122
try:
123123
F.a.__dict__ = d
124-
except TypeError: pass
124+
except (AttributeError, TypeError): pass
125125
else: raise TestFailed
126126

127127
if f2.a.one <> f1.a.one <> F.a.one <> 11:
@@ -142,7 +142,7 @@ def b():
142142

143143
try:
144144
F.id.foo = 12
145-
except TypeError: pass
145+
except (AttributeError, TypeError): pass
146146
else: raise TestFailed
147147

148148
try:
@@ -157,7 +157,7 @@ def b():
157157

158158
try:
159159
eff.id.foo = 12
160-
except TypeError: pass
160+
except (AttributeError, TypeError): pass
161161
else: raise TestFailed
162162

163163
try:
@@ -171,17 +171,17 @@ def another():
171171

172172
try:
173173
del another.__dict__
174-
except TypeError: pass
174+
except (AttributeError, TypeError): pass
175175
else: raise TestFailed
176176

177177
try:
178178
del another.func_dict
179-
except TypeError: pass
179+
except (AttributeError, TypeError): pass
180180
else: raise TestFailed
181181

182182
try:
183183
another.func_dict = None
184-
except TypeError: pass
184+
except (AttributeError, TypeError): pass
185185
else: raise TestFailed
186186

187187
try:
@@ -214,25 +214,29 @@ def temp():
214214

215215
# Test all predefined function attributes systematically
216216

217-
def test_func_closure():
218-
a = 12
219-
def f(): print a
220-
c = f.func_closure
221-
verify(isinstance(c, tuple))
222-
verify(len(c) == 1)
223-
verify(c[0].__class__.__name__ == "cell") # don't have a type object handy
217+
def cantset(obj, name, value):
218+
verify(hasattr(obj, name)) # Otherwise it's probably a typo
224219
try:
225-
f.func_closure = c
220+
setattr(obj, name, value)
226221
except (AttributeError, TypeError):
227222
pass
228223
else:
229-
raise TestFailed, "shouldn't be allowed to set func_closure"
224+
raise TestFailed, "shouldn't be able to set %s to %r" % (name, value)
230225
try:
231-
del a.func_closure
226+
delattr(obj, name)
232227
except (AttributeError, TypeError):
233228
pass
234229
else:
235-
raise TestFailed, "shouldn't be allowed to del func_closure"
230+
raise TestFailed, "shouldn't be able to del %s" % name
231+
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)
236240

237241
def test_func_doc():
238242
def f(): pass
@@ -254,59 +258,21 @@ def f(): pass
254258
def test_func_globals():
255259
def f(): pass
256260
verify(f.func_globals is globals())
257-
try:
258-
f.func_globals = globals()
259-
except (AttributeError, TypeError):
260-
pass
261-
else:
262-
raise TestFailed, "shouldn't be allowed to set func_globals"
263-
try:
264-
del f.func_globals
265-
except (AttributeError, TypeError):
266-
pass
267-
else:
268-
raise TestFailed, "shouldn't be allowed to del func_globals"
261+
cantset(f, "func_globals", globals())
269262

270263
def test_func_name():
271264
def f(): pass
272265
verify(f.__name__ == "f")
273266
verify(f.func_name == "f")
274-
try:
275-
f.func_name = "f"
276-
except (AttributeError, TypeError):
277-
pass
278-
else:
279-
raise TestFailed, "shouldn't be allowed to set func_name"
280-
try:
281-
f.__name__ = "f"
282-
except (AttributeError, TypeError):
283-
pass
284-
else:
285-
raise TestFailed, "shouldn't be allowed to set __name__"
286-
try:
287-
del f.func_name
288-
except (AttributeError, TypeError):
289-
pass
290-
else:
291-
raise TestFailed, "shouldn't be allowed to del func_name"
292-
try:
293-
del f.__name__
294-
except (AttributeError, TypeError):
295-
pass
296-
else:
297-
raise TestFailed, "shouldn't be allowed to del __name__"
267+
cantset(f, "func_name", "f")
268+
cantset(f, "__name__", "f")
298269

299270
def test_func_code():
300271
def f(): pass
301272
def g(): print 12
302273
verify(type(f.func_code) is types.CodeType)
303274
f.func_code = g.func_code
304-
try:
305-
del f.func_code
306-
except (AttributeError, TypeError):
307-
pass
308-
else:
309-
raise TestFailed, "shouldn't be allowed to del func_code"
275+
cantset(f, "func_code", None)
310276

311277
def test_func_defaults():
312278
def f(a, b): return (a, b)
@@ -335,27 +301,64 @@ def f(): pass
335301
verify(a == {'hello': 'world'})
336302
verify(f.func_dict is a is f.__dict__)
337303
f.func_dict = {}
338-
try:
339-
f.hello
340-
except (AttributeError, TypeError):
341-
pass
342-
else:
343-
raise TestFailed, "hello attribute should have disappeared"
304+
verify(not hasattr(f, "hello"))
344305
f.__dict__ = {'world': 'hello'}
345306
verify(f.world == "hello")
346307
verify(f.__dict__ is f.func_dict == {'world': 'hello'})
347-
try:
348-
del f.func_dict
349-
except (AttributeError, TypeError):
308+
cantset(f, "func_dict", None)
309+
cantset(f, "__dict__", None)
310+
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)
318+
319+
def test_im_func():
320+
def foo(self): pass
321+
class C:
350322
pass
351-
else:
352-
raise TestFailed, "shouldn't be allowed to delete func_dict"
353-
try:
354-
del f.__dict__
355-
except (AttributeError, TypeError):
356-
pass
357-
else:
358-
raise TestFailed, "shouldn't be allowed to delete __dict__"
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)
328+
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)
337+
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__)
346+
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")
354+
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")
359362

360363
def testmore():
361364
test_func_closure()
@@ -365,5 +368,12 @@ def testmore():
365368
test_func_code()
366369
test_func_defaults()
367370
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()
368378

369379
testmore()

0 commit comments

Comments
 (0)