@@ -57,8 +57,15 @@ static const char *convertsimple(PyObject *, const char **, va_list *, int,
5757static Py_ssize_t convertbuffer (PyObject * , const void * * p , const char * * );
5858static int getbuffer (PyObject * , Py_buffer * , const char * * );
5959
60- static int vgetargskeywords (PyObject * , PyObject * ,
61- const char * , const char * const * , va_list * , int );
60+ static int
61+ vgetargskeywords (PyObject * args , PyObject * kwargs ,
62+ const char * format , const char * const * kwlist ,
63+ va_list * p_va , int flags );
64+ static int
65+ vgetargskeywords_impl (PyObject * const * args , Py_ssize_t nargs ,
66+ PyObject * kwargs , PyObject * kwnames ,
67+ const char * format , const char * const * kwlist ,
68+ va_list * p_va , int flags );
6269static int vgetargskeywordsfast (PyObject * , PyObject * ,
6370 struct _PyArg_Parser * , va_list * , int );
6471static int vgetargskeywordsfast_impl (PyObject * const * args , Py_ssize_t nargs ,
@@ -129,6 +136,40 @@ _PyArg_ParseStack(PyObject *const *args, Py_ssize_t nargs, const char *format, .
129136 return retval ;
130137}
131138
139+ int
140+ PyArg_ParseArray (PyObject * const * args , Py_ssize_t nargs , const char * format , ...)
141+ {
142+ va_list va ;
143+ va_start (va , format );
144+ int retval = vgetargs1_impl (NULL , args , nargs , format , & va , 0 );
145+ va_end (va );
146+ return retval ;
147+ }
148+
149+ int
150+ PyArg_ParseArrayAndKeywords (PyObject * const * args , Py_ssize_t nargs ,
151+ PyObject * kwnames ,
152+ const char * format ,
153+ const char * const * kwlist , ...)
154+ {
155+ if ((args == NULL && nargs != 0 ) ||
156+ (kwnames != NULL && !PyTuple_Check (kwnames )) ||
157+ format == NULL ||
158+ kwlist == NULL )
159+ {
160+ PyErr_BadInternalCall ();
161+ return 0 ;
162+ }
163+
164+ va_list va ;
165+ va_start (va , kwlist );
166+ int retval = vgetargskeywords_impl (args , nargs , NULL , kwnames , format ,
167+ kwlist , & va , 0 );
168+ va_end (va );
169+ return retval ;
170+ }
171+
172+
132173int
133174PyArg_VaParse (PyObject * args , const char * format , va_list va )
134175{
@@ -1612,11 +1653,27 @@ PyArg_ValidateKeywordArguments(PyObject *kwargs)
16121653static PyObject *
16131654new_kwtuple (const char * const * keywords , int total , int pos );
16141655
1656+ static PyObject *
1657+ find_keyword_str (PyObject * kwnames , PyObject * const * kwstack , const char * key )
1658+ {
1659+ Py_ssize_t nkwargs = PyTuple_GET_SIZE (kwnames );
1660+ for (Py_ssize_t i = 0 ; i < nkwargs ; i ++ ) {
1661+ PyObject * kwname = PyTuple_GET_ITEM (kwnames , i );
1662+ assert (PyUnicode_Check (kwname ));
1663+ if (PyUnicode_EqualToUTF8 (kwname , key )) {
1664+ return Py_NewRef (kwstack [i ]);
1665+ }
1666+ }
1667+ return NULL ;
1668+ }
1669+
16151670#define IS_END_OF_FORMAT (c ) (c == '\0' || c == ';' || c == ':')
16161671
16171672static int
1618- vgetargskeywords (PyObject * args , PyObject * kwargs , const char * format ,
1619- const char * const * kwlist , va_list * p_va , int flags )
1673+ vgetargskeywords_impl (PyObject * const * args , Py_ssize_t nargs ,
1674+ PyObject * kwargs , PyObject * kwnames ,
1675+ const char * format , const char * const * kwlist ,
1676+ va_list * p_va , int flags )
16201677{
16211678 char msgbuf [512 ];
16221679 int levels [32 ];
@@ -1625,16 +1682,18 @@ vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format,
16251682 int max = INT_MAX ;
16261683 int i , pos , len ;
16271684 int skip = 0 ;
1628- Py_ssize_t nargs , nkwargs ;
1685+ Py_ssize_t nkwargs ;
16291686 freelistentry_t static_entries [STATIC_FREELIST_ENTRIES ];
16301687 freelist_t freelist ;
1688+ PyObject * const * kwstack = NULL ;
16311689
16321690 freelist .entries = static_entries ;
16331691 freelist .first_available = 0 ;
16341692 freelist .entries_malloced = 0 ;
16351693
1636- assert (args != NULL && PyTuple_Check ( args ) );
1694+ assert (args != NULL || nargs == 0 );
16371695 assert (kwargs == NULL || PyDict_Check (kwargs ));
1696+ assert (kwnames == NULL || PyTuple_Check (kwnames ));
16381697 assert (format != NULL );
16391698 assert (kwlist != NULL );
16401699 assert (p_va != NULL );
@@ -1672,8 +1731,16 @@ vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format,
16721731 freelist .entries_malloced = 1 ;
16731732 }
16741733
1675- nargs = PyTuple_GET_SIZE (args );
1676- nkwargs = (kwargs == NULL ) ? 0 : PyDict_GET_SIZE (kwargs );
1734+ if (kwargs != NULL ) {
1735+ nkwargs = PyDict_GET_SIZE (kwargs );
1736+ }
1737+ else if (kwnames != NULL ) {
1738+ nkwargs = PyTuple_GET_SIZE (kwnames );
1739+ kwstack = args + nargs ;
1740+ }
1741+ else {
1742+ nkwargs = 0 ;
1743+ }
16771744 if (nargs + nkwargs > len ) {
16781745 /* Adding "keyword" (when nargs == 0) prevents producing wrong error
16791746 messages in some special cases (see bpo-31229). */
@@ -1757,11 +1824,16 @@ vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format,
17571824 if (!skip ) {
17581825 PyObject * current_arg ;
17591826 if (i < nargs ) {
1760- current_arg = Py_NewRef (PyTuple_GET_ITEM ( args , i ) );
1827+ current_arg = Py_NewRef (args [ i ] );
17611828 }
17621829 else if (nkwargs && i >= pos ) {
1763- if (PyDict_GetItemStringRef (kwargs , kwlist [i ], & current_arg ) < 0 ) {
1764- return cleanreturn (0 , & freelist );
1830+ if (kwargs != NULL ) {
1831+ if (PyDict_GetItemStringRef (kwargs , kwlist [i ], & current_arg ) < 0 ) {
1832+ return cleanreturn (0 , & freelist );
1833+ }
1834+ }
1835+ else {
1836+ current_arg = find_keyword_str (kwnames , kwstack , kwlist [i ]);
17651837 }
17661838 if (current_arg ) {
17671839 -- nkwargs ;
@@ -1846,8 +1918,13 @@ vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format,
18461918 /* make sure there are no arguments given by name and position */
18471919 for (i = pos ; i < nargs ; i ++ ) {
18481920 PyObject * current_arg ;
1849- if (PyDict_GetItemStringRef (kwargs , kwlist [i ], & current_arg ) < 0 ) {
1850- return cleanreturn (0 , & freelist );
1921+ if (kwargs != NULL ) {
1922+ if (PyDict_GetItemStringRef (kwargs , kwlist [i ], & current_arg ) < 0 ) {
1923+ return cleanreturn (0 , & freelist );
1924+ }
1925+ }
1926+ else {
1927+ current_arg = find_keyword_str (kwnames , kwstack , kwlist [i ]);
18511928 }
18521929 if (current_arg ) {
18531930 Py_DECREF (current_arg );
@@ -1863,7 +1940,20 @@ vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format,
18631940 }
18641941 /* make sure there are no extraneous keyword arguments */
18651942 j = 0 ;
1866- while (PyDict_Next (kwargs , & j , & key , NULL )) {
1943+ while (1 ) {
1944+ if (kwargs != NULL ) {
1945+ if (!PyDict_Next (kwargs , & j , & key , NULL )) {
1946+ break ;
1947+ }
1948+ }
1949+ else {
1950+ if (j >= nkwargs ) {
1951+ break ;
1952+ }
1953+ key = PyTuple_GET_ITEM (kwnames , j );
1954+ j ++ ;
1955+ }
1956+
18671957 int match = 0 ;
18681958 if (!PyUnicode_Check (key )) {
18691959 PyErr_SetString (PyExc_TypeError ,
@@ -1921,6 +2011,16 @@ vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format,
19212011 return cleanreturn (1 , & freelist );
19222012}
19232013
2014+ static int
2015+ vgetargskeywords (PyObject * argstuple , PyObject * kwargs ,
2016+ const char * format , const char * const * kwlist ,
2017+ va_list * p_va , int flags )
2018+ {
2019+ PyObject * const * args = _PyTuple_ITEMS (argstuple );
2020+ Py_ssize_t nargs = PyTuple_GET_SIZE (argstuple );
2021+ return vgetargskeywords_impl (args , nargs , kwargs , NULL ,
2022+ format , kwlist , p_va , flags );
2023+ }
19242024
19252025static int
19262026scan_keywords (const char * const * keywords , int * ptotal , int * pposonly )
0 commit comments