@@ -7117,6 +7117,7 @@ _PyObject_SetManagedDict(PyObject *obj, PyObject *new_dict)
71177117 // since we locked it.
71187118 dict = _PyObject_ManagedDictPointer (obj )-> dict ;
71197119 err = _PyDict_DetachFromObject (dict , obj );
7120+ assert (err == 0 || new_dict == NULL );
71207121 if (err == 0 ) {
71217122 FT_ATOMIC_STORE_PTR (_PyObject_ManagedDictPointer (obj )-> dict ,
71227123 (PyDictObject * )Py_XNewRef (new_dict ));
@@ -7149,7 +7150,21 @@ void
71497150PyObject_ClearManagedDict (PyObject * obj )
71507151{
71517152 if (_PyObject_SetManagedDict (obj , NULL ) < 0 ) {
7153+ /* Must be out of memory */
7154+ assert (PyErr_Occurred () == PyExc_MemoryError );
71527155 PyErr_WriteUnraisable (NULL );
7156+ /* Clear the dict */
7157+ PyDictObject * dict = _PyObject_GetManagedDict (obj );
7158+ Py_BEGIN_CRITICAL_SECTION2 (dict , obj );
7159+ dict = _PyObject_ManagedDictPointer (obj )-> dict ;
7160+ PyInterpreterState * interp = _PyInterpreterState_GET ();
7161+ PyDictKeysObject * oldkeys = dict -> ma_keys ;
7162+ set_keys (dict , Py_EMPTY_KEYS );
7163+ dict -> ma_values = NULL ;
7164+ dictkeys_decref (interp , oldkeys , IS_DICT_SHARED (mp ));
7165+ STORE_USED (dict , 0 );
7166+ set_dict_inline_values (obj , NULL );
7167+ Py_END_CRITICAL_SECTION2 ();
71537168 }
71547169}
71557170
@@ -7173,17 +7188,11 @@ _PyDict_DetachFromObject(PyDictObject *mp, PyObject *obj)
71737188
71747189 PyDictValues * values = copy_values (mp -> ma_values );
71757190
7176- mp -> ma_values = values ;
71777191 if (values == NULL ) {
7178- /* Out of memory. Clear the dict */
7179- PyInterpreterState * interp = _PyInterpreterState_GET ();
7180- PyDictKeysObject * oldkeys = mp -> ma_keys ;
7181- set_keys (mp , Py_EMPTY_KEYS );
7182- dictkeys_decref (interp , oldkeys , IS_DICT_SHARED (mp ));
7183- STORE_USED (mp , 0 );
71847192 PyErr_NoMemory ();
71857193 return -1 ;
71867194 }
7195+ mp -> ma_values = values ;
71877196
71887197 FT_ATOMIC_STORE_UINT8 (_PyObject_InlineValues (obj )-> valid , 0 );
71897198
0 commit comments