From 87ec86c425a5cd3ad41b831b54c0ce1a0c363f4b Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Mon, 16 Mar 2020 23:06:20 +0900 Subject: [PATCH] bpo-37207: Add _PyArg_NoKwnames() helper function (GH-18980) --- Include/modsupport.h | 3 +++ .../2020-03-14-01-56-03.bpo-37207.R3jaTy.rst | 1 + Objects/rangeobject.c | 3 +-- Objects/tupleobject.c | 3 +-- Python/getargs.c | 19 ++++++++++++++++++- 5 files changed, 24 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/C API/2020-03-14-01-56-03.bpo-37207.R3jaTy.rst diff --git a/Include/modsupport.h b/Include/modsupport.h index f90ede4831e..f2dc812df2b 100644 --- a/Include/modsupport.h +++ b/Include/modsupport.h @@ -60,9 +60,12 @@ PyAPI_FUNC(int) _PyArg_UnpackStack( ...); PyAPI_FUNC(int) _PyArg_NoKeywords(const char *funcname, PyObject *kwargs); +PyAPI_FUNC(int) _PyArg_NoKwnames(const char *funcname, PyObject *kwnames); PyAPI_FUNC(int) _PyArg_NoPositional(const char *funcname, PyObject *args); #define _PyArg_NoKeywords(funcname, kwargs) \ ((kwargs) == NULL || _PyArg_NoKeywords((funcname), (kwargs))) +#define _PyArg_NoKwnames(funcname, kwnames) \ + ((kwnames) == NULL || _PyArg_NoKwnames((funcname), (kwnames))) #define _PyArg_NoPositional(funcname, args) \ ((args) == NULL || _PyArg_NoPositional((funcname), (args))) diff --git a/Misc/NEWS.d/next/C API/2020-03-14-01-56-03.bpo-37207.R3jaTy.rst b/Misc/NEWS.d/next/C API/2020-03-14-01-56-03.bpo-37207.R3jaTy.rst new file mode 100644 index 00000000000..216a8217f55 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2020-03-14-01-56-03.bpo-37207.R3jaTy.rst @@ -0,0 +1 @@ +Add _PyArg_NoKwnames helper function. Patch by Dong-hee Na. diff --git a/Objects/rangeobject.c b/Objects/rangeobject.c index 123ca0b032e..5bd178b2027 100644 --- a/Objects/rangeobject.c +++ b/Objects/rangeobject.c @@ -146,8 +146,7 @@ range_vectorcall(PyTypeObject *type, PyObject *const *args, size_t nargsf, PyObject *kwnames) { Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); - if (kwnames && PyTuple_GET_SIZE(kwnames) != 0) { - PyErr_Format(PyExc_TypeError, "range() takes no keyword arguments"); + if (!_PyArg_NoKwnames("range", kwnames)) { return NULL; } return range_from_array(type, args, nargs); diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index d4165dec17a..8a8c6ae74f8 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -709,8 +709,7 @@ static PyObject * tuple_vectorcall(PyObject *type, PyObject * const*args, size_t nargsf, PyObject *kwnames) { - if (kwnames && PyTuple_GET_SIZE(kwnames) != 0) { - PyErr_Format(PyExc_TypeError, "tuple() takes no keyword arguments"); + if (!_PyArg_NoKwnames("tuple", kwnames)) { return NULL; } diff --git a/Python/getargs.c b/Python/getargs.c index d644aea5207..062f8141926 100644 --- a/Python/getargs.c +++ b/Python/getargs.c @@ -2787,6 +2787,7 @@ _PyArg_UnpackStack(PyObject *const *args, Py_ssize_t nargs, const char *name, #undef _PyArg_NoKeywords +#undef _PyArg_NoKwnames #undef _PyArg_NoPositional /* For type constructors that don't take keyword args @@ -2813,7 +2814,6 @@ _PyArg_NoKeywords(const char *funcname, PyObject *kwargs) return 0; } - int _PyArg_NoPositional(const char *funcname, PyObject *args) { @@ -2831,6 +2831,23 @@ _PyArg_NoPositional(const char *funcname, PyObject *args) return 0; } +int +_PyArg_NoKwnames(const char *funcname, PyObject *kwnames) +{ + if (kwnames == NULL) { + return 1; + } + + assert(PyTuple_CheckExact(kwnames)); + + if (PyTuple_GET_SIZE(kwnames) == 0) { + return 1; + } + + PyErr_Format(PyExc_TypeError, "%s() takes no keyword arguments", funcname); + return 0; +} + void _PyArg_Fini(void) {