cpython: 01c57ef1b651 (original) (raw)
--- a/Include/modsupport.h +++ b/Include/modsupport.h @@ -79,17 +79,27 @@ typedef struct _PyArg_Parser { } _PyArg_Parser; #ifdef PY_SSIZE_T_CLEAN #define _PyArg_ParseTupleAndKeywordsFast _PyArg_ParseTupleAndKeywordsFast_SizeT +#define _PyArg_ParseStack _PyArg_ParseStack_SizeT #define _PyArg_ParseStackAndKeywords _PyArg_ParseStackAndKeywords_SizeT #define _PyArg_VaParseTupleAndKeywordsFast _PyArg_VaParseTupleAndKeywordsFast_SizeT #endif PyAPI_FUNC(int) _PyArg_ParseTupleAndKeywordsFast(PyObject *, PyObject *, struct _PyArg_Parser *, ...); -PyAPI_FUNC(int) _PyArg_ParseStackAndKeywords(PyObject **args, Py_ssize_t nargs, PyObject *kwnames,
struct _PyArg_Parser *, ...);[](#l1.14)
+PyAPI_FUNC(int) _PyArg_ParseStack(
+PyAPI_FUNC(int) _PyArg_ParseStackAndKeywords(
PyAPI_FUNC(int) _PyArg_VaParseTupleAndKeywordsFast(PyObject *, PyObject *, struct _PyArg_Parser , va_list); void _PyArg_Fini(void); -#endif +#endif / Py_LIMITED_API */ PyAPI_FUNC(int) PyModule_AddObject(PyObject *, const char *, PyObject *); PyAPI_FUNC(int) PyModule_AddIntConstant(PyObject *, const char *, long);
--- a/Python/getargs.c +++ b/Python/getargs.c @@ -26,6 +26,8 @@ int _PyArg_VaParseTupleAndKeywordsFast(P #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, ...);[](#l2.8)
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);[](#l2.17)
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 *, @@ -138,6 +142,31 @@ int int +_PyArg_ParseStack(PyObject **args, Py_ssize_t nargs, const char *format, ...) +{
- 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, ...) +{
- 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 *free 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)[](#l2.59)
{ char msgbuf[256]; int levels[32]; @@ -231,17 +261,18 @@ vgetargs1(PyObject *args, const char *fo int level = 0; int endfmt = 0; const char *formatsave = format;
- 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 *fo if (compat) { if (max == 0) {
if (args == NULL)[](#l2.88)
if (compat_args == NULL)[](#l2.89) return 1;[](#l2.90) PyErr_Format(PyExc_TypeError,[](#l2.91) "%.200s%s takes no arguments",[](#l2.92)
@@ -314,14 +345,14 @@ vgetargs1(PyObject *args, const char *fo return cleanreturn(0, &freelist); } else if (min == 1 && max == 1) {
if (args == NULL) {[](#l2.97)
if (compat_args == NULL) {[](#l2.98) PyErr_Format(PyExc_TypeError,[](#l2.99) "%.200s%s takes at least one argument",[](#l2.100) fname==NULL ? "function" : fname,[](#l2.101) fname==NULL ? "" : "()");[](#l2.102) return cleanreturn(0, &freelist);[](#l2.103) }[](#l2.104)
msg = convertitem(args, &format, p_va, flags, levels,[](#l2.105)
msg = convertitem(compat_args, &format, p_va, flags, levels,[](#l2.106) msgbuf, sizeof(msgbuf), &freelist);[](#l2.107) if (msg == NULL)[](#l2.108) return cleanreturn(1, &freelist);[](#l2.109)
@@ -335,34 +366,26 @@ vgetargs1(PyObject *args, const char *fo } }
- if (!PyTuple_Check(args)) {
PyErr_SetString(PyExc_SystemError,[](#l2.115)
"new style getargs format but argument is not a tuple");[](#l2.116)
return cleanreturn(0, &freelist);[](#l2.117)
- }
- 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",[](#l2.130)
len < min ? min : max,[](#l2.131)
(len < min ? min : max) == 1 ? "" : "s",[](#l2.132)
Py_SAFE_DOWNCAST(len, Py_ssize_t, long));[](#l2.133)
: nargs < min ? "at least" : "at most",[](#l2.134)
nargs < min ? min : max,[](#l2.135)
(nargs < min ? min : max) == 1 ? "" : "s",[](#l2.136)
}Py_SAFE_DOWNCAST(nargs, Py_ssize_t, long));[](#l2.137) else[](#l2.138) PyErr_SetString(PyExc_TypeError, message);[](#l2.139) return cleanreturn(0, &freelist);[](#l2.140)
msg = convertitem(PyTuple_GET_ITEM(args, i), &format, p_va,[](#l2.147)
msg = convertitem(stack[i], &format, p_va,[](#l2.148) flags, levels, msgbuf,[](#l2.149) sizeof(msgbuf), &freelist);[](#l2.150) if (msg) {[](#l2.151)
@@ -382,6 +405,31 @@ vgetargs1(PyObject *args, const char *fo return cleanreturn(1, &freelist); } +static int +vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags) +{
if (!PyTuple_Check(args)) {[](#l2.165)
PyErr_SetString(PyExc_SystemError,[](#l2.166)
"new style getargs format but argument is not a tuple");[](#l2.167)
return 0;[](#l2.168)
}[](#l2.169)