From: Guido van Rossum <guido@python.org> Date: Fri, 10 Aug 2001 20:28:28 +0000 (+0000) Subject: Add PyDict_Merge(a, b, override): X-Git-Tag: v2.2a3~661 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=05ac6de2d505b0cd69278e05be8bad3f0111e72d;p=python Add PyDict_Merge(a, b, override): PyDict_Merge(a, b, 1) is the same as PyDict_Update(a, b). PyDict_Merge(a, b, 0) does something similar but leaves existing items unchanged. --- diff --git a/Include/dictobject.h b/Include/dictobject.h index abc8ed567d..11320214e9 100644 --- a/Include/dictobject.h +++ b/Include/dictobject.h @@ -98,6 +98,7 @@ extern DL_IMPORT(PyObject *) PyDict_Items(PyObject *mp); extern DL_IMPORT(int) PyDict_Size(PyObject *mp); extern DL_IMPORT(PyObject *) PyDict_Copy(PyObject *mp); extern DL_IMPORT(int) PyDict_Update(PyObject *mp, PyObject *other); +extern DL_IMPORT(int) PyDict_Merge(PyObject *mp, PyObject *other, int override); extern DL_IMPORT(PyObject *) PyDict_GetItemString(PyObject *dp, char *key); diff --git a/Objects/dictobject.c b/Objects/dictobject.c index ce4c578f42..73c459fb41 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -999,8 +999,18 @@ dict_update(PyObject *mp, PyObject *args) return Py_None; } +/* Update unconditionally replaces existing items. + Merge has a 3rd argument 'override'; if set, it acts like Update, + otherwise it leaves existing items unchanged. */ + int PyDict_Update(PyObject *a, PyObject *b) +{ + return PyDict_Merge(a, b, 1); +} + +int +PyDict_Merge(PyObject *a, PyObject *b, int override) { register PyDictObject *mp, *other; register int i; @@ -1031,7 +1041,9 @@ PyDict_Update(PyObject *a, PyObject *b) } for (i = 0; i <= other->ma_mask; i++) { entry = &other->ma_table[i]; - if (entry->me_value != NULL) { + if (entry->me_value != NULL && + (override || + PyDict_GetItem(a, entry->me_key) == NULL)) { Py_INCREF(entry->me_key); Py_INCREF(entry->me_value); insertdict(mp, entry->me_key, entry->me_hash, @@ -1060,13 +1072,17 @@ PyDict_Update(PyObject *a, PyObject *b) return -1; for (key = PyIter_Next(iter); key; key = PyIter_Next(iter)) { + if (!override && PyDict_GetItem(a, key) != NULL) { + Py_DECREF(key); + continue; + } value = PyObject_GetItem(b, key); if (value == NULL) { Py_DECREF(iter); Py_DECREF(key); return -1; } - status = PyDict_SetItem((PyObject*)mp, key, value); + status = PyDict_SetItem(a, key, value); Py_DECREF(key); Py_DECREF(value); if (status < 0) {