From 40af889081938c1fea83cba0a9cbdb35e299119d Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Sat, 10 Aug 2002 05:42:07 +0000 Subject: [PATCH] Disallow class assignment completely unless both old and new are heap types. This prevents nonsense like 2.__class__ = bool or True.__class__ = int. --- Lib/test/test_descr.py | 5 +++++ Objects/typeobject.c | 15 +++++++++------ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index 51fa0d9f21..1ce08b7fa8 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -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..." diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 020cbf21ba..fddde515ee 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -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; } -- 2.40.0