]> granicus.if.org Git - python/commitdiff
Disallow class assignment completely unless both old and new are heap
authorGuido van Rossum <guido@python.org>
Sat, 10 Aug 2002 05:42:07 +0000 (05:42 +0000)
committerGuido van Rossum <guido@python.org>
Sat, 10 Aug 2002 05:42:07 +0000 (05:42 +0000)
types.  This prevents nonsense like 2.__class__ = bool or
True.__class__ = int.

Lib/test/test_descr.py
Objects/typeobject.c

index 51fa0d9f217a30b6f3a7a2577173513721af8134..1ce08b7fa8b40aaa03e15d9e4a85377aae5b6143 100644 (file)
@@ -2478,6 +2478,11 @@ def setclass():
     cant(C(), object)
     cant(object(), list)
     cant(list(), object)
+    class Int(int): __slots__ = []
+    cant(2, Int)
+    cant(Int(), int)
+    cant(True, int)
+    cant(2, bool)
 
 def setdict():
     if verbose: print "Testing __dict__ assignment..."
index 020cbf21ba9b8515ffc8ced5a27c274c2673952d..fddde515eed19190afe9442a572ee96bd4f95892 100644 (file)
@@ -1745,6 +1745,13 @@ object_set_class(PyObject *self, PyObject *value, void *closure)
                return -1;
        }
        new = (PyTypeObject *)value;
+       if (!(new->tp_flags & Py_TPFLAGS_HEAPTYPE) ||
+           !(old->tp_flags & Py_TPFLAGS_HEAPTYPE))
+       {
+               PyErr_Format(PyExc_TypeError,
+                            "__class__ assignment: only for heap types");
+               return -1;
+       }
        if (new->tp_dealloc != old->tp_dealloc ||
            new->tp_free != old->tp_free)
        {
@@ -1771,13 +1778,9 @@ object_set_class(PyObject *self, PyObject *value, void *closure)
                             old->tp_name);
                return -1;
        }
-       if (new->tp_flags & Py_TPFLAGS_HEAPTYPE) {
-               Py_INCREF(new);
-       }
+       Py_INCREF(new);
        self->ob_type = new;
-       if (old->tp_flags & Py_TPFLAGS_HEAPTYPE) {
-               Py_DECREF(old);
-       }
+       Py_DECREF(old);
        return 0;
 }