This is my patch:

[ 635933 ] make some type attrs writable

Plus a couple of extra tests beyond what's up there.

It hasn't been as carefully reviewed as it perhaps should, so all readers
are encouraged, nay exhorted, to give this a close reading.

There are still a couple of oddities related to assigning to __name__,
but I intend to solicit python-dev's opinions on these.
diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py
index 2c2a42b..b230d39 100644
--- a/Lib/test/test_descr.py
+++ b/Lib/test/test_descr.py
@@ -3434,6 +3434,93 @@
     # (before PyType_Ready(tuple) is called)
     type.mro(tuple)
 
+def mutable_bases():
+    # stuff that should work:
+    class C(object):
+        pass
+    class C2(object):
+        def __getattribute__(self, attr):
+            if attr == 'a':
+                return 2
+            else:
+                return super(C2, self).__getattribute__(attr)        
+        def meth(self):
+            return 1
+    class D(C):
+        pass
+    class E(D):
+        pass
+    d = D()
+    e = E()
+    D.__bases__ = (C2,)
+    vereq(d.meth(), 1)
+    vereq(e.meth(), 1)
+    vereq(d.a, 2)
+    vereq(e.a, 2)
+    vereq(C2.__subclasses__(), [D])
+
+    # stuff that shouldn't:
+    class L(list):
+        pass
+
+    try:
+        L.__bases__ = (dict,)
+    except TypeError:
+        pass
+    else:
+        raise TestFailed, "shouldn't turn list subclass into dict subclass"
+
+    try:
+        list.__bases__ = (dict,)
+    except TypeError:
+        pass
+    else:
+        raise TestFailed, "shouldn't be able to assign to list.__bases__"
+
+    try:
+        del D.__bases__
+    except TypeError:
+        pass
+    else:
+        raise TestFailed, "shouldn't be able to delete .__bases__"
+
+    try:
+        D.__bases__ = (D,)
+    except TypeError:
+        pass
+    else:
+        # actually, we'll have crashed by here...
+        raise TestFailed, "shouldn't be able to create inheritance cycles"
+
+    # let's throw a classic class into the mix:
+    class Classic:
+        def meth2(self):
+            return 3
+
+    D.__bases__ = (C, Classic)
+
+    vereq(d.meth2(), 3)
+    vereq(e.meth2(), 3)
+    try:
+        d.a
+    except AttributeError:
+        pass
+    else:
+        raise TestFailed, "attribute should have vanished"
+
+    try:
+        D.__bases__ = (Classic,)
+    except TypeError:
+        pass
+    else:
+        raise TestFailed, "new-style class must have a new-style base"
+
+def mutable_names():
+    class C(object):
+        pass
+
+    C.__name__ = 'C'
+
 def test_main():
     do_this_first()
     class_docstrings()
@@ -3513,6 +3600,8 @@
     slotmultipleinheritance()
     testrmul()
     testipow()
+    mutable_bases()
+    mutable_names()
     if verbose: print "All OK"
 
 if __name__ == "__main__":