@@ -3138,10 +3138,35 @@ type_setattro(PyTypeObject *type, PyObject *name, PyObject *value)
3138
3138
type -> tp_name );
3139
3139
return -1 ;
3140
3140
}
3141
- if (_PyObject_GenericSetAttrWithDict ((PyObject * )type , name , value , NULL ) < 0 )
3142
- return -1 ;
3143
- res = update_slot (type , name );
3144
- assert (_PyType_CheckConsistency (type ));
3141
+ if (PyUnicode_Check (name )) {
3142
+ if (PyUnicode_CheckExact (name )) {
3143
+ if (PyUnicode_READY (name ) == -1 )
3144
+ return -1 ;
3145
+ Py_INCREF (name );
3146
+ }
3147
+ else {
3148
+ name = _PyUnicode_Copy (name );
3149
+ if (name == NULL )
3150
+ return -1 ;
3151
+ }
3152
+ PyUnicode_InternInPlace (& name );
3153
+ if (!PyUnicode_CHECK_INTERNED (name )) {
3154
+ PyErr_SetString (PyExc_MemoryError ,
3155
+ "Out of memory interning an attribute name" );
3156
+ Py_DECREF (name );
3157
+ return -1 ;
3158
+ }
3159
+ }
3160
+ else {
3161
+ /* Will fail in _PyObject_GenericSetAttrWithDict. */
3162
+ Py_INCREF (name );
3163
+ }
3164
+ res = _PyObject_GenericSetAttrWithDict ((PyObject * )type , name , value , NULL );
3165
+ if (res == 0 ) {
3166
+ res = update_slot (type , name );
3167
+ assert (_PyType_CheckConsistency (type ));
3168
+ }
3169
+ Py_DECREF (name );
3145
3170
return res ;
3146
3171
}
3147
3172
@@ -7065,7 +7090,7 @@ init_slotdefs(void)
7065
7090
/* Slots must be ordered by their offset in the PyHeapTypeObject. */
7066
7091
assert (!p [1 ].name || p -> offset <= p [1 ].offset );
7067
7092
p -> name_strobj = PyUnicode_InternFromString (p -> name );
7068
- if (!p -> name_strobj )
7093
+ if (!p -> name_strobj || ! PyUnicode_CHECK_INTERNED ( p -> name_strobj ) )
7069
7094
Py_FatalError ("Out of memory interning slotdef names" );
7070
7095
}
7071
7096
slotdefs_initialized = 1 ;
@@ -7090,6 +7115,9 @@ update_slot(PyTypeObject *type, PyObject *name)
7090
7115
slotdef * * pp ;
7091
7116
int offset ;
7092
7117
7118
+ assert (PyUnicode_CheckExact (name ));
7119
+ assert (PyUnicode_CHECK_INTERNED (name ));
7120
+
7093
7121
/* Clear the VALID_VERSION flag of 'type' and all its
7094
7122
subclasses. This could possibly be unified with the
7095
7123
update_subclasses() recursion below, but carefully:
@@ -7100,7 +7128,6 @@ update_slot(PyTypeObject *type, PyObject *name)
7100
7128
init_slotdefs ();
7101
7129
pp = ptrs ;
7102
7130
for (p = slotdefs ; p -> name ; p ++ ) {
7103
- /* XXX assume name is interned! */
7104
7131
if (p -> name_strobj == name )
7105
7132
* pp ++ = p ;
7106
7133
}
0 commit comments