summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2016-10-02 08:06:43 (GMT)
committerSerhiy Storchaka <storchaka@gmail.com>2016-10-02 08:06:43 (GMT)
commite036ef8fa29f27d57fe9f8cef8d931d4122d8223 (patch)
treeb3d48b866f7339d7577f68529326fba4856b821e /Objects
parent0a3beffc8f6483da16523fceb9158af6a259a608 (diff)
downloadcpython-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.c45
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)
{