LCOV - code coverage report
Current view: top level - Python - getargs.c (source / functions) Hit Total Coverage
Test: CPython 3.12 LCOV report [commit acb105a7c1f] Lines: 1057 1330 79.5 %
Date: 2022-07-20 13:12:14 Functions: 38 50 76.0 %
Branches: 775 1102 70.3 %

           Branch data     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                 :    2364863 : _PyArg_Parse_SizeT(PyObject *args, const char *format, ...)
     112                 :            : {
     113                 :            :     int retval;
     114                 :            :     va_list va;
     115                 :            : 
     116                 :    2364863 :     va_start(va, format);
     117                 :    2364863 :     retval = vgetargs1(args, format, &va, FLAG_COMPAT|FLAG_SIZE_T);
     118                 :    2364863 :     va_end(va);
     119                 :    2364863 :     return retval;
     120                 :            : }
     121                 :            : 
     122                 :            : 
     123                 :            : int
     124                 :    2408469 : PyArg_ParseTuple(PyObject *args, const char *format, ...)
     125                 :            : {
     126                 :            :     int retval;
     127                 :            :     va_list va;
     128                 :            : 
     129                 :    2408469 :     va_start(va, format);
     130                 :    2408469 :     retval = vgetargs1(args, format, &va, 0);
     131                 :    2408469 :     va_end(va);
     132                 :    2408469 :     return retval;
     133                 :            : }
     134                 :            : 
     135                 :            : PyAPI_FUNC(int)
     136                 :   16109523 : _PyArg_ParseTuple_SizeT(PyObject *args, const char *format, ...)
     137                 :            : {
     138                 :            :     int retval;
     139                 :            :     va_list va;
     140                 :            : 
     141                 :   16109523 :     va_start(va, format);
     142                 :   16109523 :     retval = vgetargs1(args, format, &va, FLAG_SIZE_T);
     143                 :   16109523 :     va_end(va);
     144                 :   16109523 :     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                 :      61701 : _PyArg_ParseStack_SizeT(PyObject *const *args, Py_ssize_t nargs, const char *format, ...)
     162                 :            : {
     163                 :            :     int retval;
     164                 :            :     va_list va;
     165                 :            : 
     166                 :      61701 :     va_start(va, format);
     167                 :      61701 :     retval = vgetargs1_impl(NULL, args, nargs, format, &va, FLAG_SIZE_T);
     168                 :      61701 :     va_end(va);
     169                 :      61701 :     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                 :          8 : cleanup_buffer(PyObject *self, void *ptr)
     213                 :            : {
     214                 :          8 :     Py_buffer *buf = (Py_buffer *)ptr;
     215         [ +  - ]:          8 :     if (buf) {
     216                 :          8 :         PyBuffer_Release(buf);
     217                 :            :     }
     218                 :          8 :     return 0;
     219                 :            : }
     220                 :            : 
     221                 :            : static int
     222                 :    2015239 : addcleanup(void *ptr, freelist_t *freelist, destr_t destructor)
     223                 :            : {
     224                 :            :     int index;
     225                 :            : 
     226                 :    2015239 :     index = freelist->first_available;
     227                 :    2015239 :     freelist->first_available += 1;
     228                 :            : 
     229                 :    2015239 :     freelist->entries[index].item = ptr;
     230                 :    2015239 :     freelist->entries[index].destructor = destructor;
     231                 :            : 
     232                 :    2015239 :     return 0;
     233                 :            : }
     234                 :            : 
     235                 :            : static int
     236                 :   29158387 : cleanreturn(int retval, freelist_t *freelist)
     237                 :            : {
     238                 :            :     int index;
     239                 :            : 
     240         [ +  + ]:   29158387 :     if (retval == 0) {
     241                 :            :       /* A failure occurred, therefore execute all of the cleanup
     242                 :            :          functions.
     243                 :            :       */
     244         [ +  + ]:       1687 :       for (index = 0; index < freelist->first_available; ++index) {
     245                 :          9 :           freelist->entries[index].destructor(NULL,
     246                 :          9 :                                               freelist->entries[index].item);
     247                 :            :       }
     248                 :            :     }
     249         [ +  + ]:   29158387 :     if (freelist->entries_malloced)
     250                 :      91778 :         PyMem_Free(freelist->entries);
     251                 :   29158387 :     return retval;
     252                 :            : }
     253                 :            : 
     254                 :            : 
     255                 :            : static int
     256                 :   21012276 : 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                 :   21012276 :     const char *fname = NULL;
     262                 :   21012276 :     const char *message = NULL;
     263                 :   21012276 :     int min = -1;
     264                 :   21012276 :     int max = 0;
     265                 :   21012276 :     int level = 0;
     266                 :   21012276 :     int endfmt = 0;
     267                 :   21012276 :     const char *formatsave = format;
     268                 :            :     Py_ssize_t i;
     269                 :            :     const char *msg;
     270                 :   21012276 :     int compat = flags & FLAG_COMPAT;
     271                 :            :     freelistentry_t static_entries[STATIC_FREELIST_ENTRIES];
     272                 :            :     freelist_t freelist;
     273                 :            : 
     274                 :            :     assert(nargs == 0 || stack != NULL);
     275                 :            : 
     276                 :   21012276 :     freelist.entries = static_entries;
     277                 :   21012276 :     freelist.first_available = 0;
     278                 :   21012276 :     freelist.entries_malloced = 0;
     279                 :            : 
     280                 :   21012276 :     flags = flags & ~FLAG_COMPAT;
     281                 :            : 
     282         [ +  + ]:  118554625 :     while (endfmt == 0) {
     283                 :   97542349 :         int c = *format++;
     284   [ +  +  +  +  :   97542349 :         switch (c) {
                +  +  + ]
     285                 :       1274 :         case '(':
     286         [ +  - ]:       1274 :             if (level == 0)
     287                 :       1274 :                 max++;
     288                 :       1274 :             level++;
     289         [ -  + ]:       1274 :             if (level >= 30)
     290                 :            :                 Py_FatalError("too many tuple nesting levels "
     291                 :            :                               "in argument format string");
     292                 :       1274 :             break;
     293                 :       1274 :         case ')':
     294         [ -  + ]:       1274 :             if (level == 0)
     295                 :            :                 Py_FatalError("excess ')' in getargs format");
     296                 :            :             else
     297                 :       1274 :                 level--;
     298                 :       1274 :             break;
     299                 :    2408122 :         case '\0':
     300                 :    2408122 :             endfmt = 1;
     301                 :    2408122 :             break;
     302                 :   18152045 :         case ':':
     303                 :   18152045 :             fname = format;
     304                 :   18152045 :             endfmt = 1;
     305                 :   18152045 :             break;
     306                 :     452109 :         case ';':
     307                 :     452109 :             message = format;
     308                 :     452109 :             endfmt = 1;
     309                 :     452109 :             break;
     310                 :   15720302 :         case '|':
     311         [ +  - ]:   15720302 :             if (level == 0)
     312                 :   15720302 :                 min = max;
     313                 :   15720302 :             break;
     314                 :   60807223 :         default:
     315         [ +  + ]:   60807223 :             if (level == 0) {
     316         [ +  + ]:   60802949 :                 if (Py_ISALPHA(c))
     317         [ +  + ]:   55728321 :                     if (c != 'e') /* skip encoded */
     318                 :   55727666 :                         max++;
     319                 :            :             }
     320                 :   60807223 :             break;
     321                 :            :         }
     322                 :            :     }
     323                 :            : 
     324         [ -  + ]:   21012276 :     if (level != 0)
     325                 :            :         Py_FatalError(/* '(' */ "missing ')' in getargs format");
     326                 :            : 
     327         [ +  + ]:   21012276 :     if (min < 0)
     328                 :    5291974 :         min = max;
     329                 :            : 
     330                 :   21012276 :     format = formatsave;
     331                 :            : 
     332         [ +  + ]:   21012276 :     if (max > STATIC_FREELIST_ENTRIES) {
     333         [ +  - ]:      21783 :         freelist.entries = PyMem_NEW(freelistentry_t, max);
     334         [ -  + ]:      21783 :         if (freelist.entries == NULL) {
     335                 :            :             PyErr_NoMemory();
     336                 :          0 :             return 0;
     337                 :            :         }
     338                 :      21783 :         freelist.entries_malloced = 1;
     339                 :            :     }
     340                 :            : 
     341         [ +  + ]:   21012276 :     if (compat) {
     342         [ -  + ]:    2364863 :         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   [ +  -  +  - ]:    2364863 :         else if (min == 1 && max == 1) {
     352         [ -  + ]:    2364863 :             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                 :    2364863 :             msg = convertitem(compat_args, &format, p_va, flags, levels,
     360                 :            :                               msgbuf, sizeof(msgbuf), &freelist);
     361         [ +  + ]:    2364863 :             if (msg == NULL)
     362                 :    2364608 :                 return cleanreturn(1, &freelist);
     363                 :        255 :             seterror(levels[0], msg, levels+1, fname, message);
     364                 :        255 :             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   [ +  +  +  + ]:   18647413 :     if (nargs < min || max < nargs) {
     374         [ +  + ]:        179 :         if (message == NULL)
     375   [ +  +  +  +  :        342 :             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         [ +  + ]:         72 :                          : nargs < min ? "at least" : "at most",
     381         [ +  + ]:        135 :                          nargs < min ? min : max,
     382         [ +  + ]:        135 :                          (nargs < min ? min : max) == 1 ? "" : "s",
     383                 :            :                          nargs);
     384                 :            :         else
     385                 :         44 :             PyErr_SetString(PyExc_TypeError, message);
     386                 :        179 :         return cleanreturn(0, &freelist);
     387                 :            :     }
     388                 :            : 
     389         [ +  + ]:   46238505 :     for (i = 0; i < nargs; i++) {
     390         [ +  + ]:   27591843 :         if (*format == '|')
     391                 :    4787535 :             format++;
     392                 :   27591843 :         msg = convertitem(stack[i], &format, p_va,
     393                 :            :                           flags, levels, msgbuf,
     394                 :            :                           sizeof(msgbuf), &freelist);
     395         [ +  + ]:   27591843 :         if (msg) {
     396                 :        572 :             seterror(i+1, msg, levels, fname, message);
     397                 :        572 :             return cleanreturn(0, &freelist);
     398                 :            :         }
     399                 :            :     }
     400                 :            : 
     401   [ +  +  +  + ]:   18646662 :     if (*format != '\0' && !Py_ISALPHA(*format) &&
     402         [ +  - ]:   14020000 :         *format != '(' &&
     403   [ +  +  +  +  :   14020000 :         *format != '|' && *format != ':' && *format != ';') {
                   +  + ]
     404                 :          1 :         PyErr_Format(PyExc_SystemError,
     405                 :            :                      "bad format string: %.200s", formatsave);
     406                 :          1 :         return cleanreturn(0, &freelist);
     407                 :            :     }
     408                 :            : 
     409                 :   18646661 :     return cleanreturn(1, &freelist);
     410                 :            : }
     411                 :            : 
     412                 :            : static int
     413                 :   20882855 : vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
     414                 :            : {
     415                 :            :     PyObject **stack;
     416                 :            :     Py_ssize_t nargs;
     417                 :            : 
     418         [ +  + ]:   20882855 :     if (!(flags & FLAG_COMPAT)) {
     419                 :            :         assert(args != NULL);
     420                 :            : 
     421         [ -  + ]:   18517992 :         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                 :   18517992 :         stack = _PyTuple_ITEMS(args);
     428                 :   18517992 :         nargs = PyTuple_GET_SIZE(args);
     429                 :            :     }
     430                 :            :     else {
     431                 :    2364863 :         stack = NULL;
     432                 :    2364863 :         nargs = 0;
     433                 :            :     }
     434                 :            : 
     435                 :   20882855 :     return vgetargs1_impl(args, stack, nargs, format, p_va, flags);
     436                 :            : }
     437                 :            : 
     438                 :            : 
     439                 :            : static void
     440                 :       1133 : 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                 :       1133 :     char *p = buf;
     446                 :            : 
     447         [ +  + ]:       1133 :     if (PyErr_Occurred())
     448                 :        585 :         return;
     449         [ +  + ]:        548 :     else if (message == NULL) {
     450         [ +  + ]:        519 :         if (fname != NULL) {
     451                 :         91 :             PyOS_snprintf(p, sizeof(buf), "%.200s() ", fname);
     452                 :         91 :             p += strlen(p);
     453                 :            :         }
     454         [ +  + ]:        519 :         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                 :         61 :             PyOS_snprintf(p, sizeof(buf) - (p - buf), "argument");
     468                 :         61 :             p += strlen(p);
     469                 :            :         }
     470                 :        519 :         PyOS_snprintf(p, sizeof(buf) - (p - buf), " %.256s", msg);
     471                 :        519 :         message = buf;
     472                 :            :     }
     473         [ +  + ]:        548 :     if (msg[0] == '(') {
     474                 :        110 :         PyErr_SetString(PyExc_SystemError, message);
     475                 :            :     }
     476                 :            :     else {
     477                 :        438 :         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                 :       1294 : 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                 :       1294 :     int level = 0;
     506                 :       1294 :     int n = 0;
     507                 :       1294 :     const char *format = *p_format;
     508                 :            :     int i;
     509                 :            :     Py_ssize_t len;
     510                 :            : 
     511                 :       4330 :     for (;;) {
     512                 :       5624 :         int c = *format++;
     513         [ +  + ]:       5624 :         if (c == '(') {
     514         [ +  - ]:          4 :             if (level == 0)
     515                 :          4 :                 n++;
     516                 :          4 :             level++;
     517                 :            :         }
     518         [ +  + ]:       5620 :         else if (c == ')') {
     519         [ +  + ]:       1298 :             if (level == 0)
     520                 :       1294 :                 break;
     521                 :          4 :             level--;
     522                 :            :         }
     523   [ +  -  +  -  :       4322 :         else if (c == ':' || c == ';' || c == '\0')
                   +  - ]
     524                 :            :             break;
     525   [ +  +  +  + ]:       4322 :         else if (level == 0 && Py_ISALPHA(c))
     526                 :       3450 :             n++;
     527                 :            :     }
     528                 :            : 
     529   [ +  +  -  + ]:       1294 :     if (!PySequence_Check(arg) || PyBytes_Check(arg)) {
     530                 :         18 :         levels[0] = 0;
     531   [ +  -  -  + ]:         36 :         PyOS_snprintf(msgbuf, bufsize,
     532                 :            :                       toplevel ? "expected %d arguments, not %.50s" :
     533                 :            :                       "must be %d-item sequence, not %.50s",
     534                 :            :                   n,
     535                 :         18 :                   arg == Py_None ? "None" : Py_TYPE(arg)->tp_name);
     536                 :         18 :         return msgbuf;
     537                 :            :     }
     538                 :            : 
     539                 :       1276 :     len = PySequence_Size(arg);
     540         [ +  + ]:       1276 :     if (len != n) {
     541                 :         12 :         levels[0] = 0;
     542         [ -  + ]:         12 :         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                 :         12 :             PyOS_snprintf(msgbuf, bufsize,
     551                 :            :                           "must be sequence of length %d, not %zd",
     552                 :            :                           n, len);
     553                 :            :         }
     554                 :         12 :         return msgbuf;
     555                 :            :     }
     556                 :            : 
     557                 :       1264 :     format = *p_format;
     558         [ +  + ]:       4589 :     for (i = 0; i < n; i++) {
     559                 :            :         const char *msg;
     560                 :            :         PyObject *item;
     561                 :       3345 :         item = PySequence_GetItem(arg, i);
     562         [ +  + ]:       3345 :         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                 :       3344 :         msg = convertitem(item, &format, p_va, flags, levels+1,
     570                 :            :                           msgbuf, bufsize, freelist);
     571                 :            :         /* PySequence_GetItem calls tp->sq_item, which INCREFs */
     572                 :       3344 :         Py_XDECREF(item);
     573         [ +  + ]:       3344 :         if (msg != NULL) {
     574                 :         19 :             levels[0] = i+1;
     575                 :         19 :             return msg;
     576                 :            :         }
     577                 :            :     }
     578                 :            : 
     579                 :       1244 :     *p_format = format;
     580                 :       1244 :     return NULL;
     581                 :            : }
     582                 :            : 
     583                 :            : 
     584                 :            : /* Convert a single item. */
     585                 :            : 
     586                 :            : static const char *
     587                 :   33152959 : 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                 :   33152959 :     const char *format = *p_format;
     592                 :            : 
     593         [ +  + ]:   33152959 :     if (*format == '(' /* ')' */) {
     594                 :       1294 :         format++;
     595                 :       1294 :         msg = converttuple(arg, &format, p_va, flags, levels, msgbuf,
     596                 :            :                            bufsize, 0, freelist);
     597         [ +  + ]:       1294 :         if (msg == NULL)
     598                 :       1244 :             format++;
     599                 :            :     }
     600                 :            :     else {
     601                 :   33151665 :         msg = convertsimple(arg, &format, p_va, flags,
     602                 :            :                             msgbuf, bufsize, freelist);
     603         [ +  + ]:   33151665 :         if (msg != NULL)
     604                 :       1102 :             levels[0] = 0;
     605                 :            :     }
     606         [ +  + ]:   33152959 :     if (msg == NULL)
     607                 :   33151807 :         *p_format = format;
     608                 :   33152959 :     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                 :        620 : converterr(const char *expected, PyObject *arg, char *msgbuf, size_t bufsize)
     629                 :            : {
     630                 :            :     assert(expected != NULL);
     631                 :            :     assert(arg != NULL);
     632         [ +  + ]:        620 :     if (expected[0] == '(') {
     633                 :        144 :         PyOS_snprintf(msgbuf, bufsize,
     634                 :            :                       "%.100s", expected);
     635                 :            :     }
     636                 :            :     else {
     637         [ +  + ]:        905 :         PyOS_snprintf(msgbuf, bufsize,
     638                 :            :                       "must be %.50s, not %.50s", expected,
     639                 :        429 :                       arg == Py_None ? "None" : Py_TYPE(arg)->tp_name);
     640                 :            :     }
     641                 :        620 :     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                 :   33151665 : 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                 :   33151665 :     const char *format = *p_format;
     669                 :   33151665 :     char c = *format++;
     670                 :            :     const char *sarg;
     671                 :            : 
     672   [ +  +  +  +  :   33151665 :     switch (c) {
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
                   +  + ]
     673                 :            : 
     674                 :      70240 :     case 'b': { /* unsigned byte -- very short int */
     675                 :      70240 :         char *p = va_arg(*p_va, char *);
     676                 :      70240 :         long ival = PyLong_AsLong(arg);
     677   [ +  +  +  + ]:      70240 :         if (ival == -1 && PyErr_Occurred())
     678                 :         12 :             RETURN_ERR_OCCURRED;
     679         [ +  + ]:      70228 :         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         [ +  + ]:      70223 :         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                 :      70218 :             *p = (unsigned char) ival;
     691                 :      70218 :         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                 :      42419 :     case 'h': {/* signed short int */
     706                 :      42419 :         short *p = va_arg(*p_va, short *);
     707                 :      42419 :         long ival = PyLong_AsLong(arg);
     708   [ +  +  +  + ]:      42419 :         if (ival == -1 && PyErr_Occurred())
     709                 :         16 :             RETURN_ERR_OCCURRED;
     710         [ +  + ]:      42403 :         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         [ +  + ]:      42398 :         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                 :      42393 :             *p = (short) ival;
     722                 :      42393 :         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                 :    1424040 :     case 'i': {/* signed int */
     737                 :    1424040 :         int *p = va_arg(*p_va, int *);
     738                 :    1424040 :         long ival = PyLong_AsLong(arg);
     739   [ +  +  +  + ]:    1424040 :         if (ival == -1 && PyErr_Occurred())
     740                 :        188 :             RETURN_ERR_OCCURRED;
     741         [ +  + ]:    1423852 :         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         [ +  + ]:    1423826 :         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                 :    1423819 :             *p = ival;
     753                 :    1423819 :         break;
     754                 :            :     }
     755                 :            : 
     756                 :        892 :     case 'I': { /* int sized bitfield, both signed and
     757                 :            :                    unsigned allowed */
     758                 :        892 :         unsigned int *p = va_arg(*p_va, unsigned int *);
     759                 :        892 :         unsigned long ival = PyLong_AsUnsignedLongMask(arg);
     760   [ +  +  +  + ]:        892 :         if (ival == (unsigned long)-1 && PyErr_Occurred())
     761                 :          5 :             RETURN_ERR_OCCURRED;
     762                 :            :         else
     763                 :        887 :             *p = (unsigned int) ival;
     764                 :        887 :         break;
     765                 :            :     }
     766                 :            : 
     767                 :     241834 :     case 'n': /* Py_ssize_t */
     768                 :            :     {
     769                 :            :         PyObject *iobj;
     770                 :     241834 :         Py_ssize_t *p = va_arg(*p_va, Py_ssize_t *);
     771                 :     241834 :         Py_ssize_t ival = -1;
     772                 :     241834 :         iobj = _PyNumber_Index(arg);
     773         [ +  + ]:     241834 :         if (iobj != NULL) {
     774                 :     241717 :             ival = PyLong_AsSsize_t(iobj);
     775                 :     241717 :             Py_DECREF(iobj);
     776                 :            :         }
     777   [ +  +  +  + ]:     241834 :         if (ival == -1 && PyErr_Occurred())
     778                 :        121 :             RETURN_ERR_OCCURRED;
     779                 :     241713 :         *p = ival;
     780                 :     241713 :         break;
     781                 :            :     }
     782                 :      21200 :     case 'l': {/* long int */
     783                 :      21200 :         long *p = va_arg(*p_va, long *);
     784                 :      21200 :         long ival = PyLong_AsLong(arg);
     785   [ +  +  +  + ]:      21200 :         if (ival == -1 && PyErr_Occurred())
     786                 :         23 :             RETURN_ERR_OCCURRED;
     787                 :            :         else
     788                 :      21177 :             *p = ival;
     789                 :      21177 :         break;
     790                 :            :     }
     791                 :            : 
     792                 :       2357 :     case 'k': { /* long sized bitfield */
     793                 :       2357 :         unsigned long *p = va_arg(*p_va, unsigned long *);
     794                 :            :         unsigned long ival;
     795         [ +  + ]:       2357 :         if (PyLong_Check(arg))
     796                 :       2349 :             ival = PyLong_AsUnsignedLongMask(arg);
     797                 :            :         else
     798                 :          8 :             return converterr("int", arg, msgbuf, bufsize);
     799                 :       2349 :         *p = ival;
     800                 :       2349 :         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                 :      38287 :     case 'K': { /* long long sized bitfield */
     814                 :      38287 :         unsigned long long *p = va_arg(*p_va, unsigned long long *);
     815                 :            :         unsigned long long ival;
     816         [ +  + ]:      38287 :         if (PyLong_Check(arg))
     817                 :      38280 :             ival = PyLong_AsUnsignedLongLongMask(arg);
     818                 :            :         else
     819                 :          7 :             return converterr("int", arg, msgbuf, bufsize);
     820                 :      38280 :         *p = ival;
     821                 :      38280 :         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                 :      86616 :     case 'd': {/* double */
     835                 :      86616 :         double *p = va_arg(*p_va, double *);
     836                 :      86616 :         double dval = PyFloat_AsDouble(arg);
     837   [ +  +  +  + ]:      86616 :         if (dval == -1.0 && PyErr_Occurred())
     838                 :          8 :             RETURN_ERR_OCCURRED;
     839                 :            :         else
     840                 :      86608 :             *p = dval;
     841                 :      86608 :         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                 :      72313 :     case 'C': {/* unicode char */
     867                 :      72313 :         int *p = va_arg(*p_va, int *);
     868                 :            :         int kind;
     869                 :            :         const void *data;
     870                 :            : 
     871         [ +  + ]:      72313 :         if (!PyUnicode_Check(arg))
     872                 :          6 :             return converterr("a unicode character", arg, msgbuf, bufsize);
     873                 :            : 
     874         [ -  + ]:      72307 :         if (PyUnicode_READY(arg))
     875                 :          0 :             RETURN_ERR_OCCURRED;
     876                 :            : 
     877         [ +  + ]:      72307 :         if (PyUnicode_GET_LENGTH(arg) != 1)
     878                 :          2 :             return converterr("a unicode character", arg, msgbuf, bufsize);
     879                 :            : 
     880                 :      72305 :         kind = PyUnicode_KIND(arg);
     881                 :      72305 :         data = PyUnicode_DATA(arg);
     882                 :      72305 :         *p = PyUnicode_READ(kind, data, 0);
     883                 :      72305 :         break;
     884                 :            :     }
     885                 :            : 
     886                 :    1036744 :     case 'p': {/* boolean *p*redicate */
     887                 :    1036744 :         int *p = va_arg(*p_va, int *);
     888                 :    1036744 :         int val = PyObject_IsTrue(arg);
     889         [ +  + ]:    1036744 :         if (val > 0)
     890                 :    1022271 :             *p = 1;
     891         [ +  + ]:      14473 :         else if (val == 0)
     892                 :      14469 :             *p = 0;
     893                 :            :         else
     894                 :          4 :             RETURN_ERR_OCCURRED;
     895                 :    1036740 :         break;
     896                 :            :     }
     897                 :            : 
     898                 :            :     /* XXX WAAAAH!  's', 'y', 'z', 'u', 'Z', 'e', 'w' codes all
     899                 :            :        need to be cleaned up! */
     900                 :            : 
     901                 :      42756 :     case 'y': {/* any bytes-like object */
     902                 :      42756 :         void **p = (void **)va_arg(*p_va, char **);
     903                 :            :         const char *buf;
     904                 :            :         Py_ssize_t count;
     905         [ +  + ]:      42756 :         if (*format == '*') {
     906         [ +  + ]:      42675 :             if (getbuffer(arg, (Py_buffer*)p, &buf) < 0)
     907                 :         43 :                 return converterr(buf, arg, msgbuf, bufsize);
     908                 :      42642 :             format++;
     909         [ -  + ]:      42642 :             if (addcleanup(p, freelist, cleanup_buffer)) {
     910                 :          0 :                 return converterr(
     911                 :            :                     "(cleanup problem)",
     912                 :            :                     arg, msgbuf, bufsize);
     913                 :            :             }
     914                 :      42713 :             break;
     915                 :            :         }
     916                 :         81 :         count = convertbuffer(arg, (const void **)p, &buf);
     917         [ +  + ]:         81 :         if (count < 0)
     918                 :          9 :             return converterr(buf, arg, msgbuf, bufsize);
     919         [ +  + ]:         72 :         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         [ +  + ]:         24 :             if (strlen(*p) != (size_t)count) {
     926                 :          1 :                 PyErr_SetString(PyExc_ValueError, "embedded null byte");
     927                 :          1 :                 RETURN_ERR_OCCURRED;
     928                 :            :             }
     929                 :            :         }
     930                 :         71 :         break;
     931                 :            :     }
     932                 :            : 
     933                 :      81739 :     case 's': /* text string or bytes-like object */
     934                 :            :     case 'z': /* text string, bytes-like object or None */
     935                 :            :     {
     936         [ +  + ]:      81739 :         if (*format == '*') {
     937                 :            :             /* "s*" or "z*" */
     938                 :         18 :             Py_buffer *p = (Py_buffer *)va_arg(*p_va, Py_buffer *);
     939                 :            : 
     940   [ +  +  +  + ]:         18 :             if (c == 'z' && arg == Py_None)
     941                 :          1 :                 PyBuffer_FillInfo(p, NULL, NULL, 0, 1, 0);
     942         [ +  + ]:         17 :             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         [ +  + ]:         13 :                 if (getbuffer(arg, p, &buf) < 0)
     953                 :          1 :                     return converterr(buf, arg, msgbuf, bufsize);
     954                 :            :             }
     955         [ -  + ]:         17 :             if (addcleanup(p, freelist, cleanup_buffer)) {
     956                 :          0 :                 return converterr(
     957                 :            :                     "(cleanup problem)",
     958                 :            :                     arg, msgbuf, bufsize);
     959                 :            :             }
     960                 :         17 :             format++;
     961         [ +  + ]:      81721 :         } 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                 :      23590 :             const char **p = va_arg(*p_va, const char **);
     992                 :            :             Py_ssize_t len;
     993                 :      23590 :             sarg = NULL;
     994                 :            : 
     995   [ +  +  +  + ]:      23590 :             if (c == 'z' && arg == Py_None)
     996                 :          1 :                 *p = NULL;
     997         [ +  + ]:      23589 :             else if (PyUnicode_Check(arg)) {
     998                 :      23573 :                 sarg = PyUnicode_AsUTF8AndSize(arg, &len);
     999         [ +  + ]:      23573 :                 if (sarg == NULL)
    1000                 :         29 :                     return converterr(CONV_UNICODE,
    1001                 :            :                                       arg, msgbuf, bufsize);
    1002         [ +  + ]:      23565 :                 if (strlen(sarg) != (size_t)len) {
    1003                 :          5 :                     PyErr_SetString(PyExc_ValueError, "embedded null character");
    1004                 :          5 :                     RETURN_ERR_OCCURRED;
    1005                 :            :                 }
    1006                 :      23560 :                 *p = sarg;
    1007                 :            :             }
    1008                 :            :             else
    1009         [ +  + ]:         16 :                 return converterr(c == 'z' ? "str or None" : "str",
    1010                 :            :                                   arg, msgbuf, bufsize);
    1011                 :            :         }
    1012                 :      81673 :         break;
    1013                 :            :     }
    1014                 :            : 
    1015                 :        655 :     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                 :        655 :         encoding = (const char *)va_arg(*p_va, const char *);
    1025         [ +  + ]:        655 :         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         [ +  + ]:        655 :         if (*format == 's')
    1033                 :        423 :             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                 :        655 :         buffer = (char **)va_arg(*p_va, char **);
    1041                 :        655 :         format++;
    1042         [ -  + ]:        655 :         if (buffer == NULL)
    1043                 :          0 :             return converterr("(buffer is NULL)",
    1044                 :            :                               arg, msgbuf, bufsize);
    1045                 :            : 
    1046                 :            :         /* Encode object */
    1047   [ +  +  +  + ]:        887 :         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         [ +  + ]:        642 :         else if (PyUnicode_Check(arg)) {
    1061                 :            :             /* Encode object; use default error handling */
    1062                 :        629 :             s = PyUnicode_AsEncodedString(arg,
    1063                 :            :                                           encoding,
    1064                 :            :                                           NULL);
    1065         [ +  + ]:        629 :             if (s == NULL)
    1066                 :          8 :                 return converterr("(encoding failed)",
    1067                 :            :                                   arg, msgbuf, bufsize);
    1068                 :            :             assert(PyBytes_Check(s));
    1069                 :        621 :             size = PyBytes_GET_SIZE(s);
    1070                 :        621 :             ptr = PyBytes_AS_STRING(s);
    1071         [ -  + ]:        621 :             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         [ +  + ]:        634 :         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                 :            :                     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         [ +  + ]:        616 :             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         [ +  - ]:        611 :             *buffer = PyMem_NEW(char, size + 1);
    1161         [ -  + ]:        611 :             if (*buffer == NULL) {
    1162                 :          0 :                 Py_DECREF(s);
    1163                 :            :                 PyErr_NoMemory();
    1164                 :          0 :                 RETURN_ERR_OCCURRED;
    1165                 :            :             }
    1166         [ -  + ]:        611 :             if (addcleanup(*buffer, freelist, cleanup_ptr)) {
    1167                 :          0 :                 Py_DECREF(s);
    1168                 :          0 :                 return converterr("(cleanup problem)",
    1169                 :            :                                 arg, msgbuf, bufsize);
    1170                 :            :             }
    1171                 :        611 :             memcpy(*buffer, ptr, size+1);
    1172                 :            :         }
    1173                 :        625 :         Py_DECREF(s);
    1174                 :        625 :         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                 :    1329124 :     case 'U': { /* PyUnicode object */
    1196                 :    1329124 :         PyObject **p = va_arg(*p_va, PyObject **);
    1197         [ +  + ]:    1329124 :         if (PyUnicode_Check(arg)) {
    1198         [ -  + ]:    1328852 :             if (PyUnicode_READY(arg) == -1)
    1199                 :          0 :                 RETURN_ERR_OCCURRED;
    1200                 :    1328852 :             *p = arg;
    1201                 :            :         }
    1202                 :            :         else
    1203                 :        272 :             return converterr("str", arg, msgbuf, bufsize);
    1204                 :    1328852 :         break;
    1205                 :            :     }
    1206                 :            : 
    1207                 :   26647933 :     case 'O': { /* object */
    1208                 :            :         PyTypeObject *type;
    1209                 :            :         PyObject **p;
    1210         [ +  + ]:   26647933 :         if (*format == '!') {
    1211                 :    2675561 :             type = va_arg(*p_va, PyTypeObject*);
    1212                 :    2675561 :             p = va_arg(*p_va, PyObject **);
    1213                 :    2675561 :             format++;
    1214         [ +  + ]:    2675561 :             if (PyType_IsSubtype(Py_TYPE(arg), type))
    1215                 :    2675544 :                 *p = arg;
    1216                 :            :             else
    1217                 :         17 :                 return converterr(type->tp_name, arg, msgbuf, bufsize);
    1218                 :            : 
    1219                 :            :         }
    1220         [ +  + ]:   23972372 :         else if (*format == '&') {
    1221                 :            :             typedef int (*converter)(PyObject *, void *);
    1222                 :     147272 :             converter convert = va_arg(*p_va, converter);
    1223                 :     147272 :             void *addr = va_arg(*p_va, void *);
    1224                 :            :             int res;
    1225                 :     147272 :             format++;
    1226         [ +  + ]:     147272 :             if (! (res = (*convert)(arg, addr)))
    1227                 :         19 :                 return converterr("(unspecified)",
    1228                 :            :                                   arg, msgbuf, bufsize);
    1229   [ +  +  -  + ]:     156094 :             if (res == Py_CLEANUP_SUPPORTED &&
    1230                 :       8841 :                 addcleanup(addr, freelist, convert) == -1)
    1231                 :          0 :                 return converterr("(cleanup problem)",
    1232                 :            :                                 arg, msgbuf, bufsize);
    1233                 :            :         }
    1234                 :            :         else {
    1235                 :   23825100 :             p = va_arg(*p_va, PyObject **);
    1236                 :   23825100 :             *p = arg;
    1237                 :            :         }
    1238                 :   26647897 :         break;
    1239                 :            :     }
    1240                 :            : 
    1241                 :            : 
    1242                 :    1963154 :     case 'w': { /* "w*": memory buffer, read-write access */
    1243                 :    1963154 :         void **p = va_arg(*p_va, void **);
    1244                 :            : 
    1245         [ +  + ]:    1963154 :         if (*format != '*')
    1246                 :          1 :             return converterr(
    1247                 :            :                 "(invalid use of 'w' format character)",
    1248                 :            :                 arg, msgbuf, bufsize);
    1249                 :    1963153 :         format++;
    1250                 :            : 
    1251                 :            :         /* Caller is interested in Py_buffer, and the object
    1252                 :            :            supports it directly. */
    1253         [ +  + ]:    1963153 :         if (PyObject_GetBuffer(arg, (Py_buffer*)p, PyBUF_WRITABLE) < 0) {
    1254                 :         35 :             PyErr_Clear();
    1255                 :         35 :             return converterr("read-write bytes-like object",
    1256                 :            :                               arg, msgbuf, bufsize);
    1257                 :            :         }
    1258         [ -  + ]:    1963118 :         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         [ -  + ]:    1963118 :         if (addcleanup(p, freelist, cleanup_buffer)) {
    1263                 :          0 :             return converterr(
    1264                 :            :                 "(cleanup problem)",
    1265                 :            :                 arg, msgbuf, bufsize);
    1266                 :            :         }
    1267                 :    1963118 :         break;
    1268                 :            :     }
    1269                 :            : 
    1270                 :        108 :     default:
    1271                 :        108 :         return converterr("(impossible<bad format char>)", arg, msgbuf, bufsize);
    1272                 :            : 
    1273                 :            :     }
    1274                 :            : 
    1275                 :   33150563 :     *p_format = format;
    1276                 :   33150563 :     return NULL;
    1277                 :            : 
    1278                 :            : #undef REQUIRE_PY_SSIZE_T_CLEAN
    1279                 :            : #undef RETURN_ERR_OCCURRED
    1280                 :            : }
    1281                 :            : 
    1282                 :            : static Py_ssize_t
    1283                 :       1568 : convertbuffer(PyObject *arg, const void **p, const char **errmsg)
    1284                 :            : {
    1285                 :       1568 :     PyBufferProcs *pb = Py_TYPE(arg)->tp_as_buffer;
    1286                 :            :     Py_ssize_t count;
    1287                 :            :     Py_buffer view;
    1288                 :            : 
    1289                 :       1568 :     *errmsg = NULL;
    1290                 :       1568 :     *p = NULL;
    1291   [ +  +  +  + ]:       1568 :     if (pb != NULL && pb->bf_releasebuffer != NULL) {
    1292                 :          8 :         *errmsg = "read-only bytes-like object";
    1293                 :          8 :         return -1;
    1294                 :            :     }
    1295                 :            : 
    1296         [ +  + ]:       1560 :     if (getbuffer(arg, &view, errmsg) < 0)
    1297                 :         35 :         return -1;
    1298                 :       1525 :     count = view.len;
    1299                 :       1525 :     *p = view.buf;
    1300                 :       1525 :     PyBuffer_Release(&view);
    1301                 :       1525 :     return count;
    1302                 :            : }
    1303                 :            : 
    1304                 :            : static int
    1305                 :      44248 : getbuffer(PyObject *arg, Py_buffer *view, const char **errmsg)
    1306                 :            : {
    1307         [ +  + ]:      44248 :     if (PyObject_GetBuffer(arg, view, PyBUF_SIMPLE) != 0) {
    1308                 :         69 :         *errmsg = "bytes-like object";
    1309                 :         69 :         return -1;
    1310                 :            :     }
    1311         [ -  + ]:      44179 :     if (!PyBuffer_IsContiguous(view, 'C')) {
    1312                 :          0 :         PyBuffer_Release(view);
    1313                 :          0 :         *errmsg = "contiguous buffer";
    1314                 :          0 :         return -1;
    1315                 :            :     }
    1316                 :      44179 :     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                 :    6318666 : PyArg_ParseTupleAndKeywords(PyObject *args,
    1325                 :            :                             PyObject *keywords,
    1326                 :            :                             const char *format,
    1327                 :            :                             char **kwlist, ...)
    1328                 :            : {
    1329                 :            :     int retval;
    1330                 :            :     va_list va;
    1331                 :            : 
    1332   [ +  -  +  -  :    6318666 :     if ((args == NULL || !PyTuple_Check(args)) ||
                   +  + ]
    1333   [ +  -  +  - ]:    6318666 :         (keywords != NULL && !PyDict_Check(keywords)) ||
    1334         [ -  + ]:    6318666 :         format == NULL ||
    1335                 :            :         kwlist == NULL)
    1336                 :            :     {
    1337                 :          0 :         PyErr_BadInternalCall();
    1338                 :          0 :         return 0;
    1339                 :            :     }
    1340                 :            : 
    1341                 :    6318666 :     va_start(va, kwlist);
    1342                 :    6318666 :     retval = vgetargskeywords(args, keywords, format, kwlist, &va, 0);
    1343                 :    6318666 :     va_end(va);
    1344                 :    6318666 :     return retval;
    1345                 :            : }
    1346                 :            : 
    1347                 :            : PyAPI_FUNC(int)
    1348                 :    1827392 : _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   [ +  -  +  -  :    1827392 :     if ((args == NULL || !PyTuple_Check(args)) ||
                   +  + ]
    1357   [ +  -  +  - ]:    1827392 :         (keywords != NULL && !PyDict_Check(keywords)) ||
    1358         [ -  + ]:    1827392 :         format == NULL ||
    1359                 :            :         kwlist == NULL)
    1360                 :            :     {
    1361                 :          0 :         PyErr_BadInternalCall();
    1362                 :          0 :         return 0;
    1363                 :            :     }
    1364                 :            : 
    1365                 :    1827392 :     va_start(va, kwlist);
    1366                 :    1827392 :     retval = vgetargskeywords(args, keywords, format,
    1367                 :            :                               kwlist, &va, FLAG_SIZE_T);
    1368                 :    1827392 :     va_end(va);
    1369                 :    1827392 :     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                 :      49678 : PyArg_ValidateKeywordArguments(PyObject *kwargs)
    1507                 :            : {
    1508         [ -  + ]:      49678 :     if (!PyDict_Check(kwargs)) {
    1509                 :          0 :         PyErr_BadInternalCall();
    1510                 :          0 :         return 0;
    1511                 :            :     }
    1512         [ +  + ]:      49678 :     if (!_PyDict_HasOnlyStringKeys(kwargs)) {
    1513                 :          3 :         PyErr_SetString(PyExc_TypeError,
    1514                 :            :                         "keywords must be strings");
    1515                 :          3 :         return 0;
    1516                 :            :     }
    1517                 :      49675 :     return 1;
    1518                 :            : }
    1519                 :            : 
    1520                 :            : #define IS_END_OF_FORMAT(c) (c == '\0' || c == ';' || c == ':')
    1521                 :            : 
    1522                 :            : static int
    1523                 :    8146058 : 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                 :    8146058 :     int min = INT_MAX;
    1530                 :    8146058 :     int max = INT_MAX;
    1531                 :            :     int i, pos, len;
    1532                 :    8146058 :     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                 :    8146058 :     freelist.entries = static_entries;
    1539                 :    8146058 :     freelist.first_available = 0;
    1540                 :    8146058 :     freelist.entries_malloced = 0;
    1541                 :            : 
    1542                 :            :     assert(args != NULL && PyTuple_Check(args));
    1543                 :            :     assert(kwargs == NULL || PyDict_Check(kwargs));
    1544                 :            :     assert(format != NULL);
    1545                 :            :     assert(kwlist != NULL);
    1546                 :            :     assert(p_va != NULL);
    1547                 :            : 
    1548                 :            :     /* grab the function name or custom error msg first (mutually exclusive) */
    1549                 :    8146058 :     fname = strchr(format, ':');
    1550         [ +  + ]:    8146058 :     if (fname) {
    1551                 :    7652083 :         fname++;
    1552                 :    7652083 :         custom_msg = NULL;
    1553                 :            :     }
    1554                 :            :     else {
    1555                 :     493975 :         custom_msg = strchr(format,';');
    1556         [ +  + ]:     493975 :         if (custom_msg)
    1557                 :          3 :             custom_msg++;
    1558                 :            :     }
    1559                 :            : 
    1560                 :            :     /* scan kwlist and count the number of positional-only parameters */
    1561   [ +  +  +  + ]:    8147279 :     for (pos = 0; kwlist[pos] && !*kwlist[pos]; pos++) {
    1562                 :            :     }
    1563                 :            :     /* scan kwlist and get greatest possible nbr of args */
    1564         [ +  + ]:   25043480 :     for (len = pos; kwlist[len]; len++) {
    1565         [ +  + ]:   16897424 :         if (!*kwlist[len]) {
    1566                 :          2 :             PyErr_SetString(PyExc_SystemError,
    1567                 :            :                             "Empty keyword parameter name");
    1568                 :          2 :             return cleanreturn(0, &freelist);
    1569                 :            :         }
    1570                 :            :     }
    1571                 :            : 
    1572         [ +  + ]:    8146056 :     if (len > STATIC_FREELIST_ENTRIES) {
    1573         [ +  - ]:      69995 :         freelist.entries = PyMem_NEW(freelistentry_t, len);
    1574         [ -  + ]:      69995 :         if (freelist.entries == NULL) {
    1575                 :            :             PyErr_NoMemory();
    1576                 :          0 :             return 0;
    1577                 :            :         }
    1578                 :      69995 :         freelist.entries_malloced = 1;
    1579                 :            :     }
    1580                 :            : 
    1581                 :    8146056 :     nargs = PyTuple_GET_SIZE(args);
    1582         [ +  + ]:    8146056 :     nkwargs = (kwargs == NULL) ? 0 : PyDict_GET_SIZE(kwargs);
    1583         [ +  + ]:    8146056 :     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         [ +  + ]:   12025796 :     for (i = 0; i < len; i++) {
    1599         [ +  + ]:   10550621 :         if (*format == '|') {
    1600         [ +  + ]:    7985095 :             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                 :    7985094 :             min = i;
    1607                 :    7985094 :             format++;
    1608                 :            : 
    1609         [ +  + ]:    7985094 :             if (max != INT_MAX) {
    1610                 :          1 :                 PyErr_SetString(PyExc_SystemError,
    1611                 :            :                                 "Invalid format string ($ before |)");
    1612                 :          1 :                 return cleanreturn(0, &freelist);
    1613                 :            :             }
    1614                 :            :         }
    1615         [ +  + ]:   10550619 :         if (*format == '$') {
    1616         [ +  + ]:    5608559 :             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                 :    5608558 :             max = i;
    1623                 :    5608558 :             format++;
    1624                 :            : 
    1625         [ +  + ]:    5608558 :             if (max < pos) {
    1626                 :          2 :                 PyErr_SetString(PyExc_SystemError,
    1627                 :            :                                 "Empty parameter name after $");
    1628                 :          2 :                 return cleanreturn(0, &freelist);
    1629                 :            :             }
    1630         [ +  + ]:    5608556 :             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         [ +  + ]:    5608552 :             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   [ +  +  +  +  :   10550604 :         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         [ +  + ]:   10550599 :         if (!skip) {
    1664         [ +  + ]:   10550590 :             if (i < nargs) {
    1665                 :    1536024 :                 current_arg = PyTuple_GET_ITEM(args, i);
    1666                 :            :             }
    1667   [ +  +  +  + ]:    9014566 :             else if (nkwargs && i >= pos) {
    1668                 :    2344268 :                 current_arg = _PyDict_GetItemStringWithError(kwargs, kwlist[i]);
    1669         [ +  + ]:    2344268 :                 if (current_arg) {
    1670                 :    1656817 :                     --nkwargs;
    1671                 :            :                 }
    1672         [ -  + ]:     687451 :                 else if (PyErr_Occurred()) {
    1673                 :          0 :                     return cleanreturn(0, &freelist);
    1674                 :            :                 }
    1675                 :            :             }
    1676                 :            :             else {
    1677                 :    6670298 :                 current_arg = NULL;
    1678                 :            :             }
    1679                 :            : 
    1680         [ +  + ]:   10550590 :             if (current_arg) {
    1681                 :    3192841 :                 msg = convertitem(current_arg, &format, p_va, flags,
    1682                 :            :                     levels, msgbuf, sizeof(msgbuf), &freelist);
    1683         [ +  + ]:    3192841 :                 if (msg) {
    1684                 :        306 :                     seterror(i+1, msg, levels, fname, custom_msg);
    1685                 :        306 :                     return cleanreturn(0, &freelist);
    1686                 :            :                 }
    1687                 :    3192535 :                 continue;
    1688                 :            :             }
    1689                 :            : 
    1690         [ +  + ]:    7357749 :             if (i < min) {
    1691         [ +  + ]:         49 :                 if (i < pos) {
    1692                 :            :                     assert (min == INT_MAX);
    1693                 :            :                     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   [ +  +  +  + ]:    7357710 :             if (!nkwargs && !skip) {
    1714                 :    6670260 :                 return cleanreturn(1, &freelist);
    1715                 :            :             }
    1716                 :            :         }
    1717                 :            : 
    1718                 :            :         /* We are into optional args, skip through to any remaining
    1719                 :            :          * keyword args */
    1720                 :     687459 :         msg = skipitem(&format, p_va, flags);
    1721         [ +  + ]:     687459 :         if (msg) {
    1722                 :        215 :             PyErr_Format(PyExc_SystemError, "%s: '%s'", msg,
    1723                 :            :                          format);
    1724                 :        215 :             return cleanreturn(0, &freelist);
    1725                 :            :         }
    1726                 :            :     }
    1727                 :            : 
    1728         [ +  + ]:    1475179 :     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   [ +  +  +  -  :    1475169 :     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         [ +  + ]:    1475168 :     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                 :    1475127 :     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                 :    1214255 : 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                 :            :     assert(parser->keywords != NULL);
    1811         [ +  + ]:    1214255 :     if (parser->kwtuple != NULL) {
    1812                 :    1194448 :         return 1;
    1813                 :            :     }
    1814                 :            : 
    1815                 :      19807 :     keywords = parser->keywords;
    1816                 :            :     /* scan keywords and count the number of positional-only parameters */
    1817   [ +  +  +  + ]:      19900 :     for (i = 0; keywords[i] && !*keywords[i]; i++) {
    1818                 :            :     }
    1819                 :      19807 :     parser->pos = i;
    1820                 :            :     /* scan keywords and get greatest possible nbr of args */
    1821         [ +  + ]:      91896 :     for (; keywords[i]; i++) {
    1822         [ -  + ]:      72089 :         if (!*keywords[i]) {
    1823                 :          0 :             PyErr_SetString(PyExc_SystemError,
    1824                 :            :                             "Empty keyword parameter name");
    1825                 :          0 :             return 0;
    1826                 :            :         }
    1827                 :            :     }
    1828                 :      19807 :     len = i;
    1829                 :            : 
    1830                 :      19807 :     format = parser->format;
    1831         [ +  + ]:      19807 :     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                 :      19807 :     nkw = len - parser->pos;
    1900                 :      19807 :     kwtuple = PyTuple_New(nkw);
    1901         [ -  + ]:      19807 :     if (kwtuple == NULL) {
    1902                 :          0 :         return 0;
    1903                 :            :     }
    1904                 :      19807 :     keywords = parser->keywords + parser->pos;
    1905         [ +  + ]:      91896 :     for (i = 0; i < nkw; i++) {
    1906                 :      72089 :         PyObject *str = PyUnicode_FromString(keywords[i]);
    1907         [ -  + ]:      72089 :         if (str == NULL) {
    1908                 :          0 :             Py_DECREF(kwtuple);
    1909                 :          0 :             return 0;
    1910                 :            :         }
    1911                 :      72089 :         PyUnicode_InternInPlace(&str);
    1912                 :      72089 :         PyTuple_SET_ITEM(kwtuple, i, str);
    1913                 :            :     }
    1914                 :      19807 :     parser->kwtuple = kwtuple;
    1915                 :            : 
    1916                 :            :     assert(parser->next == NULL);
    1917                 :      19807 :     parser->next = static_arg_parsers;
    1918                 :      19807 :     static_arg_parsers = parser;
    1919                 :      19807 :     return 1;
    1920                 :            : }
    1921                 :            : 
    1922                 :            : static void
    1923                 :      19792 : parser_clear(struct _PyArg_Parser *parser)
    1924                 :            : {
    1925         [ +  - ]:      19792 :     Py_CLEAR(parser->kwtuple);
    1926                 :      19792 : }
    1927                 :            : 
    1928                 :            : static PyObject*
    1929                 :    1528384 : find_keyword(PyObject *kwnames, PyObject *const *kwstack, PyObject *key)
    1930                 :            : {
    1931                 :            :     Py_ssize_t i, nkwargs;
    1932                 :            : 
    1933                 :    1528384 :     nkwargs = PyTuple_GET_SIZE(kwnames);
    1934         [ +  + ]:    2069243 :     for (i = 0; i < nkwargs; i++) {
    1935                 :    1712257 :         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         [ +  + ]:    1712257 :         if (kwname == key) {
    1940                 :    1171398 :             return kwstack[i];
    1941                 :            :         }
    1942                 :            :     }
    1943                 :            : 
    1944         [ +  + ]:     804138 :     for (i = 0; i < nkwargs; i++) {
    1945                 :     447407 :         PyObject *kwname = PyTuple_GET_ITEM(kwnames, i);
    1946                 :            :         assert(PyUnicode_Check(kwname));
    1947         [ +  + ]:     447407 :         if (_PyUnicode_EQ(kwname, key)) {
    1948                 :        255 :             return kwstack[i];
    1949                 :            :         }
    1950                 :            :     }
    1951                 :     356731 :     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                 :            :     assert(kwargs == NULL || PyDict_Check(kwargs));
    1978                 :            :     assert(kwargs == NULL || kwnames == NULL);
    1979                 :            :     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                 :            :             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                 :            :         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                 :            :         assert(msg == NULL);
    2130                 :            :     }
    2131                 :            : 
    2132                 :            :     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                 :    1120767 : _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         [ -  + ]:    1120767 :     int reqlimit = minkw ? maxpos + minkw : minpos;
    2227                 :            :     Py_ssize_t nkwargs;
    2228                 :            :     PyObject *current_arg;
    2229                 :    1120767 :     PyObject * const *kwstack = NULL;
    2230                 :            : 
    2231                 :            :     assert(kwargs == NULL || PyDict_Check(kwargs));
    2232                 :            :     assert(kwargs == NULL || kwnames == NULL);
    2233                 :            : 
    2234         [ -  + ]:    1120767 :     if (parser == NULL) {
    2235                 :          0 :         PyErr_BadInternalCall();
    2236                 :          0 :         return NULL;
    2237                 :            :     }
    2238                 :            : 
    2239   [ +  +  -  + ]:    1120767 :     if (kwnames != NULL && !PyTuple_Check(kwnames)) {
    2240                 :          0 :         PyErr_BadInternalCall();
    2241                 :          0 :         return NULL;
    2242                 :            :     }
    2243                 :            : 
    2244   [ +  +  +  - ]:    1120767 :     if (args == NULL && nargs == 0) {
    2245                 :        816 :         args = buf;
    2246                 :            :     }
    2247                 :            : 
    2248         [ -  + ]:    1120767 :     if (!parser_init(parser)) {
    2249                 :          0 :         return NULL;
    2250                 :            :     }
    2251                 :            : 
    2252                 :    1120767 :     kwtuple = parser->kwtuple;
    2253                 :    1120767 :     posonly = parser->pos;
    2254                 :    1120767 :     minposonly = Py_MIN(posonly, minpos);
    2255                 :    1120767 :     maxargs = posonly + (int)PyTuple_GET_SIZE(kwtuple);
    2256                 :            : 
    2257         [ +  + ]:    1120767 :     if (kwargs != NULL) {
    2258                 :      90010 :         nkwargs = PyDict_GET_SIZE(kwargs);
    2259                 :            :     }
    2260         [ +  + ]:    1030757 :     else if (kwnames != NULL) {
    2261                 :    1029759 :         nkwargs = PyTuple_GET_SIZE(kwnames);
    2262                 :    1029759 :         kwstack = args + nargs;
    2263                 :            :     }
    2264                 :            :     else {
    2265                 :        998 :         nkwargs = 0;
    2266                 :            :     }
    2267   [ +  +  +  -  :    1120767 :     if (nkwargs == 0 && minkw == 0 && minpos <= nargs && nargs <= maxpos) {
             +  +  +  + ]
    2268                 :            :         /* Fast path. */
    2269                 :      45385 :         return args;
    2270                 :            :     }
    2271         [ +  + ]:    1075382 :     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         [ +  + ]:    1075343 :     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         [ +  + ]:    1075323 :     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         [ +  + ]:    1582532 :     for (i = 0; i < nargs; i++) {
    2318                 :     507269 :         buf[i] = args[i];
    2319                 :            :     }
    2320                 :            : 
    2321                 :            :     /* copy keyword args using kwtuple to drive process */
    2322         [ +  + ]:    2509236 :     for (i = Py_MAX((int)nargs, posonly); i < maxargs; i++) {
    2323         [ +  + ]:    1803705 :         if (nkwargs) {
    2324                 :    1433984 :             keyword = PyTuple_GET_ITEM(kwtuple, i - posonly);
    2325         [ +  + ]:    1433984 :             if (kwargs != NULL) {
    2326                 :      94516 :                 current_arg = PyDict_GetItemWithError(kwargs, keyword);
    2327   [ +  +  -  + ]:      94516 :                 if (!current_arg && PyErr_Occurred()) {
    2328                 :          0 :                     return NULL;
    2329                 :            :                 }
    2330                 :            :             }
    2331                 :            :             else {
    2332                 :    1339468 :                 current_arg = find_keyword(kwnames, kwstack, keyword);
    2333                 :            :             }
    2334                 :            :         }
    2335         [ +  + ]:     369721 :         else if (i >= reqlimit) {
    2336                 :     369626 :             break;
    2337                 :            :         }
    2338                 :            :         else {
    2339                 :         95 :             current_arg = NULL;
    2340                 :            :         }
    2341                 :            : 
    2342                 :    1434079 :         buf[i] = current_arg;
    2343                 :            : 
    2344         [ +  + ]:    1434079 :         if (current_arg) {
    2345                 :    1154375 :             --nkwargs;
    2346                 :            :         }
    2347   [ +  +  +  +  :     279704 :         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         [ +  + ]:    1075157 :     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                 :    1075138 :     return buf;
    2415                 :            : }
    2416                 :            : 
    2417                 :            : PyObject * const *
    2418                 :      93435 : _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                 :      93435 :     Py_ssize_t varargssize = 0;
    2427                 :            :     int i, posonly, minposonly, maxargs;
    2428         [ -  + ]:      93435 :     int reqlimit = minkw ? maxpos + minkw : minpos;
    2429                 :            :     Py_ssize_t nkwargs;
    2430                 :            :     PyObject *current_arg;
    2431                 :      93435 :     PyObject * const *kwstack = NULL;
    2432                 :            : 
    2433                 :            :     assert(kwargs == NULL || PyDict_Check(kwargs));
    2434                 :            :     assert(kwargs == NULL || kwnames == NULL);
    2435                 :            : 
    2436         [ -  + ]:      93435 :     if (parser == NULL) {
    2437                 :          0 :         PyErr_BadInternalCall();
    2438                 :          0 :         return NULL;
    2439                 :            :     }
    2440                 :            : 
    2441   [ +  +  -  + ]:      93435 :     if (kwnames != NULL && !PyTuple_Check(kwnames)) {
    2442                 :          0 :         PyErr_BadInternalCall();
    2443                 :          0 :         return NULL;
    2444                 :            :     }
    2445                 :            : 
    2446   [ -  +  -  - ]:      93435 :     if (args == NULL && nargs == 0) {
    2447                 :          0 :         args = buf;
    2448                 :            :     }
    2449                 :            : 
    2450         [ -  + ]:      93435 :     if (!parser_init(parser)) {
    2451                 :          0 :         return NULL;
    2452                 :            :     }
    2453                 :            : 
    2454                 :      93435 :     kwtuple = parser->kwtuple;
    2455                 :      93435 :     posonly = parser->pos;
    2456                 :      93435 :     minposonly = Py_MIN(posonly, minpos);
    2457                 :      93435 :     maxargs = posonly + (int)PyTuple_GET_SIZE(kwtuple);
    2458         [ -  + ]:      93435 :     if (kwargs != NULL) {
    2459                 :          0 :         nkwargs = PyDict_GET_SIZE(kwargs);
    2460                 :            :     }
    2461         [ +  + ]:      93435 :     else if (kwnames != NULL) {
    2462                 :      64163 :         nkwargs = PyTuple_GET_SIZE(kwnames);
    2463                 :      64163 :         kwstack = args + nargs;
    2464                 :            :     }
    2465                 :            :     else {
    2466                 :      29272 :         nkwargs = 0;
    2467                 :            :     }
    2468         [ -  + ]:      93435 :     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                 :      93435 :     varargssize = nargs - maxpos;
    2483         [ -  + ]:      93435 :     if (varargssize < 0) {
    2484                 :          0 :         varargssize = 0;
    2485                 :            :     }
    2486                 :      93435 :     buf[vararg] = PyTuple_New(varargssize);
    2487         [ -  + ]:      93435 :     if (!buf[vararg]) {
    2488                 :          0 :         return NULL;
    2489                 :            :     }
    2490                 :            : 
    2491                 :            :     /* copy tuple args */
    2492         [ +  + ]:     184837 :     for (i = 0; i < nargs; i++) {
    2493         [ +  - ]:      91402 :         if (i >= vararg) {
    2494                 :      91402 :             Py_INCREF(args[i]);
    2495                 :      91402 :             PyTuple_SET_ITEM(buf[vararg], i - vararg, args[i]);
    2496                 :      91402 :             continue;
    2497                 :            :         }
    2498                 :            :         else {
    2499                 :          0 :             buf[i] = args[i];
    2500                 :            :         }
    2501                 :            :     }
    2502                 :            : 
    2503                 :            :     /* copy keyword args using kwtuple to drive process */
    2504                 :      93435 :     for (i = Py_MAX((int)nargs, posonly) -
    2505         [ +  + ]:     467175 :          Py_SAFE_DOWNCAST(varargssize, Py_ssize_t, int); i < maxargs; i++) {
    2506         [ +  + ]:     373740 :         if (nkwargs) {
    2507                 :     188914 :             keyword = PyTuple_GET_ITEM(kwtuple, i - posonly);
    2508         [ -  + ]:     188914 :             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                 :     188914 :                 current_arg = find_keyword(kwnames, kwstack, keyword);
    2516                 :            :             }
    2517                 :            :         }
    2518                 :            :         else {
    2519                 :     184826 :             current_arg = NULL;
    2520                 :            :         }
    2521                 :            : 
    2522                 :     373740 :         buf[i + vararg + 1] = current_arg;
    2523                 :            : 
    2524         [ +  + ]:     373740 :         if (current_arg) {
    2525                 :      80806 :             --nkwargs;
    2526                 :            :         }
    2527   [ +  -  +  -  :     292934 :         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         [ +  + ]:      93435 :     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                 :      93434 :     return buf;
    2572                 :            : 
    2573                 :          1 : exit:
    2574                 :          1 :     Py_XDECREF(buf[vararg]);
    2575                 :          1 :     return NULL;
    2576                 :            : }
    2577                 :            : 
    2578                 :            : 
    2579                 :            : static const char *
    2580                 :     687494 : skipitem(const char **p_format, va_list *p_va, int flags)
    2581                 :            : {
    2582                 :     687494 :     const char *format = *p_format;
    2583                 :     687494 :     char c = *format++;
    2584                 :            : 
    2585   [ +  +  +  +  :     687494 :     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                 :     368693 :     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         [ +  + ]:     368693 :             if (p_va != NULL) {
    2614                 :     368685 :                 (void) va_arg(*p_va, void *);
    2615                 :            :             }
    2616                 :     368693 :             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                 :         28 :     case 's': /* string */
    2634                 :            :     case 'z': /* string or None */
    2635                 :            :     case 'y': /* bytes */
    2636                 :            :     case 'w': /* buffer, read-write */
    2637                 :            :         {
    2638         [ +  + ]:         28 :             if (p_va != NULL) {
    2639                 :         23 :                 (void) va_arg(*p_va, char **);
    2640                 :            :             }
    2641         [ +  + ]:         28 :             if (*format == '#') {
    2642         [ +  + ]:         13 :                 if (p_va != NULL) {
    2643         [ +  + ]:          8 :                     if (!(flags & FLAG_SIZE_T)) {
    2644                 :          4 :                         return "PY_SSIZE_T_CLEAN macro must be defined for '#' formats";
    2645                 :            :                     }
    2646                 :          4 :                     (void) va_arg(*p_va, Py_ssize_t *);
    2647                 :            :                 }
    2648                 :          9 :                 format++;
    2649   [ +  +  +  +  :         15 :             } else if ((c == 's' || c == 'z' || c == 'y' || c == 'w')
             +  +  +  + ]
    2650         [ +  + ]:         13 :                        && *format == '*')
    2651                 :            :             {
    2652                 :          6 :                 format++;
    2653                 :            :             }
    2654                 :         24 :             break;
    2655                 :            :         }
    2656                 :            : 
    2657                 :     318554 :     case 'O': /* object */
    2658                 :            :         {
    2659         [ +  + ]:     318554 :             if (*format == '!') {
    2660                 :          1 :                 format++;
    2661         [ +  - ]:          1 :                 if (p_va != NULL) {
    2662                 :          1 :                     (void) va_arg(*p_va, PyTypeObject*);
    2663                 :          1 :                     (void) va_arg(*p_va, PyObject **);
    2664                 :            :                 }
    2665                 :            :             }
    2666         [ +  + ]:     318553 :             else if (*format == '&') {
    2667                 :            :                 typedef int (*converter)(PyObject *, void *);
    2668         [ +  + ]:         40 :                 if (p_va != NULL) {
    2669                 :         38 :                     (void) va_arg(*p_va, converter);
    2670                 :         38 :                     (void) va_arg(*p_va, void *);
    2671                 :            :                 }
    2672                 :         40 :                 format++;
    2673                 :            :             }
    2674                 :            :             else {
    2675         [ +  + ]:     318513 :                 if (p_va != NULL) {
    2676                 :     318509 :                     (void) va_arg(*p_va, PyObject **);
    2677                 :            :                 }
    2678                 :            :             }
    2679                 :     318554 :             break;
    2680                 :            :         }
    2681                 :            : 
    2682                 :         22 :     case '(':           /* bypass tuple, not handled at all previously */
    2683                 :            :         {
    2684                 :            :             const char *msg;
    2685                 :            :             for (;;) {
    2686         [ +  + ]:         22 :                 if (*format==')')
    2687                 :          6 :                     break;
    2688   [ +  -  +  -  :         16 :                 if (IS_END_OF_FORMAT(*format))
                   -  + ]
    2689                 :          0 :                     return "Unmatched left paren in format "
    2690                 :            :                            "string";
    2691                 :         16 :                 msg = skipitem(&format, p_va, flags);
    2692         [ +  + ]:         16 :                 if (msg)
    2693                 :          2 :                     return msg;
    2694                 :            :             }
    2695                 :          6 :             format++;
    2696                 :          6 :             break;
    2697                 :            :         }
    2698                 :            : 
    2699                 :          0 :     case ')':
    2700                 :          0 :         return "Unmatched right paren in format string";
    2701                 :            : 
    2702                 :            :     default:
    2703                 :        211 : err:
    2704                 :        211 :         return "impossible<bad format char>";
    2705                 :            : 
    2706                 :            :     }
    2707                 :            : 
    2708                 :     687277 :     *p_format = format;
    2709                 :     687277 :     return NULL;
    2710                 :            : }
    2711                 :            : 
    2712                 :            : 
    2713                 :            : #undef _PyArg_CheckPositional
    2714                 :            : 
    2715                 :            : int
    2716                 :   12012774 : _PyArg_CheckPositional(const char *name, Py_ssize_t nargs,
    2717                 :            :                        Py_ssize_t min, Py_ssize_t max)
    2718                 :            : {
    2719                 :            :     assert(min >= 0);
    2720                 :            :     assert(min <= max);
    2721                 :            : 
    2722         [ +  + ]:   12012774 :     if (nargs < min) {
    2723         [ +  - ]:        284 :         if (name != NULL)
    2724   [ +  +  +  + ]:        284 :             PyErr_Format(
    2725                 :            :                 PyExc_TypeError,
    2726                 :            :                 "%.200s expected %s%zd argument%s, got %zd",
    2727                 :            :                 name, (min == max ? "" : "at least "), min, min == 1 ? "" : "s", nargs);
    2728                 :            :         else
    2729   [ #  #  #  # ]:          0 :             PyErr_Format(
    2730                 :            :                 PyExc_TypeError,
    2731                 :            :                 "unpacked tuple should have %s%zd element%s,"
    2732                 :            :                 " but has %zd",
    2733                 :            :                 (min == max ? "" : "at least "), min, min == 1 ? "" : "s", nargs);
    2734                 :        284 :         return 0;
    2735                 :            :     }
    2736                 :            : 
    2737         [ +  + ]:   12012490 :     if (nargs == 0) {
    2738                 :      92125 :         return 1;
    2739                 :            :     }
    2740                 :            : 
    2741         [ +  + ]:   11920365 :     if (nargs > max) {
    2742         [ +  - ]:        111 :         if (name != NULL)
    2743   [ +  +  +  + ]:        111 :             PyErr_Format(
    2744                 :            :                 PyExc_TypeError,
    2745                 :            :                 "%.200s expected %s%zd argument%s, got %zd",
    2746                 :            :                 name, (min == max ? "" : "at most "), max, max == 1 ? "" : "s", nargs);
    2747                 :            :         else
    2748   [ #  #  #  # ]:          0 :             PyErr_Format(
    2749                 :            :                 PyExc_TypeError,
    2750                 :            :                 "unpacked tuple should have %s%zd element%s,"
    2751                 :            :                 " but has %zd",
    2752                 :            :                 (min == max ? "" : "at most "), max, max == 1 ? "" : "s", nargs);
    2753                 :        111 :         return 0;
    2754                 :            :     }
    2755                 :            : 
    2756                 :   11920254 :     return 1;
    2757                 :            : }
    2758                 :            : 
    2759                 :            : static int
    2760                 :   12012436 : unpack_stack(PyObject *const *args, Py_ssize_t nargs, const char *name,
    2761                 :            :              Py_ssize_t min, Py_ssize_t max, va_list vargs)
    2762                 :            : {
    2763                 :            :     Py_ssize_t i;
    2764                 :            :     PyObject **o;
    2765                 :            : 
    2766         [ +  + ]:   12012436 :     if (!_PyArg_CheckPositional(name, nargs, min, max)) {
    2767                 :         61 :         return 0;
    2768                 :            :     }
    2769                 :            : 
    2770         [ +  + ]:   29160243 :     for (i = 0; i < nargs; i++) {
    2771                 :   17147868 :         o = va_arg(vargs, PyObject **);
    2772                 :   17147868 :         *o = args[i];
    2773                 :            :     }
    2774                 :   12012375 :     return 1;
    2775                 :            : }
    2776                 :            : 
    2777                 :            : int
    2778                 :   10910750 : PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, ...)
    2779                 :            : {
    2780                 :            :     PyObject **stack;
    2781                 :            :     Py_ssize_t nargs;
    2782                 :            :     int retval;
    2783                 :            :     va_list vargs;
    2784                 :            : 
    2785         [ -  + ]:   10910750 :     if (!PyTuple_Check(args)) {
    2786                 :          0 :         PyErr_SetString(PyExc_SystemError,
    2787                 :            :             "PyArg_UnpackTuple() argument list is not a tuple");
    2788                 :          0 :         return 0;
    2789                 :            :     }
    2790                 :   10910750 :     stack = _PyTuple_ITEMS(args);
    2791                 :   10910750 :     nargs = PyTuple_GET_SIZE(args);
    2792                 :            : 
    2793                 :   10910750 :     va_start(vargs, max);
    2794                 :   10910750 :     retval = unpack_stack(stack, nargs, name, min, max, vargs);
    2795                 :   10910750 :     va_end(vargs);
    2796                 :   10910750 :     return retval;
    2797                 :            : }
    2798                 :            : 
    2799                 :            : int
    2800                 :    1101686 : _PyArg_UnpackStack(PyObject *const *args, Py_ssize_t nargs, const char *name,
    2801                 :            :                    Py_ssize_t min, Py_ssize_t max, ...)
    2802                 :            : {
    2803                 :            :     int retval;
    2804                 :            :     va_list vargs;
    2805                 :            : 
    2806                 :    1101686 :     va_start(vargs, max);
    2807                 :    1101686 :     retval = unpack_stack(args, nargs, name, min, max, vargs);
    2808                 :    1101686 :     va_end(vargs);
    2809                 :    1101686 :     return retval;
    2810                 :            : }
    2811                 :            : 
    2812                 :            : 
    2813                 :            : #undef _PyArg_NoKeywords
    2814                 :            : #undef _PyArg_NoKwnames
    2815                 :            : #undef _PyArg_NoPositional
    2816                 :            : 
    2817                 :            : /* For type constructors that don't take keyword args
    2818                 :            :  *
    2819                 :            :  * Sets a TypeError and returns 0 if the args/kwargs is
    2820                 :            :  * not empty, returns 1 otherwise
    2821                 :            :  */
    2822                 :            : int
    2823                 :      58734 : _PyArg_NoKeywords(const char *funcname, PyObject *kwargs)
    2824                 :            : {
    2825         [ -  + ]:      58734 :     if (kwargs == NULL) {
    2826                 :          0 :         return 1;
    2827                 :            :     }
    2828         [ -  + ]:      58734 :     if (!PyDict_CheckExact(kwargs)) {
    2829                 :          0 :         PyErr_BadInternalCall();
    2830                 :          0 :         return 0;
    2831                 :            :     }
    2832         [ +  + ]:      58734 :     if (PyDict_GET_SIZE(kwargs) == 0) {
    2833                 :      58705 :         return 1;
    2834                 :            :     }
    2835                 :            : 
    2836                 :         29 :     PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments",
    2837                 :            :                     funcname);
    2838                 :         29 :     return 0;
    2839                 :            : }
    2840                 :            : 
    2841                 :            : int
    2842                 :      12060 : _PyArg_NoPositional(const char *funcname, PyObject *args)
    2843                 :            : {
    2844         [ -  + ]:      12060 :     if (args == NULL)
    2845                 :          0 :         return 1;
    2846         [ -  + ]:      12060 :     if (!PyTuple_CheckExact(args)) {
    2847                 :          0 :         PyErr_BadInternalCall();
    2848                 :          0 :         return 0;
    2849                 :            :     }
    2850         [ +  + ]:      12060 :     if (PyTuple_GET_SIZE(args) == 0)
    2851                 :      12059 :         return 1;
    2852                 :            : 
    2853                 :          1 :     PyErr_Format(PyExc_TypeError, "%.200s() takes no positional arguments",
    2854                 :            :                     funcname);
    2855                 :          1 :     return 0;
    2856                 :            : }
    2857                 :            : 
    2858                 :            : int
    2859                 :         18 : _PyArg_NoKwnames(const char *funcname, PyObject *kwnames)
    2860                 :            : {
    2861         [ -  + ]:         18 :     if (kwnames == NULL) {
    2862                 :          0 :         return 1;
    2863                 :            :     }
    2864                 :            : 
    2865                 :            :     assert(PyTuple_CheckExact(kwnames));
    2866                 :            : 
    2867         [ -  + ]:         18 :     if (PyTuple_GET_SIZE(kwnames) == 0) {
    2868                 :          0 :         return 1;
    2869                 :            :     }
    2870                 :            : 
    2871                 :         18 :     PyErr_Format(PyExc_TypeError, "%s() takes no keyword arguments", funcname);
    2872                 :         18 :     return 0;
    2873                 :            : }
    2874                 :            : 
    2875                 :            : void
    2876                 :       2956 : _PyArg_Fini(void)
    2877                 :            : {
    2878                 :       2956 :     struct _PyArg_Parser *tmp, *s = static_arg_parsers;
    2879         [ +  + ]:      22748 :     while (s) {
    2880                 :      19792 :         tmp = s->next;
    2881                 :      19792 :         s->next = NULL;
    2882                 :      19792 :         parser_clear(s);
    2883                 :      19792 :         s = tmp;
    2884                 :            :     }
    2885                 :       2956 :     static_arg_parsers = NULL;
    2886                 :       2956 : }
    2887                 :            : 
    2888                 :            : #ifdef __cplusplus
    2889                 :            : };
    2890                 :            : #endif

Generated by: LCOV version 1.14