@@ -1747,45 +1747,47 @@ builtin_locals_impl(PyObject *module)
17471747
17481748
17491749static PyObject *
1750- min_max (PyObject * args , PyObject * kwds , int op )
1750+ min_max (PyObject * const * args , Py_ssize_t nargs , PyObject * kwnames , int op )
17511751{
1752- PyObject * v , * it , * item , * val , * maxitem , * maxval , * keyfunc = NULL ;
1753- PyObject * emptytuple , * defaultval = NULL ;
1754- static char * kwlist [] = {"key" , "default" , NULL };
1755- const char * name = op == Py_LT ? "min" : "max" ;
1756- const int positional = PyTuple_Size (args ) > 1 ;
1757- int ret ;
1752+ PyObject * it = NULL , * item , * val , * maxitem , * maxval , * keyfunc = NULL ;
1753+ PyObject * defaultval = NULL ;
1754+ static const char * const keywords [] = {"key" , "default" , NULL };
1755+ static _PyArg_Parser _parser_min = {
1756+ .format = "|$OO:min" ,
1757+ .keywords = keywords ,
1758+ .fname = 0 ,
1759+ };
1760+ static _PyArg_Parser _parser_max = {
1761+ .format = "|$OO:max" ,
1762+ .keywords = keywords ,
1763+ .fname = 0 ,
1764+ };
1765+ const char * name = (op == Py_LT ) ? "min" : "max" ;
1766+ _PyArg_Parser * _parser = (op == Py_LT ) ? & _parser_min : & _parser_max ;
17581767
1759- if (positional ) {
1760- v = args ;
1761- }
1762- else if (!PyArg_UnpackTuple (args , name , 1 , 1 , & v )) {
1763- if (PyExceptionClass_Check (PyExc_TypeError )) {
1764- PyErr_Format (PyExc_TypeError , "%s expected at least 1 argument, got 0" , name );
1765- }
1768+ if (nargs == 0 ) {
1769+ PyErr_Format (PyExc_TypeError , "%s expected at least 1 argument, got 0" , name );
17661770 return NULL ;
17671771 }
17681772
1769- emptytuple = PyTuple_New (0 );
1770- if (emptytuple == NULL )
1771- return NULL ;
1772- ret = PyArg_ParseTupleAndKeywords (emptytuple , kwds ,
1773- (op == Py_LT ) ? "|$OO:min" : "|$OO:max" ,
1774- kwlist , & keyfunc , & defaultval );
1775- Py_DECREF (emptytuple );
1776- if (!ret )
1773+ if (kwnames != NULL && !_PyArg_ParseStackAndKeywords (args + nargs , 0 , kwnames , _parser ,
1774+ & keyfunc , & defaultval )) {
17771775 return NULL ;
1776+ }
17781777
1778+ const int positional = nargs > 1 ; // False iff nargs == 1
17791779 if (positional && defaultval != NULL ) {
17801780 PyErr_Format (PyExc_TypeError ,
17811781 "Cannot specify a default for %s() with multiple "
17821782 "positional arguments" , name );
17831783 return NULL ;
17841784 }
17851785
1786- it = PyObject_GetIter (v );
1787- if (it == NULL ) {
1788- return NULL ;
1786+ if (!positional ) {
1787+ it = PyObject_GetIter (args [0 ]);
1788+ if (it == NULL ) {
1789+ return NULL ;
1790+ }
17891791 }
17901792
17911793 if (keyfunc == Py_None ) {
@@ -1794,7 +1796,24 @@ min_max(PyObject *args, PyObject *kwds, int op)
17941796
17951797 maxitem = NULL ; /* the result */
17961798 maxval = NULL ; /* the value associated with the result */
1797- while (( item = PyIter_Next (it ) )) {
1799+ while (1 ) {
1800+ if (it == NULL ) {
1801+ if (nargs -- <= 0 ) {
1802+ break ;
1803+ }
1804+ item = * args ++ ;
1805+ Py_INCREF (item );
1806+ }
1807+ else {
1808+ item = PyIter_Next (it );
1809+ if (item == NULL ) {
1810+ if (PyErr_Occurred ()) {
1811+ goto Fail_it ;
1812+ }
1813+ break ;
1814+ }
1815+ }
1816+
17981817 /* get the value from the key function */
17991818 if (keyfunc != NULL ) {
18001819 val = PyObject_CallOneArg (keyfunc , item );
@@ -1828,8 +1847,6 @@ min_max(PyObject *args, PyObject *kwds, int op)
18281847 }
18291848 }
18301849 }
1831- if (PyErr_Occurred ())
1832- goto Fail_it ;
18331850 if (maxval == NULL ) {
18341851 assert (maxitem == NULL );
18351852 if (defaultval != NULL ) {
@@ -1841,7 +1858,7 @@ min_max(PyObject *args, PyObject *kwds, int op)
18411858 }
18421859 else
18431860 Py_DECREF (maxval );
1844- Py_DECREF (it );
1861+ Py_XDECREF (it );
18451862 return maxitem ;
18461863
18471864Fail_it_item_and_val :
@@ -1851,15 +1868,15 @@ min_max(PyObject *args, PyObject *kwds, int op)
18511868Fail_it :
18521869 Py_XDECREF (maxval );
18531870 Py_XDECREF (maxitem );
1854- Py_DECREF (it );
1871+ Py_XDECREF (it );
18551872 return NULL ;
18561873}
18571874
18581875/* AC: cannot convert yet, waiting for *args support */
18591876static PyObject *
1860- builtin_min (PyObject * self , PyObject * args , PyObject * kwds )
1877+ builtin_min (PyObject * self , PyObject * const * args , Py_ssize_t nargs , PyObject * kwnames )
18611878{
1862- return min_max (args , kwds , Py_LT );
1879+ return min_max (args , nargs , kwnames , Py_LT );
18631880}
18641881
18651882PyDoc_STRVAR (min_doc ,
@@ -1874,9 +1891,9 @@ With two or more arguments, return the smallest argument.");
18741891
18751892/* AC: cannot convert yet, waiting for *args support */
18761893static PyObject *
1877- builtin_max (PyObject * self , PyObject * args , PyObject * kwds )
1894+ builtin_max (PyObject * self , PyObject * const * args , Py_ssize_t nargs , PyObject * kwnames )
18781895{
1879- return min_max (args , kwds , Py_GT );
1896+ return min_max (args , nargs , kwnames , Py_GT );
18801897}
18811898
18821899PyDoc_STRVAR (max_doc ,
@@ -3042,8 +3059,8 @@ static PyMethodDef builtin_methods[] = {
30423059 BUILTIN_AITER_METHODDEF
30433060 BUILTIN_LEN_METHODDEF
30443061 BUILTIN_LOCALS_METHODDEF
3045- {"max" , _PyCFunction_CAST (builtin_max ), METH_VARARGS | METH_KEYWORDS , max_doc },
3046- {"min" , _PyCFunction_CAST (builtin_min ), METH_VARARGS | METH_KEYWORDS , min_doc },
3062+ {"max" , _PyCFunction_CAST (builtin_max ), METH_FASTCALL | METH_KEYWORDS , max_doc },
3063+ {"min" , _PyCFunction_CAST (builtin_min ), METH_FASTCALL | METH_KEYWORDS , min_doc },
30473064 BUILTIN_NEXT_METHODDEF
30483065 BUILTIN_ANEXT_METHODDEF
30493066 BUILTIN_OCT_METHODDEF
0 commit comments