From 5d858465b6ebdafa05f86309457848cc26913b6a Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 20 Nov 2016 10:16:47 +0200 Subject: Added the const qualifier to char* variables that refer to readonly internal UTF-8 represenatation of Unicode objects. --- Python/getargs.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'Python/getargs.c') diff --git a/Python/getargs.c b/Python/getargs.c index 616c6eb107..a6636f461b 100644 --- a/Python/getargs.c +++ b/Python/getargs.c @@ -74,7 +74,7 @@ static const char *converttuple(PyObject *, const char **, va_list *, int, int *, char *, size_t, int, freelist_t *); static const char *convertsimple(PyObject *, const char **, va_list *, int, char *, size_t, freelist_t *); -static Py_ssize_t convertbuffer(PyObject *, void **p, const char **); +static Py_ssize_t convertbuffer(PyObject *, const void **p, const char **); static int getbuffer(PyObject *, Py_buffer *, const char**); static int vgetargskeywords(PyObject *, PyObject *, @@ -625,7 +625,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, const char *format = *p_format; char c = *format++; - char *sarg; + const char *sarg; switch (c) { @@ -897,7 +897,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, } break; } - count = convertbuffer(arg, p, &buf); + count = convertbuffer(arg, (const void **)p, &buf); if (count < 0) return converterr(buf, arg, msgbuf, bufsize); if (*format == '#') { @@ -928,7 +928,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, if (sarg == NULL) return converterr(CONV_UNICODE, arg, msgbuf, bufsize); - PyBuffer_FillInfo(p, arg, sarg, len, 1, 0); + PyBuffer_FillInfo(p, arg, (void *)sarg, len, 1, 0); } else { /* any bytes-like object */ const char *buf; @@ -943,7 +943,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, format++; } else if (*format == '#') { /* a string or read-only bytes-like object */ /* "s#" or "z#" */ - void **p = (void **)va_arg(*p_va, char **); + const void **p = (const void **)va_arg(*p_va, const char **); FETCH_SIZE; if (c == 'z' && arg == Py_None) { @@ -970,7 +970,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, format++; } else { /* "s" or "z" */ - char **p = va_arg(*p_va, char **); + const char **p = va_arg(*p_va, const char **); Py_ssize_t len; sarg = NULL; @@ -1300,7 +1300,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, } static Py_ssize_t -convertbuffer(PyObject *arg, void **p, const char **errmsg) +convertbuffer(PyObject *arg, const void **p, const char **errmsg) { PyBufferProcs *pb = Py_TYPE(arg)->tp_as_buffer; Py_ssize_t count; -- cgit v1.2.1 From ba86008aac6890c5c4a2c6d30ea8110f228d483e Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 20 Nov 2016 12:16:46 +0200 Subject: Issue #19569: Compiler warnings are now emitted if use most of deprecated functions. --- Python/getargs.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'Python/getargs.c') diff --git a/Python/getargs.c b/Python/getargs.c index a6636f461b..c552d0fe27 100644 --- a/Python/getargs.c +++ b/Python/getargs.c @@ -1027,7 +1027,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, *p = PyUnicode_AsUnicodeAndSize(arg, &len); if (*p == NULL) RETURN_ERR_OCCURRED; - if (Py_UNICODE_strlen(*p) != (size_t)len) { + if (wcslen(*p) != (size_t)len) { PyErr_SetString(PyExc_ValueError, "embedded null character"); RETURN_ERR_OCCURRED; } @@ -1074,9 +1074,14 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, (PyBytes_Check(arg) || PyByteArray_Check(arg))) { s = arg; Py_INCREF(s); - if (PyObject_AsCharBuffer(s, &ptr, &size) < 0) - return converterr("(AsCharBuffer failed)", - arg, msgbuf, bufsize); + if (PyBytes_Check(arg)) { + size = PyBytes_GET_SIZE(s); + ptr = PyBytes_AS_STRING(s); + } + else { + size = PyByteArray_GET_SIZE(s); + ptr = PyByteArray_AS_STRING(s); + } } else if (PyUnicode_Check(arg)) { /* Encode object; use default error handling */ -- cgit v1.2.1 From f22b56b777f7134b5c4e6c9caa9249e92c4f4fd9 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 16 Dec 2016 16:18:57 +0200 Subject: Issue #28959: Added private macro PyDict_GET_SIZE for retrieving the size of dict. --- Python/getargs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Python/getargs.c') diff --git a/Python/getargs.c b/Python/getargs.c index c552d0fe27..49888d11b6 100644 --- a/Python/getargs.c +++ b/Python/getargs.c @@ -1650,7 +1650,7 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format, } nargs = PyTuple_GET_SIZE(args); - nkeywords = (keywords == NULL) ? 0 : PyDict_Size(keywords); + nkeywords = (keywords == NULL) ? 0 : PyDict_GET_SIZE(keywords); if (nargs + nkeywords > len) { PyErr_Format(PyExc_TypeError, "%s%s takes at most %d argument%s (%zd given)", @@ -2034,7 +2034,7 @@ vgetargskeywordsfast_impl(PyObject **args, Py_ssize_t nargs, } if (keywords != NULL) { - nkeywords = PyDict_Size(keywords); + nkeywords = PyDict_GET_SIZE(keywords); } else if (kwnames != NULL) { nkeywords = PyTuple_GET_SIZE(kwnames); @@ -2421,7 +2421,7 @@ _PyArg_NoKeywords(const char *funcname, PyObject *kw) PyErr_BadInternalCall(); return 0; } - if (PyDict_Size(kw) == 0) + if (PyDict_GET_SIZE(kw) == 0) return 1; PyErr_Format(PyExc_TypeError, "%s does not take keyword arguments", -- cgit v1.2.1 From cbfd2d5359b8ec44360fafd769b122ce097228f9 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 16 Jan 2017 23:16:47 +0100 Subject: Cleanup getargs.c Factorize argument checks in: * vgetargskeywordsfast() * vgetargskeywordsfast_impl() --- Python/getargs.c | 66 +++++++++++++++----------------------------------------- 1 file changed, 17 insertions(+), 49 deletions(-) (limited to 'Python/getargs.c') diff --git a/Python/getargs.c b/Python/getargs.c index 49888d11b6..4c34b2a5d3 100644 --- a/Python/getargs.c +++ b/Python/getargs.c @@ -1453,14 +1453,6 @@ _PyArg_ParseTupleAndKeywordsFast(PyObject *args, PyObject *keywords, int retval; va_list va; - if ((args == NULL || !PyTuple_Check(args)) || - (keywords != NULL && !PyDict_Check(keywords)) || - parser == NULL) - { - PyErr_BadInternalCall(); - return 0; - } - va_start(va, parser); retval = vgetargskeywordsfast(args, keywords, parser, &va, 0); va_end(va); @@ -1474,14 +1466,6 @@ _PyArg_ParseTupleAndKeywordsFast_SizeT(PyObject *args, PyObject *keywords, int retval; va_list va; - if ((args == NULL || !PyTuple_Check(args)) || - (keywords != NULL && !PyDict_Check(keywords)) || - parser == NULL) - { - PyErr_BadInternalCall(); - return 0; - } - va_start(va, parser); retval = vgetargskeywordsfast(args, keywords, parser, &va, FLAG_SIZE_T); va_end(va); @@ -1495,13 +1479,6 @@ _PyArg_ParseStack(PyObject **args, Py_ssize_t nargs, PyObject *kwnames, int retval; va_list va; - if ((kwnames != NULL && !PyTuple_Check(kwnames)) || - parser == NULL) - { - PyErr_BadInternalCall(); - return 0; - } - va_start(va, parser); retval = vgetargskeywordsfast_impl(args, nargs, NULL, kwnames, parser, &va, 0); va_end(va); @@ -1515,13 +1492,6 @@ _PyArg_ParseStack_SizeT(PyObject **args, Py_ssize_t nargs, PyObject *kwnames, int retval; va_list va; - if ((kwnames != NULL && !PyTuple_Check(kwnames)) || - parser == NULL) - { - PyErr_BadInternalCall(); - return 0; - } - va_start(va, parser); retval = vgetargskeywordsfast_impl(args, nargs, NULL, kwnames, parser, &va, FLAG_SIZE_T); va_end(va); @@ -1536,14 +1506,6 @@ _PyArg_VaParseTupleAndKeywordsFast(PyObject *args, PyObject *keywords, int retval; va_list lva; - if ((args == NULL || !PyTuple_Check(args)) || - (keywords != NULL && !PyDict_Check(keywords)) || - parser == NULL) - { - PyErr_BadInternalCall(); - return 0; - } - va_copy(lva, va); retval = vgetargskeywordsfast(args, keywords, parser, &lva, 0); @@ -1558,14 +1520,6 @@ _PyArg_VaParseTupleAndKeywordsFast_SizeT(PyObject *args, PyObject *keywords, int retval; va_list lva; - if ((args == NULL || !PyTuple_Check(args)) || - (keywords != NULL && !PyDict_Check(keywords)) || - parser == NULL) - { - PyErr_BadInternalCall(); - return 0; - } - va_copy(lva, va); retval = vgetargskeywordsfast(args, keywords, parser, &lva, FLAG_SIZE_T); @@ -2010,12 +1964,20 @@ vgetargskeywordsfast_impl(PyObject **args, Py_ssize_t nargs, freelist.entries_malloced = 0; assert(keywords == NULL || PyDict_Check(keywords)); - assert(kwnames == NULL || PyTuple_Check(kwnames)); assert((keywords != NULL || kwnames != NULL) || (keywords == NULL && kwnames == NULL)); - assert(parser != NULL); assert(p_va != NULL); + if (parser == NULL) { + PyErr_BadInternalCall(); + return 0; + } + + if (kwnames != NULL && !PyTuple_Check(kwnames)) { + PyErr_BadInternalCall(); + return 0; + } + if (!parser_init(parser)) { return 0; } @@ -2204,7 +2166,13 @@ vgetargskeywordsfast(PyObject *args, PyObject *keywords, PyObject **stack; Py_ssize_t nargs; - assert(args != NULL && PyTuple_Check(args)); + if (args == NULL + || !PyTuple_Check(args) + || (keywords != NULL && !PyDict_Check(keywords))) + { + PyErr_BadInternalCall(); + return 0; + } stack = &PyTuple_GET_ITEM(args, 0); nargs = PyTuple_GET_SIZE(args); -- cgit v1.2.1 From ac0fa81183497c5a9acf90ec9cf72518c4ed0ddf Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 17 Jan 2017 00:37:42 +0100 Subject: Rename keywords to kwargs in getargs.c Issue #29029. Patch written by Serhiy Storchaka. --- Python/getargs.c | 62 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 31 insertions(+), 31 deletions(-) (limited to 'Python/getargs.c') diff --git a/Python/getargs.c b/Python/getargs.c index 4c34b2a5d3..f35d59a351 100644 --- a/Python/getargs.c +++ b/Python/getargs.c @@ -1545,7 +1545,7 @@ PyArg_ValidateKeywordArguments(PyObject *kwargs) #define IS_END_OF_FORMAT(c) (c == '\0' || c == ';' || c == ':') static int -vgetargskeywords(PyObject *args, PyObject *keywords, const char *format, +vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format, char **kwlist, va_list *p_va, int flags) { char msgbuf[512]; @@ -1555,7 +1555,7 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format, int max = INT_MAX; int i, pos, len; int skip = 0; - Py_ssize_t nargs, nkeywords; + Py_ssize_t nargs, nkwargs; PyObject *current_arg; freelistentry_t static_entries[STATIC_FREELIST_ENTRIES]; freelist_t freelist; @@ -1565,7 +1565,7 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format, freelist.entries_malloced = 0; assert(args != NULL && PyTuple_Check(args)); - assert(keywords == NULL || PyDict_Check(keywords)); + assert(kwargs == NULL || PyDict_Check(kwargs)); assert(format != NULL); assert(kwlist != NULL); assert(p_va != NULL); @@ -1604,15 +1604,15 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format, } nargs = PyTuple_GET_SIZE(args); - nkeywords = (keywords == NULL) ? 0 : PyDict_GET_SIZE(keywords); - if (nargs + nkeywords > len) { + nkwargs = (kwargs == NULL) ? 0 : PyDict_GET_SIZE(kwargs); + if (nargs + nkwargs > len) { PyErr_Format(PyExc_TypeError, "%s%s takes at most %d argument%s (%zd given)", (fname == NULL) ? "function" : fname, (fname == NULL) ? "" : "()", len, (len == 1) ? "" : "s", - nargs + nkeywords); + nargs + nkwargs); return cleanreturn(0, &freelist); } @@ -1673,14 +1673,14 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format, } if (!skip) { current_arg = NULL; - if (nkeywords && i >= pos) { - current_arg = PyDict_GetItemString(keywords, keyword); + if (nkwargs && i >= pos) { + current_arg = PyDict_GetItemString(kwargs, keyword); if (!current_arg && PyErr_Occurred()) { return cleanreturn(0, &freelist); } } if (current_arg) { - --nkeywords; + --nkwargs; if (i < nargs) { /* arg present in tuple and in dict */ PyErr_Format(PyExc_TypeError, @@ -1724,7 +1724,7 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format, * fulfilled and no keyword args left, with no further * validation. XXX Maybe skip this in debug build ? */ - if (!nkeywords && !skip) { + if (!nkwargs && !skip) { return cleanreturn(1, &freelist); } } @@ -1756,10 +1756,10 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format, } /* make sure there are no extraneous keyword arguments */ - if (nkeywords > 0) { + if (nkwargs > 0) { PyObject *key, *value; Py_ssize_t pos = 0; - while (PyDict_Next(keywords, &pos, &key, &value)) { + while (PyDict_Next(kwargs, &pos, &key, &value)) { int match = 0; if (!PyUnicode_Check(key)) { PyErr_SetString(PyExc_TypeError, @@ -1942,7 +1942,7 @@ find_keyword(PyObject *kwnames, PyObject **kwstack, PyObject *key) static int vgetargskeywordsfast_impl(PyObject **args, Py_ssize_t nargs, - PyObject *keywords, PyObject *kwnames, + PyObject *kwargs, PyObject *kwnames, struct _PyArg_Parser *parser, va_list *p_va, int flags) { @@ -1953,7 +1953,7 @@ vgetargskeywordsfast_impl(PyObject **args, Py_ssize_t nargs, const char *msg; PyObject *keyword; int i, pos, len; - Py_ssize_t nkeywords; + Py_ssize_t nkwargs; PyObject *current_arg; freelistentry_t static_entries[STATIC_FREELIST_ENTRIES]; freelist_t freelist; @@ -1963,9 +1963,9 @@ vgetargskeywordsfast_impl(PyObject **args, Py_ssize_t nargs, freelist.first_available = 0; freelist.entries_malloced = 0; - assert(keywords == NULL || PyDict_Check(keywords)); - assert((keywords != NULL || kwnames != NULL) - || (keywords == NULL && kwnames == NULL)); + assert(kwargs == NULL || PyDict_Check(kwargs)); + assert((kwargs != NULL || kwnames != NULL) + || (kwargs == NULL && kwnames == NULL)); assert(p_va != NULL); if (parser == NULL) { @@ -1995,24 +1995,24 @@ vgetargskeywordsfast_impl(PyObject **args, Py_ssize_t nargs, freelist.entries_malloced = 1; } - if (keywords != NULL) { - nkeywords = PyDict_GET_SIZE(keywords); + if (kwargs != NULL) { + nkwargs = PyDict_GET_SIZE(kwargs); } else if (kwnames != NULL) { - nkeywords = PyTuple_GET_SIZE(kwnames); + nkwargs = PyTuple_GET_SIZE(kwnames); kwstack = args + nargs; } else { - nkeywords = 0; + nkwargs = 0; } - if (nargs + nkeywords > len) { + if (nargs + nkwargs > len) { PyErr_Format(PyExc_TypeError, "%s%s takes at most %d argument%s (%zd given)", (parser->fname == NULL) ? "function" : parser->fname, (parser->fname == NULL) ? "" : "()", len, (len == 1) ? "" : "s", - nargs + nkeywords); + nargs + nkwargs); return cleanreturn(0, &freelist); } if (parser->max < nargs) { @@ -2036,9 +2036,9 @@ vgetargskeywordsfast_impl(PyObject **args, Py_ssize_t nargs, assert(!IS_END_OF_FORMAT(*format)); current_arg = NULL; - if (nkeywords && i >= pos) { - if (keywords != NULL) { - current_arg = PyDict_GetItem(keywords, keyword); + if (nkwargs && i >= pos) { + if (kwargs != NULL) { + current_arg = PyDict_GetItem(kwargs, keyword); if (!current_arg && PyErr_Occurred()) { return cleanreturn(0, &freelist); } @@ -2048,7 +2048,7 @@ vgetargskeywordsfast_impl(PyObject **args, Py_ssize_t nargs, } } if (current_arg) { - --nkeywords; + --nkwargs; if (i < nargs) { /* arg present in tuple and in dict */ PyErr_Format(PyExc_TypeError, @@ -2092,7 +2092,7 @@ vgetargskeywordsfast_impl(PyObject **args, Py_ssize_t nargs, * fulfilled and no keyword args left, with no further * validation. XXX Maybe skip this in debug build ? */ - if (!nkeywords) { + if (!nkwargs) { return cleanreturn(1, &freelist); } @@ -2105,11 +2105,11 @@ vgetargskeywordsfast_impl(PyObject **args, Py_ssize_t nargs, assert(IS_END_OF_FORMAT(*format) || (*format == '|') || (*format == '$')); /* make sure there are no extraneous keyword arguments */ - if (nkeywords > 0) { - if (keywords != NULL) { + if (nkwargs > 0) { + if (kwargs != NULL) { PyObject *key, *value; Py_ssize_t pos = 0; - while (PyDict_Next(keywords, &pos, &key, &value)) { + while (PyDict_Next(kwargs, &pos, &key, &value)) { int match; if (!PyUnicode_Check(key)) { PyErr_SetString(PyExc_TypeError, -- cgit v1.2.1 From 271403abe36069797ac332e1c6eae3473878db20 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 17 Jan 2017 01:29:01 +0100 Subject: Rename _PyArg_ParseStack to _PyArg_ParseStackAndKeywords Issue #29286. --- Python/getargs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Python/getargs.c') diff --git a/Python/getargs.c b/Python/getargs.c index f35d59a351..8dd579fe40 100644 --- a/Python/getargs.c +++ b/Python/getargs.c @@ -26,7 +26,7 @@ int _PyArg_VaParseTupleAndKeywordsFast(PyObject *, PyObject *, #ifdef HAVE_DECLSPEC_DLL /* Export functions */ PyAPI_FUNC(int) _PyArg_Parse_SizeT(PyObject *, const char *, ...); -PyAPI_FUNC(int) _PyArg_ParseStack_SizeT(PyObject **args, Py_ssize_t nargs, PyObject *kwnames, +PyAPI_FUNC(int) _PyArg_ParseStackAndKeywords_SizeT(PyObject **args, Py_ssize_t nargs, PyObject *kwnames, struct _PyArg_Parser *parser, ...); PyAPI_FUNC(int) _PyArg_ParseTuple_SizeT(PyObject *, const char *, ...); PyAPI_FUNC(int) _PyArg_ParseTupleAndKeywords_SizeT(PyObject *, PyObject *, @@ -1473,7 +1473,7 @@ _PyArg_ParseTupleAndKeywordsFast_SizeT(PyObject *args, PyObject *keywords, } int -_PyArg_ParseStack(PyObject **args, Py_ssize_t nargs, PyObject *kwnames, +_PyArg_ParseStackAndKeywords(PyObject **args, Py_ssize_t nargs, PyObject *kwnames, struct _PyArg_Parser *parser, ...) { int retval; @@ -1486,7 +1486,7 @@ _PyArg_ParseStack(PyObject **args, Py_ssize_t nargs, PyObject *kwnames, } int -_PyArg_ParseStack_SizeT(PyObject **args, Py_ssize_t nargs, PyObject *kwnames, +_PyArg_ParseStackAndKeywords_SizeT(PyObject **args, Py_ssize_t nargs, PyObject *kwnames, struct _PyArg_Parser *parser, ...) { int retval; -- cgit v1.2.1 From 78a0bd77f603b38267d6e8084cd09873f3beecc1 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 17 Jan 2017 01:29:49 +0100 Subject: Add _PyArg_ParseStack() helper function Issue #29286. Function similar to PyArg_ParseTuple(), but uses a C array of PyObject* to pass arguments. Don't support the compatibility mode. --- Python/getargs.c | 90 +++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 69 insertions(+), 21 deletions(-) (limited to 'Python/getargs.c') diff --git a/Python/getargs.c b/Python/getargs.c index 8dd579fe40..35500d7e7d 100644 --- a/Python/getargs.c +++ b/Python/getargs.c @@ -26,6 +26,8 @@ int _PyArg_VaParseTupleAndKeywordsFast(PyObject *, PyObject *, #ifdef HAVE_DECLSPEC_DLL /* Export functions */ PyAPI_FUNC(int) _PyArg_Parse_SizeT(PyObject *, const char *, ...); +PyAPI_FUNC(int) _PyArg_ParseStack_SizeT(PyObject **args, Py_ssize_t nargs, + const char *format, ...); PyAPI_FUNC(int) _PyArg_ParseStackAndKeywords_SizeT(PyObject **args, Py_ssize_t nargs, PyObject *kwnames, struct _PyArg_Parser *parser, ...); PyAPI_FUNC(int) _PyArg_ParseTuple_SizeT(PyObject *, const char *, ...); @@ -66,6 +68,8 @@ typedef struct { #define STATIC_FREELIST_ENTRIES 8 /* Forward */ +static int vgetargs1_impl(PyObject *args, PyObject **stack, Py_ssize_t nargs, + const char *format, va_list *p_va, int flags); static int vgetargs1(PyObject *, const char *, va_list *, int); static void seterror(Py_ssize_t, const char *, int *, const char *, const char *); static const char *convertitem(PyObject *, const char **, va_list *, int, int *, @@ -137,6 +141,31 @@ _PyArg_ParseTuple_SizeT(PyObject *args, const char *format, ...) } +int +_PyArg_ParseStack(PyObject **args, Py_ssize_t nargs, const char *format, ...) +{ + int retval; + va_list va; + + va_start(va, format); + retval = vgetargs1_impl(NULL, args, nargs, format, &va, 0); + va_end(va); + return retval; +} + +int +_PyArg_ParseStack_SizeT(PyObject **args, Py_ssize_t nargs, const char *format, ...) +{ + int retval; + va_list va; + + va_start(va, format); + retval = vgetargs1_impl(NULL, args, nargs, format, &va, FLAG_SIZE_T); + va_end(va); + return retval; +} + + int PyArg_VaParse(PyObject *args, const char *format, va_list va) { @@ -220,7 +249,8 @@ cleanreturn(int retval, freelist_t *freelist) static int -vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags) +vgetargs1_impl(PyObject *compat_args, PyObject **stack, Py_ssize_t nargs, const char *format, + va_list *p_va, int flags) { char msgbuf[256]; int levels[32]; @@ -231,17 +261,18 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags) int level = 0; int endfmt = 0; const char *formatsave = format; - Py_ssize_t i, len; + Py_ssize_t i; const char *msg; int compat = flags & FLAG_COMPAT; freelistentry_t static_entries[STATIC_FREELIST_ENTRIES]; freelist_t freelist; + assert(nargs == 0 || stack != NULL); + freelist.entries = static_entries; freelist.first_available = 0; freelist.entries_malloced = 0; - assert(compat || (args != (PyObject*)NULL)); flags = flags & ~FLAG_COMPAT; while (endfmt == 0) { @@ -305,7 +336,7 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags) if (compat) { if (max == 0) { - if (args == NULL) + if (compat_args == NULL) return 1; PyErr_Format(PyExc_TypeError, "%.200s%s takes no arguments", @@ -314,14 +345,14 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags) return cleanreturn(0, &freelist); } else if (min == 1 && max == 1) { - if (args == NULL) { + if (compat_args == NULL) { PyErr_Format(PyExc_TypeError, "%.200s%s takes at least one argument", fname==NULL ? "function" : fname, fname==NULL ? "" : "()"); return cleanreturn(0, &freelist); } - msg = convertitem(args, &format, p_va, flags, levels, + msg = convertitem(compat_args, &format, p_va, flags, levels, msgbuf, sizeof(msgbuf), &freelist); if (msg == NULL) return cleanreturn(1, &freelist); @@ -335,34 +366,26 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags) } } - if (!PyTuple_Check(args)) { - PyErr_SetString(PyExc_SystemError, - "new style getargs format but argument is not a tuple"); - return cleanreturn(0, &freelist); - } - - len = PyTuple_GET_SIZE(args); - - if (len < min || max < len) { + if (nargs < min || max < nargs) { if (message == NULL) PyErr_Format(PyExc_TypeError, "%.150s%s takes %s %d argument%s (%ld given)", fname==NULL ? "function" : fname, fname==NULL ? "" : "()", min==max ? "exactly" - : len < min ? "at least" : "at most", - len < min ? min : max, - (len < min ? min : max) == 1 ? "" : "s", - Py_SAFE_DOWNCAST(len, Py_ssize_t, long)); + : nargs < min ? "at least" : "at most", + nargs < min ? min : max, + (nargs < min ? min : max) == 1 ? "" : "s", + Py_SAFE_DOWNCAST(nargs, Py_ssize_t, long)); else PyErr_SetString(PyExc_TypeError, message); return cleanreturn(0, &freelist); } - for (i = 0; i < len; i++) { + for (i = 0; i < nargs; i++) { if (*format == '|') format++; - msg = convertitem(PyTuple_GET_ITEM(args, i), &format, p_va, + msg = convertitem(stack[i], &format, p_va, flags, levels, msgbuf, sizeof(msgbuf), &freelist); if (msg) { @@ -382,6 +405,31 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags) return cleanreturn(1, &freelist); } +static int +vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags) +{ + PyObject **stack; + Py_ssize_t nargs; + + if (!(flags & FLAG_COMPAT)) { + assert(args != NULL); + + if (!PyTuple_Check(args)) { + PyErr_SetString(PyExc_SystemError, + "new style getargs format but argument is not a tuple"); + return 0; + } + + stack = &PyTuple_GET_ITEM(args, 0); + nargs = PyTuple_GET_SIZE(args); + } + else { + stack = NULL; + nargs = 0; + } + + return vgetargs1_impl(args, stack, nargs, format, p_va, flags); +} static void -- cgit v1.2.1 From 314561ad8463212043ac4a61f44a8ba9e5784390 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 17 Jan 2017 01:40:01 +0100 Subject: Add _PyArg_NoStackKeywords() helper function Issue #29286. Similar to _PyArg_NoKeywords(), but expects a tuple of keyword names, instead of a dict. --- Python/getargs.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) (limited to 'Python/getargs.c') diff --git a/Python/getargs.c b/Python/getargs.c index 35500d7e7d..e3611d8153 100644 --- a/Python/getargs.c +++ b/Python/getargs.c @@ -2429,16 +2429,33 @@ PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t m * not empty, returns 1 otherwise */ int -_PyArg_NoKeywords(const char *funcname, PyObject *kw) +_PyArg_NoKeywords(const char *funcname, PyObject *kwargs) { - if (kw == NULL) + if (kwargs == NULL) return 1; - if (!PyDict_CheckExact(kw)) { + if (!PyDict_CheckExact(kwargs)) { PyErr_BadInternalCall(); return 0; } - if (PyDict_GET_SIZE(kw) == 0) + if (PyDict_GET_SIZE(kwargs) == 0) { return 1; + } + + PyErr_Format(PyExc_TypeError, "%s does not take keyword arguments", + funcname); + return 0; +} + + +int +_PyArg_NoStackKeywords(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 does not take keyword arguments", funcname); -- cgit v1.2.1 From 1dde4af8a283e03ccfe2766c9cfd1a4d0a983d65 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 17 Jan 2017 02:33:55 +0100 Subject: Add _PyArg_UnpackStack() function helper Issue #29286. --- Python/getargs.c | 73 ++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 55 insertions(+), 18 deletions(-) (limited to 'Python/getargs.c') diff --git a/Python/getargs.c b/Python/getargs.c index e3611d8153..47b00af442 100644 --- a/Python/getargs.c +++ b/Python/getargs.c @@ -2363,21 +2363,16 @@ err: } -int -PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, ...) +static int +PyArg_UnpackStack_impl(PyObject **args, Py_ssize_t l, const char *name, + Py_ssize_t min, Py_ssize_t max, va_list vargs) { - Py_ssize_t i, l; + Py_ssize_t i; PyObject **o; - va_list vargs; assert(min >= 0); assert(min <= max); - if (!PyTuple_Check(args)) { - PyErr_SetString(PyExc_SystemError, - "PyArg_UnpackTuple() argument list is not a tuple"); - return 0; - } - l = PyTuple_GET_SIZE(args); + if (l < min) { if (name != NULL) PyErr_Format( @@ -2392,8 +2387,11 @@ PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t m (min == max ? "" : "at least "), min, l); return 0; } - if (l == 0) + + if (l == 0) { return 1; + } + if (l > max) { if (name != NULL) PyErr_Format( @@ -2409,17 +2407,54 @@ PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t m return 0; } + for (i = 0; i < l; i++) { + o = va_arg(vargs, PyObject **); + *o = args[i]; + } + return 1; +} + +int +PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, ...) +{ + PyObject **stack; + Py_ssize_t nargs; + int retval; + va_list vargs; + + if (!PyTuple_Check(args)) { + PyErr_SetString(PyExc_SystemError, + "PyArg_UnpackTuple() argument list is not a tuple"); + return 0; + } + stack = &PyTuple_GET_ITEM(args, 0); + nargs = PyTuple_GET_SIZE(args); + #ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, max); #else va_start(vargs); #endif - for (i = 0; i < l; i++) { - o = va_arg(vargs, PyObject **); - *o = PyTuple_GET_ITEM(args, i); - } + retval = PyArg_UnpackStack_impl(stack, nargs, name, min, max, vargs); va_end(vargs); - return 1; + return retval; +} + +int +_PyArg_UnpackStack(PyObject **args, Py_ssize_t nargs, const char *name, + Py_ssize_t min, Py_ssize_t max, ...) +{ + int retval; + va_list vargs; + +#ifdef HAVE_STDARG_PROTOTYPES + va_start(vargs, max); +#else + va_start(vargs); +#endif + retval = PyArg_UnpackStack_impl(args, nargs, name, min, max, vargs); + va_end(vargs); + return retval; } @@ -2431,8 +2466,9 @@ PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t m int _PyArg_NoKeywords(const char *funcname, PyObject *kwargs) { - if (kwargs == NULL) + if (kwargs == NULL) { return 1; + } if (!PyDict_CheckExact(kwargs)) { PyErr_BadInternalCall(); return 0; @@ -2450,8 +2486,9 @@ _PyArg_NoKeywords(const char *funcname, PyObject *kwargs) int _PyArg_NoStackKeywords(const char *funcname, PyObject *kwnames) { - if (kwnames == NULL) + if (kwnames == NULL) { return 1; + } assert(PyTuple_CheckExact(kwnames)); if (PyTuple_GET_SIZE(kwnames) == 0) { return 1; -- cgit v1.2.1 From 0ce0c38a1af6d4b6e5bad17ef443df75edb97b0c Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Tue, 17 Jan 2017 10:07:25 +0200 Subject: Issue #29029: Speed up processing positional arguments in PyArg_ParseTupleAndKeywords(), _PyArg_ParseTupleAndKeywordsFast() and like. --- Python/getargs.c | 190 ++++++++++++++++++++++++++----------------------------- 1 file changed, 89 insertions(+), 101 deletions(-) (limited to 'Python/getargs.c') diff --git a/Python/getargs.c b/Python/getargs.c index 47b00af442..e3be6d9280 100644 --- a/Python/getargs.c +++ b/Python/getargs.c @@ -1598,7 +1598,7 @@ vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format, { char msgbuf[512]; int levels[32]; - const char *fname, *msg, *custom_msg, *keyword; + const char *fname, *msg, *custom_msg; int min = INT_MAX; int max = INT_MAX; int i, pos, len; @@ -1666,7 +1666,6 @@ vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format, /* convert tuple args and keyword args in same loop, using kwlist to drive process */ for (i = 0; i < len; i++) { - keyword = kwlist[i]; if (*format == '|') { if (min != INT_MAX) { PyErr_SetString(PyExc_SystemError, @@ -1720,26 +1719,17 @@ vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format, return cleanreturn(0, &freelist); } if (!skip) { - current_arg = NULL; - if (nkwargs && i >= pos) { - current_arg = PyDict_GetItemString(kwargs, keyword); - if (!current_arg && PyErr_Occurred()) { - return cleanreturn(0, &freelist); - } + if (i < nargs) { + current_arg = PyTuple_GET_ITEM(args, i); } - if (current_arg) { - --nkwargs; - if (i < nargs) { - /* arg present in tuple and in dict */ - PyErr_Format(PyExc_TypeError, - "Argument given by name ('%s') " - "and position (%d)", - keyword, i+1); - return cleanreturn(0, &freelist); - } + else if (nkwargs && i >= pos) { + current_arg = PyDict_GetItemString(kwargs, kwlist[i]); + if (current_arg) + --nkwargs; + } + else { + current_arg = NULL; } - else if (i < nargs) - current_arg = PyTuple_GET_ITEM(args, i); if (current_arg) { msg = convertitem(current_arg, &format, p_va, flags, @@ -1763,8 +1753,8 @@ vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format, } else { PyErr_Format(PyExc_TypeError, "Required argument " - "'%s' (pos %d) not found", - keyword, i+1); + "'%s' (pos %d) not found", + kwlist[i], i+1); return cleanreturn(0, &freelist); } } @@ -1803,19 +1793,32 @@ vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format, return cleanreturn(0, &freelist); } - /* make sure there are no extraneous keyword arguments */ if (nkwargs > 0) { - PyObject *key, *value; - Py_ssize_t pos = 0; - while (PyDict_Next(kwargs, &pos, &key, &value)) { + PyObject *key; + Py_ssize_t j; + /* make sure there are no arguments given by name and position */ + for (i = pos; i < nargs; i++) { + current_arg = PyDict_GetItemString(kwargs, kwlist[i]); + if (current_arg) { + /* arg present in tuple and in dict */ + PyErr_Format(PyExc_TypeError, + "Argument given by name ('%s') " + "and position (%d)", + kwlist[i], i+1); + return cleanreturn(0, &freelist); + } + } + /* make sure there are no extraneous keyword arguments */ + j = 0; + while (PyDict_Next(kwargs, &j, &key, NULL)) { int match = 0; if (!PyUnicode_Check(key)) { PyErr_SetString(PyExc_TypeError, "keywords must be strings"); return cleanreturn(0, &freelist); } - for (i = 0; i < len; i++) { - if (*kwlist[i] && _PyUnicode_EqualToASCIIString(key, kwlist[i])) { + for (i = pos; i < len; i++) { + if (_PyUnicode_EqualToASCIIString(key, kwlist[i])) { match = 1; break; } @@ -1963,10 +1966,13 @@ parser_clear(struct _PyArg_Parser *parser) } static PyObject* -find_keyword(PyObject *kwnames, PyObject **kwstack, PyObject *key) +find_keyword(PyObject *kwargs, PyObject *kwnames, PyObject **kwstack, PyObject *key) { Py_ssize_t i, nkwargs; + if (kwargs != NULL) { + return PyDict_GetItem(kwargs, key); + } nkwargs = PyTuple_GET_SIZE(kwnames); for (i=0; i < nkwargs; i++) { PyObject *kwname = PyTuple_GET_ITEM(kwnames, i); @@ -1978,7 +1984,7 @@ find_keyword(PyObject *kwnames, PyObject **kwstack, PyObject *key) } if (!PyUnicode_Check(kwname)) { /* ignore non-string keyword keys: - an error will be raised above */ + an error will be raised below */ continue; } if (_PyUnicode_EQ(kwname, key)) { @@ -2012,8 +2018,7 @@ vgetargskeywordsfast_impl(PyObject **args, Py_ssize_t nargs, freelist.entries_malloced = 0; assert(kwargs == NULL || PyDict_Check(kwargs)); - assert((kwargs != NULL || kwnames != NULL) - || (kwargs == NULL && kwnames == NULL)); + assert(kwargs == NULL || kwnames == NULL); assert(p_va != NULL); if (parser == NULL) { @@ -2074,7 +2079,6 @@ vgetargskeywordsfast_impl(PyObject **args, Py_ssize_t nargs, format = parser->format; /* convert tuple args and keyword args in same loop, using kwtuple to drive process */ for (i = 0; i < len; i++) { - keyword = (i >= pos) ? PyTuple_GET_ITEM(kwtuple, i - pos) : NULL; if (*format == '|') { format++; } @@ -2083,31 +2087,17 @@ vgetargskeywordsfast_impl(PyObject **args, Py_ssize_t nargs, } assert(!IS_END_OF_FORMAT(*format)); - current_arg = NULL; - if (nkwargs && i >= pos) { - if (kwargs != NULL) { - current_arg = PyDict_GetItem(kwargs, keyword); - if (!current_arg && PyErr_Occurred()) { - return cleanreturn(0, &freelist); - } - } - else { - current_arg = find_keyword(kwnames, kwstack, keyword); - } + if (i < nargs) { + current_arg = args[i]; } - if (current_arg) { - --nkwargs; - if (i < nargs) { - /* arg present in tuple and in dict */ - PyErr_Format(PyExc_TypeError, - "Argument given by name ('%U') " - "and position (%d)", - keyword, i+1); - return cleanreturn(0, &freelist); - } + else if (nkwargs && i >= pos) { + keyword = PyTuple_GET_ITEM(kwtuple, i - pos); + current_arg = find_keyword(kwargs, kwnames, kwstack, keyword); + if (current_arg) + --nkwargs; } - else if (i < nargs) { - current_arg = args[i]; + else { + current_arg = NULL; } if (current_arg) { @@ -2123,13 +2113,15 @@ vgetargskeywordsfast_impl(PyObject **args, Py_ssize_t nargs, if (i < parser->min) { /* Less arguments than required */ if (i < pos) { + Py_ssize_t min = Py_MIN(pos, parser->min); PyErr_Format(PyExc_TypeError, "Function takes %s %d positional arguments" " (%d given)", - (Py_MIN(pos, parser->min) < parser->max) ? "at least" : "exactly", - Py_MIN(pos, parser->min), nargs); + min < parser->max ? "at least" : "exactly", + min, nargs); } else { + keyword = PyTuple_GET_ITEM(kwtuple, i - pos); PyErr_Format(PyExc_TypeError, "Required argument " "'%U' (pos %d) not found", keyword, i+1); @@ -2152,54 +2144,50 @@ vgetargskeywordsfast_impl(PyObject **args, Py_ssize_t nargs, assert(IS_END_OF_FORMAT(*format) || (*format == '|') || (*format == '$')); - /* make sure there are no extraneous keyword arguments */ if (nkwargs > 0) { - if (kwargs != NULL) { - PyObject *key, *value; - Py_ssize_t pos = 0; - while (PyDict_Next(kwargs, &pos, &key, &value)) { - int match; - if (!PyUnicode_Check(key)) { - PyErr_SetString(PyExc_TypeError, - "keywords must be strings"); - return cleanreturn(0, &freelist); - } - match = PySequence_Contains(kwtuple, key); - if (match <= 0) { - if (!match) { - PyErr_Format(PyExc_TypeError, - "'%U' is an invalid keyword " - "argument for this function", - key); - } - return cleanreturn(0, &freelist); - } + Py_ssize_t j; + /* make sure there are no arguments given by name and position */ + for (i = pos; i < nargs; i++) { + keyword = PyTuple_GET_ITEM(kwtuple, i - pos); + current_arg = find_keyword(kwargs, kwnames, kwstack, keyword); + if (current_arg) { + /* arg present in tuple and in dict */ + PyErr_Format(PyExc_TypeError, + "Argument given by name ('%U') " + "and position (%d)", + keyword, i+1); + return cleanreturn(0, &freelist); } } - else { - Py_ssize_t j, nkwargs; - - nkwargs = PyTuple_GET_SIZE(kwnames); - for (j=0; j < nkwargs; j++) { - PyObject *key = PyTuple_GET_ITEM(kwnames, j); - int match; - - if (!PyUnicode_Check(key)) { - PyErr_SetString(PyExc_TypeError, - "keywords must be strings"); - return cleanreturn(0, &freelist); - } + /* make sure there are no extraneous keyword arguments */ + j = 0; + while (1) { + int match; + if (kwargs != NULL) { + if (!PyDict_Next(kwargs, &j, &keyword, NULL)) + break; + } + else { + if (j >= PyTuple_GET_SIZE(kwnames)) + break; + keyword = PyTuple_GET_ITEM(kwnames, j); + j++; + } - match = PySequence_Contains(kwtuple, key); - if (match <= 0) { - if (!match) { - PyErr_Format(PyExc_TypeError, - "'%U' is an invalid keyword " - "argument for this function", - key); - } - return cleanreturn(0, &freelist); + if (!PyUnicode_Check(keyword)) { + PyErr_SetString(PyExc_TypeError, + "keywords must be strings"); + return cleanreturn(0, &freelist); + } + match = PySequence_Contains(kwtuple, keyword); + if (match <= 0) { + if (!match) { + PyErr_Format(PyExc_TypeError, + "'%U' is an invalid keyword " + "argument for this function", + keyword); } + return cleanreturn(0, &freelist); } } } -- cgit v1.2.1 From f4bb50d8e1bc9fb5eee226b901838ce9c399824e Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 1 Feb 2017 17:42:18 +0100 Subject: Issue #29286: Rename private PyArg_UnpackStack_impl() to unpack_stack() Rename also "l" argument to "nargs". --- Python/getargs.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'Python/getargs.c') diff --git a/Python/getargs.c b/Python/getargs.c index e3be6d9280..952a662ecf 100644 --- a/Python/getargs.c +++ b/Python/getargs.c @@ -2352,8 +2352,8 @@ err: static int -PyArg_UnpackStack_impl(PyObject **args, Py_ssize_t l, const char *name, - Py_ssize_t min, Py_ssize_t max, va_list vargs) +unpack_stack(PyObject **args, Py_ssize_t nargs, const char *name, + Py_ssize_t min, Py_ssize_t max, va_list vargs) { Py_ssize_t i; PyObject **o; @@ -2361,41 +2361,41 @@ PyArg_UnpackStack_impl(PyObject **args, Py_ssize_t l, const char *name, assert(min >= 0); assert(min <= max); - if (l < min) { + if (nargs < min) { if (name != NULL) PyErr_Format( PyExc_TypeError, "%s expected %s%zd arguments, got %zd", - name, (min == max ? "" : "at least "), min, l); + name, (min == max ? "" : "at least "), min, nargs); else PyErr_Format( PyExc_TypeError, "unpacked tuple should have %s%zd elements," " but has %zd", - (min == max ? "" : "at least "), min, l); + (min == max ? "" : "at least "), min, nargs); return 0; } - if (l == 0) { + if (nargs == 0) { return 1; } - if (l > max) { + if (nargs > max) { if (name != NULL) PyErr_Format( PyExc_TypeError, "%s expected %s%zd arguments, got %zd", - name, (min == max ? "" : "at most "), max, l); + name, (min == max ? "" : "at most "), max, nargs); else PyErr_Format( PyExc_TypeError, "unpacked tuple should have %s%zd elements," " but has %zd", - (min == max ? "" : "at most "), max, l); + (min == max ? "" : "at most "), max, nargs); return 0; } - for (i = 0; i < l; i++) { + for (i = 0; i < nargs; i++) { o = va_arg(vargs, PyObject **); *o = args[i]; } @@ -2423,7 +2423,7 @@ PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t m #else va_start(vargs); #endif - retval = PyArg_UnpackStack_impl(stack, nargs, name, min, max, vargs); + retval = unpack_stack(stack, nargs, name, min, max, vargs); va_end(vargs); return retval; } @@ -2440,7 +2440,7 @@ _PyArg_UnpackStack(PyObject **args, Py_ssize_t nargs, const char *name, #else va_start(vargs); #endif - retval = PyArg_UnpackStack_impl(args, nargs, name, min, max, vargs); + retval = unpack_stack(args, nargs, name, min, max, vargs); va_end(vargs); return retval; } -- cgit v1.2.1 From 54ab9ca906471f8a49e22c7f85d4f34c2ef7212c Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 6 Feb 2017 10:41:46 +0200 Subject: Issue #29460: _PyArg_NoKeywords(), _PyArg_NoStackKeywords() and _PyArg_NoPositional() now are macros. --- Python/getargs.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'Python/getargs.c') diff --git a/Python/getargs.c b/Python/getargs.c index 952a662ecf..8cb672d6ab 100644 --- a/Python/getargs.c +++ b/Python/getargs.c @@ -2446,6 +2446,10 @@ _PyArg_UnpackStack(PyObject **args, Py_ssize_t nargs, const char *name, } +#undef _PyArg_NoKeywords +#undef _PyArg_NoStackKeywords +#undef _PyArg_NoPositional + /* For type constructors that don't take keyword args * * Sets a TypeError and returns 0 if the args/kwargs is -- cgit v1.2.1