|
|
|
@ -3138,10 +3138,35 @@ type_setattro(PyTypeObject *type, PyObject *name, PyObject *value) |
|
|
|
type->tp_name); |
|
|
|
return -1; |
|
|
|
} |
|
|
|
if (_PyObject_GenericSetAttrWithDict((PyObject *)type, name, value, NULL) < 0) |
|
|
|
return -1; |
|
|
|
res = update_slot(type, name); |
|
|
|
assert(_PyType_CheckConsistency(type)); |
|
|
|
if (PyUnicode_Check(name)) { |
|
|
|
if (PyUnicode_CheckExact(name)) { |
|
|
|
if (PyUnicode_READY(name) == -1) |
|
|
|
return -1; |
|
|
|
Py_INCREF(name); |
|
|
|
} |
|
|
|
else { |
|
|
|
name = _PyUnicode_Copy(name); |
|
|
|
if (name == NULL) |
|
|
|
return -1; |
|
|
|
} |
|
|
|
PyUnicode_InternInPlace(&name); |
|
|
|
if (!PyUnicode_CHECK_INTERNED(name)) { |
|
|
|
PyErr_SetString(PyExc_MemoryError, |
|
|
|
"Out of memory interning an attribute name"); |
|
|
|
Py_DECREF(name); |
|
|
|
return -1; |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
/* Will fail in _PyObject_GenericSetAttrWithDict. */ |
|
|
|
Py_INCREF(name); |
|
|
|
} |
|
|
|
res = _PyObject_GenericSetAttrWithDict((PyObject *)type, name, value, NULL); |
|
|
|
if (res == 0) { |
|
|
|
res = update_slot(type, name); |
|
|
|
assert(_PyType_CheckConsistency(type)); |
|
|
|
} |
|
|
|
Py_DECREF(name); |
|
|
|
return res; |
|
|
|
} |
|
|
|
|
|
|
|
@ -7065,7 +7090,7 @@ init_slotdefs(void) |
|
|
|
/* Slots must be ordered by their offset in the PyHeapTypeObject. */ |
|
|
|
assert(!p[1].name || p->offset <= p[1].offset); |
|
|
|
p->name_strobj = PyUnicode_InternFromString(p->name); |
|
|
|
if (!p->name_strobj) |
|
|
|
if (!p->name_strobj || !PyUnicode_CHECK_INTERNED(p->name_strobj)) |
|
|
|
Py_FatalError("Out of memory interning slotdef names"); |
|
|
|
} |
|
|
|
slotdefs_initialized = 1; |
|
|
|
@ -7090,6 +7115,9 @@ update_slot(PyTypeObject *type, PyObject *name) |
|
|
|
slotdef **pp; |
|
|
|
int offset; |
|
|
|
|
|
|
|
assert(PyUnicode_CheckExact(name)); |
|
|
|
assert(PyUnicode_CHECK_INTERNED(name)); |
|
|
|
|
|
|
|
/* Clear the VALID_VERSION flag of 'type' and all its |
|
|
|
subclasses. This could possibly be unified with the |
|
|
|
update_subclasses() recursion below, but carefully: |
|
|
|
@ -7100,7 +7128,6 @@ update_slot(PyTypeObject *type, PyObject *name) |
|
|
|
init_slotdefs(); |
|
|
|
pp = ptrs; |
|
|
|
for (p = slotdefs; p->name; p++) { |
|
|
|
/* XXX assume name is interned! */ |
|
|
|
if (p->name_strobj == name) |
|
|
|
*pp++ = p; |
|
|
|
} |
|
|
|
|