diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2019-01-12 08:12:24 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-01-12 08:12:24 (GMT) |
commit | f1ec3cefad4639797c37eaa8c074830188fa0a44 (patch) | |
tree | 45310fd762d8b8c71e73ee6e481d9f759c16bd79 /Python/ceval.c | |
parent | 58159ef856846d0235e0779aeb6013d70499570d (diff) | |
download | cpython-f1ec3cefad4639797c37eaa8c074830188fa0a44.zip cpython-f1ec3cefad4639797c37eaa8c074830188fa0a44.tar.gz cpython-f1ec3cefad4639797c37eaa8c074830188fa0a44.tar.bz2 |
bpo-35634: Raise an error when first passed kwargs contains duplicated keys. (GH-11438)
Diffstat (limited to 'Python/ceval.c')
-rw-r--r-- | Python/ceval.c | 93 |
1 files changed, 45 insertions, 48 deletions
diff --git a/Python/ceval.c b/Python/ceval.c index 3e82ceb..3db7c7c 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -70,7 +70,7 @@ static PyObject * unicode_concatenate(PyObject *, PyObject *, PyFrameObject *, const _Py_CODEUNIT *); static PyObject * special_lookup(PyObject *, _Py_Identifier *); static int check_args_iterable(PyObject *func, PyObject *vararg); -static void format_kwargs_mapping_error(PyObject *func, PyObject *kwargs); +static void format_kwargs_error(PyObject *func, PyObject *kwargs); static void format_awaitable_error(PyTypeObject *, int); #define NAME_ERROR_MSG \ @@ -2660,37 +2660,8 @@ main_loop: for (i = oparg; i > 0; i--) { PyObject *arg = PEEK(i); if (_PyDict_MergeEx(sum, arg, 2) < 0) { - PyObject *func = PEEK(2 + oparg); - if (PyErr_ExceptionMatches(PyExc_AttributeError)) { - format_kwargs_mapping_error(func, arg); - } - else if (PyErr_ExceptionMatches(PyExc_KeyError)) { - PyObject *exc, *val, *tb; - PyErr_Fetch(&exc, &val, &tb); - if (val && PyTuple_Check(val) && PyTuple_GET_SIZE(val) == 1) { - PyObject *key = PyTuple_GET_ITEM(val, 0); - if (!PyUnicode_Check(key)) { - PyErr_Format(PyExc_TypeError, - "%.200s%.200s keywords must be strings", - PyEval_GetFuncName(func), - PyEval_GetFuncDesc(func)); - } else { - PyErr_Format(PyExc_TypeError, - "%.200s%.200s got multiple " - "values for keyword argument '%U'", - PyEval_GetFuncName(func), - PyEval_GetFuncDesc(func), - key); - } - Py_XDECREF(exc); - Py_XDECREF(val); - Py_XDECREF(tb); - } - else { - PyErr_Restore(exc, val, tb); - } - } Py_DECREF(sum); + format_kwargs_error(PEEK(2 + oparg), arg); goto error; } } @@ -3286,17 +3257,9 @@ main_loop: PyObject *d = PyDict_New(); if (d == NULL) goto error; - if (PyDict_Update(d, kwargs) != 0) { + if (_PyDict_MergeEx(d, kwargs, 2) < 0) { Py_DECREF(d); - /* PyDict_Update raises attribute - * error (percolated from an attempt - * to get 'keys' attribute) instead of - * a type error if its second argument - * is not a mapping. - */ - if (PyErr_ExceptionMatches(PyExc_AttributeError)) { - format_kwargs_mapping_error(SECOND(), kwargs); - } + format_kwargs_error(SECOND(), kwargs); Py_DECREF(kwargs); goto error; } @@ -5063,14 +5026,48 @@ check_args_iterable(PyObject *func, PyObject *args) } static void -format_kwargs_mapping_error(PyObject *func, PyObject *kwargs) +format_kwargs_error(PyObject *func, PyObject *kwargs) { - PyErr_Format(PyExc_TypeError, - "%.200s%.200s argument after ** " - "must be a mapping, not %.200s", - PyEval_GetFuncName(func), - PyEval_GetFuncDesc(func), - kwargs->ob_type->tp_name); + /* _PyDict_MergeEx raises attribute + * error (percolated from an attempt + * to get 'keys' attribute) instead of + * a type error if its second argument + * is not a mapping. + */ + if (PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Format(PyExc_TypeError, + "%.200s%.200s argument after ** " + "must be a mapping, not %.200s", + PyEval_GetFuncName(func), + PyEval_GetFuncDesc(func), + kwargs->ob_type->tp_name); + } + else if (PyErr_ExceptionMatches(PyExc_KeyError)) { + PyObject *exc, *val, *tb; + PyErr_Fetch(&exc, &val, &tb); + if (val && PyTuple_Check(val) && PyTuple_GET_SIZE(val) == 1) { + PyObject *key = PyTuple_GET_ITEM(val, 0); + if (!PyUnicode_Check(key)) { + PyErr_Format(PyExc_TypeError, + "%.200s%.200s keywords must be strings", + PyEval_GetFuncName(func), + PyEval_GetFuncDesc(func)); + } else { + PyErr_Format(PyExc_TypeError, + "%.200s%.200s got multiple " + "values for keyword argument '%U'", + PyEval_GetFuncName(func), + PyEval_GetFuncDesc(func), + key); + } + Py_XDECREF(exc); + Py_XDECREF(val); + Py_XDECREF(tb); + } + else { + PyErr_Restore(exc, val, tb); + } + } } static void |