@@ -139,7 +139,7 @@ As a consequence of this, split keys have a maximum size of 16.
139139static PyObject * frozendict_new (PyTypeObject * type , PyObject * args ,
140140 PyObject * kwds );
141141static PyObject * dict_new (PyTypeObject * type , PyObject * args , PyObject * kwds );
142- static int dict_merge (PyObject * a , PyObject * b , int override );
142+ static int dict_merge (PyObject * a , PyObject * b , int override , PyObject * * dupkey );
143143static int dict_contains (PyObject * op , PyObject * key );
144144static int dict_merge_from_seq2 (PyObject * d , PyObject * seq2 , int override );
145145
@@ -3391,7 +3391,7 @@ _PyDict_FromKeys(PyObject *cls, PyObject *iterable, PyObject *value)
33913391 Py_DECREF (d );
33923392 return NULL ;
33933393 }
3394- if (dict_merge (copy , d , 1 ) < 0 ) {
3394+ if (dict_merge (copy , d , 1 , NULL ) < 0 ) {
33953395 Py_DECREF (d );
33963396 Py_DECREF (copy );
33973397 return NULL ;
@@ -3887,14 +3887,14 @@ static int
38873887dict_update_arg (PyObject * self , PyObject * arg )
38883888{
38893889 if (PyAnyDict_CheckExact (arg )) {
3890- return dict_merge (self , arg , 1 );
3890+ return dict_merge (self , arg , 1 , NULL );
38913891 }
38923892 int has_keys = PyObject_HasAttrWithError (arg , & _Py_ID (keys ));
38933893 if (has_keys < 0 ) {
38943894 return -1 ;
38953895 }
38963896 if (has_keys ) {
3897- return dict_merge (self , arg , 1 );
3897+ return dict_merge (self , arg , 1 , NULL );
38983898 }
38993899 return dict_merge_from_seq2 (self , arg , 1 );
39003900}
@@ -3915,7 +3915,7 @@ dict_update_common(PyObject *self, PyObject *args, PyObject *kwds,
39153915
39163916 if (result == 0 && kwds != NULL ) {
39173917 if (PyArg_ValidateKeywordArguments (kwds ))
3918- result = dict_merge (self , kwds , 1 );
3918+ result = dict_merge (self , kwds , 1 , NULL );
39193919 else
39203920 result = -1 ;
39213921 }
@@ -4059,7 +4059,7 @@ PyDict_MergeFromSeq2(PyObject *d, PyObject *seq2, int override)
40594059}
40604060
40614061static int
4062- dict_dict_merge (PyDictObject * mp , PyDictObject * other , int override )
4062+ dict_dict_merge (PyDictObject * mp , PyDictObject * other , int override , PyObject * * dupkey )
40634063{
40644064 assert (can_modify_dict (mp ));
40654065 ASSERT_DICT_LOCKED (other );
@@ -4068,10 +4068,10 @@ dict_dict_merge(PyDictObject *mp, PyDictObject *other, int override)
40684068 /* a.update(a) or a.update({}); nothing to do */
40694069 return 0 ;
40704070 if (mp -> ma_used == 0 ) {
4071- /* Since the target dict is empty, PyDict_GetItem ()
4072- * always returns NULL . Setting override to 1
4073- * skips the unnecessary test.
4074- */
4071+ /* Since the target dict is empty, _PyDict_Contains_KnownHash ()
4072+ * always returns 0 . Setting override to 1
4073+ * skips the unnecessary test.
4074+ */
40754075 override = 1 ;
40764076 PyDictKeysObject * okeys = other -> ma_keys ;
40774077
@@ -4131,11 +4131,10 @@ dict_dict_merge(PyDictObject *mp, PyDictObject *other, int override)
41314131 err = insertdict (mp , Py_NewRef (key ), hash , Py_NewRef (value ));
41324132 }
41334133 else if (err > 0 ) {
4134- if (override != 0 ) {
4135- _PyErr_SetKeyError ( key ) ;
4134+ if (dupkey != NULL ) {
4135+ * dupkey = key ;
41364136 Py_DECREF (value );
4137- Py_DECREF (key );
4138- return -1 ;
4137+ return -2 ;
41394138 }
41404139 err = 0 ;
41414140 }
@@ -4155,7 +4154,7 @@ dict_dict_merge(PyDictObject *mp, PyDictObject *other, int override)
41554154}
41564155
41574156static int
4158- dict_merge (PyObject * a , PyObject * b , int override )
4157+ dict_merge (PyObject * a , PyObject * b , int override , PyObject * * dupkey )
41594158{
41604159 assert (a != NULL );
41614160 assert (b != NULL );
@@ -4167,7 +4166,7 @@ dict_merge(PyObject *a, PyObject *b, int override)
41674166 PyDictObject * other = (PyDictObject * )b ;
41684167 int res ;
41694168 Py_BEGIN_CRITICAL_SECTION2 (a , b );
4170- res = dict_dict_merge ((PyDictObject * )a , other , override );
4169+ res = dict_dict_merge ((PyDictObject * )a , other , override , dupkey );
41714170 ASSERT_CONSISTENT (a );
41724171 Py_END_CRITICAL_SECTION2 ();
41734172 return res ;
@@ -4202,15 +4201,18 @@ dict_merge(PyObject *a, PyObject *b, int override)
42024201 status = dict_contains (a , key );
42034202 if (status != 0 ) {
42044203 if (status > 0 ) {
4205- if (override == 0 ) {
4204+ if (dupkey == NULL ) {
42064205 Py_DECREF (key );
42074206 continue ;
42084207 }
4209- _PyErr_SetKeyError (key );
4208+ * dupkey = key ;
4209+ res = -2 ;
4210+ }
4211+ else {
4212+ Py_DECREF (key );
4213+ res = -1 ;
42104214 }
4211- Py_DECREF (key );
42124215 Py_DECREF (iter );
4213- res = -1 ;
42144216 goto slow_exit ;
42154217 }
42164218 }
@@ -4246,7 +4248,7 @@ dict_merge(PyObject *a, PyObject *b, int override)
42464248}
42474249
42484250static int
4249- dict_merge_api (PyObject * a , PyObject * b , int override )
4251+ dict_merge_api (PyObject * a , PyObject * b , int override , PyObject * * dupkey )
42504252{
42514253 /* We accept for the argument either a concrete dictionary object,
42524254 * or an abstract "mapping" object. For the former, we can do
@@ -4262,26 +4264,26 @@ dict_merge_api(PyObject *a, PyObject *b, int override)
42624264 }
42634265 return -1 ;
42644266 }
4265- return dict_merge (a , b , override );
4267+ return dict_merge (a , b , override , dupkey );
42664268}
42674269
42684270int
42694271PyDict_Update (PyObject * a , PyObject * b )
42704272{
4271- return dict_merge_api (a , b , 1 );
4273+ return dict_merge_api (a , b , 1 , NULL );
42724274}
42734275
42744276int
42754277PyDict_Merge (PyObject * a , PyObject * b , int override )
42764278{
42774279 /* XXX Deprecate override not in (0, 1). */
4278- return dict_merge_api (a , b , override != 0 );
4280+ return dict_merge_api (a , b , override != 0 , NULL );
42794281}
42804282
42814283int
4282- _PyDict_MergeEx (PyObject * a , PyObject * b , int override )
4284+ _PyDict_MergeUniq (PyObject * a , PyObject * b , PyObject * * dupkey )
42834285{
4284- return dict_merge_api (a , b , override );
4286+ return dict_merge_api (a , b , 2 , dupkey );
42854287}
42864288
42874289/*[clinic input]
@@ -4421,7 +4423,7 @@ copy_lock_held(PyObject *o, int as_frozendict)
44214423 }
44224424 if (copy == NULL )
44234425 return NULL ;
4424- if (dict_merge (copy , o , 1 ) == 0 )
4426+ if (dict_merge (copy , o , 1 , NULL ) == 0 )
44254427 return copy ;
44264428 Py_DECREF (copy );
44274429 return NULL ;
0 commit comments