diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2016-10-02 08:06:43 (GMT) |
---|---|---|
committer | Serhiy Storchaka <storchaka@gmail.com> | 2016-10-02 08:06:43 (GMT) |
commit | e036ef8fa29f27d57fe9f8cef8d931d4122d8223 (patch) | |
tree | b3d48b866f7339d7577f68529326fba4856b821e /Objects | |
parent | 0a3beffc8f6483da16523fceb9158af6a259a608 (diff) | |
download | cpython-e036ef8fa29f27d57fe9f8cef8d931d4122d8223.zip cpython-e036ef8fa29f27d57fe9f8cef8d931d4122d8223.tar.gz cpython-e036ef8fa29f27d57fe9f8cef8d931d4122d8223.tar.bz2 |
Issue #27358: Optimized merging var-keyword arguments and improved error
message when pass a non-mapping as a var-keyword argument.
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/dictobject.c | 45 |
1 files changed, 36 insertions, 9 deletions
diff --git a/Objects/dictobject.c b/Objects/dictobject.c index fe19445..da061aa 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -2380,18 +2380,14 @@ Return: } int -PyDict_Update(PyObject *a, PyObject *b) -{ - return PyDict_Merge(a, b, 1); -} - -int -PyDict_Merge(PyObject *a, PyObject *b, int override) +dict_merge(PyObject *a, PyObject *b, int override) { PyDictObject *mp, *other; Py_ssize_t i, n; PyDictKeyEntry *entry, *ep0; + assert(0 <= override && override <= 2); + /* We accept for the argument either a concrete dictionary object, * or an abstract "mapping" object. For the former, we can do * things quite efficiently. For the latter, we only require that @@ -2436,8 +2432,14 @@ PyDict_Merge(PyObject *a, PyObject *b, int override) int err = 0; Py_INCREF(key); Py_INCREF(value); - if (override || PyDict_GetItem(a, key) == NULL) + if (override == 1 || _PyDict_GetItem_KnownHash(a, key, hash) == NULL) err = insertdict(mp, key, hash, value); + else if (override != 0) { + _PyErr_SetKeyError(key); + Py_DECREF(value); + Py_DECREF(key); + return -1; + } Py_DECREF(value); Py_DECREF(key); if (err != 0) @@ -2472,7 +2474,13 @@ PyDict_Merge(PyObject *a, PyObject *b, int override) return -1; for (key = PyIter_Next(iter); key; key = PyIter_Next(iter)) { - if (!override && PyDict_GetItem(a, key) != NULL) { + if (override != 1 && PyDict_GetItem(a, key) != NULL) { + if (override != 0) { + _PyErr_SetKeyError(key); + Py_DECREF(key); + Py_DECREF(iter); + return -1; + } Py_DECREF(key); continue; } @@ -2499,6 +2507,25 @@ PyDict_Merge(PyObject *a, PyObject *b, int override) return 0; } +int +PyDict_Update(PyObject *a, PyObject *b) +{ + return dict_merge(a, b, 1); +} + +int +PyDict_Merge(PyObject *a, PyObject *b, int override) +{ + /* XXX Deprecate override not in (0, 1). */ + return dict_merge(a, b, override != 0); +} + +int +_PyDict_MergeEx(PyObject *a, PyObject *b, int override) +{ + return dict_merge(a, b, override); +} + static PyObject * dict_copy(PyDictObject *mp) { |