diff options
Diffstat (limited to 'Python/getargs.c')
-rw-r--r-- | Python/getargs.c | 345 |
1 files changed, 210 insertions, 135 deletions
diff --git a/Python/getargs.c b/Python/getargs.c index 616c6eb107..47b00af442 100644 --- a/Python/getargs.c +++ b/Python/getargs.c @@ -26,7 +26,9 @@ 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_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 *, ...); PyAPI_FUNC(int) _PyArg_ParseTupleAndKeywords_SizeT(PyObject *, PyObject *, @@ -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 *, @@ -74,7 +78,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 *, @@ -138,6 +142,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) { va_list lva; @@ -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 @@ -625,7 +673,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 +945,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 +976,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 +991,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 +1018,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; @@ -1027,7 +1075,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 +1122,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 */ @@ -1300,7 +1353,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; @@ -1448,14 +1501,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); @@ -1469,14 +1514,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); @@ -1484,19 +1521,12 @@ _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; 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); @@ -1504,19 +1534,12 @@ _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; 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); @@ -1531,14 +1554,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); @@ -1553,14 +1568,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); @@ -1586,7 +1593,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]; @@ -1596,7 +1603,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; @@ -1606,7 +1613,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); @@ -1645,15 +1652,15 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format, } nargs = PyTuple_GET_SIZE(args); - nkeywords = (keywords == NULL) ? 0 : PyDict_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); } @@ -1714,14 +1721,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, @@ -1765,7 +1772,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); } } @@ -1797,10 +1804,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, @@ -1983,7 +1990,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) { @@ -1994,7 +2001,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; @@ -2004,13 +2011,21 @@ vgetargskeywordsfast_impl(PyObject **args, Py_ssize_t nargs, freelist.first_available = 0; 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(kwargs == NULL || PyDict_Check(kwargs)); + assert((kwargs != NULL || kwnames != NULL) + || (kwargs == NULL && kwnames == 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; } @@ -2028,24 +2043,24 @@ vgetargskeywordsfast_impl(PyObject **args, Py_ssize_t nargs, freelist.entries_malloced = 1; } - if (keywords != NULL) { - nkeywords = PyDict_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) { @@ -2069,9 +2084,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); } @@ -2081,7 +2096,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, @@ -2125,7 +2140,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); } @@ -2138,11 +2153,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, @@ -2199,7 +2214,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); @@ -2342,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( @@ -2371,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( @@ -2388,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; } @@ -2408,16 +2464,35 @@ 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_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); |