@@ -26,6 +26,8 @@ int _PyArg_VaParseTupleAndKeywordsFast(PyObject *, PyObject *,
2626#ifdef HAVE_DECLSPEC_DLL
2727/* Export functions */
2828PyAPI_FUNC (int ) _PyArg_Parse_SizeT (PyObject * , const char * , ...);
29+ PyAPI_FUNC (int ) _PyArg_ParseStack_SizeT (PyObject * * args , Py_ssize_t nargs ,
30+ const char * format , ...);
2931PyAPI_FUNC (int ) _PyArg_ParseStackAndKeywords_SizeT (PyObject * * args , Py_ssize_t nargs , PyObject * kwnames ,
3032 struct _PyArg_Parser * parser , ...);
3133PyAPI_FUNC (int ) _PyArg_ParseTuple_SizeT (PyObject * , const char * , ...);
@@ -66,6 +68,8 @@ typedef struct {
6668#define STATIC_FREELIST_ENTRIES 8
6769
6870/* Forward */
71+ static int vgetargs1_impl (PyObject * args , PyObject * * stack , Py_ssize_t nargs ,
72+ const char * format , va_list * p_va , int flags );
6973static int vgetargs1 (PyObject * , const char * , va_list * , int );
7074static void seterror (Py_ssize_t , const char * , int * , const char * , const char * );
7175static const char * convertitem (PyObject * , const char * * , va_list * , int , int * ,
@@ -137,6 +141,31 @@ _PyArg_ParseTuple_SizeT(PyObject *args, const char *format, ...)
137141}
138142
139143
144+ int
145+ _PyArg_ParseStack (PyObject * * args , Py_ssize_t nargs , const char * format , ...)
146+ {
147+ int retval ;
148+ va_list va ;
149+
150+ va_start (va , format );
151+ retval = vgetargs1_impl (NULL , args , nargs , format , & va , 0 );
152+ va_end (va );
153+ return retval ;
154+ }
155+
156+ int
157+ _PyArg_ParseStack_SizeT (PyObject * * args , Py_ssize_t nargs , const char * format , ...)
158+ {
159+ int retval ;
160+ va_list va ;
161+
162+ va_start (va , format );
163+ retval = vgetargs1_impl (NULL , args , nargs , format , & va , FLAG_SIZE_T );
164+ va_end (va );
165+ return retval ;
166+ }
167+
168+
140169int
141170PyArg_VaParse (PyObject * args , const char * format , va_list va )
142171{
@@ -220,7 +249,8 @@ cleanreturn(int retval, freelist_t *freelist)
220249
221250
222251static int
223- vgetargs1 (PyObject * args , const char * format , va_list * p_va , int flags )
252+ vgetargs1_impl (PyObject * compat_args , PyObject * * stack , Py_ssize_t nargs , const char * format ,
253+ va_list * p_va , int flags )
224254{
225255 char msgbuf [256 ];
226256 int levels [32 ];
@@ -231,17 +261,18 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
231261 int level = 0 ;
232262 int endfmt = 0 ;
233263 const char * formatsave = format ;
234- Py_ssize_t i , len ;
264+ Py_ssize_t i ;
235265 const char * msg ;
236266 int compat = flags & FLAG_COMPAT ;
237267 freelistentry_t static_entries [STATIC_FREELIST_ENTRIES ];
238268 freelist_t freelist ;
239269
270+ assert (nargs == 0 || stack != NULL );
271+
240272 freelist .entries = static_entries ;
241273 freelist .first_available = 0 ;
242274 freelist .entries_malloced = 0 ;
243275
244- assert (compat || (args != (PyObject * )NULL ));
245276 flags = flags & ~FLAG_COMPAT ;
246277
247278 while (endfmt == 0 ) {
@@ -305,7 +336,7 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
305336
306337 if (compat ) {
307338 if (max == 0 ) {
308- if (args == NULL )
339+ if (compat_args == NULL )
309340 return 1 ;
310341 PyErr_Format (PyExc_TypeError ,
311342 "%.200s%s takes no arguments" ,
@@ -314,14 +345,14 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
314345 return cleanreturn (0 , & freelist );
315346 }
316347 else if (min == 1 && max == 1 ) {
317- if (args == NULL ) {
348+ if (compat_args == NULL ) {
318349 PyErr_Format (PyExc_TypeError ,
319350 "%.200s%s takes at least one argument" ,
320351 fname == NULL ? "function" : fname ,
321352 fname == NULL ? "" : "()" );
322353 return cleanreturn (0 , & freelist );
323354 }
324- msg = convertitem (args , & format , p_va , flags , levels ,
355+ msg = convertitem (compat_args , & format , p_va , flags , levels ,
325356 msgbuf , sizeof (msgbuf ), & freelist );
326357 if (msg == NULL )
327358 return cleanreturn (1 , & freelist );
@@ -335,34 +366,26 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
335366 }
336367 }
337368
338- if (!PyTuple_Check (args )) {
339- PyErr_SetString (PyExc_SystemError ,
340- "new style getargs format but argument is not a tuple" );
341- return cleanreturn (0 , & freelist );
342- }
343-
344- len = PyTuple_GET_SIZE (args );
345-
346- if (len < min || max < len ) {
369+ if (nargs < min || max < nargs ) {
347370 if (message == NULL )
348371 PyErr_Format (PyExc_TypeError ,
349372 "%.150s%s takes %s %d argument%s (%ld given)" ,
350373 fname == NULL ? "function" : fname ,
351374 fname == NULL ? "" : "()" ,
352375 min == max ? "exactly"
353- : len < min ? "at least" : "at most" ,
354- len < min ? min : max ,
355- (len < min ? min : max ) == 1 ? "" : "s" ,
356- Py_SAFE_DOWNCAST (len , Py_ssize_t , long ));
376+ : nargs < min ? "at least" : "at most" ,
377+ nargs < min ? min : max ,
378+ (nargs < min ? min : max ) == 1 ? "" : "s" ,
379+ Py_SAFE_DOWNCAST (nargs , Py_ssize_t , long ));
357380 else
358381 PyErr_SetString (PyExc_TypeError , message );
359382 return cleanreturn (0 , & freelist );
360383 }
361384
362- for (i = 0 ; i < len ; i ++ ) {
385+ for (i = 0 ; i < nargs ; i ++ ) {
363386 if (* format == '|' )
364387 format ++ ;
365- msg = convertitem (PyTuple_GET_ITEM ( args , i ) , & format , p_va ,
388+ msg = convertitem (stack [ i ] , & format , p_va ,
366389 flags , levels , msgbuf ,
367390 sizeof (msgbuf ), & freelist );
368391 if (msg ) {
@@ -382,6 +405,31 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
382405 return cleanreturn (1 , & freelist );
383406}
384407
408+ static int
409+ vgetargs1 (PyObject * args , const char * format , va_list * p_va , int flags )
410+ {
411+ PyObject * * stack ;
412+ Py_ssize_t nargs ;
413+
414+ if (!(flags & FLAG_COMPAT )) {
415+ assert (args != NULL );
416+
417+ if (!PyTuple_Check (args )) {
418+ PyErr_SetString (PyExc_SystemError ,
419+ "new style getargs format but argument is not a tuple" );
420+ return 0 ;
421+ }
422+
423+ stack = & PyTuple_GET_ITEM (args , 0 );
424+ nargs = PyTuple_GET_SIZE (args );
425+ }
426+ else {
427+ stack = NULL ;
428+ nargs = 0 ;
429+ }
430+
431+ return vgetargs1_impl (args , stack , nargs , format , p_va , flags );
432+ }
385433
386434
387435static void
0 commit comments