@@ -1766,45 +1766,39 @@ builtin_locals_impl(PyObject *module)
17661766
17671767
17681768static PyObject *
1769- min_max (PyObject * args , PyObject * kwds , int op )
1769+ min_max (PyObject * const * args , Py_ssize_t nargs , PyObject * kwnames , int op )
17701770{
1771- PyObject * v , * it , * item , * val , * maxitem , * maxval , * keyfunc = NULL ;
1772- PyObject * emptytuple , * defaultval = NULL ;
1773- static char * kwlist [] = {"key" , "default" , NULL };
1774- const char * name = op == Py_LT ? "min" : "max" ;
1775- const int positional = PyTuple_Size (args ) > 1 ;
1776- int ret ;
1771+ PyObject * it = NULL , * item , * val , * maxitem , * maxval , * keyfunc = NULL ;
1772+ PyObject * defaultval = NULL ;
1773+ static const char * const keywords [] = {"key" , "default" , NULL };
1774+ static _PyArg_Parser _parser_min = {"|$OO:min" , keywords , 0 };
1775+ static _PyArg_Parser _parser_max = {"|$OO:max" , keywords , 0 };
1776+ const char * name = (op == Py_LT ) ? "min" : "max" ;
1777+ _PyArg_Parser * _parser = (op == Py_LT ) ? & _parser_min : & _parser_max ;
17771778
1778- if (positional ) {
1779- v = args ;
1780- }
1781- else if (!PyArg_UnpackTuple (args , name , 1 , 1 , & v )) {
1782- if (PyExceptionClass_Check (PyExc_TypeError )) {
1783- PyErr_Format (PyExc_TypeError , "%s expected at least 1 argument, got 0" , name );
1784- }
1779+ if (nargs == 0 ) {
1780+ PyErr_Format (PyExc_TypeError , "%s expected at least 1 argument, got 0" , name );
17851781 return NULL ;
17861782 }
17871783
1788- emptytuple = PyTuple_New (0 );
1789- if (emptytuple == NULL )
1790- return NULL ;
1791- ret = PyArg_ParseTupleAndKeywords (emptytuple , kwds ,
1792- (op == Py_LT ) ? "|$OO:min" : "|$OO:max" ,
1793- kwlist , & keyfunc , & defaultval );
1794- Py_DECREF (emptytuple );
1795- if (!ret )
1784+ if (kwnames != NULL && !_PyArg_ParseStackAndKeywords (args + nargs , 0 , kwnames , _parser ,
1785+ & keyfunc , & defaultval )) {
17961786 return NULL ;
1787+ }
17971788
1789+ const int positional = nargs > 1 ; // False iff nargs == 1
17981790 if (positional && defaultval != NULL ) {
17991791 PyErr_Format (PyExc_TypeError ,
18001792 "Cannot specify a default for %s() with multiple "
18011793 "positional arguments" , name );
18021794 return NULL ;
18031795 }
18041796
1805- it = PyObject_GetIter (v );
1806- if (it == NULL ) {
1807- return NULL ;
1797+ if (!positional ) {
1798+ it = PyObject_GetIter (args [0 ]);
1799+ if (it == NULL ) {
1800+ return NULL ;
1801+ }
18081802 }
18091803
18101804 if (keyfunc == Py_None ) {
@@ -1813,7 +1807,24 @@ min_max(PyObject *args, PyObject *kwds, int op)
18131807
18141808 maxitem = NULL ; /* the result */
18151809 maxval = NULL ; /* the value associated with the result */
1816- while (( item = PyIter_Next (it ) )) {
1810+ while (1 ) {
1811+ if (it == NULL ) {
1812+ if (nargs -- <= 0 ) {
1813+ break ;
1814+ }
1815+ item = * args ++ ;
1816+ Py_INCREF (item );
1817+ }
1818+ else {
1819+ item = PyIter_Next (it );
1820+ if (item == NULL ) {
1821+ if (PyErr_Occurred ()) {
1822+ goto Fail_it ;
1823+ }
1824+ break ;
1825+ }
1826+ }
1827+
18171828 /* get the value from the key function */
18181829 if (keyfunc != NULL ) {
18191830 val = PyObject_CallOneArg (keyfunc , item );
@@ -1847,8 +1858,6 @@ min_max(PyObject *args, PyObject *kwds, int op)
18471858 }
18481859 }
18491860 }
1850- if (PyErr_Occurred ())
1851- goto Fail_it ;
18521861 if (maxval == NULL ) {
18531862 assert (maxitem == NULL );
18541863 if (defaultval != NULL ) {
@@ -1860,7 +1869,7 @@ min_max(PyObject *args, PyObject *kwds, int op)
18601869 }
18611870 else
18621871 Py_DECREF (maxval );
1863- Py_DECREF (it );
1872+ Py_XDECREF (it );
18641873 return maxitem ;
18651874
18661875Fail_it_item_and_val :
@@ -1870,15 +1879,15 @@ min_max(PyObject *args, PyObject *kwds, int op)
18701879Fail_it :
18711880 Py_XDECREF (maxval );
18721881 Py_XDECREF (maxitem );
1873- Py_DECREF (it );
1882+ Py_XDECREF (it );
18741883 return NULL ;
18751884}
18761885
18771886/* AC: cannot convert yet, waiting for *args support */
18781887static PyObject *
1879- builtin_min (PyObject * self , PyObject * args , PyObject * kwds )
1888+ builtin_min (PyObject * self , PyObject * const * args , Py_ssize_t nargs , PyObject * kwnames )
18801889{
1881- return min_max (args , kwds , Py_LT );
1890+ return min_max (args , nargs , kwnames , Py_LT );
18821891}
18831892
18841893PyDoc_STRVAR (min_doc ,
@@ -1893,9 +1902,9 @@ With two or more positional arguments, return the smallest argument.");
18931902
18941903/* AC: cannot convert yet, waiting for *args support */
18951904static PyObject *
1896- builtin_max (PyObject * self , PyObject * args , PyObject * kwds )
1905+ builtin_max (PyObject * self , PyObject * const * args , Py_ssize_t nargs , PyObject * kwnames )
18971906{
1898- return min_max (args , kwds , Py_GT );
1907+ return min_max (args , nargs , kwnames , Py_GT );
18991908}
19001909
19011910PyDoc_STRVAR (max_doc ,
@@ -3054,8 +3063,8 @@ static PyMethodDef builtin_methods[] = {
30543063 BUILTIN_AITER_METHODDEF
30553064 BUILTIN_LEN_METHODDEF
30563065 BUILTIN_LOCALS_METHODDEF
3057- {"max" , _PyCFunction_CAST (builtin_max ), METH_VARARGS | METH_KEYWORDS , max_doc },
3058- {"min" , _PyCFunction_CAST (builtin_min ), METH_VARARGS | METH_KEYWORDS , min_doc },
3066+ {"max" , _PyCFunction_CAST (builtin_max ), METH_FASTCALL | METH_KEYWORDS , max_doc },
3067+ {"min" , _PyCFunction_CAST (builtin_min ), METH_FASTCALL | METH_KEYWORDS , min_doc },
30593068 {"next" , _PyCFunction_CAST (builtin_next ), METH_FASTCALL , next_doc },
30603069 BUILTIN_ANEXT_METHODDEF
30613070 BUILTIN_OCT_METHODDEF
0 commit comments