@@ -3138,10 +3138,35 @@ type_setattro(PyTypeObject *type, PyObject *name, PyObject *value)
31383138 type -> tp_name );
31393139 return -1 ;
31403140 }
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 );
31453170 return res ;
31463171}
31473172
@@ -7065,7 +7090,7 @@ init_slotdefs(void)
70657090 /* Slots must be ordered by their offset in the PyHeapTypeObject. */
70667091 assert (!p [1 ].name || p -> offset <= p [1 ].offset );
70677092 p -> name_strobj = PyUnicode_InternFromString (p -> name );
7068- if (!p -> name_strobj )
7093+ if (!p -> name_strobj || ! PyUnicode_CHECK_INTERNED ( p -> name_strobj ) )
70697094 Py_FatalError ("Out of memory interning slotdef names" );
70707095 }
70717096 slotdefs_initialized = 1 ;
@@ -7090,6 +7115,9 @@ update_slot(PyTypeObject *type, PyObject *name)
70907115 slotdef * * pp ;
70917116 int offset ;
70927117
7118+ assert (PyUnicode_CheckExact (name ));
7119+ assert (PyUnicode_CHECK_INTERNED (name ));
7120+
70937121 /* Clear the VALID_VERSION flag of 'type' and all its
70947122 subclasses. This could possibly be unified with the
70957123 update_subclasses() recursion below, but carefully:
@@ -7100,7 +7128,6 @@ update_slot(PyTypeObject *type, PyObject *name)
71007128 init_slotdefs ();
71017129 pp = ptrs ;
71027130 for (p = slotdefs ; p -> name ; p ++ ) {
7103- /* XXX assume name is interned! */
71047131 if (p -> name_strobj == name )
71057132 * pp ++ = p ;
71067133 }
0 commit comments