diff options
author | Victor Stinner <victor.stinner@gmail.com> | 2017-01-19 11:37:13 (GMT) |
---|---|---|
committer | Victor Stinner <victor.stinner@gmail.com> | 2017-01-19 11:37:13 (GMT) |
commit | 7dc6a5f50aa47d32a75941dcb091eabe7958b2a1 (patch) | |
tree | c909658d7f5e9dc17bac36ef8552132b0cdd81de | |
parent | 06d34393c2f1f28bf97873418e2b981e7b188811 (diff) | |
download | cpython-7dc6a5f50aa47d32a75941dcb091eabe7958b2a1.zip cpython-7dc6a5f50aa47d32a75941dcb091eabe7958b2a1.tar.gz cpython-7dc6a5f50aa47d32a75941dcb091eabe7958b2a1.tar.bz2 |
dict.get() and dict.setdefault() now use AC
Issue #29311: dict.get() and dict.setdefault() methods now use Argument Clinic
to parse arguments. Their calling convention changes from METH_VARARGS to
METH_FASTCALL which avoids the creation of a temporary tuple.
The signature of docstrings is also enhanced. For example,
get(...)
becomes:
get(self, key, default=None, /)
-rw-r--r-- | Objects/clinic/dictobject.c.h | 70 | ||||
-rw-r--r-- | Objects/dictobject.c | 53 |
2 files changed, 98 insertions, 25 deletions
diff --git a/Objects/clinic/dictobject.c.h b/Objects/clinic/dictobject.c.h index 3f06c0b..21c2b0b 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 9950f50..1a6eedd 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, |