diff options
author | Jelle Zijlstra <jelle.zijlstra@gmail.com> | 2022-01-26 15:46:48 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-26 15:46:48 (GMT) |
commit | ac0c6e128cb6553585af096c851c488b53a6c952 (patch) | |
tree | 28ada0f6fa8c6fcd40e3b863c57651c5462c9348 /Objects/enumobject.c | |
parent | 1e8a3a5579c9a96a45073b24d1af2dbe3039d366 (diff) | |
download | cpython-ac0c6e128cb6553585af096c851c488b53a6c952.zip cpython-ac0c6e128cb6553585af096c851c488b53a6c952.tar.gz cpython-ac0c6e128cb6553585af096c851c488b53a6c952.tar.bz2 |
bpo-46527: allow calling enumerate(iterable=...) again (GH-30904)
Diffstat (limited to 'Objects/enumobject.c')
-rw-r--r-- | Objects/enumobject.c | 47 |
1 files changed, 37 insertions, 10 deletions
diff --git a/Objects/enumobject.c b/Objects/enumobject.c index 36f592d..828f1f9 100644 --- a/Objects/enumobject.c +++ b/Objects/enumobject.c @@ -83,6 +83,18 @@ enum_new_impl(PyTypeObject *type, PyObject *iterable, PyObject *start) return (PyObject *)en; } +static int check_keyword(PyObject *kwnames, int index, + const char *name) +{ + PyObject *kw = PyTuple_GET_ITEM(kwnames, index); + if (!_PyUnicode_EqualToASCIIString(kw, name)) { + PyErr_Format(PyExc_TypeError, + "'%S' is an invalid keyword argument for enumerate()", kw); + return 0; + } + return 1; +} + // TODO: Use AC when bpo-43447 is supported static PyObject * enumerate_vectorcall(PyObject *type, PyObject *const *args, @@ -91,31 +103,46 @@ enumerate_vectorcall(PyObject *type, PyObject *const *args, PyTypeObject *tp = _PyType_CAST(type); Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); Py_ssize_t nkwargs = 0; - if (nargs == 0) { - PyErr_SetString(PyExc_TypeError, - "enumerate() missing required argument 'iterable'"); - return NULL; - } if (kwnames != NULL) { nkwargs = PyTuple_GET_SIZE(kwnames); } + // Manually implement enumerate(iterable, start=...) if (nargs + nkwargs == 2) { if (nkwargs == 1) { - PyObject *kw = PyTuple_GET_ITEM(kwnames, 0); - if (!_PyUnicode_EqualToASCIIString(kw, "start")) { - PyErr_Format(PyExc_TypeError, - "'%S' is an invalid keyword argument for enumerate()", kw); + if (!check_keyword(kwnames, 0, "start")) { + return NULL; + } + } else if (nkwargs == 2) { + PyObject *kw0 = PyTuple_GET_ITEM(kwnames, 0); + if (_PyUnicode_EqualToASCIIString(kw0, "start")) { + if (!check_keyword(kwnames, 1, "iterable")) { + return NULL; + } + return enum_new_impl(tp, args[1], args[0]); + } + if (!check_keyword(kwnames, 0, "iterable") || + !check_keyword(kwnames, 1, "start")) { return NULL; } + } return enum_new_impl(tp, args[0], args[1]); } - if (nargs == 1 && nkwargs == 0) { + if (nargs + nkwargs == 1) { + if (nkwargs == 1 && !check_keyword(kwnames, 0, "iterable")) { + return NULL; + } return enum_new_impl(tp, args[0], NULL); } + if (nargs == 0) { + PyErr_SetString(PyExc_TypeError, + "enumerate() missing required argument 'iterable'"); + return NULL; + } + PyErr_Format(PyExc_TypeError, "enumerate() takes at most 2 arguments (%d given)", nargs + nkwargs); return NULL; |