@@ -7168,7 +7168,8 @@ try_set_dict_inline_only_or_other_dict(PyObject *obj, PyObject *new_dict, PyDict
71687168// and replaced it with another dictionary though.
71697169static int
71707170replace_dict_probably_inline_materialized (PyObject * obj , PyDictObject * inline_dict ,
7171- PyObject * new_dict , PyDictObject * * replaced_dict )
7171+ PyObject * new_dict , bool clear ,
7172+ PyDictObject * * replaced_dict )
71727173{
71737174 // But we could have had another thread race in after we released
71747175 // the object lock
@@ -7184,7 +7185,11 @@ replace_dict_probably_inline_materialized(PyObject *obj, PyDictObject *inline_di
71847185 // We incref'd the inline dict and the object owns a ref.
71857186 // Clear the object's reference, we'll clear the local
71867187 // reference after releasing the lock.
7187- _PyObject_XDecRefDelayed ((PyObject * )* replaced_dict );
7188+ if (clear ) {
7189+ Py_XDECREF ((PyObject * )replaced_dict );
7190+ } else {
7191+ _PyObject_XDecRefDelayed ((PyObject * )* replaced_dict );
7192+ }
71887193 * replaced_dict = NULL ;
71897194 }
71907195
@@ -7195,8 +7200,8 @@ replace_dict_probably_inline_materialized(PyObject *obj, PyDictObject *inline_di
71957200
71967201#endif
71977202
7198- int
7199- _PyObject_SetManagedDict (PyObject * obj , PyObject * new_dict )
7203+ static int
7204+ set_or_clear_managed_dict (PyObject * obj , PyObject * new_dict , bool clear )
72007205{
72017206 assert (Py_TYPE (obj )-> tp_flags & Py_TPFLAGS_MANAGED_DICT );
72027207 assert (_PyObject_InlineValuesConsistencyCheck (obj ));
@@ -7215,7 +7220,8 @@ _PyObject_SetManagedDict(PyObject *obj, PyObject *new_dict)
72157220 assert (prev_dict != NULL );
72167221 Py_BEGIN_CRITICAL_SECTION2 (obj , prev_dict );
72177222
7218- err = replace_dict_probably_inline_materialized (obj , prev_dict , new_dict , & replaced_dict );
7223+ err = replace_dict_probably_inline_materialized (obj , prev_dict , new_dict ,
7224+ clear , & replaced_dict );
72197225
72207226 Py_END_CRITICAL_SECTION2 ();
72217227
@@ -7229,7 +7235,11 @@ _PyObject_SetManagedDict(PyObject *obj, PyObject *new_dict)
72297235 if (prev_dict != NULL ) {
72307236 // Readers from the old dictionary use a borrowed reference. We need
72317237 // to set the decref the dict at the next safe point.
7232- _PyObject_XDecRefDelayed ((PyObject * )prev_dict );
7238+ if (clear ) {
7239+ Py_XDECREF ((PyObject * )prev_dict );
7240+ } else {
7241+ _PyObject_XDecRefDelayed ((PyObject * )prev_dict );
7242+ }
72337243 }
72347244 return 0 ;
72357245#else
@@ -7257,16 +7267,26 @@ _PyObject_SetManagedDict(PyObject *obj, PyObject *new_dict)
72577267 (PyDictObject * )Py_XNewRef (new_dict ));
72587268
72597269 Py_END_CRITICAL_SECTION ();
7260- _PyObject_XDecRefDelayed ((PyObject * )dict );
7270+ if (clear ) {
7271+ Py_XDECREF ((PyObject * )dict );
7272+ } else {
7273+ _PyObject_XDecRefDelayed ((PyObject * )dict );
7274+ }
72617275 }
72627276 assert (_PyObject_InlineValuesConsistencyCheck (obj ));
72637277 return err ;
72647278}
72657279
7280+ int
7281+ _PyObject_SetManagedDict (PyObject * obj , PyObject * new_dict )
7282+ {
7283+ return set_or_clear_managed_dict (obj , new_dict , false);
7284+ }
7285+
72667286void
72677287PyObject_ClearManagedDict (PyObject * obj )
72687288{
7269- if (_PyObject_SetManagedDict (obj , NULL ) < 0 ) {
7289+ if (set_or_clear_managed_dict (obj , NULL , true ) < 0 ) {
72707290 PyErr_WriteUnraisable (NULL );
72717291 }
72727292}
0 commit comments