summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2001-09-25 03:43:42 (GMT)
committerGuido van Rossum <guido@python.org>2001-09-25 03:43:42 (GMT)
commit5c294fb0e634afc4807ca83032ace356512c97dc (patch)
tree71a9bb4e810bbb936dca64369f49098a4a225196 /Lib
parent2306d246e8c5bb928a432726178047b8d50776f5 (diff)
downloadcpython-5c294fb0e634afc4807ca83032ace356512c97dc.zip
cpython-5c294fb0e634afc4807ca83032ace356512c97dc.tar.gz
cpython-5c294fb0e634afc4807ca83032ace356512c97dc.tar.bz2
Make __class__ assignment possible, when the object structures are the
same. I hope the test for structural equivalence is stringent enough. It only allows the assignment if the old and new types: - have the same basic size - have the same item size - have the same dict offset - have the same weaklist offset - have the same GC flag bit - have a common base that is the same except for maybe the dict and weaklist (which may have been added separately at the same offsets in both types)
Diffstat (limited to 'Lib')
-rw-r--r--Lib/test/test_descr.py28
1 files changed, 28 insertions, 0 deletions
diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py
index 5bd837e..766c399 100644
--- a/Lib/test/test_descr.py
+++ b/Lib/test/test_descr.py
@@ -2005,6 +2005,33 @@ def descrdoc():
check(file.closed, "flag set if the file is closed") # getset descriptor
check(file.name, "file name") # member descriptor
+def setclass():
+ if verbose: print "Testing __class__ assignment..."
+ class C(object): pass
+ class D(object): pass
+ class E(object): pass
+ class F(D, E): pass
+ for cls in C, D, E, F:
+ for cls2 in C, D, E, F:
+ x = cls()
+ x.__class__ = cls2
+ verify(x.__class__ is cls2)
+ x.__class__ = cls
+ verify(x.__class__ is cls)
+ def cant(x, C):
+ try:
+ x.__class__ = C
+ except TypeError:
+ pass
+ else:
+ raise TestFailed, "shouldn't allow %r.__class__ = %r" % (x, C)
+ cant(C(), list)
+ cant(list(), C)
+ cant(C(), 1)
+ cant(C(), object)
+ cant(object(), list)
+ cant(list(), object)
+
def test_main():
lists()
@@ -2047,6 +2074,7 @@ def test_main():
rich_comparisons()
coercions()
descrdoc()
+ setclass()
if verbose: print "All OK"
if __name__ == "__main__":