diff --git a/Objects/clinic/dictobject.c.h b/Objects/clinic/dictobject.c.h index 3f06c0b5da7..21c2b0b3d08 100644 --- a/Objects/clinic/dictobject.c.h +++ b/Objects/clinic/dictobject.c.h @@ -44,4 +44,72 @@ PyDoc_STRVAR(dict___contains____doc__, #define DICT___CONTAINS___METHODDEF \ {"__contains__", (PyCFunction)dict___contains__, METH_O|METH_COEXIST, dict___contains____doc__}, -/*[clinic end generated code: output=69f3d767ed44e8ec input=a9049054013a1b77]*/ + +PyDoc_STRVAR(dict_get__doc__, +"get($self, key, default=None, /)\n" +"--\n" +"\n" +"D.get(key[, default]) -> D[key] if key in D, else default."); + +#define DICT_GET_METHODDEF \ + {"get", (PyCFunction)dict_get, METH_FASTCALL, dict_get__doc__}, + +static PyObject * +dict_get_impl(PyDictObject *self, PyObject *key, PyObject *failobj); + +static PyObject * +dict_get(PyDictObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + PyObject *key; + PyObject *failobj = Py_None; + + if (!_PyArg_UnpackStack(args, nargs, "get", + 1, 2, + &key, &failobj)) { + goto exit; + } + + if (!_PyArg_NoStackKeywords("get", kwnames)) { + goto exit; + } + return_value = dict_get_impl(self, key, failobj); + +exit: + return return_value; +} + +PyDoc_STRVAR(dict_setdefault__doc__, +"setdefault($self, key, default=None, /)\n" +"--\n" +"\n" +"D.get(key,default), also set D[key]=default if key not in D."); + +#define DICT_SETDEFAULT_METHODDEF \ + {"setdefault", (PyCFunction)dict_setdefault, METH_FASTCALL, dict_setdefault__doc__}, + +static PyObject * +dict_setdefault_impl(PyDictObject *self, PyObject *key, PyObject *defaultobj); + +static PyObject * +dict_setdefault(PyDictObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + PyObject *key; + PyObject *defaultobj = Py_None; + + if (!_PyArg_UnpackStack(args, nargs, "setdefault", + 1, 2, + &key, &defaultobj)) { + goto exit; + } + + if (!_PyArg_NoStackKeywords("setdefault", kwnames)) { + goto exit; + } + return_value = dict_setdefault_impl(self, key, defaultobj); + +exit: + return return_value; +} +/*[clinic end generated code: output=1b0cea84b4b6989e input=a9049054013a1b77]*/ diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 9950f50896a..1a6eedd738c 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -2787,25 +2787,31 @@ dict___contains__(PyDictObject *self, PyObject *key) Py_RETURN_TRUE; } +/*[clinic input] +dict.get + + key: object + default as failobj: object = None + / + +D.get(key[, default]) -> D[key] if key in D, else default. +[clinic start generated code]*/ + static PyObject * -dict_get(PyDictObject *mp, PyObject *args) +dict_get_impl(PyDictObject *self, PyObject *key, PyObject *failobj) +/*[clinic end generated code: output=c4a84a7ddbca9b7b input=7c976a78f258e915]*/ { - PyObject *key; - PyObject *failobj = Py_None; PyObject *val = NULL; Py_hash_t hash; Py_ssize_t ix; - if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &failobj)) - return NULL; - if (!PyUnicode_CheckExact(key) || (hash = ((PyASCIIObject *) key)->hash) == -1) { hash = PyObject_Hash(key); if (hash == -1) return NULL; } - ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &val, NULL); + ix = (self->ma_keys->dk_lookup) (self, key, hash, &val, NULL); if (ix == DKIX_ERROR) return NULL; if (ix == DKIX_EMPTY || val == NULL) { @@ -2899,16 +2905,23 @@ PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *defaultobj) return value; } +/*[clinic input] +dict.setdefault + + key: object + default as defaultobj: object = None + / + +D.get(key,default), also set D[key]=default if key not in D. +[clinic start generated code]*/ + static PyObject * -dict_setdefault(PyDictObject *mp, PyObject *args) +dict_setdefault_impl(PyDictObject *self, PyObject *key, PyObject *defaultobj) +/*[clinic end generated code: output=692f85384b0b292e input=178f0c81d496d5cd]*/ { - PyObject *key, *val; - PyObject *defaultobj = Py_None; + PyObject *val; - if (!PyArg_UnpackTuple(args, "setdefault", 1, 2, &key, &defaultobj)) - return NULL; - - val = PyDict_SetDefault((PyObject *)mp, key, defaultobj); + val = PyDict_SetDefault((PyObject *)self, key, defaultobj); Py_XINCREF(val); return val; } @@ -3072,12 +3085,6 @@ PyDoc_STRVAR(getitem__doc__, "x.__getitem__(y) <==> x[y]"); PyDoc_STRVAR(sizeof__doc__, "D.__sizeof__() -> size of D in memory, in bytes"); -PyDoc_STRVAR(get__doc__, -"D.get(k[,d]) -> D[k] if k in D, else d. d defaults to None."); - -PyDoc_STRVAR(setdefault_doc__, -"D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D"); - PyDoc_STRVAR(pop__doc__, "D.pop(k[,d]) -> v, remove specified key and return the corresponding value.\n\ If key is not found, d is returned if given, otherwise KeyError is raised"); @@ -3116,10 +3123,8 @@ static PyMethodDef mapp_methods[] = { getitem__doc__}, {"__sizeof__", (PyCFunction)dict_sizeof, METH_NOARGS, sizeof__doc__}, - {"get", (PyCFunction)dict_get, METH_VARARGS, - get__doc__}, - {"setdefault", (PyCFunction)dict_setdefault, METH_VARARGS, - setdefault_doc__}, + DICT_GET_METHODDEF + DICT_SETDEFAULT_METHODDEF {"pop", (PyCFunction)dict_pop, METH_VARARGS, pop__doc__}, {"popitem", (PyCFunction)dict_popitem, METH_NOARGS,