diff --git a/Python/ceval.c b/Python/ceval.c index 38ac509..38c9b52 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -2684,8 +2684,9 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) TARGET(BUILD_MAP_UNPACK) { int with_call = opcode == BUILD_MAP_UNPACK_WITH_CALL; int num_maps; - int function_location; + int function_location = 0; int i; + Py_ssize_t endsize = 0; PyObject *sum = PyDict_New(); if (sum == NULL) goto error; @@ -2699,58 +2700,67 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) for (i = num_maps; i > 0; i--) { PyObject *arg = PEEK(i); - if (with_call) { - PyObject *intersection = _PyDictView_Intersect(sum, arg); - - if (intersection == NULL) { + if (with_call && !PyDict_CheckExact(arg)) { + PyObject *newarg = PyDict_New(); + if (newarg == NULL) { + goto map_unpack_error; + } + if (PyDict_Update(newarg, arg) < 0) { if (PyErr_ExceptionMatches(PyExc_AttributeError)) { - PyObject *func = ( - PEEK(function_location + num_maps)); PyErr_Format(PyExc_TypeError, - "%.200s%.200s argument after ** " - "must be a mapping, not %.200s", - PyEval_GetFuncName(func), - PyEval_GetFuncDesc(func), + "'%.200s' object is not a mapping", arg->ob_type->tp_name); } - Py_DECREF(sum); - goto error; - } - - if (PySet_GET_SIZE(intersection)) { - Py_ssize_t idx = 0; - PyObject *key; - PyObject *func = PEEK(function_location + num_maps); - Py_hash_t hash; - _PySet_NextEntry(intersection, &idx, &key, &hash); - 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_DECREF(intersection); - Py_DECREF(sum); - goto error; + goto map_unpack_error; } - Py_DECREF(intersection); + Py_DECREF(arg); + SET_VALUE(i, newarg); + arg = newarg; } - if (PyDict_Update(sum, arg) < 0) { if (PyErr_ExceptionMatches(PyExc_AttributeError)) { PyErr_Format(PyExc_TypeError, "'%.200s' object is not a mapping", arg->ob_type->tp_name); } - Py_DECREF(sum); - goto error; + goto map_unpack_error; + } + if (with_call) { + endsize += PyDict_Size(arg); + if (endsize != PyDict_Size(sum)) { + for (Py_ssize_t j = num_maps; j > i; j--) { + PyObject *jth = PEEK(j); + PyObject *intersection = _PyDictView_Intersect(arg, jth); + if (intersection == NULL) { + goto map_unpack_error; + } + + if (PySet_GET_SIZE(intersection)) { + Py_ssize_t idx = 0; + PyObject *key; + PyObject *func = PEEK(function_location + num_maps); + Py_hash_t hash; + _PySet_NextEntry(intersection, &idx, &key, &hash); + 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_DECREF(intersection); + goto map_unpack_error; + } + Py_DECREF(intersection); + + } + } } } @@ -2758,6 +2768,9 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) Py_DECREF(POP()); PUSH(sum); DISPATCH(); +map_unpack_error: + Py_DECREF(sum); + goto error; } TARGET(MAP_ADD) {