LCOV - code coverage report
Current view: top level - Python - getargs.c (source / functions) Hit Total Coverage
Test: CPython lcov report Lines: 1084 1367 79.3 %
Date: 2022-07-07 18:19:46 Functions: 38 50 76.0 %

          Line data    Source code
       1             : 
       2             : /* New getargs implementation */
       3             : 
       4             : #include "Python.h"
       5             : #include "pycore_tuple.h"         // _PyTuple_ITEMS()
       6             : #include "pycore_pylifecycle.h"   // _PyArg_Fini
       7             : 
       8             : #include <ctype.h>
       9             : #include <float.h>
      10             : 
      11             : 
      12             : #ifdef __cplusplus
      13             : extern "C" {
      14             : #endif
      15             : int PyArg_Parse(PyObject *, const char *, ...);
      16             : int PyArg_ParseTuple(PyObject *, const char *, ...);
      17             : int PyArg_VaParse(PyObject *, const char *, va_list);
      18             : 
      19             : int PyArg_ParseTupleAndKeywords(PyObject *, PyObject *,
      20             :                                 const char *, char **, ...);
      21             : int PyArg_VaParseTupleAndKeywords(PyObject *, PyObject *,
      22             :                                 const char *, char **, va_list);
      23             : 
      24             : int _PyArg_ParseTupleAndKeywordsFast(PyObject *, PyObject *,
      25             :                                             struct _PyArg_Parser *, ...);
      26             : int _PyArg_VaParseTupleAndKeywordsFast(PyObject *, PyObject *,
      27             :                                             struct _PyArg_Parser *, va_list);
      28             : 
      29             : #ifdef HAVE_DECLSPEC_DLL
      30             : /* Export functions */
      31             : PyAPI_FUNC(int) _PyArg_Parse_SizeT(PyObject *, const char *, ...);
      32             : PyAPI_FUNC(int) _PyArg_ParseStack_SizeT(PyObject *const *args, Py_ssize_t nargs,
      33             :                                         const char *format, ...);
      34             : PyAPI_FUNC(int) _PyArg_ParseStackAndKeywords_SizeT(PyObject *const *args, Py_ssize_t nargs,
      35             :                                         PyObject *kwnames,
      36             :                                         struct _PyArg_Parser *parser, ...);
      37             : PyAPI_FUNC(int) _PyArg_ParseTuple_SizeT(PyObject *, const char *, ...);
      38             : PyAPI_FUNC(int) _PyArg_ParseTupleAndKeywords_SizeT(PyObject *, PyObject *,
      39             :                                                   const char *, char **, ...);
      40             : PyAPI_FUNC(PyObject *) _Py_BuildValue_SizeT(const char *, ...);
      41             : PyAPI_FUNC(int) _PyArg_VaParse_SizeT(PyObject *, const char *, va_list);
      42             : PyAPI_FUNC(int) _PyArg_VaParseTupleAndKeywords_SizeT(PyObject *, PyObject *,
      43             :                                               const char *, char **, va_list);
      44             : 
      45             : PyAPI_FUNC(int) _PyArg_ParseTupleAndKeywordsFast_SizeT(PyObject *, PyObject *,
      46             :                                             struct _PyArg_Parser *, ...);
      47             : PyAPI_FUNC(int) _PyArg_VaParseTupleAndKeywordsFast_SizeT(PyObject *, PyObject *,
      48             :                                             struct _PyArg_Parser *, va_list);
      49             : #endif
      50             : 
      51             : #define FLAG_COMPAT 1
      52             : #define FLAG_SIZE_T 2
      53             : 
      54             : typedef int (*destr_t)(PyObject *, void *);
      55             : 
      56             : 
      57             : /* Keep track of "objects" that have been allocated or initialized and
      58             :    which will need to be deallocated or cleaned up somehow if overall
      59             :    parsing fails.
      60             : */
      61             : typedef struct {
      62             :   void *item;
      63             :   destr_t destructor;
      64             : } freelistentry_t;
      65             : 
      66             : typedef struct {
      67             :   freelistentry_t *entries;
      68             :   int first_available;
      69             :   int entries_malloced;
      70             : } freelist_t;
      71             : 
      72             : #define STATIC_FREELIST_ENTRIES 8
      73             : 
      74             : /* Forward */
      75             : static int vgetargs1_impl(PyObject *args, PyObject *const *stack, Py_ssize_t nargs,
      76             :                           const char *format, va_list *p_va, int flags);
      77             : static int vgetargs1(PyObject *, const char *, va_list *, int);
      78             : static void seterror(Py_ssize_t, const char *, int *, const char *, const char *);
      79             : static const char *convertitem(PyObject *, const char **, va_list *, int, int *,
      80             :                                char *, size_t, freelist_t *);
      81             : static const char *converttuple(PyObject *, const char **, va_list *, int,
      82             :                                 int *, char *, size_t, int, freelist_t *);
      83             : static const char *convertsimple(PyObject *, const char **, va_list *, int,
      84             :                                  char *, size_t, freelist_t *);
      85             : static Py_ssize_t convertbuffer(PyObject *, const void **p, const char **);
      86             : static int getbuffer(PyObject *, Py_buffer *, const char**);
      87             : 
      88             : static int vgetargskeywords(PyObject *, PyObject *,
      89             :                             const char *, char **, va_list *, int);
      90             : static int vgetargskeywordsfast(PyObject *, PyObject *,
      91             :                             struct _PyArg_Parser *, va_list *, int);
      92             : static int vgetargskeywordsfast_impl(PyObject *const *args, Py_ssize_t nargs,
      93             :                           PyObject *keywords, PyObject *kwnames,
      94             :                           struct _PyArg_Parser *parser,
      95             :                           va_list *p_va, int flags);
      96             : static const char *skipitem(const char **, va_list *, int);
      97             : 
      98             : int
      99           0 : PyArg_Parse(PyObject *args, const char *format, ...)
     100             : {
     101             :     int retval;
     102             :     va_list va;
     103             : 
     104           0 :     va_start(va, format);
     105           0 :     retval = vgetargs1(args, format, &va, FLAG_COMPAT);
     106           0 :     va_end(va);
     107           0 :     return retval;
     108             : }
     109             : 
     110             : PyAPI_FUNC(int)
     111     1937640 : _PyArg_Parse_SizeT(PyObject *args, const char *format, ...)
     112             : {
     113             :     int retval;
     114             :     va_list va;
     115             : 
     116     1937640 :     va_start(va, format);
     117     1937640 :     retval = vgetargs1(args, format, &va, FLAG_COMPAT|FLAG_SIZE_T);
     118     1937640 :     va_end(va);
     119     1937640 :     return retval;
     120             : }
     121             : 
     122             : 
     123             : int
     124     2009170 : PyArg_ParseTuple(PyObject *args, const char *format, ...)
     125             : {
     126             :     int retval;
     127             :     va_list va;
     128             : 
     129     2009170 :     va_start(va, format);
     130     2009170 :     retval = vgetargs1(args, format, &va, 0);
     131     2009170 :     va_end(va);
     132     2009170 :     return retval;
     133             : }
     134             : 
     135             : PyAPI_FUNC(int)
     136    16099800 : _PyArg_ParseTuple_SizeT(PyObject *args, const char *format, ...)
     137             : {
     138             :     int retval;
     139             :     va_list va;
     140             : 
     141    16099800 :     va_start(va, format);
     142    16099800 :     retval = vgetargs1(args, format, &va, FLAG_SIZE_T);
     143    16099800 :     va_end(va);
     144    16099800 :     return retval;
     145             : }
     146             : 
     147             : 
     148             : int
     149       67720 : _PyArg_ParseStack(PyObject *const *args, Py_ssize_t nargs, const char *format, ...)
     150             : {
     151             :     int retval;
     152             :     va_list va;
     153             : 
     154       67720 :     va_start(va, format);
     155       67720 :     retval = vgetargs1_impl(NULL, args, nargs, format, &va, 0);
     156       67720 :     va_end(va);
     157       67720 :     return retval;
     158             : }
     159             : 
     160             : PyAPI_FUNC(int)
     161       98826 : _PyArg_ParseStack_SizeT(PyObject *const *args, Py_ssize_t nargs, const char *format, ...)
     162             : {
     163             :     int retval;
     164             :     va_list va;
     165             : 
     166       98826 :     va_start(va, format);
     167       98826 :     retval = vgetargs1_impl(NULL, args, nargs, format, &va, FLAG_SIZE_T);
     168       98826 :     va_end(va);
     169       98826 :     return retval;
     170             : }
     171             : 
     172             : 
     173             : int
     174           0 : PyArg_VaParse(PyObject *args, const char *format, va_list va)
     175             : {
     176             :     va_list lva;
     177             :     int retval;
     178             : 
     179           0 :     va_copy(lva, va);
     180             : 
     181           0 :     retval = vgetargs1(args, format, &lva, 0);
     182           0 :     va_end(lva);
     183           0 :     return retval;
     184             : }
     185             : 
     186             : PyAPI_FUNC(int)
     187           0 : _PyArg_VaParse_SizeT(PyObject *args, const char *format, va_list va)
     188             : {
     189             :     va_list lva;
     190             :     int retval;
     191             : 
     192           0 :     va_copy(lva, va);
     193             : 
     194           0 :     retval = vgetargs1(args, format, &lva, FLAG_SIZE_T);
     195           0 :     va_end(lva);
     196           0 :     return retval;
     197             : }
     198             : 
     199             : 
     200             : /* Handle cleanup of allocated memory in case of exception */
     201             : 
     202             : static int
     203           0 : cleanup_ptr(PyObject *self, void *ptr)
     204             : {
     205           0 :     if (ptr) {
     206           0 :         PyMem_Free(ptr);
     207             :     }
     208           0 :     return 0;
     209             : }
     210             : 
     211             : static int
     212           2 : cleanup_buffer(PyObject *self, void *ptr)
     213             : {
     214           2 :     Py_buffer *buf = (Py_buffer *)ptr;
     215           2 :     if (buf) {
     216           2 :         PyBuffer_Release(buf);
     217             :     }
     218           2 :     return 0;
     219             : }
     220             : 
     221             : static int
     222     1587650 : addcleanup(void *ptr, freelist_t *freelist, destr_t destructor)
     223             : {
     224             :     int index;
     225             : 
     226     1587650 :     index = freelist->first_available;
     227     1587650 :     freelist->first_available += 1;
     228             : 
     229     1587650 :     freelist->entries[index].item = ptr;
     230     1587650 :     freelist->entries[index].destructor = destructor;
     231             : 
     232     1587650 :     return 0;
     233             : }
     234             : 
     235             : static int
     236    28497500 : cleanreturn(int retval, freelist_t *freelist)
     237             : {
     238             :     int index;
     239             : 
     240    28497500 :     if (retval == 0) {
     241             :       /* A failure occurred, therefore execute all of the cleanup
     242             :          functions.
     243             :       */
     244        1696 :       for (index = 0; index < freelist->first_available; ++index) {
     245           3 :           freelist->entries[index].destructor(NULL,
     246           3 :                                               freelist->entries[index].item);
     247             :       }
     248             :     }
     249    28497500 :     if (freelist->entries_malloced)
     250       91867 :         PyMem_Free(freelist->entries);
     251    28497500 :     return retval;
     252             : }
     253             : 
     254             : 
     255             : static int
     256    20213200 : vgetargs1_impl(PyObject *compat_args, PyObject *const *stack, Py_ssize_t nargs, const char *format,
     257             :                va_list *p_va, int flags)
     258             : {
     259             :     char msgbuf[256];
     260             :     int levels[32];
     261    20213200 :     const char *fname = NULL;
     262    20213200 :     const char *message = NULL;
     263    20213200 :     int min = -1;
     264    20213200 :     int max = 0;
     265    20213200 :     int level = 0;
     266    20213200 :     int endfmt = 0;
     267    20213200 :     const char *formatsave = format;
     268             :     Py_ssize_t i;
     269             :     const char *msg;
     270    20213200 :     int compat = flags & FLAG_COMPAT;
     271             :     freelistentry_t static_entries[STATIC_FREELIST_ENTRIES];
     272             :     freelist_t freelist;
     273             : 
     274    20213200 :     assert(nargs == 0 || stack != NULL);
     275             : 
     276    20213200 :     freelist.entries = static_entries;
     277    20213200 :     freelist.first_available = 0;
     278    20213200 :     freelist.entries_malloced = 0;
     279             : 
     280    20213200 :     flags = flags & ~FLAG_COMPAT;
     281             : 
     282   115858000 :     while (endfmt == 0) {
     283    95645200 :         int c = *format++;
     284    95645200 :         switch (c) {
     285        1353 :         case '(':
     286        1353 :             if (level == 0)
     287        1353 :                 max++;
     288        1353 :             level++;
     289        1353 :             if (level >= 30)
     290           0 :                 Py_FatalError("too many tuple nesting levels "
     291             :                               "in argument format string");
     292        1353 :             break;
     293        1353 :         case ')':
     294        1353 :             if (level == 0)
     295           0 :                 Py_FatalError("excess ')' in getargs format");
     296             :             else
     297        1353 :                 level--;
     298        1353 :             break;
     299     1950360 :         case '\0':
     300     1950360 :             endfmt = 1;
     301     1950360 :             break;
     302    17809900 :         case ':':
     303    17809900 :             fname = format;
     304    17809900 :             endfmt = 1;
     305    17809900 :             break;
     306      452879 :         case ';':
     307      452879 :             message = format;
     308      452879 :             endfmt = 1;
     309      452879 :             break;
     310    15739900 :         case '|':
     311    15739900 :             if (level == 0)
     312    15739900 :                 min = max;
     313    15739900 :             break;
     314    59689300 :         default:
     315    59689300 :             if (level == 0) {
     316    59684900 :                 if (Py_ISALPHA(c))
     317    55006700 :                     if (c != 'e') /* skip encoded */
     318    55006000 :                         max++;
     319             :             }
     320    59689300 :             break;
     321             :         }
     322             :     }
     323             : 
     324    20213200 :     if (level != 0)
     325           0 :         Py_FatalError(/* '(' */ "missing ')' in getargs format");
     326             : 
     327    20213200 :     if (min < 0)
     328     4473220 :         min = max;
     329             : 
     330    20213200 :     format = formatsave;
     331             : 
     332    20213200 :     if (max > STATIC_FREELIST_ENTRIES) {
     333       21713 :         freelist.entries = PyMem_NEW(freelistentry_t, max);
     334       21713 :         if (freelist.entries == NULL) {
     335           0 :             PyErr_NoMemory();
     336           0 :             return 0;
     337             :         }
     338       21713 :         freelist.entries_malloced = 1;
     339             :     }
     340             : 
     341    20213200 :     if (compat) {
     342     1937640 :         if (max == 0) {
     343           0 :             if (compat_args == NULL)
     344           0 :                 return 1;
     345           0 :             PyErr_Format(PyExc_TypeError,
     346             :                          "%.200s%s takes no arguments",
     347             :                          fname==NULL ? "function" : fname,
     348             :                          fname==NULL ? "" : "()");
     349           0 :             return cleanreturn(0, &freelist);
     350             :         }
     351     1937640 :         else if (min == 1 && max == 1) {
     352     1937640 :             if (compat_args == NULL) {
     353           0 :                 PyErr_Format(PyExc_TypeError,
     354             :                              "%.200s%s takes at least one argument",
     355             :                              fname==NULL ? "function" : fname,
     356             :                              fname==NULL ? "" : "()");
     357           0 :                 return cleanreturn(0, &freelist);
     358             :             }
     359     1937640 :             msg = convertitem(compat_args, &format, p_va, flags, levels,
     360             :                               msgbuf, sizeof(msgbuf), &freelist);
     361     1937640 :             if (msg == NULL)
     362     1937380 :                 return cleanreturn(1, &freelist);
     363         264 :             seterror(levels[0], msg, levels+1, fname, message);
     364         264 :             return cleanreturn(0, &freelist);
     365             :         }
     366             :         else {
     367           0 :             PyErr_SetString(PyExc_SystemError,
     368             :                 "old style getargs format uses new features");
     369           0 :             return cleanreturn(0, &freelist);
     370             :         }
     371             :     }
     372             : 
     373    18275500 :     if (nargs < min || max < nargs) {
     374         182 :         if (message == NULL)
     375         351 :             PyErr_Format(PyExc_TypeError,
     376             :                          "%.150s%s takes %s %d argument%s (%zd given)",
     377             :                          fname==NULL ? "function" : fname,
     378             :                          fname==NULL ? "" : "()",
     379             :                          min==max ? "exactly"
     380          75 :                          : nargs < min ? "at least" : "at most",
     381         138 :                          nargs < min ? min : max,
     382         138 :                          (nargs < min ? min : max) == 1 ? "" : "s",
     383             :                          nargs);
     384             :         else
     385          44 :             PyErr_SetString(PyExc_TypeError, message);
     386         182 :         return cleanreturn(0, &freelist);
     387             :     }
     388             : 
     389    45471200 :     for (i = 0; i < nargs; i++) {
     390    27196400 :         if (*format == '|')
     391     4725960 :             format++;
     392    27196400 :         msg = convertitem(stack[i], &format, p_va,
     393             :                           flags, levels, msgbuf,
     394             :                           sizeof(msgbuf), &freelist);
     395    27196400 :         if (msg) {
     396         579 :             seterror(i+1, msg, levels, fname, message);
     397         579 :             return cleanreturn(0, &freelist);
     398             :         }
     399             :     }
     400             : 
     401    18274800 :     if (*format != '\0' && !Py_ISALPHA(*format) &&
     402    13739200 :         *format != '(' &&
     403    13739200 :         *format != '|' && *format != ':' && *format != ';') {
     404           1 :         PyErr_Format(PyExc_SystemError,
     405             :                      "bad format string: %.200s", formatsave);
     406           1 :         return cleanreturn(0, &freelist);
     407             :     }
     408             : 
     409    18274800 :     return cleanreturn(1, &freelist);
     410             : }
     411             : 
     412             : static int
     413    20046600 : vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
     414             : {
     415             :     PyObject **stack;
     416             :     Py_ssize_t nargs;
     417             : 
     418    20046600 :     if (!(flags & FLAG_COMPAT)) {
     419    18109000 :         assert(args != NULL);
     420             : 
     421    18109000 :         if (!PyTuple_Check(args)) {
     422           0 :             PyErr_SetString(PyExc_SystemError,
     423             :                 "new style getargs format but argument is not a tuple");
     424           0 :             return 0;
     425             :         }
     426             : 
     427    18109000 :         stack = _PyTuple_ITEMS(args);
     428    18109000 :         nargs = PyTuple_GET_SIZE(args);
     429             :     }
     430             :     else {
     431     1937640 :         stack = NULL;
     432     1937640 :         nargs = 0;
     433             :     }
     434             : 
     435    20046600 :     return vgetargs1_impl(args, stack, nargs, format, p_va, flags);
     436             : }
     437             : 
     438             : 
     439             : static void
     440        1149 : seterror(Py_ssize_t iarg, const char *msg, int *levels, const char *fname,
     441             :          const char *message)
     442             : {
     443             :     char buf[512];
     444             :     int i;
     445        1149 :     char *p = buf;
     446             : 
     447        1149 :     if (PyErr_Occurred())
     448         598 :         return;
     449         551 :     else if (message == NULL) {
     450         518 :         if (fname != NULL) {
     451          90 :             PyOS_snprintf(p, sizeof(buf), "%.200s() ", fname);
     452          90 :             p += strlen(p);
     453             :         }
     454         518 :         if (iarg != 0) {
     455         458 :             PyOS_snprintf(p, sizeof(buf) - (p - buf),
     456             :                           "argument %zd", iarg);
     457         458 :             i = 0;
     458         458 :             p += strlen(p);
     459         459 :             while (i < 32 && levels[i] > 0 && (int)(p-buf) < 220) {
     460           1 :                 PyOS_snprintf(p, sizeof(buf) - (p - buf),
     461           1 :                               ", item %d", levels[i]-1);
     462           1 :                 p += strlen(p);
     463           1 :                 i++;
     464             :             }
     465             :         }
     466             :         else {
     467          60 :             PyOS_snprintf(p, sizeof(buf) - (p - buf), "argument");
     468          60 :             p += strlen(p);
     469             :         }
     470         518 :         PyOS_snprintf(p, sizeof(buf) - (p - buf), " %.256s", msg);
     471         518 :         message = buf;
     472             :     }
     473         551 :     if (msg[0] == '(') {
     474         110 :         PyErr_SetString(PyExc_SystemError, message);
     475             :     }
     476             :     else {
     477         441 :         PyErr_SetString(PyExc_TypeError, message);
     478             :     }
     479             : }
     480             : 
     481             : 
     482             : /* Convert a tuple argument.
     483             :    On entry, *p_format points to the character _after_ the opening '('.
     484             :    On successful exit, *p_format points to the closing ')'.
     485             :    If successful:
     486             :       *p_format and *p_va are updated,
     487             :       *levels and *msgbuf are untouched,
     488             :       and NULL is returned.
     489             :    If the argument is invalid:
     490             :       *p_format is unchanged,
     491             :       *p_va is undefined,
     492             :       *levels is a 0-terminated list of item numbers,
     493             :       *msgbuf contains an error message, whose format is:
     494             :      "must be <typename1>, not <typename2>", where:
     495             :         <typename1> is the name of the expected type, and
     496             :         <typename2> is the name of the actual type,
     497             :       and msgbuf is returned.
     498             : */
     499             : 
     500             : static const char *
     501        1372 : converttuple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
     502             :              int *levels, char *msgbuf, size_t bufsize, int toplevel,
     503             :              freelist_t *freelist)
     504             : {
     505        1372 :     int level = 0;
     506        1372 :     int n = 0;
     507        1372 :     const char *format = *p_format;
     508             :     int i;
     509             :     Py_ssize_t len;
     510             : 
     511        4516 :     for (;;) {
     512        5888 :         int c = *format++;
     513        5888 :         if (c == '(') {
     514           4 :             if (level == 0)
     515           4 :                 n++;
     516           4 :             level++;
     517             :         }
     518        5884 :         else if (c == ')') {
     519        1376 :             if (level == 0)
     520        1372 :                 break;
     521           4 :             level--;
     522             :         }
     523        4508 :         else if (c == ':' || c == ';' || c == '\0')
     524             :             break;
     525        4508 :         else if (level == 0 && Py_ISALPHA(c))
     526        3622 :             n++;
     527             :     }
     528             : 
     529        1372 :     if (!PySequence_Check(arg) || PyBytes_Check(arg)) {
     530          21 :         levels[0] = 0;
     531          42 :         PyOS_snprintf(msgbuf, bufsize,
     532             :                       toplevel ? "expected %d arguments, not %.50s" :
     533             :                       "must be %d-item sequence, not %.50s",
     534             :                   n,
     535          21 :                   arg == Py_None ? "None" : Py_TYPE(arg)->tp_name);
     536          21 :         return msgbuf;
     537             :     }
     538             : 
     539        1351 :     len = PySequence_Size(arg);
     540        1351 :     if (len != n) {
     541          14 :         levels[0] = 0;
     542          14 :         if (toplevel) {
     543           0 :             PyOS_snprintf(msgbuf, bufsize,
     544             :                           "expected %d argument%s, not %zd",
     545             :                           n,
     546             :                           n == 1 ? "" : "s",
     547             :                           len);
     548             :         }
     549             :         else {
     550          14 :             PyOS_snprintf(msgbuf, bufsize,
     551             :                           "must be sequence of length %d, not %zd",
     552             :                           n, len);
     553             :         }
     554          14 :         return msgbuf;
     555             :     }
     556             : 
     557        1337 :     format = *p_format;
     558        4814 :     for (i = 0; i < n; i++) {
     559             :         const char *msg;
     560             :         PyObject *item;
     561        3499 :         item = PySequence_GetItem(arg, i);
     562        3499 :         if (item == NULL) {
     563           1 :             PyErr_Clear();
     564           1 :             levels[0] = i+1;
     565           1 :             levels[1] = 0;
     566           1 :             strncpy(msgbuf, "is not retrievable", bufsize);
     567           1 :             return msgbuf;
     568             :         }
     569        3498 :         msg = convertitem(item, &format, p_va, flags, levels+1,
     570             :                           msgbuf, bufsize, freelist);
     571             :         /* PySequence_GetItem calls tp->sq_item, which INCREFs */
     572        3498 :         Py_XDECREF(item);
     573        3498 :         if (msg != NULL) {
     574          21 :             levels[0] = i+1;
     575          21 :             return msg;
     576             :         }
     577             :     }
     578             : 
     579        1315 :     *p_format = format;
     580        1315 :     return NULL;
     581             : }
     582             : 
     583             : 
     584             : /* Convert a single item. */
     585             : 
     586             : static const char *
     587    32327400 : convertitem(PyObject *arg, const char **p_format, va_list *p_va, int flags,
     588             :             int *levels, char *msgbuf, size_t bufsize, freelist_t *freelist)
     589             : {
     590             :     const char *msg;
     591    32327400 :     const char *format = *p_format;
     592             : 
     593    32327400 :     if (*format == '(' /* ')' */) {
     594        1372 :         format++;
     595        1372 :         msg = converttuple(arg, &format, p_va, flags, levels, msgbuf,
     596             :                            bufsize, 0, freelist);
     597        1372 :         if (msg == NULL)
     598        1315 :             format++;
     599             :     }
     600             :     else {
     601    32326100 :         msg = convertsimple(arg, &format, p_va, flags,
     602             :                             msgbuf, bufsize, freelist);
     603    32326100 :         if (msg != NULL)
     604        1113 :             levels[0] = 0;
     605             :     }
     606    32327400 :     if (msg == NULL)
     607    32326300 :         *p_format = format;
     608    32327400 :     return msg;
     609             : }
     610             : 
     611             : 
     612             : 
     613             : /* Format an error message generated by convertsimple().
     614             :    displayname must be UTF-8 encoded.
     615             : */
     616             : 
     617             : void
     618         126 : _PyArg_BadArgument(const char *fname, const char *displayname,
     619             :                    const char *expected, PyObject *arg)
     620             : {
     621         238 :     PyErr_Format(PyExc_TypeError,
     622             :                  "%.200s() %.200s must be %.50s, not %.50s",
     623             :                  fname, displayname, expected,
     624         112 :                  arg == Py_None ? "None" : Py_TYPE(arg)->tp_name);
     625         126 : }
     626             : 
     627             : static const char *
     628         622 : converterr(const char *expected, PyObject *arg, char *msgbuf, size_t bufsize)
     629             : {
     630         622 :     assert(expected != NULL);
     631         622 :     assert(arg != NULL);
     632         622 :     if (expected[0] == '(') {
     633         144 :         PyOS_snprintf(msgbuf, bufsize,
     634             :                       "%.100s", expected);
     635             :     }
     636             :     else {
     637         909 :         PyOS_snprintf(msgbuf, bufsize,
     638             :                       "must be %.50s, not %.50s", expected,
     639         431 :                       arg == Py_None ? "None" : Py_TYPE(arg)->tp_name);
     640             :     }
     641         622 :     return msgbuf;
     642             : }
     643             : 
     644             : #define CONV_UNICODE "(unicode conversion error)"
     645             : 
     646             : /* Convert a non-tuple argument.  Return NULL if conversion went OK,
     647             :    or a string with a message describing the failure.  The message is
     648             :    formatted as "must be <desired type>, not <actual type>".
     649             :    When failing, an exception may or may not have been raised.
     650             :    Don't call if a tuple is expected.
     651             : 
     652             :    When you add new format codes, please don't forget poor skipitem() below.
     653             : */
     654             : 
     655             : static const char *
     656    32326100 : convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
     657             :               char *msgbuf, size_t bufsize, freelist_t *freelist)
     658             : {
     659             : #define RETURN_ERR_OCCURRED return msgbuf
     660             :     /* For # codes */
     661             : #define REQUIRE_PY_SSIZE_T_CLEAN \
     662             :     if (!(flags & FLAG_SIZE_T)) { \
     663             :         PyErr_SetString(PyExc_SystemError, \
     664             :                         "PY_SSIZE_T_CLEAN macro must be defined for '#' formats"); \
     665             :         RETURN_ERR_OCCURRED; \
     666             :     }
     667             : 
     668    32326100 :     const char *format = *p_format;
     669    32326100 :     char c = *format++;
     670             :     const char *sarg;
     671             : 
     672    32326100 :     switch (c) {
     673             : 
     674       70300 :     case 'b': { /* unsigned byte -- very short int */
     675       70300 :         char *p = va_arg(*p_va, char *);
     676       70300 :         long ival = PyLong_AsLong(arg);
     677       70300 :         if (ival == -1 && PyErr_Occurred())
     678          12 :             RETURN_ERR_OCCURRED;
     679       70288 :         else if (ival < 0) {
     680           5 :             PyErr_SetString(PyExc_OverflowError,
     681             :                             "unsigned byte integer is less than minimum");
     682           5 :             RETURN_ERR_OCCURRED;
     683             :         }
     684       70283 :         else if (ival > UCHAR_MAX) {
     685           5 :             PyErr_SetString(PyExc_OverflowError,
     686             :                             "unsigned byte integer is greater than maximum");
     687           5 :             RETURN_ERR_OCCURRED;
     688             :         }
     689             :         else
     690       70278 :             *p = (unsigned char) ival;
     691       70278 :         break;
     692             :     }
     693             : 
     694          74 :     case 'B': {/* byte sized bitfield - both signed and unsigned
     695             :                   values allowed */
     696          74 :         char *p = va_arg(*p_va, char *);
     697          74 :         unsigned long ival = PyLong_AsUnsignedLongMask(arg);
     698          74 :         if (ival == (unsigned long)-1 && PyErr_Occurred())
     699           5 :             RETURN_ERR_OCCURRED;
     700             :         else
     701          69 :             *p = (unsigned char) ival;
     702          69 :         break;
     703             :     }
     704             : 
     705       42437 :     case 'h': {/* signed short int */
     706       42437 :         short *p = va_arg(*p_va, short *);
     707       42437 :         long ival = PyLong_AsLong(arg);
     708       42437 :         if (ival == -1 && PyErr_Occurred())
     709          16 :             RETURN_ERR_OCCURRED;
     710       42421 :         else if (ival < SHRT_MIN) {
     711           5 :             PyErr_SetString(PyExc_OverflowError,
     712             :                             "signed short integer is less than minimum");
     713           5 :             RETURN_ERR_OCCURRED;
     714             :         }
     715       42416 :         else if (ival > SHRT_MAX) {
     716           5 :             PyErr_SetString(PyExc_OverflowError,
     717             :                             "signed short integer is greater than maximum");
     718           5 :             RETURN_ERR_OCCURRED;
     719             :         }
     720             :         else
     721       42411 :             *p = (short) ival;
     722       42411 :         break;
     723             :     }
     724             : 
     725          19 :     case 'H': { /* short int sized bitfield, both signed and
     726             :                    unsigned allowed */
     727          19 :         unsigned short *p = va_arg(*p_va, unsigned short *);
     728          19 :         unsigned long ival = PyLong_AsUnsignedLongMask(arg);
     729          19 :         if (ival == (unsigned long)-1 && PyErr_Occurred())
     730           5 :             RETURN_ERR_OCCURRED;
     731             :         else
     732          14 :             *p = (unsigned short) ival;
     733          14 :         break;
     734             :     }
     735             : 
     736     1497950 :     case 'i': {/* signed int */
     737     1497950 :         int *p = va_arg(*p_va, int *);
     738     1497950 :         long ival = PyLong_AsLong(arg);
     739     1497950 :         if (ival == -1 && PyErr_Occurred())
     740         193 :             RETURN_ERR_OCCURRED;
     741     1497760 :         else if (ival > INT_MAX) {
     742          26 :             PyErr_SetString(PyExc_OverflowError,
     743             :                             "signed integer is greater than maximum");
     744          26 :             RETURN_ERR_OCCURRED;
     745             :         }
     746     1497730 :         else if (ival < INT_MIN) {
     747           7 :             PyErr_SetString(PyExc_OverflowError,
     748             :                             "signed integer is less than minimum");
     749           7 :             RETURN_ERR_OCCURRED;
     750             :         }
     751             :         else
     752     1497720 :             *p = ival;
     753     1497720 :         break;
     754             :     }
     755             : 
     756         854 :     case 'I': { /* int sized bitfield, both signed and
     757             :                    unsigned allowed */
     758         854 :         unsigned int *p = va_arg(*p_va, unsigned int *);
     759         854 :         unsigned long ival = PyLong_AsUnsignedLongMask(arg);
     760         854 :         if (ival == (unsigned long)-1 && PyErr_Occurred())
     761           5 :             RETURN_ERR_OCCURRED;
     762             :         else
     763         849 :             *p = (unsigned int) ival;
     764         849 :         break;
     765             :     }
     766             : 
     767      242410 :     case 'n': /* Py_ssize_t */
     768             :     {
     769             :         PyObject *iobj;
     770      242410 :         Py_ssize_t *p = va_arg(*p_va, Py_ssize_t *);
     771      242410 :         Py_ssize_t ival = -1;
     772      242410 :         iobj = _PyNumber_Index(arg);
     773      242410 :         if (iobj != NULL) {
     774      242289 :             ival = PyLong_AsSsize_t(iobj);
     775      242289 :             Py_DECREF(iobj);
     776             :         }
     777      242410 :         if (ival == -1 && PyErr_Occurred())
     778         125 :             RETURN_ERR_OCCURRED;
     779      242285 :         *p = ival;
     780      242285 :         break;
     781             :     }
     782       21179 :     case 'l': {/* long int */
     783       21179 :         long *p = va_arg(*p_va, long *);
     784       21179 :         long ival = PyLong_AsLong(arg);
     785       21179 :         if (ival == -1 && PyErr_Occurred())
     786          23 :             RETURN_ERR_OCCURRED;
     787             :         else
     788       21156 :             *p = ival;
     789       21156 :         break;
     790             :     }
     791             : 
     792        2506 :     case 'k': { /* long sized bitfield */
     793        2506 :         unsigned long *p = va_arg(*p_va, unsigned long *);
     794             :         unsigned long ival;
     795        2506 :         if (PyLong_Check(arg))
     796        2498 :             ival = PyLong_AsUnsignedLongMask(arg);
     797             :         else
     798           8 :             return converterr("int", arg, msgbuf, bufsize);
     799        2498 :         *p = ival;
     800        2498 :         break;
     801             :     }
     802             : 
     803       27803 :     case 'L': {/* long long */
     804       27803 :         long long *p = va_arg( *p_va, long long * );
     805       27803 :         long long ival = PyLong_AsLongLong(arg);
     806       27803 :         if (ival == (long long)-1 && PyErr_Occurred())
     807          22 :             RETURN_ERR_OCCURRED;
     808             :         else
     809       27781 :             *p = ival;
     810       27781 :         break;
     811             :     }
     812             : 
     813       38246 :     case 'K': { /* long long sized bitfield */
     814       38246 :         unsigned long long *p = va_arg(*p_va, unsigned long long *);
     815             :         unsigned long long ival;
     816       38246 :         if (PyLong_Check(arg))
     817       38239 :             ival = PyLong_AsUnsignedLongLongMask(arg);
     818             :         else
     819           7 :             return converterr("int", arg, msgbuf, bufsize);
     820       38239 :         *p = ival;
     821       38239 :         break;
     822             :     }
     823             : 
     824       20996 :     case 'f': {/* float */
     825       20996 :         float *p = va_arg(*p_va, float *);
     826       20996 :         double dval = PyFloat_AsDouble(arg);
     827       20996 :         if (dval == -1.0 && PyErr_Occurred())
     828           6 :             RETURN_ERR_OCCURRED;
     829             :         else
     830       20990 :             *p = (float) dval;
     831       20990 :         break;
     832             :     }
     833             : 
     834       86596 :     case 'd': {/* double */
     835       86596 :         double *p = va_arg(*p_va, double *);
     836       86596 :         double dval = PyFloat_AsDouble(arg);
     837       86596 :         if (dval == -1.0 && PyErr_Occurred())
     838           8 :             RETURN_ERR_OCCURRED;
     839             :         else
     840       86588 :             *p = dval;
     841       86588 :         break;
     842             :     }
     843             : 
     844          28 :     case 'D': {/* complex double */
     845          28 :         Py_complex *p = va_arg(*p_va, Py_complex *);
     846             :         Py_complex cval;
     847          28 :         cval = PyComplex_AsCComplex(arg);
     848          28 :         if (PyErr_Occurred())
     849           2 :             RETURN_ERR_OCCURRED;
     850             :         else
     851          26 :             *p = cval;
     852          26 :         break;
     853             :     }
     854             : 
     855           8 :     case 'c': {/* char */
     856           8 :         char *p = va_arg(*p_va, char *);
     857           8 :         if (PyBytes_Check(arg) && PyBytes_Size(arg) == 1)
     858           1 :             *p = PyBytes_AS_STRING(arg)[0];
     859           7 :         else if (PyByteArray_Check(arg) && PyByteArray_Size(arg) == 1)
     860           1 :             *p = PyByteArray_AS_STRING(arg)[0];
     861             :         else
     862           6 :             return converterr("a byte string of length 1", arg, msgbuf, bufsize);
     863           2 :         break;
     864             :     }
     865             : 
     866       72326 :     case 'C': {/* unicode char */
     867       72326 :         int *p = va_arg(*p_va, int *);
     868             :         int kind;
     869             :         const void *data;
     870             : 
     871       72326 :         if (!PyUnicode_Check(arg))
     872           6 :             return converterr("a unicode character", arg, msgbuf, bufsize);
     873             : 
     874       72320 :         if (PyUnicode_READY(arg))
     875           0 :             RETURN_ERR_OCCURRED;
     876             : 
     877       72320 :         if (PyUnicode_GET_LENGTH(arg) != 1)
     878           2 :             return converterr("a unicode character", arg, msgbuf, bufsize);
     879             : 
     880       72318 :         kind = PyUnicode_KIND(arg);
     881       72318 :         data = PyUnicode_DATA(arg);
     882       72318 :         *p = PyUnicode_READ(kind, data, 0);
     883       72318 :         break;
     884             :     }
     885             : 
     886     1035120 :     case 'p': {/* boolean *p*redicate */
     887     1035120 :         int *p = va_arg(*p_va, int *);
     888     1035120 :         int val = PyObject_IsTrue(arg);
     889     1035120 :         if (val > 0)
     890     1020470 :             *p = 1;
     891       14647 :         else if (val == 0)
     892       14643 :             *p = 0;
     893             :         else
     894           4 :             RETURN_ERR_OCCURRED;
     895     1035110 :         break;
     896             :     }
     897             : 
     898             :     /* XXX WAAAAH!  's', 'y', 'z', 'u', 'Z', 'e', 'w' codes all
     899             :        need to be cleaned up! */
     900             : 
     901       43334 :     case 'y': {/* any bytes-like object */
     902       43334 :         void **p = (void **)va_arg(*p_va, char **);
     903             :         const char *buf;
     904             :         Py_ssize_t count;
     905       43334 :         if (*format == '*') {
     906       43257 :             if (getbuffer(arg, (Py_buffer*)p, &buf) < 0)
     907          47 :                 return converterr(buf, arg, msgbuf, bufsize);
     908       43220 :             format++;
     909       43220 :             if (addcleanup(p, freelist, cleanup_buffer)) {
     910           0 :                 return converterr(
     911             :                     "(cleanup problem)",
     912             :                     arg, msgbuf, bufsize);
     913             :             }
     914       43287 :             break;
     915             :         }
     916          77 :         count = convertbuffer(arg, (const void **)p, &buf);
     917          77 :         if (count < 0)
     918           9 :             return converterr(buf, arg, msgbuf, bufsize);
     919          68 :         if (*format == '#') {
     920          48 :             REQUIRE_PY_SSIZE_T_CLEAN;
     921          48 :             Py_ssize_t *psize = va_arg(*p_va, Py_ssize_t*);
     922          48 :             *psize = count;
     923          48 :             format++;
     924             :         } else {
     925          20 :             if (strlen(*p) != (size_t)count) {
     926           1 :                 PyErr_SetString(PyExc_ValueError, "embedded null byte");
     927           1 :                 RETURN_ERR_OCCURRED;
     928             :             }
     929             :         }
     930          67 :         break;
     931             :     }
     932             : 
     933       81706 :     case 's': /* text string or bytes-like object */
     934             :     case 'z': /* text string, bytes-like object or None */
     935             :     {
     936       81706 :         if (*format == '*') {
     937             :             /* "s*" or "z*" */
     938          12 :             Py_buffer *p = (Py_buffer *)va_arg(*p_va, Py_buffer *);
     939             : 
     940          12 :             if (c == 'z' && arg == Py_None)
     941           1 :                 PyBuffer_FillInfo(p, NULL, NULL, 0, 1, 0);
     942          11 :             else if (PyUnicode_Check(arg)) {
     943             :                 Py_ssize_t len;
     944           4 :                 sarg = PyUnicode_AsUTF8AndSize(arg, &len);
     945           4 :                 if (sarg == NULL)
     946           0 :                     return converterr(CONV_UNICODE,
     947             :                                       arg, msgbuf, bufsize);
     948           4 :                 PyBuffer_FillInfo(p, arg, (void *)sarg, len, 1, 0);
     949             :             }
     950             :             else { /* any bytes-like object */
     951             :                 const char *buf;
     952           7 :                 if (getbuffer(arg, p, &buf) < 0)
     953           1 :                     return converterr(buf, arg, msgbuf, bufsize);
     954             :             }
     955          11 :             if (addcleanup(p, freelist, cleanup_buffer)) {
     956           0 :                 return converterr(
     957             :                     "(cleanup problem)",
     958             :                     arg, msgbuf, bufsize);
     959             :             }
     960          11 :             format++;
     961       81694 :         } else if (*format == '#') { /* a string or read-only bytes-like object */
     962             :             /* "s#" or "z#" */
     963       58131 :             const void **p = (const void **)va_arg(*p_va, const char **);
     964       58131 :             REQUIRE_PY_SSIZE_T_CLEAN;
     965       58129 :             Py_ssize_t *psize = va_arg(*p_va, Py_ssize_t*);
     966             : 
     967       58129 :             if (c == 'z' && arg == Py_None) {
     968           1 :                 *p = NULL;
     969           1 :                 *psize = 0;
     970             :             }
     971       58128 :             else if (PyUnicode_Check(arg)) {
     972             :                 Py_ssize_t len;
     973       56641 :                 sarg = PyUnicode_AsUTF8AndSize(arg, &len);
     974       56641 :                 if (sarg == NULL)
     975           0 :                     return converterr(CONV_UNICODE,
     976             :                                       arg, msgbuf, bufsize);
     977       56641 :                 *p = sarg;
     978       56641 :                 *psize = len;
     979             :             }
     980             :             else { /* read-only bytes-like object */
     981             :                 /* XXX Really? */
     982             :                 const char *buf;
     983        1487 :                 Py_ssize_t count = convertbuffer(arg, p, &buf);
     984        1487 :                 if (count < 0)
     985          34 :                     return converterr(buf, arg, msgbuf, bufsize);
     986        1453 :                 *psize = count;
     987             :             }
     988       58095 :             format++;
     989             :         } else {
     990             :             /* "s" or "z" */
     991       23563 :             const char **p = va_arg(*p_va, const char **);
     992             :             Py_ssize_t len;
     993       23563 :             sarg = NULL;
     994             : 
     995       23563 :             if (c == 'z' && arg == Py_None)
     996           1 :                 *p = NULL;
     997       23562 :             else if (PyUnicode_Check(arg)) {
     998       23546 :                 sarg = PyUnicode_AsUTF8AndSize(arg, &len);
     999       23546 :                 if (sarg == NULL)
    1000          29 :                     return converterr(CONV_UNICODE,
    1001             :                                       arg, msgbuf, bufsize);
    1002       23538 :                 if (strlen(sarg) != (size_t)len) {
    1003           5 :                     PyErr_SetString(PyExc_ValueError, "embedded null character");
    1004           5 :                     RETURN_ERR_OCCURRED;
    1005             :                 }
    1006       23533 :                 *p = sarg;
    1007             :             }
    1008             :             else
    1009          16 :                 return converterr(c == 'z' ? "str or None" : "str",
    1010             :                                   arg, msgbuf, bufsize);
    1011             :         }
    1012       81640 :         break;
    1013             :     }
    1014             : 
    1015         652 :     case 'e': {/* encoded string */
    1016             :         char **buffer;
    1017             :         const char *encoding;
    1018             :         PyObject *s;
    1019             :         int recode_strings;
    1020             :         Py_ssize_t size;
    1021             :         const char *ptr;
    1022             : 
    1023             :         /* Get 'e' parameter: the encoding name */
    1024         652 :         encoding = (const char *)va_arg(*p_va, const char *);
    1025         652 :         if (encoding == NULL)
    1026           4 :             encoding = PyUnicode_GetDefaultEncoding();
    1027             : 
    1028             :         /* Get output buffer parameter:
    1029             :            's' (recode all objects via Unicode) or
    1030             :            't' (only recode non-string objects)
    1031             :         */
    1032         652 :         if (*format == 's')
    1033         420 :             recode_strings = 1;
    1034         232 :         else if (*format == 't')
    1035         232 :             recode_strings = 0;
    1036             :         else
    1037           0 :             return converterr(
    1038             :                 "(unknown parser marker combination)",
    1039             :                 arg, msgbuf, bufsize);
    1040         652 :         buffer = (char **)va_arg(*p_va, char **);
    1041         652 :         format++;
    1042         652 :         if (buffer == NULL)
    1043           0 :             return converterr("(buffer is NULL)",
    1044             :                               arg, msgbuf, bufsize);
    1045             : 
    1046             :         /* Encode object */
    1047         884 :         if (!recode_strings &&
    1048         455 :             (PyBytes_Check(arg) || PyByteArray_Check(arg))) {
    1049          13 :             s = arg;
    1050          13 :             Py_INCREF(s);
    1051          13 :             if (PyBytes_Check(arg)) {
    1052           9 :                 size = PyBytes_GET_SIZE(s);
    1053           9 :                 ptr = PyBytes_AS_STRING(s);
    1054             :             }
    1055             :             else {
    1056           4 :                 size = PyByteArray_GET_SIZE(s);
    1057           4 :                 ptr = PyByteArray_AS_STRING(s);
    1058             :             }
    1059             :         }
    1060         639 :         else if (PyUnicode_Check(arg)) {
    1061             :             /* Encode object; use default error handling */
    1062         626 :             s = PyUnicode_AsEncodedString(arg,
    1063             :                                           encoding,
    1064             :                                           NULL);
    1065         626 :             if (s == NULL)
    1066           8 :                 return converterr("(encoding failed)",
    1067             :                                   arg, msgbuf, bufsize);
    1068         618 :             assert(PyBytes_Check(s));
    1069         618 :             size = PyBytes_GET_SIZE(s);
    1070         618 :             ptr = PyBytes_AS_STRING(s);
    1071         618 :             if (ptr == NULL)
    1072           0 :                 ptr = "";
    1073             :         }
    1074             :         else {
    1075          13 :             return converterr(
    1076             :                 recode_strings ? "str" : "str, bytes or bytearray",
    1077             :                 arg, msgbuf, bufsize);
    1078             :         }
    1079             : 
    1080             :         /* Write output; output is guaranteed to be 0-terminated */
    1081         631 :         if (*format == '#') {
    1082             :             /* Using buffer length parameter '#':
    1083             : 
    1084             :                - if *buffer is NULL, a new buffer of the
    1085             :                needed size is allocated and the data
    1086             :                copied into it; *buffer is updated to point
    1087             :                to the new buffer; the caller is
    1088             :                responsible for PyMem_Free()ing it after
    1089             :                usage
    1090             : 
    1091             :                - if *buffer is not NULL, the data is
    1092             :                copied to *buffer; *buffer_len has to be
    1093             :                set to the size of the buffer on input;
    1094             :                buffer overflow is signalled with an error;
    1095             :                buffer has to provide enough room for the
    1096             :                encoded string plus the trailing 0-byte
    1097             : 
    1098             :                - in both cases, *buffer_len is updated to
    1099             :                the size of the buffer /excluding/ the
    1100             :                trailing 0-byte
    1101             : 
    1102             :             */
    1103          18 :             REQUIRE_PY_SSIZE_T_CLEAN;
    1104          18 :             Py_ssize_t *psize = va_arg(*p_va, Py_ssize_t*);
    1105             : 
    1106          18 :             format++;
    1107          18 :             if (psize == NULL) {
    1108           0 :                 Py_DECREF(s);
    1109           0 :                 return converterr(
    1110             :                     "(buffer_len is NULL)",
    1111             :                     arg, msgbuf, bufsize);
    1112             :             }
    1113          18 :             if (*buffer == NULL) {
    1114          10 :                 *buffer = PyMem_NEW(char, size + 1);
    1115          10 :                 if (*buffer == NULL) {
    1116           0 :                     Py_DECREF(s);
    1117           0 :                     PyErr_NoMemory();
    1118           0 :                     RETURN_ERR_OCCURRED;
    1119             :                 }
    1120          10 :                 if (addcleanup(*buffer, freelist, cleanup_ptr)) {
    1121           0 :                     Py_DECREF(s);
    1122           0 :                     return converterr(
    1123             :                         "(cleanup problem)",
    1124             :                         arg, msgbuf, bufsize);
    1125             :                 }
    1126             :             } else {
    1127           8 :                 if (size + 1 > *psize) {
    1128           4 :                     Py_DECREF(s);
    1129           4 :                     PyErr_Format(PyExc_ValueError,
    1130             :                                  "encoded string too long "
    1131             :                                  "(%zd, maximum length %zd)",
    1132           4 :                                  (Py_ssize_t)size, (Py_ssize_t)(*psize - 1));
    1133           4 :                     RETURN_ERR_OCCURRED;
    1134             :                 }
    1135             :             }
    1136          14 :             memcpy(*buffer, ptr, size+1);
    1137             : 
    1138          14 :             *psize = size;
    1139             :         }
    1140             :         else {
    1141             :             /* Using a 0-terminated buffer:
    1142             : 
    1143             :                - the encoded string has to be 0-terminated
    1144             :                for this variant to work; if it is not, an
    1145             :                error raised
    1146             : 
    1147             :                - a new buffer of the needed size is
    1148             :                allocated and the data copied into it;
    1149             :                *buffer is updated to point to the new
    1150             :                buffer; the caller is responsible for
    1151             :                PyMem_Free()ing it after usage
    1152             : 
    1153             :             */
    1154         613 :             if ((Py_ssize_t)strlen(ptr) != size) {
    1155           5 :                 Py_DECREF(s);
    1156           5 :                 return converterr(
    1157             :                     "encoded string without null bytes",
    1158             :                     arg, msgbuf, bufsize);
    1159             :             }
    1160         608 :             *buffer = PyMem_NEW(char, size + 1);
    1161         608 :             if (*buffer == NULL) {
    1162           0 :                 Py_DECREF(s);
    1163           0 :                 PyErr_NoMemory();
    1164           0 :                 RETURN_ERR_OCCURRED;
    1165             :             }
    1166         608 :             if (addcleanup(*buffer, freelist, cleanup_ptr)) {
    1167           0 :                 Py_DECREF(s);
    1168           0 :                 return converterr("(cleanup problem)",
    1169             :                                 arg, msgbuf, bufsize);
    1170             :             }
    1171         608 :             memcpy(*buffer, ptr, size+1);
    1172             :         }
    1173         622 :         Py_DECREF(s);
    1174         622 :         break;
    1175             :     }
    1176             : 
    1177         312 :     case 'S': { /* PyBytes object */
    1178         312 :         PyObject **p = va_arg(*p_va, PyObject **);
    1179         312 :         if (PyBytes_Check(arg))
    1180         305 :             *p = arg;
    1181             :         else
    1182           7 :             return converterr("bytes", arg, msgbuf, bufsize);
    1183         305 :         break;
    1184             :     }
    1185             : 
    1186          14 :     case 'Y': { /* PyByteArray object */
    1187          14 :         PyObject **p = va_arg(*p_va, PyObject **);
    1188          14 :         if (PyByteArray_Check(arg))
    1189           9 :             *p = arg;
    1190             :         else
    1191           5 :             return converterr("bytearray", arg, msgbuf, bufsize);
    1192           9 :         break;
    1193             :     }
    1194             : 
    1195     1344790 :     case 'U': { /* PyUnicode object */
    1196     1344790 :         PyObject **p = va_arg(*p_va, PyObject **);
    1197     1344790 :         if (PyUnicode_Check(arg)) {
    1198     1344520 :             if (PyUnicode_READY(arg) == -1)
    1199           0 :                 RETURN_ERR_OCCURRED;
    1200     1344520 :             *p = arg;
    1201             :         }
    1202             :         else
    1203         272 :             return converterr("str", arg, msgbuf, bufsize);
    1204     1344520 :         break;
    1205             :     }
    1206             : 
    1207    26161400 :     case 'O': { /* object */
    1208             :         PyTypeObject *type;
    1209             :         PyObject **p;
    1210    26161400 :         if (*format == '!') {
    1211     2706550 :             type = va_arg(*p_va, PyTypeObject*);
    1212     2706550 :             p = va_arg(*p_va, PyObject **);
    1213     2706550 :             format++;
    1214     2706550 :             if (PyType_IsSubtype(Py_TYPE(arg), type))
    1215     2706540 :                 *p = arg;
    1216             :             else
    1217          17 :                 return converterr(type->tp_name, arg, msgbuf, bufsize);
    1218             : 
    1219             :         }
    1220    23454900 :         else if (*format == '&') {
    1221             :             typedef int (*converter)(PyObject *, void *);
    1222      147398 :             converter convert = va_arg(*p_va, converter);
    1223      147398 :             void *addr = va_arg(*p_va, void *);
    1224             :             int res;
    1225      147398 :             format++;
    1226      147398 :             if (! (res = (*convert)(arg, addr)))
    1227          19 :                 return converterr("(unspecified)",
    1228             :                                   arg, msgbuf, bufsize);
    1229      156345 :             if (res == Py_CLEANUP_SUPPORTED &&
    1230        8966 :                 addcleanup(addr, freelist, convert) == -1)
    1231           0 :                 return converterr("(cleanup problem)",
    1232             :                                 arg, msgbuf, bufsize);
    1233             :         }
    1234             :         else {
    1235    23307500 :             p = va_arg(*p_va, PyObject **);
    1236    23307500 :             *p = arg;
    1237             :         }
    1238    26161400 :         break;
    1239             :     }
    1240             : 
    1241             : 
    1242     1534870 :     case 'w': { /* "w*": memory buffer, read-write access */
    1243     1534870 :         void **p = va_arg(*p_va, void **);
    1244             : 
    1245     1534870 :         if (*format != '*')
    1246           1 :             return converterr(
    1247             :                 "(invalid use of 'w' format character)",
    1248             :                 arg, msgbuf, bufsize);
    1249     1534860 :         format++;
    1250             : 
    1251             :         /* Caller is interested in Py_buffer, and the object
    1252             :            supports it directly. */
    1253     1534860 :         if (PyObject_GetBuffer(arg, (Py_buffer*)p, PyBUF_WRITABLE) < 0) {
    1254          33 :             PyErr_Clear();
    1255          33 :             return converterr("read-write bytes-like object",
    1256             :                               arg, msgbuf, bufsize);
    1257             :         }
    1258     1534830 :         if (!PyBuffer_IsContiguous((Py_buffer*)p, 'C')) {
    1259           0 :             PyBuffer_Release((Py_buffer*)p);
    1260           0 :             return converterr("contiguous buffer", arg, msgbuf, bufsize);
    1261             :         }
    1262     1534830 :         if (addcleanup(p, freelist, cleanup_buffer)) {
    1263           0 :             return converterr(
    1264             :                 "(cleanup problem)",
    1265             :                 arg, msgbuf, bufsize);
    1266             :         }
    1267     1534830 :         break;
    1268             :     }
    1269             : 
    1270         108 :     default:
    1271         108 :         return converterr("(impossible<bad format char>)", arg, msgbuf, bufsize);
    1272             : 
    1273             :     }
    1274             : 
    1275    32325000 :     *p_format = format;
    1276    32325000 :     return NULL;
    1277             : 
    1278             : #undef REQUIRE_PY_SSIZE_T_CLEAN
    1279             : #undef RETURN_ERR_OCCURRED
    1280             : }
    1281             : 
    1282             : static Py_ssize_t
    1283        1564 : convertbuffer(PyObject *arg, const void **p, const char **errmsg)
    1284             : {
    1285        1564 :     PyBufferProcs *pb = Py_TYPE(arg)->tp_as_buffer;
    1286             :     Py_ssize_t count;
    1287             :     Py_buffer view;
    1288             : 
    1289        1564 :     *errmsg = NULL;
    1290        1564 :     *p = NULL;
    1291        1564 :     if (pb != NULL && pb->bf_releasebuffer != NULL) {
    1292           8 :         *errmsg = "read-only bytes-like object";
    1293           8 :         return -1;
    1294             :     }
    1295             : 
    1296        1556 :     if (getbuffer(arg, &view, errmsg) < 0)
    1297          35 :         return -1;
    1298        1521 :     count = view.len;
    1299        1521 :     *p = view.buf;
    1300        1521 :     PyBuffer_Release(&view);
    1301        1521 :     return count;
    1302             : }
    1303             : 
    1304             : static int
    1305       44820 : getbuffer(PyObject *arg, Py_buffer *view, const char **errmsg)
    1306             : {
    1307       44820 :     if (PyObject_GetBuffer(arg, view, PyBUF_SIMPLE) != 0) {
    1308          73 :         *errmsg = "bytes-like object";
    1309          73 :         return -1;
    1310             :     }
    1311       44747 :     if (!PyBuffer_IsContiguous(view, 'C')) {
    1312           0 :         PyBuffer_Release(view);
    1313           0 :         *errmsg = "contiguous buffer";
    1314           0 :         return -1;
    1315             :     }
    1316       44747 :     return 0;
    1317             : }
    1318             : 
    1319             : /* Support for keyword arguments donated by
    1320             :    Geoff Philbrick <philbric@delphi.hks.com> */
    1321             : 
    1322             : /* Return false (0) for error, else true. */
    1323             : int
    1324     6372560 : PyArg_ParseTupleAndKeywords(PyObject *args,
    1325             :                             PyObject *keywords,
    1326             :                             const char *format,
    1327             :                             char **kwlist, ...)
    1328             : {
    1329             :     int retval;
    1330             :     va_list va;
    1331             : 
    1332     6372560 :     if ((args == NULL || !PyTuple_Check(args)) ||
    1333     6372560 :         (keywords != NULL && !PyDict_Check(keywords)) ||
    1334     6372560 :         format == NULL ||
    1335             :         kwlist == NULL)
    1336             :     {
    1337           0 :         PyErr_BadInternalCall();
    1338           0 :         return 0;
    1339             :     }
    1340             : 
    1341     6372560 :     va_start(va, kwlist);
    1342     6372560 :     retval = vgetargskeywords(args, keywords, format, kwlist, &va, 0);
    1343     6372560 :     va_end(va);
    1344     6372560 :     return retval;
    1345             : }
    1346             : 
    1347             : PyAPI_FUNC(int)
    1348     1911680 : _PyArg_ParseTupleAndKeywords_SizeT(PyObject *args,
    1349             :                                   PyObject *keywords,
    1350             :                                   const char *format,
    1351             :                                   char **kwlist, ...)
    1352             : {
    1353             :     int retval;
    1354             :     va_list va;
    1355             : 
    1356     1911680 :     if ((args == NULL || !PyTuple_Check(args)) ||
    1357     1911680 :         (keywords != NULL && !PyDict_Check(keywords)) ||
    1358     1911680 :         format == NULL ||
    1359             :         kwlist == NULL)
    1360             :     {
    1361           0 :         PyErr_BadInternalCall();
    1362           0 :         return 0;
    1363             :     }
    1364             : 
    1365     1911680 :     va_start(va, kwlist);
    1366     1911680 :     retval = vgetargskeywords(args, keywords, format,
    1367             :                               kwlist, &va, FLAG_SIZE_T);
    1368     1911680 :     va_end(va);
    1369     1911680 :     return retval;
    1370             : }
    1371             : 
    1372             : 
    1373             : int
    1374           0 : PyArg_VaParseTupleAndKeywords(PyObject *args,
    1375             :                               PyObject *keywords,
    1376             :                               const char *format,
    1377             :                               char **kwlist, va_list va)
    1378             : {
    1379             :     int retval;
    1380             :     va_list lva;
    1381             : 
    1382           0 :     if ((args == NULL || !PyTuple_Check(args)) ||
    1383           0 :         (keywords != NULL && !PyDict_Check(keywords)) ||
    1384           0 :         format == NULL ||
    1385             :         kwlist == NULL)
    1386             :     {
    1387           0 :         PyErr_BadInternalCall();
    1388           0 :         return 0;
    1389             :     }
    1390             : 
    1391           0 :     va_copy(lva, va);
    1392             : 
    1393           0 :     retval = vgetargskeywords(args, keywords, format, kwlist, &lva, 0);
    1394           0 :     va_end(lva);
    1395           0 :     return retval;
    1396             : }
    1397             : 
    1398             : PyAPI_FUNC(int)
    1399           0 : _PyArg_VaParseTupleAndKeywords_SizeT(PyObject *args,
    1400             :                                     PyObject *keywords,
    1401             :                                     const char *format,
    1402             :                                     char **kwlist, va_list va)
    1403             : {
    1404             :     int retval;
    1405             :     va_list lva;
    1406             : 
    1407           0 :     if ((args == NULL || !PyTuple_Check(args)) ||
    1408           0 :         (keywords != NULL && !PyDict_Check(keywords)) ||
    1409           0 :         format == NULL ||
    1410             :         kwlist == NULL)
    1411             :     {
    1412           0 :         PyErr_BadInternalCall();
    1413           0 :         return 0;
    1414             :     }
    1415             : 
    1416           0 :     va_copy(lva, va);
    1417             : 
    1418           0 :     retval = vgetargskeywords(args, keywords, format,
    1419             :                               kwlist, &lva, FLAG_SIZE_T);
    1420           0 :     va_end(lva);
    1421           0 :     return retval;
    1422             : }
    1423             : 
    1424             : PyAPI_FUNC(int)
    1425           0 : _PyArg_ParseTupleAndKeywordsFast(PyObject *args, PyObject *keywords,
    1426             :                             struct _PyArg_Parser *parser, ...)
    1427             : {
    1428             :     int retval;
    1429             :     va_list va;
    1430             : 
    1431           0 :     va_start(va, parser);
    1432           0 :     retval = vgetargskeywordsfast(args, keywords, parser, &va, 0);
    1433           0 :     va_end(va);
    1434           0 :     return retval;
    1435             : }
    1436             : 
    1437             : PyAPI_FUNC(int)
    1438           0 : _PyArg_ParseTupleAndKeywordsFast_SizeT(PyObject *args, PyObject *keywords,
    1439             :                             struct _PyArg_Parser *parser, ...)
    1440             : {
    1441             :     int retval;
    1442             :     va_list va;
    1443             : 
    1444           0 :     va_start(va, parser);
    1445           0 :     retval = vgetargskeywordsfast(args, keywords, parser, &va, FLAG_SIZE_T);
    1446           0 :     va_end(va);
    1447           0 :     return retval;
    1448             : }
    1449             : 
    1450             : PyAPI_FUNC(int)
    1451           0 : _PyArg_ParseStackAndKeywords(PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames,
    1452             :                   struct _PyArg_Parser *parser, ...)
    1453             : {
    1454             :     int retval;
    1455             :     va_list va;
    1456             : 
    1457           0 :     va_start(va, parser);
    1458           0 :     retval = vgetargskeywordsfast_impl(args, nargs, NULL, kwnames, parser, &va, 0);
    1459           0 :     va_end(va);
    1460           0 :     return retval;
    1461             : }
    1462             : 
    1463             : PyAPI_FUNC(int)
    1464          53 : _PyArg_ParseStackAndKeywords_SizeT(PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames,
    1465             :                         struct _PyArg_Parser *parser, ...)
    1466             : {
    1467             :     int retval;
    1468             :     va_list va;
    1469             : 
    1470          53 :     va_start(va, parser);
    1471          53 :     retval = vgetargskeywordsfast_impl(args, nargs, NULL, kwnames, parser, &va, FLAG_SIZE_T);
    1472          53 :     va_end(va);
    1473          53 :     return retval;
    1474             : }
    1475             : 
    1476             : 
    1477             : PyAPI_FUNC(int)
    1478           0 : _PyArg_VaParseTupleAndKeywordsFast(PyObject *args, PyObject *keywords,
    1479             :                             struct _PyArg_Parser *parser, va_list va)
    1480             : {
    1481             :     int retval;
    1482             :     va_list lva;
    1483             : 
    1484           0 :     va_copy(lva, va);
    1485             : 
    1486           0 :     retval = vgetargskeywordsfast(args, keywords, parser, &lva, 0);
    1487           0 :     va_end(lva);
    1488           0 :     return retval;
    1489             : }
    1490             : 
    1491             : PyAPI_FUNC(int)
    1492           0 : _PyArg_VaParseTupleAndKeywordsFast_SizeT(PyObject *args, PyObject *keywords,
    1493             :                             struct _PyArg_Parser *parser, va_list va)
    1494             : {
    1495             :     int retval;
    1496             :     va_list lva;
    1497             : 
    1498           0 :     va_copy(lva, va);
    1499             : 
    1500           0 :     retval = vgetargskeywordsfast(args, keywords, parser, &lva, FLAG_SIZE_T);
    1501           0 :     va_end(lva);
    1502           0 :     return retval;
    1503             : }
    1504             : 
    1505             : int
    1506       13577 : PyArg_ValidateKeywordArguments(PyObject *kwargs)
    1507             : {
    1508       13577 :     if (!PyDict_Check(kwargs)) {
    1509           0 :         PyErr_BadInternalCall();
    1510           0 :         return 0;
    1511             :     }
    1512       13577 :     if (!_PyDict_HasOnlyStringKeys(kwargs)) {
    1513           3 :         PyErr_SetString(PyExc_TypeError,
    1514             :                         "keywords must be strings");
    1515           3 :         return 0;
    1516             :     }
    1517       13574 :     return 1;
    1518             : }
    1519             : 
    1520             : #define IS_END_OF_FORMAT(c) (c == '\0' || c == ';' || c == ':')
    1521             : 
    1522             : static int
    1523     8284240 : vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format,
    1524             :                  char **kwlist, va_list *p_va, int flags)
    1525             : {
    1526             :     char msgbuf[512];
    1527             :     int levels[32];
    1528             :     const char *fname, *msg, *custom_msg;
    1529     8284240 :     int min = INT_MAX;
    1530     8284240 :     int max = INT_MAX;
    1531             :     int i, pos, len;
    1532     8284240 :     int skip = 0;
    1533             :     Py_ssize_t nargs, nkwargs;
    1534             :     PyObject *current_arg;
    1535             :     freelistentry_t static_entries[STATIC_FREELIST_ENTRIES];
    1536             :     freelist_t freelist;
    1537             : 
    1538     8284240 :     freelist.entries = static_entries;
    1539     8284240 :     freelist.first_available = 0;
    1540     8284240 :     freelist.entries_malloced = 0;
    1541             : 
    1542     8284240 :     assert(args != NULL && PyTuple_Check(args));
    1543     8284240 :     assert(kwargs == NULL || PyDict_Check(kwargs));
    1544     8284240 :     assert(format != NULL);
    1545     8284240 :     assert(kwlist != NULL);
    1546     8284240 :     assert(p_va != NULL);
    1547             : 
    1548             :     /* grab the function name or custom error msg first (mutually exclusive) */
    1549     8284240 :     fname = strchr(format, ':');
    1550     8284240 :     if (fname) {
    1551     7791330 :         fname++;
    1552     7791330 :         custom_msg = NULL;
    1553             :     }
    1554             :     else {
    1555      492912 :         custom_msg = strchr(format,';');
    1556      492912 :         if (custom_msg)
    1557           3 :             custom_msg++;
    1558             :     }
    1559             : 
    1560             :     /* scan kwlist and count the number of positional-only parameters */
    1561     8285450 :     for (pos = 0; kwlist[pos] && !*kwlist[pos]; pos++) {
    1562             :     }
    1563             :     /* scan kwlist and get greatest possible nbr of args */
    1564    25454400 :     for (len = pos; kwlist[len]; len++) {
    1565    17170100 :         if (!*kwlist[len]) {
    1566           2 :             PyErr_SetString(PyExc_SystemError,
    1567             :                             "Empty keyword parameter name");
    1568           2 :             return cleanreturn(0, &freelist);
    1569             :         }
    1570             :     }
    1571             : 
    1572     8284240 :     if (len > STATIC_FREELIST_ENTRIES) {
    1573       70154 :         freelist.entries = PyMem_NEW(freelistentry_t, len);
    1574       70154 :         if (freelist.entries == NULL) {
    1575           0 :             PyErr_NoMemory();
    1576           0 :             return 0;
    1577             :         }
    1578       70154 :         freelist.entries_malloced = 1;
    1579             :     }
    1580             : 
    1581     8284240 :     nargs = PyTuple_GET_SIZE(args);
    1582     8284240 :     nkwargs = (kwargs == NULL) ? 0 : PyDict_GET_SIZE(kwargs);
    1583     8284240 :     if (nargs + nkwargs > len) {
    1584             :         /* Adding "keyword" (when nargs == 0) prevents producing wrong error
    1585             :            messages in some special cases (see bpo-31229). */
    1586          39 :         PyErr_Format(PyExc_TypeError,
    1587             :                      "%.200s%s takes at most %d %sargument%s (%zd given)",
    1588             :                      (fname == NULL) ? "function" : fname,
    1589             :                      (fname == NULL) ? "" : "()",
    1590             :                      len,
    1591             :                      (nargs == 0) ? "keyword " : "",
    1592             :                      (len == 1) ? "" : "s",
    1593             :                      nargs + nkwargs);
    1594          39 :         return cleanreturn(0, &freelist);
    1595             :     }
    1596             : 
    1597             :     /* convert tuple args and keyword args in same loop, using kwlist to drive process */
    1598    12158800 :     for (i = 0; i < len; i++) {
    1599    10683900 :         if (*format == '|') {
    1600     8122610 :             if (min != INT_MAX) {
    1601           1 :                 PyErr_SetString(PyExc_SystemError,
    1602             :                                 "Invalid format string (| specified twice)");
    1603           1 :                 return cleanreturn(0, &freelist);
    1604             :             }
    1605             : 
    1606     8122610 :             min = i;
    1607     8122610 :             format++;
    1608             : 
    1609     8122610 :             if (max != INT_MAX) {
    1610           1 :                 PyErr_SetString(PyExc_SystemError,
    1611             :                                 "Invalid format string ($ before |)");
    1612           1 :                 return cleanreturn(0, &freelist);
    1613             :             }
    1614             :         }
    1615    10683900 :         if (*format == '$') {
    1616     5761230 :             if (max != INT_MAX) {
    1617           1 :                 PyErr_SetString(PyExc_SystemError,
    1618             :                                 "Invalid format string ($ specified twice)");
    1619           1 :                 return cleanreturn(0, &freelist);
    1620             :             }
    1621             : 
    1622     5761230 :             max = i;
    1623     5761230 :             format++;
    1624             : 
    1625     5761230 :             if (max < pos) {
    1626           2 :                 PyErr_SetString(PyExc_SystemError,
    1627             :                                 "Empty parameter name after $");
    1628           2 :                 return cleanreturn(0, &freelist);
    1629             :             }
    1630     5761230 :             if (skip) {
    1631             :                 /* Now we know the minimal and the maximal numbers of
    1632             :                  * positional arguments and can raise an exception with
    1633             :                  * informative message (see below). */
    1634           4 :                 break;
    1635             :             }
    1636     5761230 :             if (max < nargs) {
    1637           8 :                 if (max == 0) {
    1638           1 :                     PyErr_Format(PyExc_TypeError,
    1639             :                                  "%.200s%s takes no positional arguments",
    1640             :                                  (fname == NULL) ? "function" : fname,
    1641             :                                  (fname == NULL) ? "" : "()");
    1642             :                 }
    1643             :                 else {
    1644           7 :                     PyErr_Format(PyExc_TypeError,
    1645             :                                  "%.200s%s takes %s %d positional argument%s"
    1646             :                                  " (%zd given)",
    1647             :                                  (fname == NULL) ? "function" : fname,
    1648             :                                  (fname == NULL) ? "" : "()",
    1649             :                                  (min != INT_MAX) ? "at most" : "exactly",
    1650             :                                  max,
    1651             :                                  max == 1 ? "" : "s",
    1652             :                                  nargs);
    1653             :                 }
    1654           8 :                 return cleanreturn(0, &freelist);
    1655             :             }
    1656             :         }
    1657    10683900 :         if (IS_END_OF_FORMAT(*format)) {
    1658           5 :             PyErr_Format(PyExc_SystemError,
    1659             :                          "More keyword list entries (%d) than "
    1660             :                          "format specifiers (%d)", len, i);
    1661           5 :             return cleanreturn(0, &freelist);
    1662             :         }
    1663    10683900 :         if (!skip) {
    1664    10683900 :             if (i < nargs) {
    1665     1537950 :                 current_arg = PyTuple_GET_ITEM(args, i);
    1666             :             }
    1667     9145960 :             else if (nkwargs && i >= pos) {
    1668     2337160 :                 current_arg = _PyDict_GetItemStringWithError(kwargs, kwlist[i]);
    1669     2337160 :                 if (current_arg) {
    1670     1651870 :                     --nkwargs;
    1671             :                 }
    1672      685287 :                 else if (PyErr_Occurred()) {
    1673           0 :                     return cleanreturn(0, &freelist);
    1674             :                 }
    1675             :             }
    1676             :             else {
    1677     6808800 :                 current_arg = NULL;
    1678             :             }
    1679             : 
    1680    10683900 :             if (current_arg) {
    1681     3189830 :                 msg = convertitem(current_arg, &format, p_va, flags,
    1682             :                     levels, msgbuf, sizeof(msgbuf), &freelist);
    1683     3189830 :                 if (msg) {
    1684         306 :                     seterror(i+1, msg, levels, fname, custom_msg);
    1685         306 :                     return cleanreturn(0, &freelist);
    1686             :                 }
    1687     3189520 :                 continue;
    1688             :             }
    1689             : 
    1690     7494090 :             if (i < min) {
    1691          49 :                 if (i < pos) {
    1692          10 :                     assert (min == INT_MAX);
    1693          10 :                     assert (max == INT_MAX);
    1694          10 :                     skip = 1;
    1695             :                     /* At that moment we still don't know the minimal and
    1696             :                      * the maximal numbers of positional arguments.  Raising
    1697             :                      * an exception is deferred until we encounter | and $
    1698             :                      * or the end of the format. */
    1699             :                 }
    1700             :                 else {
    1701          39 :                     PyErr_Format(PyExc_TypeError,  "%.200s%s missing required "
    1702             :                                  "argument '%s' (pos %d)",
    1703             :                                  (fname == NULL) ? "function" : fname,
    1704             :                                  (fname == NULL) ? "" : "()",
    1705          39 :                                  kwlist[i], i+1);
    1706          39 :                     return cleanreturn(0, &freelist);
    1707             :                 }
    1708             :             }
    1709             :             /* current code reports success when all required args
    1710             :              * fulfilled and no keyword args left, with no further
    1711             :              * validation. XXX Maybe skip this in debug build ?
    1712             :              */
    1713     7494050 :             if (!nkwargs && !skip) {
    1714     6808770 :                 return cleanreturn(1, &freelist);
    1715             :             }
    1716             :         }
    1717             : 
    1718             :         /* We are into optional args, skip through to any remaining
    1719             :          * keyword args */
    1720      685292 :         msg = skipitem(&format, p_va, flags);
    1721      685292 :         if (msg) {
    1722         211 :             PyErr_Format(PyExc_SystemError, "%s: '%s'", msg,
    1723             :                          format);
    1724         211 :             return cleanreturn(0, &freelist);
    1725             :         }
    1726             :     }
    1727             : 
    1728     1474860 :     if (skip) {
    1729          20 :         PyErr_Format(PyExc_TypeError,
    1730             :                      "%.200s%s takes %s %d positional argument%s"
    1731             :                      " (%zd given)",
    1732             :                      (fname == NULL) ? "function" : fname,
    1733             :                      (fname == NULL) ? "" : "()",
    1734          10 :                      (Py_MIN(pos, min) < i) ? "at least" : "exactly",
    1735             :                      Py_MIN(pos, min),
    1736          10 :                      Py_MIN(pos, min) == 1 ? "" : "s",
    1737             :                      nargs);
    1738          10 :         return cleanreturn(0, &freelist);
    1739             :     }
    1740             : 
    1741     1474850 :     if (!IS_END_OF_FORMAT(*format) && (*format != '|') && (*format != '$')) {
    1742           1 :         PyErr_Format(PyExc_SystemError,
    1743             :             "more argument specifiers than keyword list entries "
    1744             :             "(remaining format:'%s')", format);
    1745           1 :         return cleanreturn(0, &freelist);
    1746             :     }
    1747             : 
    1748     1474850 :     if (nkwargs > 0) {
    1749             :         PyObject *key;
    1750             :         Py_ssize_t j;
    1751             :         /* make sure there are no arguments given by name and position */
    1752          64 :         for (i = pos; i < nargs; i++) {
    1753          24 :             current_arg = _PyDict_GetItemStringWithError(kwargs, kwlist[i]);
    1754          24 :             if (current_arg) {
    1755             :                 /* arg present in tuple and in dict */
    1756           1 :                 PyErr_Format(PyExc_TypeError,
    1757             :                              "argument for %.200s%s given by name ('%s') "
    1758             :                              "and position (%d)",
    1759             :                              (fname == NULL) ? "function" : fname,
    1760             :                              (fname == NULL) ? "" : "()",
    1761           1 :                              kwlist[i], i+1);
    1762          41 :                 return cleanreturn(0, &freelist);
    1763             :             }
    1764          23 :             else if (PyErr_Occurred()) {
    1765           0 :                 return cleanreturn(0, &freelist);
    1766             :             }
    1767             :         }
    1768             :         /* make sure there are no extraneous keyword arguments */
    1769          40 :         j = 0;
    1770          56 :         while (PyDict_Next(kwargs, &j, &key, NULL)) {
    1771          56 :             int match = 0;
    1772          56 :             if (!PyUnicode_Check(key)) {
    1773           0 :                 PyErr_SetString(PyExc_TypeError,
    1774             :                                 "keywords must be strings");
    1775           0 :                 return cleanreturn(0, &freelist);
    1776             :             }
    1777         234 :             for (i = pos; i < len; i++) {
    1778         194 :                 if (_PyUnicode_EqualToASCIIString(key, kwlist[i])) {
    1779          16 :                     match = 1;
    1780          16 :                     break;
    1781             :                 }
    1782             :             }
    1783          56 :             if (!match) {
    1784          40 :                 PyErr_Format(PyExc_TypeError,
    1785             :                              "'%U' is an invalid keyword "
    1786             :                              "argument for %.200s%s",
    1787             :                              key,
    1788             :                              (fname == NULL) ? "this function" : fname,
    1789             :                              (fname == NULL) ? "" : "()");
    1790          40 :                 return cleanreturn(0, &freelist);
    1791             :             }
    1792             :         }
    1793             :     }
    1794             : 
    1795     1474810 :     return cleanreturn(1, &freelist);
    1796             : }
    1797             : 
    1798             : 
    1799             : /* List of static parsers. */
    1800             : static struct _PyArg_Parser *static_arg_parsers = NULL;
    1801             : 
    1802             : static int
    1803     1123730 : parser_init(struct _PyArg_Parser *parser)
    1804             : {
    1805             :     const char * const *keywords;
    1806             :     const char *format, *msg;
    1807             :     int i, len, min, max, nkw;
    1808             :     PyObject *kwtuple;
    1809             : 
    1810     1123730 :     assert(parser->keywords != NULL);
    1811     1123730 :     if (parser->kwtuple != NULL) {
    1812     1103920 :         return 1;
    1813             :     }
    1814             : 
    1815       19805 :     keywords = parser->keywords;
    1816             :     /* scan keywords and count the number of positional-only parameters */
    1817       19898 :     for (i = 0; keywords[i] && !*keywords[i]; i++) {
    1818             :     }
    1819       19805 :     parser->pos = i;
    1820             :     /* scan keywords and get greatest possible nbr of args */
    1821       91872 :     for (; keywords[i]; i++) {
    1822       72067 :         if (!*keywords[i]) {
    1823           0 :             PyErr_SetString(PyExc_SystemError,
    1824             :                             "Empty keyword parameter name");
    1825           0 :             return 0;
    1826             :         }
    1827             :     }
    1828       19805 :     len = i;
    1829             : 
    1830       19805 :     format = parser->format;
    1831       19805 :     if (format) {
    1832             :         /* grab the function name or custom error msg first (mutually exclusive) */
    1833          11 :         parser->fname = strchr(parser->format, ':');
    1834          11 :         if (parser->fname) {
    1835          11 :             parser->fname++;
    1836          11 :             parser->custom_msg = NULL;
    1837             :         }
    1838             :         else {
    1839           0 :             parser->custom_msg = strchr(parser->format,';');
    1840           0 :             if (parser->custom_msg)
    1841           0 :                 parser->custom_msg++;
    1842             :         }
    1843             : 
    1844          11 :         min = max = INT_MAX;
    1845          30 :         for (i = 0; i < len; i++) {
    1846          19 :             if (*format == '|') {
    1847           6 :                 if (min != INT_MAX) {
    1848           0 :                     PyErr_SetString(PyExc_SystemError,
    1849             :                                     "Invalid format string (| specified twice)");
    1850           0 :                     return 0;
    1851             :                 }
    1852           6 :                 if (max != INT_MAX) {
    1853           0 :                     PyErr_SetString(PyExc_SystemError,
    1854             :                                     "Invalid format string ($ before |)");
    1855           0 :                     return 0;
    1856             :                 }
    1857           6 :                 min = i;
    1858           6 :                 format++;
    1859             :             }
    1860          19 :             if (*format == '$') {
    1861           0 :                 if (max != INT_MAX) {
    1862           0 :                     PyErr_SetString(PyExc_SystemError,
    1863             :                                     "Invalid format string ($ specified twice)");
    1864           0 :                     return 0;
    1865             :                 }
    1866           0 :                 if (i < parser->pos) {
    1867           0 :                     PyErr_SetString(PyExc_SystemError,
    1868             :                                     "Empty parameter name after $");
    1869           0 :                     return 0;
    1870             :                 }
    1871           0 :                 max = i;
    1872           0 :                 format++;
    1873             :             }
    1874          19 :             if (IS_END_OF_FORMAT(*format)) {
    1875           0 :                 PyErr_Format(PyExc_SystemError,
    1876             :                             "More keyword list entries (%d) than "
    1877             :                             "format specifiers (%d)", len, i);
    1878           0 :                 return 0;
    1879             :             }
    1880             : 
    1881          19 :             msg = skipitem(&format, NULL, 0);
    1882          19 :             if (msg) {
    1883           0 :                 PyErr_Format(PyExc_SystemError, "%s: '%s'", msg,
    1884             :                             format);
    1885           0 :                 return 0;
    1886             :             }
    1887             :         }
    1888          11 :         parser->min = Py_MIN(min, len);
    1889          11 :         parser->max = Py_MIN(max, len);
    1890             : 
    1891          11 :         if (!IS_END_OF_FORMAT(*format) && (*format != '|') && (*format != '$')) {
    1892           0 :             PyErr_Format(PyExc_SystemError,
    1893             :                 "more argument specifiers than keyword list entries "
    1894             :                 "(remaining format:'%s')", format);
    1895           0 :             return 0;
    1896             :         }
    1897             :     }
    1898             : 
    1899       19805 :     nkw = len - parser->pos;
    1900       19805 :     kwtuple = PyTuple_New(nkw);
    1901       19805 :     if (kwtuple == NULL) {
    1902           0 :         return 0;
    1903             :     }
    1904       19805 :     keywords = parser->keywords + parser->pos;
    1905       91872 :     for (i = 0; i < nkw; i++) {
    1906       72067 :         PyObject *str = PyUnicode_FromString(keywords[i]);
    1907       72067 :         if (str == NULL) {
    1908           0 :             Py_DECREF(kwtuple);
    1909           0 :             return 0;
    1910             :         }
    1911       72067 :         PyUnicode_InternInPlace(&str);
    1912       72067 :         PyTuple_SET_ITEM(kwtuple, i, str);
    1913             :     }
    1914       19805 :     parser->kwtuple = kwtuple;
    1915             : 
    1916       19805 :     assert(parser->next == NULL);
    1917       19805 :     parser->next = static_arg_parsers;
    1918       19805 :     static_arg_parsers = parser;
    1919       19805 :     return 1;
    1920             : }
    1921             : 
    1922             : static void
    1923       19791 : parser_clear(struct _PyArg_Parser *parser)
    1924             : {
    1925       19791 :     Py_CLEAR(parser->kwtuple);
    1926       19791 : }
    1927             : 
    1928             : static PyObject*
    1929     1411220 : find_keyword(PyObject *kwnames, PyObject *const *kwstack, PyObject *key)
    1930             : {
    1931             :     Py_ssize_t i, nkwargs;
    1932             : 
    1933     1411220 :     nkwargs = PyTuple_GET_SIZE(kwnames);
    1934     1914830 :     for (i = 0; i < nkwargs; i++) {
    1935     1583210 :         PyObject *kwname = PyTuple_GET_ITEM(kwnames, i);
    1936             : 
    1937             :         /* kwname == key will normally find a match in since keyword keys
    1938             :            should be interned strings; if not retry below in a new loop. */
    1939     1583210 :         if (kwname == key) {
    1940     1079600 :             return kwstack[i];
    1941             :         }
    1942             :     }
    1943             : 
    1944      743060 :     for (i = 0; i < nkwargs; i++) {
    1945      411694 :         PyObject *kwname = PyTuple_GET_ITEM(kwnames, i);
    1946      411694 :         assert(PyUnicode_Check(kwname));
    1947      411694 :         if (_PyUnicode_EQ(kwname, key)) {
    1948         255 :             return kwstack[i];
    1949             :         }
    1950             :     }
    1951      331366 :     return NULL;
    1952             : }
    1953             : 
    1954             : static int
    1955          53 : vgetargskeywordsfast_impl(PyObject *const *args, Py_ssize_t nargs,
    1956             :                           PyObject *kwargs, PyObject *kwnames,
    1957             :                           struct _PyArg_Parser *parser,
    1958             :                           va_list *p_va, int flags)
    1959             : {
    1960             :     PyObject *kwtuple;
    1961             :     char msgbuf[512];
    1962             :     int levels[32];
    1963             :     const char *format;
    1964             :     const char *msg;
    1965             :     PyObject *keyword;
    1966             :     int i, pos, len;
    1967             :     Py_ssize_t nkwargs;
    1968             :     PyObject *current_arg;
    1969             :     freelistentry_t static_entries[STATIC_FREELIST_ENTRIES];
    1970             :     freelist_t freelist;
    1971          53 :     PyObject *const *kwstack = NULL;
    1972             : 
    1973          53 :     freelist.entries = static_entries;
    1974          53 :     freelist.first_available = 0;
    1975          53 :     freelist.entries_malloced = 0;
    1976             : 
    1977          53 :     assert(kwargs == NULL || PyDict_Check(kwargs));
    1978          53 :     assert(kwargs == NULL || kwnames == NULL);
    1979          53 :     assert(p_va != NULL);
    1980             : 
    1981          53 :     if (parser == NULL) {
    1982           0 :         PyErr_BadInternalCall();
    1983           0 :         return 0;
    1984             :     }
    1985             : 
    1986          53 :     if (kwnames != NULL && !PyTuple_Check(kwnames)) {
    1987           0 :         PyErr_BadInternalCall();
    1988           0 :         return 0;
    1989             :     }
    1990             : 
    1991          53 :     if (!parser_init(parser)) {
    1992           0 :         return 0;
    1993             :     }
    1994             : 
    1995          53 :     kwtuple = parser->kwtuple;
    1996          53 :     pos = parser->pos;
    1997          53 :     len = pos + (int)PyTuple_GET_SIZE(kwtuple);
    1998             : 
    1999          53 :     if (len > STATIC_FREELIST_ENTRIES) {
    2000           0 :         freelist.entries = PyMem_NEW(freelistentry_t, len);
    2001           0 :         if (freelist.entries == NULL) {
    2002           0 :             PyErr_NoMemory();
    2003           0 :             return 0;
    2004             :         }
    2005           0 :         freelist.entries_malloced = 1;
    2006             :     }
    2007             : 
    2008          53 :     if (kwargs != NULL) {
    2009           0 :         nkwargs = PyDict_GET_SIZE(kwargs);
    2010             :     }
    2011          53 :     else if (kwnames != NULL) {
    2012           0 :         nkwargs = PyTuple_GET_SIZE(kwnames);
    2013           0 :         kwstack = args + nargs;
    2014             :     }
    2015             :     else {
    2016          53 :         nkwargs = 0;
    2017             :     }
    2018          53 :     if (nargs + nkwargs > len) {
    2019             :         /* Adding "keyword" (when nargs == 0) prevents producing wrong error
    2020             :            messages in some special cases (see bpo-31229). */
    2021           0 :         PyErr_Format(PyExc_TypeError,
    2022             :                      "%.200s%s takes at most %d %sargument%s (%zd given)",
    2023           0 :                      (parser->fname == NULL) ? "function" : parser->fname,
    2024           0 :                      (parser->fname == NULL) ? "" : "()",
    2025             :                      len,
    2026             :                      (nargs == 0) ? "keyword " : "",
    2027             :                      (len == 1) ? "" : "s",
    2028             :                      nargs + nkwargs);
    2029           0 :         return cleanreturn(0, &freelist);
    2030             :     }
    2031          53 :     if (parser->max < nargs) {
    2032           0 :         if (parser->max == 0) {
    2033           0 :             PyErr_Format(PyExc_TypeError,
    2034             :                          "%.200s%s takes no positional arguments",
    2035           0 :                          (parser->fname == NULL) ? "function" : parser->fname,
    2036           0 :                          (parser->fname == NULL) ? "" : "()");
    2037             :         }
    2038             :         else {
    2039           0 :             PyErr_Format(PyExc_TypeError,
    2040             :                          "%.200s%s takes %s %d positional argument%s (%zd given)",
    2041           0 :                          (parser->fname == NULL) ? "function" : parser->fname,
    2042           0 :                          (parser->fname == NULL) ? "" : "()",
    2043           0 :                          (parser->min < parser->max) ? "at most" : "exactly",
    2044             :                          parser->max,
    2045           0 :                          parser->max == 1 ? "" : "s",
    2046             :                          nargs);
    2047             :         }
    2048           0 :         return cleanreturn(0, &freelist);
    2049             :     }
    2050             : 
    2051          53 :     format = parser->format;
    2052             :     /* convert tuple args and keyword args in same loop, using kwtuple to drive process */
    2053         121 :     for (i = 0; i < len; i++) {
    2054         101 :         if (*format == '|') {
    2055          38 :             format++;
    2056             :         }
    2057         101 :         if (*format == '$') {
    2058           0 :             format++;
    2059             :         }
    2060         101 :         assert(!IS_END_OF_FORMAT(*format));
    2061             : 
    2062         101 :         if (i < nargs) {
    2063          68 :             current_arg = args[i];
    2064             :         }
    2065          33 :         else if (nkwargs && i >= pos) {
    2066           0 :             keyword = PyTuple_GET_ITEM(kwtuple, i - pos);
    2067           0 :             if (kwargs != NULL) {
    2068           0 :                 current_arg = PyDict_GetItemWithError(kwargs, keyword);
    2069           0 :                 if (!current_arg && PyErr_Occurred()) {
    2070           0 :                     return cleanreturn(0, &freelist);
    2071             :                 }
    2072             :             }
    2073             :             else {
    2074           0 :                 current_arg = find_keyword(kwnames, kwstack, keyword);
    2075             :             }
    2076           0 :             if (current_arg) {
    2077           0 :                 --nkwargs;
    2078             :             }
    2079             :         }
    2080             :         else {
    2081          33 :             current_arg = NULL;
    2082             :         }
    2083             : 
    2084         101 :         if (current_arg) {
    2085          68 :             msg = convertitem(current_arg, &format, p_va, flags,
    2086             :                 levels, msgbuf, sizeof(msgbuf), &freelist);
    2087          68 :             if (msg) {
    2088           0 :                 seterror(i+1, msg, levels, parser->fname, parser->custom_msg);
    2089           0 :                 return cleanreturn(0, &freelist);
    2090             :             }
    2091          68 :             continue;
    2092             :         }
    2093             : 
    2094          33 :         if (i < parser->min) {
    2095             :             /* Less arguments than required */
    2096           0 :             if (i < pos) {
    2097           0 :                 Py_ssize_t min = Py_MIN(pos, parser->min);
    2098           0 :                 PyErr_Format(PyExc_TypeError,
    2099             :                              "%.200s%s takes %s %d positional argument%s"
    2100             :                              " (%zd given)",
    2101           0 :                              (parser->fname == NULL) ? "function" : parser->fname,
    2102           0 :                              (parser->fname == NULL) ? "" : "()",
    2103           0 :                              min < parser->max ? "at least" : "exactly",
    2104             :                              min,
    2105             :                              min == 1 ? "" : "s",
    2106             :                              nargs);
    2107             :             }
    2108             :             else {
    2109           0 :                 keyword = PyTuple_GET_ITEM(kwtuple, i - pos);
    2110           0 :                 PyErr_Format(PyExc_TypeError,  "%.200s%s missing required "
    2111             :                              "argument '%U' (pos %d)",
    2112           0 :                              (parser->fname == NULL) ? "function" : parser->fname,
    2113           0 :                              (parser->fname == NULL) ? "" : "()",
    2114             :                              keyword, i+1);
    2115             :             }
    2116           0 :             return cleanreturn(0, &freelist);
    2117             :         }
    2118             :         /* current code reports success when all required args
    2119             :          * fulfilled and no keyword args left, with no further
    2120             :          * validation. XXX Maybe skip this in debug build ?
    2121             :          */
    2122          33 :         if (!nkwargs) {
    2123          33 :             return cleanreturn(1, &freelist);
    2124             :         }
    2125             : 
    2126             :         /* We are into optional args, skip through to any remaining
    2127             :          * keyword args */
    2128           0 :         msg = skipitem(&format, p_va, flags);
    2129           0 :         assert(msg == NULL);
    2130             :     }
    2131             : 
    2132          20 :     assert(IS_END_OF_FORMAT(*format) || (*format == '|') || (*format == '$'));
    2133             : 
    2134          20 :     if (nkwargs > 0) {
    2135             :         Py_ssize_t j;
    2136             :         /* make sure there are no arguments given by name and position */
    2137           0 :         for (i = pos; i < nargs; i++) {
    2138           0 :             keyword = PyTuple_GET_ITEM(kwtuple, i - pos);
    2139           0 :             if (kwargs != NULL) {
    2140           0 :                 current_arg = PyDict_GetItemWithError(kwargs, keyword);
    2141           0 :                 if (!current_arg && PyErr_Occurred()) {
    2142           0 :                     return cleanreturn(0, &freelist);
    2143             :                 }
    2144             :             }
    2145             :             else {
    2146           0 :                 current_arg = find_keyword(kwnames, kwstack, keyword);
    2147             :             }
    2148           0 :             if (current_arg) {
    2149             :                 /* arg present in tuple and in dict */
    2150           0 :                 PyErr_Format(PyExc_TypeError,
    2151             :                              "argument for %.200s%s given by name ('%U') "
    2152             :                              "and position (%d)",
    2153           0 :                              (parser->fname == NULL) ? "function" : parser->fname,
    2154           0 :                              (parser->fname == NULL) ? "" : "()",
    2155             :                              keyword, i+1);
    2156           0 :                 return cleanreturn(0, &freelist);
    2157             :             }
    2158             :         }
    2159             :         /* make sure there are no extraneous keyword arguments */
    2160           0 :         j = 0;
    2161           0 :         while (1) {
    2162             :             int match;
    2163           0 :             if (kwargs != NULL) {
    2164           0 :                 if (!PyDict_Next(kwargs, &j, &keyword, NULL))
    2165           0 :                     break;
    2166             :             }
    2167             :             else {
    2168           0 :                 if (j >= PyTuple_GET_SIZE(kwnames))
    2169           0 :                     break;
    2170           0 :                 keyword = PyTuple_GET_ITEM(kwnames, j);
    2171           0 :                 j++;
    2172             :             }
    2173             : 
    2174           0 :             match = PySequence_Contains(kwtuple, keyword);
    2175           0 :             if (match <= 0) {
    2176           0 :                 if (!match) {
    2177           0 :                     PyErr_Format(PyExc_TypeError,
    2178             :                                  "'%S' is an invalid keyword "
    2179             :                                  "argument for %.200s%s",
    2180             :                                  keyword,
    2181           0 :                                  (parser->fname == NULL) ? "this function" : parser->fname,
    2182           0 :                                  (parser->fname == NULL) ? "" : "()");
    2183             :                 }
    2184           0 :                 return cleanreturn(0, &freelist);
    2185             :             }
    2186             :         }
    2187             :     }
    2188             : 
    2189          20 :     return cleanreturn(1, &freelist);
    2190             : }
    2191             : 
    2192             : static int
    2193           0 : vgetargskeywordsfast(PyObject *args, PyObject *keywords,
    2194             :                      struct _PyArg_Parser *parser, va_list *p_va, int flags)
    2195             : {
    2196             :     PyObject **stack;
    2197             :     Py_ssize_t nargs;
    2198             : 
    2199           0 :     if (args == NULL
    2200           0 :         || !PyTuple_Check(args)
    2201           0 :         || (keywords != NULL && !PyDict_Check(keywords)))
    2202             :     {
    2203           0 :         PyErr_BadInternalCall();
    2204           0 :         return 0;
    2205             :     }
    2206             : 
    2207           0 :     stack = _PyTuple_ITEMS(args);
    2208           0 :     nargs = PyTuple_GET_SIZE(args);
    2209           0 :     return vgetargskeywordsfast_impl(stack, nargs, keywords, NULL,
    2210             :                                      parser, p_va, flags);
    2211             : }
    2212             : 
    2213             : 
    2214             : #undef _PyArg_UnpackKeywords
    2215             : 
    2216             : PyObject * const *
    2217     1014020 : _PyArg_UnpackKeywords(PyObject *const *args, Py_ssize_t nargs,
    2218             :                       PyObject *kwargs, PyObject *kwnames,
    2219             :                       struct _PyArg_Parser *parser,
    2220             :                       int minpos, int maxpos, int minkw,
    2221             :                       PyObject **buf)
    2222             : {
    2223             :     PyObject *kwtuple;
    2224             :     PyObject *keyword;
    2225             :     int i, posonly, minposonly, maxargs;
    2226     1014020 :     int reqlimit = minkw ? maxpos + minkw : minpos;
    2227             :     Py_ssize_t nkwargs;
    2228             :     PyObject *current_arg;
    2229     1014020 :     PyObject * const *kwstack = NULL;
    2230             : 
    2231     1014020 :     assert(kwargs == NULL || PyDict_Check(kwargs));
    2232     1014020 :     assert(kwargs == NULL || kwnames == NULL);
    2233             : 
    2234     1014020 :     if (parser == NULL) {
    2235           0 :         PyErr_BadInternalCall();
    2236           0 :         return NULL;
    2237             :     }
    2238             : 
    2239     1014020 :     if (kwnames != NULL && !PyTuple_Check(kwnames)) {
    2240           0 :         PyErr_BadInternalCall();
    2241           0 :         return NULL;
    2242             :     }
    2243             : 
    2244     1014020 :     if (args == NULL && nargs == 0) {
    2245         816 :         args = buf;
    2246             :     }
    2247             : 
    2248     1014020 :     if (!parser_init(parser)) {
    2249           0 :         return NULL;
    2250             :     }
    2251             : 
    2252     1014020 :     kwtuple = parser->kwtuple;
    2253     1014020 :     posonly = parser->pos;
    2254     1014020 :     minposonly = Py_MIN(posonly, minpos);
    2255     1014020 :     maxargs = posonly + (int)PyTuple_GET_SIZE(kwtuple);
    2256             : 
    2257     1014020 :     if (kwargs != NULL) {
    2258       90143 :         nkwargs = PyDict_GET_SIZE(kwargs);
    2259             :     }
    2260      923881 :     else if (kwnames != NULL) {
    2261      922883 :         nkwargs = PyTuple_GET_SIZE(kwnames);
    2262      922883 :         kwstack = args + nargs;
    2263             :     }
    2264             :     else {
    2265         998 :         nkwargs = 0;
    2266             :     }
    2267     1014020 :     if (nkwargs == 0 && minkw == 0 && minpos <= nargs && nargs <= maxpos) {
    2268             :         /* Fast path. */
    2269       45375 :         return args;
    2270             :     }
    2271      968649 :     if (nargs + nkwargs > maxargs) {
    2272             :         /* Adding "keyword" (when nargs == 0) prevents producing wrong error
    2273             :            messages in some special cases (see bpo-31229). */
    2274         117 :         PyErr_Format(PyExc_TypeError,
    2275             :                      "%.200s%s takes at most %d %sargument%s (%zd given)",
    2276          39 :                      (parser->fname == NULL) ? "function" : parser->fname,
    2277          39 :                      (parser->fname == NULL) ? "" : "()",
    2278             :                      maxargs,
    2279             :                      (nargs == 0) ? "keyword " : "",
    2280             :                      (maxargs == 1) ? "" : "s",
    2281             :                      nargs + nkwargs);
    2282          39 :         return NULL;
    2283             :     }
    2284      968610 :     if (nargs > maxpos) {
    2285          20 :         if (maxpos == 0) {
    2286          14 :             PyErr_Format(PyExc_TypeError,
    2287             :                          "%.200s%s takes no positional arguments",
    2288           7 :                          (parser->fname == NULL) ? "function" : parser->fname,
    2289           7 :                          (parser->fname == NULL) ? "" : "()");
    2290             :         }
    2291             :         else {
    2292          39 :             PyErr_Format(PyExc_TypeError,
    2293             :                          "%.200s%s takes %s %d positional argument%s (%zd given)",
    2294          13 :                          (parser->fname == NULL) ? "function" : parser->fname,
    2295          13 :                          (parser->fname == NULL) ? "" : "()",
    2296             :                          (minpos < maxpos) ? "at most" : "exactly",
    2297             :                          maxpos,
    2298             :                          (maxpos == 1) ? "" : "s",
    2299             :                          nargs);
    2300             :         }
    2301          20 :         return NULL;
    2302             :     }
    2303      968590 :     if (nargs < minposonly) {
    2304         180 :         PyErr_Format(PyExc_TypeError,
    2305             :                      "%.200s%s takes %s %d positional argument%s"
    2306             :                      " (%zd given)",
    2307          60 :                      (parser->fname == NULL) ? "function" : parser->fname,
    2308          60 :                      (parser->fname == NULL) ? "" : "()",
    2309             :                      minposonly < maxpos ? "at least" : "exactly",
    2310             :                      minposonly,
    2311             :                      minposonly == 1 ? "" : "s",
    2312             :                      nargs);
    2313          60 :         return NULL;
    2314             :     }
    2315             : 
    2316             :     /* copy tuple args */
    2317     1318060 :     for (i = 0; i < nargs; i++) {
    2318      349534 :         buf[i] = args[i];
    2319             :     }
    2320             : 
    2321             :     /* copy keyword args using kwtuple to drive process */
    2322     2236640 :     for (i = Py_MAX((int)nargs, posonly); i < maxargs; i++) {
    2323     1634210 :         if (nkwargs) {
    2324     1268120 :             keyword = PyTuple_GET_ITEM(kwtuple, i - posonly);
    2325     1268120 :             if (kwargs != NULL) {
    2326       94707 :                 current_arg = PyDict_GetItemWithError(kwargs, keyword);
    2327       94707 :                 if (!current_arg && PyErr_Occurred()) {
    2328           0 :                     return NULL;
    2329             :                 }
    2330             :             }
    2331             :             else {
    2332     1173410 :                 current_arg = find_keyword(kwnames, kwstack, keyword);
    2333             :             }
    2334             :         }
    2335      366088 :         else if (i >= reqlimit) {
    2336      365993 :             break;
    2337             :         }
    2338             :         else {
    2339          95 :             current_arg = NULL;
    2340             :         }
    2341             : 
    2342     1268210 :         buf[i] = current_arg;
    2343             : 
    2344     1268210 :         if (current_arg) {
    2345     1038500 :             --nkwargs;
    2346             :         }
    2347      229716 :         else if (i < minpos || (maxpos <= i && i < reqlimit)) {
    2348             :             /* Less arguments than required */
    2349         106 :             keyword = PyTuple_GET_ITEM(kwtuple, i - posonly);
    2350         212 :             PyErr_Format(PyExc_TypeError,  "%.200s%s missing required "
    2351             :                          "argument '%U' (pos %d)",
    2352         106 :                          (parser->fname == NULL) ? "function" : parser->fname,
    2353         106 :                          (parser->fname == NULL) ? "" : "()",
    2354             :                          keyword, i+1);
    2355         106 :             return NULL;
    2356             :         }
    2357             :     }
    2358             : 
    2359      968424 :     if (nkwargs > 0) {
    2360             :         Py_ssize_t j;
    2361             :         /* make sure there are no arguments given by name and position */
    2362          20 :         for (i = posonly; i < nargs; i++) {
    2363           3 :             keyword = PyTuple_GET_ITEM(kwtuple, i - posonly);
    2364           3 :             if (kwargs != NULL) {
    2365           1 :                 current_arg = PyDict_GetItemWithError(kwargs, keyword);
    2366           1 :                 if (!current_arg && PyErr_Occurred()) {
    2367          19 :                     return NULL;
    2368             :                 }
    2369             :             }
    2370             :             else {
    2371           2 :                 current_arg = find_keyword(kwnames, kwstack, keyword);
    2372             :             }
    2373           3 :             if (current_arg) {
    2374             :                 /* arg present in tuple and in dict */
    2375           4 :                 PyErr_Format(PyExc_TypeError,
    2376             :                              "argument for %.200s%s given by name ('%U') "
    2377             :                              "and position (%d)",
    2378           2 :                              (parser->fname == NULL) ? "function" : parser->fname,
    2379           2 :                              (parser->fname == NULL) ? "" : "()",
    2380             :                              keyword, i+1);
    2381           2 :                 return NULL;
    2382             :             }
    2383             :         }
    2384             :         /* make sure there are no extraneous keyword arguments */
    2385          17 :         j = 0;
    2386           1 :         while (1) {
    2387             :             int match;
    2388          18 :             if (kwargs != NULL) {
    2389          15 :                 if (!PyDict_Next(kwargs, &j, &keyword, NULL))
    2390           0 :                     break;
    2391             :             }
    2392             :             else {
    2393           3 :                 if (j >= PyTuple_GET_SIZE(kwnames))
    2394           0 :                     break;
    2395           3 :                 keyword = PyTuple_GET_ITEM(kwnames, j);
    2396           3 :                 j++;
    2397             :             }
    2398             : 
    2399          18 :             match = PySequence_Contains(kwtuple, keyword);
    2400          18 :             if (match <= 0) {
    2401          17 :                 if (!match) {
    2402          34 :                     PyErr_Format(PyExc_TypeError,
    2403             :                                  "'%S' is an invalid keyword "
    2404             :                                  "argument for %.200s%s",
    2405             :                                  keyword,
    2406          17 :                                  (parser->fname == NULL) ? "this function" : parser->fname,
    2407          17 :                                  (parser->fname == NULL) ? "" : "()");
    2408             :                 }
    2409          17 :                 return NULL;
    2410             :             }
    2411             :         }
    2412             :     }
    2413             : 
    2414      968405 :     return buf;
    2415             : }
    2416             : 
    2417             : PyObject * const *
    2418      109653 : _PyArg_UnpackKeywordsWithVararg(PyObject *const *args, Py_ssize_t nargs,
    2419             :                                 PyObject *kwargs, PyObject *kwnames,
    2420             :                                 struct _PyArg_Parser *parser,
    2421             :                                 int minpos, int maxpos, int minkw,
    2422             :                                 int vararg, PyObject **buf)
    2423             : {
    2424             :     PyObject *kwtuple;
    2425             :     PyObject *keyword;
    2426      109653 :     Py_ssize_t varargssize = 0;
    2427             :     int i, posonly, minposonly, maxargs;
    2428      109653 :     int reqlimit = minkw ? maxpos + minkw : minpos;
    2429             :     Py_ssize_t nkwargs;
    2430             :     PyObject *current_arg;
    2431      109653 :     PyObject * const *kwstack = NULL;
    2432             : 
    2433      109653 :     assert(kwargs == NULL || PyDict_Check(kwargs));
    2434      109653 :     assert(kwargs == NULL || kwnames == NULL);
    2435             : 
    2436      109653 :     if (parser == NULL) {
    2437           0 :         PyErr_BadInternalCall();
    2438           0 :         return NULL;
    2439             :     }
    2440             : 
    2441      109653 :     if (kwnames != NULL && !PyTuple_Check(kwnames)) {
    2442           0 :         PyErr_BadInternalCall();
    2443           0 :         return NULL;
    2444             :     }
    2445             : 
    2446      109653 :     if (args == NULL && nargs == 0) {
    2447           0 :         args = buf;
    2448             :     }
    2449             : 
    2450      109653 :     if (!parser_init(parser)) {
    2451           0 :         return NULL;
    2452             :     }
    2453             : 
    2454      109653 :     kwtuple = parser->kwtuple;
    2455      109653 :     posonly = parser->pos;
    2456      109653 :     minposonly = Py_MIN(posonly, minpos);
    2457      109653 :     maxargs = posonly + (int)PyTuple_GET_SIZE(kwtuple);
    2458      109653 :     if (kwargs != NULL) {
    2459           0 :         nkwargs = PyDict_GET_SIZE(kwargs);
    2460             :     }
    2461      109653 :     else if (kwnames != NULL) {
    2462       80416 :         nkwargs = PyTuple_GET_SIZE(kwnames);
    2463       80416 :         kwstack = args + nargs;
    2464             :     }
    2465             :     else {
    2466       29237 :         nkwargs = 0;
    2467             :     }
    2468      109653 :     if (nargs < minposonly) {
    2469           0 :         PyErr_Format(PyExc_TypeError,
    2470             :                      "%.200s%s takes %s %d positional argument%s"
    2471             :                      " (%zd given)",
    2472           0 :                      (parser->fname == NULL) ? "function" : parser->fname,
    2473           0 :                      (parser->fname == NULL) ? "" : "()",
    2474             :                      minposonly < maxpos ? "at least" : "exactly",
    2475             :                      minposonly,
    2476             :                      minposonly == 1 ? "" : "s",
    2477             :                      nargs);
    2478           0 :         return NULL;
    2479             :     }
    2480             : 
    2481             :     /* create varargs tuple */
    2482      109653 :     varargssize = nargs - maxpos;
    2483      109653 :     if (varargssize < 0) {
    2484           0 :         varargssize = 0;
    2485             :     }
    2486      109653 :     buf[vararg] = PyTuple_New(varargssize);
    2487      109653 :     if (!buf[vararg]) {
    2488           0 :         return NULL;
    2489             :     }
    2490             : 
    2491             :     /* copy tuple args */
    2492      217048 :     for (i = 0; i < nargs; i++) {
    2493      107395 :         if (i >= vararg) {
    2494      107395 :             Py_INCREF(args[i]);
    2495      107395 :             PyTuple_SET_ITEM(buf[vararg], i - vararg, args[i]);
    2496      107395 :             continue;
    2497             :         }
    2498             :         else {
    2499           0 :             buf[i] = args[i];
    2500             :         }
    2501             :     }
    2502             : 
    2503             :     /* copy keyword args using kwtuple to drive process */
    2504      548265 :     for (i = Py_MAX((int)nargs, posonly) -
    2505      548265 :          Py_SAFE_DOWNCAST(varargssize, Py_ssize_t, int); i < maxargs; i++) {
    2506      438612 :         if (nkwargs) {
    2507      237804 :             keyword = PyTuple_GET_ITEM(kwtuple, i - posonly);
    2508      237804 :             if (kwargs != NULL) {
    2509           0 :                 current_arg = PyDict_GetItemWithError(kwargs, keyword);
    2510           0 :                 if (!current_arg && PyErr_Occurred()) {
    2511           0 :                     goto exit;
    2512             :                 }
    2513             :             }
    2514             :             else {
    2515      237804 :                 current_arg = find_keyword(kwnames, kwstack, keyword);
    2516             :             }
    2517             :         }
    2518             :         else {
    2519      200808 :             current_arg = NULL;
    2520             :         }
    2521             : 
    2522      438612 :         buf[i + vararg + 1] = current_arg;
    2523             : 
    2524      438612 :         if (current_arg) {
    2525      105014 :             --nkwargs;
    2526             :         }
    2527      333598 :         else if (i < minpos || (maxpos <= i && i < reqlimit)) {
    2528             :             /* Less arguments than required */
    2529           0 :             keyword = PyTuple_GET_ITEM(kwtuple, i - posonly);
    2530           0 :             PyErr_Format(PyExc_TypeError,  "%.200s%s missing required "
    2531             :                          "argument '%U' (pos %d)",
    2532           0 :                          (parser->fname == NULL) ? "function" : parser->fname,
    2533           0 :                          (parser->fname == NULL) ? "" : "()",
    2534             :                          keyword, i+1);
    2535           0 :             goto exit;
    2536             :         }
    2537             :     }
    2538             : 
    2539      109653 :     if (nkwargs > 0) {
    2540             :         Py_ssize_t j;
    2541             :         /* make sure there are no extraneous keyword arguments */
    2542           1 :         j = 0;
    2543           4 :         while (1) {
    2544             :             int match;
    2545           5 :             if (kwargs != NULL) {
    2546           0 :                 if (!PyDict_Next(kwargs, &j, &keyword, NULL))
    2547           0 :                     break;
    2548             :             }
    2549             :             else {
    2550           5 :                 if (j >= PyTuple_GET_SIZE(kwnames))
    2551           0 :                     break;
    2552           5 :                 keyword = PyTuple_GET_ITEM(kwnames, j);
    2553           5 :                 j++;
    2554             :             }
    2555             : 
    2556           5 :             match = PySequence_Contains(kwtuple, keyword);
    2557           5 :             if (match <= 0) {
    2558           1 :                 if (!match) {
    2559           2 :                     PyErr_Format(PyExc_TypeError,
    2560             :                                  "'%S' is an invalid keyword "
    2561             :                                  "argument for %.200s%s",
    2562             :                                  keyword,
    2563           1 :                                  (parser->fname == NULL) ? "this function" : parser->fname,
    2564           1 :                                  (parser->fname == NULL) ? "" : "()");
    2565             :                 }
    2566           1 :                 goto exit;
    2567             :             }
    2568             :         }
    2569             :     }
    2570             : 
    2571      109652 :     return buf;
    2572             : 
    2573           1 : exit:
    2574           1 :     Py_XDECREF(buf[vararg]);
    2575           1 :     return NULL;
    2576             : }
    2577             : 
    2578             : 
    2579             : static const char *
    2580      685325 : skipitem(const char **p_format, va_list *p_va, int flags)
    2581             : {
    2582      685325 :     const char *format = *p_format;
    2583      685325 :     char c = *format++;
    2584             : 
    2585      685325 :     switch (c) {
    2586             : 
    2587             :     /*
    2588             :      * codes that take a single data pointer as an argument
    2589             :      * (the type of the pointer is irrelevant)
    2590             :      */
    2591             : 
    2592      367384 :     case 'b': /* byte -- very short int */
    2593             :     case 'B': /* byte as bitfield */
    2594             :     case 'h': /* short int */
    2595             :     case 'H': /* short int as bitfield */
    2596             :     case 'i': /* int */
    2597             :     case 'I': /* int sized bitfield */
    2598             :     case 'l': /* long int */
    2599             :     case 'k': /* long int sized bitfield */
    2600             :     case 'L': /* long long */
    2601             :     case 'K': /* long long sized bitfield */
    2602             :     case 'n': /* Py_ssize_t */
    2603             :     case 'f': /* float */
    2604             :     case 'd': /* double */
    2605             :     case 'D': /* complex double */
    2606             :     case 'c': /* char */
    2607             :     case 'C': /* unicode char */
    2608             :     case 'p': /* boolean predicate */
    2609             :     case 'S': /* string object */
    2610             :     case 'Y': /* string object */
    2611             :     case 'U': /* unicode string object */
    2612             :         {
    2613      367384 :             if (p_va != NULL) {
    2614      367376 :                 (void) va_arg(*p_va, void *);
    2615             :             }
    2616      367384 :             break;
    2617             :         }
    2618             : 
    2619             :     /* string codes */
    2620             : 
    2621          98 :     case 'e': /* string with encoding */
    2622             :         {
    2623          98 :             if (p_va != NULL) {
    2624          98 :                 (void) va_arg(*p_va, const char *);
    2625             :             }
    2626          98 :             if (!(*format == 's' || *format == 't'))
    2627             :                 /* after 'e', only 's' and 't' is allowed */
    2628          96 :                 goto err;
    2629           2 :             format++;
    2630             :         }
    2631             :         /* fall through */
    2632             : 
    2633          25 :     case 's': /* string */
    2634             :     case 'z': /* string or None */
    2635             :     case 'y': /* bytes */
    2636             :     case 'w': /* buffer, read-write */
    2637             :         {
    2638          25 :             if (p_va != NULL) {
    2639          20 :                 (void) va_arg(*p_va, char **);
    2640             :             }
    2641          25 :             if (*format == '#') {
    2642          10 :                 if (p_va != NULL) {
    2643           5 :                     if (!(flags & FLAG_SIZE_T)) {
    2644           1 :                         PyErr_SetString(PyExc_SystemError,
    2645             :                                 "PY_SSIZE_T_CLEAN macro must be defined for '#' formats");
    2646           1 :                         return NULL;
    2647             :                     }
    2648           4 :                     (void) va_arg(*p_va, Py_ssize_t *);
    2649             :                 }
    2650           9 :                 format++;
    2651          15 :             } else if ((c == 's' || c == 'z' || c == 'y' || c == 'w')
    2652          13 :                        && *format == '*')
    2653             :             {
    2654           6 :                 format++;
    2655             :             }
    2656          24 :             break;
    2657             :         }
    2658             : 
    2659      317699 :     case 'O': /* object */
    2660             :         {
    2661      317699 :             if (*format == '!') {
    2662           1 :                 format++;
    2663           1 :                 if (p_va != NULL) {
    2664           1 :                     (void) va_arg(*p_va, PyTypeObject*);
    2665           1 :                     (void) va_arg(*p_va, PyObject **);
    2666             :                 }
    2667             :             }
    2668      317698 :             else if (*format == '&') {
    2669             :                 typedef int (*converter)(PyObject *, void *);
    2670          40 :                 if (p_va != NULL) {
    2671          38 :                     (void) va_arg(*p_va, converter);
    2672          38 :                     (void) va_arg(*p_va, void *);
    2673             :                 }
    2674          40 :                 format++;
    2675             :             }
    2676             :             else {
    2677      317658 :                 if (p_va != NULL) {
    2678      317654 :                     (void) va_arg(*p_va, PyObject **);
    2679             :                 }
    2680             :             }
    2681      317699 :             break;
    2682             :         }
    2683             : 
    2684          20 :     case '(':           /* bypass tuple, not handled at all previously */
    2685             :         {
    2686             :             const char *msg;
    2687             :             for (;;) {
    2688          20 :                 if (*format==')')
    2689           6 :                     break;
    2690          14 :                 if (IS_END_OF_FORMAT(*format))
    2691           0 :                     return "Unmatched left paren in format "
    2692             :                            "string";
    2693          14 :                 msg = skipitem(&format, p_va, flags);
    2694          14 :                 if (msg)
    2695           0 :                     return msg;
    2696             :             }
    2697           6 :             format++;
    2698           6 :             break;
    2699             :         }
    2700             : 
    2701           0 :     case ')':
    2702           0 :         return "Unmatched right paren in format string";
    2703             : 
    2704             :     default:
    2705         211 : err:
    2706         211 :         return "impossible<bad format char>";
    2707             : 
    2708             :     }
    2709             : 
    2710      685113 :     *p_format = format;
    2711      685113 :     return NULL;
    2712             : }
    2713             : 
    2714             : 
    2715             : #undef _PyArg_CheckPositional
    2716             : 
    2717             : int
    2718    13283300 : _PyArg_CheckPositional(const char *name, Py_ssize_t nargs,
    2719             :                        Py_ssize_t min, Py_ssize_t max)
    2720             : {
    2721    13283300 :     assert(min >= 0);
    2722    13283300 :     assert(min <= max);
    2723             : 
    2724    13283300 :     if (nargs < min) {
    2725         284 :         if (name != NULL)
    2726         284 :             PyErr_Format(
    2727             :                 PyExc_TypeError,
    2728             :                 "%.200s expected %s%zd argument%s, got %zd",
    2729             :                 name, (min == max ? "" : "at least "), min, min == 1 ? "" : "s", nargs);
    2730             :         else
    2731           0 :             PyErr_Format(
    2732             :                 PyExc_TypeError,
    2733             :                 "unpacked tuple should have %s%zd element%s,"
    2734             :                 " but has %zd",
    2735             :                 (min == max ? "" : "at least "), min, min == 1 ? "" : "s", nargs);
    2736         284 :         return 0;
    2737             :     }
    2738             : 
    2739    13283000 :     if (nargs == 0) {
    2740       92160 :         return 1;
    2741             :     }
    2742             : 
    2743    13190800 :     if (nargs > max) {
    2744         109 :         if (name != NULL)
    2745         109 :             PyErr_Format(
    2746             :                 PyExc_TypeError,
    2747             :                 "%.200s expected %s%zd argument%s, got %zd",
    2748             :                 name, (min == max ? "" : "at most "), max, max == 1 ? "" : "s", nargs);
    2749             :         else
    2750           0 :             PyErr_Format(
    2751             :                 PyExc_TypeError,
    2752             :                 "unpacked tuple should have %s%zd element%s,"
    2753             :                 " but has %zd",
    2754             :                 (min == max ? "" : "at most "), max, max == 1 ? "" : "s", nargs);
    2755         109 :         return 0;
    2756             :     }
    2757             : 
    2758    13190700 :     return 1;
    2759             : }
    2760             : 
    2761             : static int
    2762    13282900 : unpack_stack(PyObject *const *args, Py_ssize_t nargs, const char *name,
    2763             :              Py_ssize_t min, Py_ssize_t max, va_list vargs)
    2764             : {
    2765             :     Py_ssize_t i;
    2766             :     PyObject **o;
    2767             : 
    2768    13282900 :     if (!_PyArg_CheckPositional(name, nargs, min, max)) {
    2769          61 :         return 0;
    2770             :     }
    2771             : 
    2772    32862200 :     for (i = 0; i < nargs; i++) {
    2773    19579400 :         o = va_arg(vargs, PyObject **);
    2774    19579400 :         *o = args[i];
    2775             :     }
    2776    13282900 :     return 1;
    2777             : }
    2778             : 
    2779             : int
    2780    12084200 : PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, ...)
    2781             : {
    2782             :     PyObject **stack;
    2783             :     Py_ssize_t nargs;
    2784             :     int retval;
    2785             :     va_list vargs;
    2786             : 
    2787    12084200 :     if (!PyTuple_Check(args)) {
    2788           0 :         PyErr_SetString(PyExc_SystemError,
    2789             :             "PyArg_UnpackTuple() argument list is not a tuple");
    2790           0 :         return 0;
    2791             :     }
    2792    12084200 :     stack = _PyTuple_ITEMS(args);
    2793    12084200 :     nargs = PyTuple_GET_SIZE(args);
    2794             : 
    2795    12084200 :     va_start(vargs, max);
    2796    12084200 :     retval = unpack_stack(stack, nargs, name, min, max, vargs);
    2797    12084200 :     va_end(vargs);
    2798    12084200 :     return retval;
    2799             : }
    2800             : 
    2801             : int
    2802     1198750 : _PyArg_UnpackStack(PyObject *const *args, Py_ssize_t nargs, const char *name,
    2803             :                    Py_ssize_t min, Py_ssize_t max, ...)
    2804             : {
    2805             :     int retval;
    2806             :     va_list vargs;
    2807             : 
    2808     1198750 :     va_start(vargs, max);
    2809     1198750 :     retval = unpack_stack(args, nargs, name, min, max, vargs);
    2810     1198750 :     va_end(vargs);
    2811     1198750 :     return retval;
    2812             : }
    2813             : 
    2814             : 
    2815             : #undef _PyArg_NoKeywords
    2816             : #undef _PyArg_NoKwnames
    2817             : #undef _PyArg_NoPositional
    2818             : 
    2819             : /* For type constructors that don't take keyword args
    2820             :  *
    2821             :  * Sets a TypeError and returns 0 if the args/kwargs is
    2822             :  * not empty, returns 1 otherwise
    2823             :  */
    2824             : int
    2825       58734 : _PyArg_NoKeywords(const char *funcname, PyObject *kwargs)
    2826             : {
    2827       58734 :     if (kwargs == NULL) {
    2828           0 :         return 1;
    2829             :     }
    2830       58734 :     if (!PyDict_CheckExact(kwargs)) {
    2831           0 :         PyErr_BadInternalCall();
    2832           0 :         return 0;
    2833             :     }
    2834       58734 :     if (PyDict_GET_SIZE(kwargs) == 0) {
    2835       58705 :         return 1;
    2836             :     }
    2837             : 
    2838          29 :     PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments",
    2839             :                     funcname);
    2840          29 :     return 0;
    2841             : }
    2842             : 
    2843             : int
    2844       12168 : _PyArg_NoPositional(const char *funcname, PyObject *args)
    2845             : {
    2846       12168 :     if (args == NULL)
    2847           0 :         return 1;
    2848       12168 :     if (!PyTuple_CheckExact(args)) {
    2849           0 :         PyErr_BadInternalCall();
    2850           0 :         return 0;
    2851             :     }
    2852       12168 :     if (PyTuple_GET_SIZE(args) == 0)
    2853       12167 :         return 1;
    2854             : 
    2855           1 :     PyErr_Format(PyExc_TypeError, "%.200s() takes no positional arguments",
    2856             :                     funcname);
    2857           1 :     return 0;
    2858             : }
    2859             : 
    2860             : int
    2861          18 : _PyArg_NoKwnames(const char *funcname, PyObject *kwnames)
    2862             : {
    2863          18 :     if (kwnames == NULL) {
    2864           0 :         return 1;
    2865             :     }
    2866             : 
    2867          18 :     assert(PyTuple_CheckExact(kwnames));
    2868             : 
    2869          18 :     if (PyTuple_GET_SIZE(kwnames) == 0) {
    2870           0 :         return 1;
    2871             :     }
    2872             : 
    2873          18 :     PyErr_Format(PyExc_TypeError, "%s() takes no keyword arguments", funcname);
    2874          18 :     return 0;
    2875             : }
    2876             : 
    2877             : void
    2878        2951 : _PyArg_Fini(void)
    2879             : {
    2880        2951 :     struct _PyArg_Parser *tmp, *s = static_arg_parsers;
    2881       22742 :     while (s) {
    2882       19791 :         tmp = s->next;
    2883       19791 :         s->next = NULL;
    2884       19791 :         parser_clear(s);
    2885       19791 :         s = tmp;
    2886             :     }
    2887        2951 :     static_arg_parsers = NULL;
    2888        2951 : }
    2889             : 
    2890             : #ifdef __cplusplus
    2891             : };
    2892             : #endif

Generated by: LCOV version 1.14