@@ -3355,8 +3355,9 @@ dict_get_impl(PyDictObject *self, PyObject *key, PyObject *default_value)
33553355 return Py_NewRef (val );
33563356}
33573357
3358- PyObject *
3359- PyDict_SetDefault (PyObject * d , PyObject * key , PyObject * defaultobj )
3358+ static int
3359+ dict_setdefault_ref (PyObject * d , PyObject * key , PyObject * default_value ,
3360+ PyObject * * result , int incref_result )
33603361{
33613362 PyDictObject * mp = (PyDictObject * )d ;
33623363 PyObject * value ;
@@ -3365,41 +3366,64 @@ PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *defaultobj)
33653366
33663367 if (!PyDict_Check (d )) {
33673368 PyErr_BadInternalCall ();
3368- return NULL ;
3369+ if (result ) {
3370+ * result = NULL ;
3371+ }
3372+ return -1 ;
33693373 }
33703374
33713375 if (!PyUnicode_CheckExact (key ) || (hash = unicode_get_hash (key )) == -1 ) {
33723376 hash = PyObject_Hash (key );
3373- if (hash == -1 )
3374- return NULL ;
3377+ if (hash == -1 ) {
3378+ if (result ) {
3379+ * result = NULL ;
3380+ }
3381+ return -1 ;
3382+ }
33753383 }
33763384
33773385 if (mp -> ma_keys == Py_EMPTY_KEYS ) {
33783386 if (insert_to_emptydict (interp , mp , Py_NewRef (key ), hash ,
3379- Py_NewRef (defaultobj )) < 0 ) {
3380- return NULL ;
3387+ Py_NewRef (default_value )) < 0 ) {
3388+ if (result ) {
3389+ * result = NULL ;
3390+ }
3391+ return -1 ;
3392+ }
3393+ if (result ) {
3394+ * result = incref_result ? Py_NewRef (default_value ) : default_value ;
33813395 }
3382- return defaultobj ;
3396+ return 0 ;
33833397 }
33843398
33853399 if (!PyUnicode_CheckExact (key ) && DK_IS_UNICODE (mp -> ma_keys )) {
33863400 if (insertion_resize (interp , mp , 0 ) < 0 ) {
3387- return NULL ;
3401+ if (result ) {
3402+ * result = NULL ;
3403+ }
3404+ return -1 ;
33883405 }
33893406 }
33903407
33913408 Py_ssize_t ix = _Py_dict_lookup (mp , key , hash , & value );
3392- if (ix == DKIX_ERROR )
3393- return NULL ;
3409+ if (ix == DKIX_ERROR ) {
3410+ if (result ) {
3411+ * result = NULL ;
3412+ }
3413+ return -1 ;
3414+ }
33943415
33953416 if (ix == DKIX_EMPTY ) {
33963417 uint64_t new_version = _PyDict_NotifyEvent (
3397- interp , PyDict_EVENT_ADDED , mp , key , defaultobj );
3418+ interp , PyDict_EVENT_ADDED , mp , key , default_value );
33983419 mp -> ma_keys -> dk_version = 0 ;
3399- value = defaultobj ;
3420+ value = default_value ;
34003421 if (mp -> ma_keys -> dk_usable <= 0 ) {
34013422 if (insertion_resize (interp , mp , 1 ) < 0 ) {
3402- return NULL ;
3423+ if (result ) {
3424+ * result = NULL ;
3425+ }
3426+ return -1 ;
34033427 }
34043428 }
34053429 Py_ssize_t hashpos = find_empty_slot (mp -> ma_keys , hash );
@@ -3431,22 +3455,50 @@ PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *defaultobj)
34313455 mp -> ma_keys -> dk_usable -- ;
34323456 mp -> ma_keys -> dk_nentries ++ ;
34333457 assert (mp -> ma_keys -> dk_usable >= 0 );
3458+ ASSERT_CONSISTENT (mp );
3459+ if (result ) {
3460+ * result = incref_result ? Py_NewRef (value ) : value ;
3461+ }
3462+ return 0 ;
34343463 }
34353464 else if (value == NULL ) {
34363465 uint64_t new_version = _PyDict_NotifyEvent (
3437- interp , PyDict_EVENT_ADDED , mp , key , defaultobj );
3438- value = defaultobj ;
3466+ interp , PyDict_EVENT_ADDED , mp , key , default_value );
3467+ value = default_value ;
34393468 assert (_PyDict_HasSplitTable (mp ));
34403469 assert (mp -> ma_values -> values [ix ] == NULL );
34413470 MAINTAIN_TRACKING (mp , key , value );
34423471 mp -> ma_values -> values [ix ] = Py_NewRef (value );
34433472 _PyDictValues_AddToInsertionOrder (mp -> ma_values , ix );
34443473 mp -> ma_used ++ ;
34453474 mp -> ma_version_tag = new_version ;
3475+ ASSERT_CONSISTENT (mp );
3476+ if (result ) {
3477+ * result = incref_result ? Py_NewRef (value ) : value ;
3478+ }
3479+ return 0 ;
34463480 }
34473481
34483482 ASSERT_CONSISTENT (mp );
3449- return value ;
3483+ if (result ) {
3484+ * result = incref_result ? Py_NewRef (value ) : value ;
3485+ }
3486+ return 1 ;
3487+ }
3488+
3489+ int
3490+ PyDict_SetDefaultRef (PyObject * d , PyObject * key , PyObject * default_value ,
3491+ PyObject * * result )
3492+ {
3493+ return dict_setdefault_ref (d , key , default_value , result , 1 );
3494+ }
3495+
3496+ PyObject *
3497+ PyDict_SetDefault (PyObject * d , PyObject * key , PyObject * defaultobj )
3498+ {
3499+ PyObject * result ;
3500+ dict_setdefault_ref (d , key , defaultobj , & result , 0 );
3501+ return result ;
34503502}
34513503
34523504/*[clinic input]
@@ -3467,9 +3519,8 @@ dict_setdefault_impl(PyDictObject *self, PyObject *key,
34673519/*[clinic end generated code: output=f8c1101ebf69e220 input=0f063756e815fd9d]*/
34683520{
34693521 PyObject * val ;
3470-
3471- val = PyDict_SetDefault ((PyObject * )self , key , default_value );
3472- return Py_XNewRef (val );
3522+ PyDict_SetDefaultRef ((PyObject * )self , key , default_value , & val );
3523+ return val ;
34733524}
34743525
34753526
0 commit comments