--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/python-2.5.2/win32/Lib/test/test_funcattrs.py Fri Apr 03 17:19:34 2009 +0100
@@ -0,0 +1,414 @@
+from test.test_support import verbose, TestFailed, verify
+import types
+
+class F:
+ def a(self):
+ pass
+
+def b():
+ 'my docstring'
+ pass
+
+# __module__ is a special attribute
+verify(b.__module__ == __name__)
+verify(verify.__module__ == "test.test_support")
+
+# setting attributes on functions
+try:
+ b.publish
+except AttributeError: pass
+else: raise TestFailed, 'expected AttributeError'
+
+if b.__dict__ <> {}:
+ raise TestFailed, 'expected unassigned func.__dict__ to be {}'
+
+b.publish = 1
+if b.publish <> 1:
+ raise TestFailed, 'function attribute not set to expected value'
+
+docstring = 'its docstring'
+b.__doc__ = docstring
+if b.__doc__ <> docstring:
+ raise TestFailed, 'problem with setting __doc__ attribute'
+
+if 'publish' not in dir(b):
+ raise TestFailed, 'attribute not in dir()'
+
+try:
+ del b.__dict__
+except TypeError: pass
+else: raise TestFailed, 'del func.__dict__ expected TypeError'
+
+b.publish = 1
+try:
+ b.__dict__ = None
+except TypeError: pass
+else: raise TestFailed, 'func.__dict__ = None expected TypeError'
+
+d = {'hello': 'world'}
+b.__dict__ = d
+if b.func_dict is not d:
+ raise TestFailed, 'func.__dict__ assignment to dictionary failed'
+if b.hello <> 'world':
+ raise TestFailed, 'attribute after func.__dict__ assignment failed'
+
+f1 = F()
+f2 = F()
+
+try:
+ F.a.publish
+except AttributeError: pass
+else: raise TestFailed, 'expected AttributeError'
+
+try:
+ f1.a.publish
+except AttributeError: pass
+else: raise TestFailed, 'expected AttributeError'
+
+# In Python 2.1 beta 1, we disallowed setting attributes on unbound methods
+# (it was already disallowed on bound methods). See the PEP for details.
+try:
+ F.a.publish = 1
+except (AttributeError, TypeError): pass
+else: raise TestFailed, 'expected AttributeError or TypeError'
+
+# But setting it explicitly on the underlying function object is okay.
+F.a.im_func.publish = 1
+
+if F.a.publish <> 1:
+ raise TestFailed, 'unbound method attribute not set to expected value'
+
+if f1.a.publish <> 1:
+ raise TestFailed, 'bound method attribute access did not work'
+
+if f2.a.publish <> 1:
+ raise TestFailed, 'bound method attribute access did not work'
+
+if 'publish' not in dir(F.a):
+ raise TestFailed, 'attribute not in dir()'
+
+try:
+ f1.a.publish = 0
+except (AttributeError, TypeError): pass
+else: raise TestFailed, 'expected AttributeError or TypeError'
+
+# See the comment above about the change in semantics for Python 2.1b1
+try:
+ F.a.myclass = F
+except (AttributeError, TypeError): pass
+else: raise TestFailed, 'expected AttributeError or TypeError'
+
+F.a.im_func.myclass = F
+
+f1.a.myclass
+f2.a.myclass
+f1.a.myclass
+F.a.myclass
+
+if f1.a.myclass is not f2.a.myclass or \
+ f1.a.myclass is not F.a.myclass:
+ raise TestFailed, 'attributes were not the same'
+
+# try setting __dict__
+try:
+ F.a.__dict__ = (1, 2, 3)
+except (AttributeError, TypeError): pass
+else: raise TestFailed, 'expected TypeError or AttributeError'
+
+F.a.im_func.__dict__ = {'one': 11, 'two': 22, 'three': 33}
+
+if f1.a.two <> 22:
+ raise TestFailed, 'setting __dict__'
+
+from UserDict import UserDict
+d = UserDict({'four': 44, 'five': 55})
+
+try:
+ F.a.__dict__ = d
+except (AttributeError, TypeError): pass
+else: raise TestFailed
+
+if f2.a.one <> f1.a.one <> F.a.one <> 11:
+ raise TestFailed
+
+# im_func may not be a Python method!
+import new
+F.id = new.instancemethod(id, None, F)
+
+eff = F()
+if eff.id() <> id(eff):
+ raise TestFailed
+
+try:
+ F.id.foo
+except AttributeError: pass
+else: raise TestFailed
+
+try:
+ F.id.foo = 12
+except (AttributeError, TypeError): pass
+else: raise TestFailed
+
+try:
+ F.id.foo
+except AttributeError: pass
+else: raise TestFailed
+
+try:
+ eff.id.foo
+except AttributeError: pass
+else: raise TestFailed
+
+try:
+ eff.id.foo = 12
+except (AttributeError, TypeError): pass
+else: raise TestFailed
+
+try:
+ eff.id.foo
+except AttributeError: pass
+else: raise TestFailed
+
+# Regression test for a crash in pre-2.1a1
+def another():
+ pass
+
+try:
+ del another.__dict__
+except TypeError: pass
+else: raise TestFailed
+
+try:
+ del another.func_dict
+except TypeError: pass
+else: raise TestFailed
+
+try:
+ another.func_dict = None
+except TypeError: pass
+else: raise TestFailed
+
+try:
+ del another.bar
+except AttributeError: pass
+else: raise TestFailed
+
+# This isn't specifically related to function attributes, but it does test a
+# core dump regression in funcobject.c
+del another.func_defaults
+
+def foo():
+ pass
+
+def bar():
+ pass
+
+def temp():
+ print 1
+
+if foo==bar:
+ raise TestFailed
+
+d={}
+d[foo] = 1
+
+foo.func_code = temp.func_code
+
+d[foo]
+
+# Test all predefined function attributes systematically
+
+def cantset(obj, name, value, exception=(AttributeError, TypeError)):
+ verify(hasattr(obj, name)) # Otherwise it's probably a typo
+ try:
+ setattr(obj, name, value)
+ except exception:
+ pass
+ else:
+ raise TestFailed, "shouldn't be able to set %s to %r" % (name, value)
+ try:
+ delattr(obj, name)
+ except (AttributeError, TypeError):
+ pass
+ else:
+ raise TestFailed, "shouldn't be able to del %s" % name
+
+def test_func_closure():
+ a = 12
+ def f(): print a
+ c = f.func_closure
+ verify(isinstance(c, tuple))
+ verify(len(c) == 1)
+ verify(c[0].__class__.__name__ == "cell") # don't have a type object handy
+ cantset(f, "func_closure", c)
+
+def test_empty_cell():
+ def f(): print a
+ try:
+ f.func_closure[0].cell_contents
+ except ValueError:
+ pass
+ else:
+ raise TestFailed, "shouldn't be able to read an empty cell"
+
+ a = 12
+
+def test_func_doc():
+ def f(): pass
+ verify(f.__doc__ is None)
+ verify(f.func_doc is None)
+ f.__doc__ = "hello"
+ verify(f.__doc__ == "hello")
+ verify(f.func_doc == "hello")
+ del f.__doc__
+ verify(f.__doc__ is None)
+ verify(f.func_doc is None)
+ f.func_doc = "world"
+ verify(f.__doc__ == "world")
+ verify(f.func_doc == "world")
+ del f.func_doc
+ verify(f.func_doc is None)
+ verify(f.__doc__ is None)
+
+def test_func_globals():
+ def f(): pass
+ verify(f.func_globals is globals())
+ cantset(f, "func_globals", globals())
+
+def test_func_name():
+ def f(): pass
+ verify(f.__name__ == "f")
+ verify(f.func_name == "f")
+ f.__name__ = "g"
+ verify(f.__name__ == "g")
+ verify(f.func_name == "g")
+ f.func_name = "h"
+ verify(f.__name__ == "h")
+ verify(f.func_name == "h")
+ cantset(f, "func_globals", 1)
+ cantset(f, "__name__", 1)
+ # test that you can access func.__name__ in restricted mode
+ s = """def f(): pass\nf.__name__"""
+ exec s in {'__builtins__':{}}
+
+
+def test_func_code():
+ a = b = 24
+ def f(): pass
+ def g(): print 12
+ def f1(): print a
+ def g1(): print b
+ def f2(): print a, b
+ verify(type(f.func_code) is types.CodeType)
+ f.func_code = g.func_code
+ cantset(f, "func_code", None)
+ # can't change the number of free vars
+ cantset(f, "func_code", f1.func_code, exception=ValueError)
+ cantset(f1, "func_code", f.func_code, exception=ValueError)
+ cantset(f1, "func_code", f2.func_code, exception=ValueError)
+ f1.func_code = g1.func_code
+
+def test_func_defaults():
+ def f(a, b): return (a, b)
+ verify(f.func_defaults is None)
+ f.func_defaults = (1, 2)
+ verify(f.func_defaults == (1, 2))
+ verify(f(10) == (10, 2))
+ def g(a=1, b=2): return (a, b)
+ verify(g.func_defaults == (1, 2))
+ del g.func_defaults
+ verify(g.func_defaults is None)
+ try:
+ g()
+ except TypeError:
+ pass
+ else:
+ raise TestFailed, "shouldn't be allowed to call g() w/o defaults"
+
+def test_func_dict():
+ def f(): pass
+ a = f.__dict__
+ b = f.func_dict
+ verify(a == {})
+ verify(a is b)
+ f.hello = 'world'
+ verify(a == {'hello': 'world'})
+ verify(f.func_dict is a is f.__dict__)
+ f.func_dict = {}
+ verify(not hasattr(f, "hello"))
+ f.__dict__ = {'world': 'hello'}
+ verify(f.world == "hello")
+ verify(f.__dict__ is f.func_dict == {'world': 'hello'})
+ cantset(f, "func_dict", None)
+ cantset(f, "__dict__", None)
+
+def test_im_class():
+ class C:
+ def foo(self): pass
+ verify(C.foo.im_class is C)
+ verify(C().foo.im_class is C)
+ cantset(C.foo, "im_class", C)
+ cantset(C().foo, "im_class", C)
+
+def test_im_func():
+ def foo(self): pass
+ class C:
+ pass
+ C.foo = foo
+ verify(C.foo.im_func is foo)
+ verify(C().foo.im_func is foo)
+ cantset(C.foo, "im_func", foo)
+ cantset(C().foo, "im_func", foo)
+
+def test_im_self():
+ class C:
+ def foo(self): pass
+ verify(C.foo.im_self is None)
+ c = C()
+ verify(c.foo.im_self is c)
+ cantset(C.foo, "im_self", None)
+ cantset(c.foo, "im_self", c)
+
+def test_im_dict():
+ class C:
+ def foo(self): pass
+ foo.bar = 42
+ verify(C.foo.__dict__ == {'bar': 42})
+ verify(C().foo.__dict__ == {'bar': 42})
+ cantset(C.foo, "__dict__", C.foo.__dict__)
+ cantset(C().foo, "__dict__", C.foo.__dict__)
+
+def test_im_doc():
+ class C:
+ def foo(self): "hello"
+ verify(C.foo.__doc__ == "hello")
+ verify(C().foo.__doc__ == "hello")
+ cantset(C.foo, "__doc__", "hello")
+ cantset(C().foo, "__doc__", "hello")
+
+def test_im_name():
+ class C:
+ def foo(self): pass
+ verify(C.foo.__name__ == "foo")
+ verify(C().foo.__name__ == "foo")
+ cantset(C.foo, "__name__", "foo")
+ cantset(C().foo, "__name__", "foo")
+
+def testmore():
+ test_func_closure()
+ test_empty_cell()
+ test_func_doc()
+ test_func_globals()
+ test_func_name()
+ test_func_code()
+ test_func_defaults()
+ test_func_dict()
+ # Tests for instance method attributes
+ test_im_class()
+ test_im_func()
+ test_im_self()
+ test_im_dict()
+ test_im_doc()
+ test_im_name()
+
+testmore()