diff -r 127401469628 Objects/dictobject.c --- a/Objects/dictobject.c Wed Jan 18 17:20:01 2017 +0100 +++ b/Objects/dictobject.c Thu Jan 19 10:49:47 2017 +0100 @@ -2322,13 +2322,13 @@ dict_fromkeys_impl(PyTypeObject *type, P } static int -dict_update_common(PyObject *self, PyObject *args, PyObject *kwds, - const char *methname) +dict_update_common(PyObject *self, PyObject **args, Py_ssize_t nargs, + PyObject *kwds, const char *methname) { PyObject *arg = NULL; int result = 0; - if (!PyArg_UnpackTuple(args, methname, 0, 1, &arg)) + if (!_PyArg_UnpackStack(args, nargs, methname, 0, 1, &arg)) result = -1; else if (arg != NULL) { @@ -2348,9 +2348,42 @@ dict_update_common(PyObject *self, PyObj } static PyObject * -dict_update(PyObject *self, PyObject *args, PyObject *kwds) +dict_update(PyObject *self, PyObject **args, Py_ssize_t nargs, + PyObject *kwnames) { - if (dict_update_common(self, args, kwds, "update") != -1) + PyObject *kwargs; + int res; + + if (kwnames != NULL) { + PyObject **values; + Py_ssize_t nkwargs; + Py_ssize_t i; + + nkwargs = PyTuple_GET_SIZE(kwnames); + kwargs = _PyDict_NewPresized(nkwargs); + if (kwargs == NULL) { + return NULL; + } + + values = args + nargs; + for (i = 0; i < nkwargs; i++) { + PyObject *key = PyTuple_GET_ITEM(kwnames, i); + PyObject *value = *values++; + assert(PyDict_GetItem(kwargs, key) == NULL); + if (PyDict_SetItem(kwargs, key, value)) { + Py_DECREF(kwargs); + return NULL; + } + } + + res = dict_update_common(self, args, nargs, kwargs, "update"); + Py_DECREF(kwargs); + } + else { + res = dict_update_common(self, args, nargs, NULL, "update"); + } + + if (res != -1) Py_RETURN_NONE; return NULL; } @@ -3130,7 +3163,7 @@ static PyMethodDef mapp_methods[] = { items__doc__}, {"values", (PyCFunction)dictvalues_new, METH_NOARGS, values__doc__}, - {"update", (PyCFunction)dict_update, METH_VARARGS | METH_KEYWORDS, + {"update", (PyCFunction)dict_update, METH_FASTCALL, update__doc__}, DICT_FROMKEYS_METHODDEF {"clear", (PyCFunction)dict_clear, METH_NOARGS, @@ -3219,7 +3252,10 @@ dict_new(PyTypeObject *type, PyObject *a static int dict_init(PyObject *self, PyObject *args, PyObject *kwds) { - return dict_update_common(self, args, kwds, "dict"); + return dict_update_common(self, + &PyTuple_GET_ITEM(args, 0), + PyTuple_GET_SIZE(args), + kwds, "dict"); } static PyObject *