Disallow class assignment completely unless both old and new are heap
types. This prevents nonsense like 2.__class__ = bool or True.__class__ = int.
This commit is contained in:
parent
e05f65a0c6
commit
40af889081
|
@ -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..."
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue