@@ -1705,45 +1705,39 @@ builtin_locals_impl(PyObject *module)
1705
1705
1706
1706
1707
1707
static PyObject *
1708
- min_max (PyObject * args , PyObject * kwds , int op )
1708
+ min_max (PyObject * const * args , Py_ssize_t nargs , PyObject * kwnames , int op )
1709
1709
{
1710
- PyObject * v , * it , * item , * val , * maxitem , * maxval , * keyfunc = NULL ;
1711
- PyObject * emptytuple , * defaultval = NULL ;
1712
- static char * kwlist [] = {"key" , "default" , NULL };
1713
- const char * name = op == Py_LT ? "min" : "max" ;
1714
- const int positional = PyTuple_Size (args ) > 1 ;
1715
- int ret ;
1710
+ PyObject * it , * item , * val , * maxitem , * maxval , * keyfunc = NULL ;
1711
+ PyObject * defaultval = NULL ;
1712
+ static const char * const keywords [] = {"key" , "default" , NULL };
1713
+ static _PyArg_Parser _parser_min = {"|$OO:min" , keywords , 0 };
1714
+ static _PyArg_Parser _parser_max = {"|$OO:max" , keywords , 0 };
1715
+ const char * name = (op == Py_LT ) ? "min" : "max" ;
1716
+ _PyArg_Parser * _parser = (op == Py_LT ) ? & _parser_min : & _parser_max ;
1716
1717
1717
- if (positional ) {
1718
- v = args ;
1719
- }
1720
- else if (!PyArg_UnpackTuple (args , name , 1 , 1 , & v )) {
1721
- if (PyExceptionClass_Check (PyExc_TypeError )) {
1722
- PyErr_Format (PyExc_TypeError , "%s expected at least 1 argument, got 0" , name );
1723
- }
1718
+ if (nargs == 0 ) {
1719
+ PyErr_Format (PyExc_TypeError , "%s expected at least 1 argument, got 0" , name );
1724
1720
return NULL ;
1725
1721
}
1726
1722
1727
- emptytuple = PyTuple_New (0 );
1728
- if (emptytuple == NULL )
1729
- return NULL ;
1730
- ret = PyArg_ParseTupleAndKeywords (emptytuple , kwds ,
1731
- (op == Py_LT ) ? "|$OO:min" : "|$OO:max" ,
1732
- kwlist , & keyfunc , & defaultval );
1733
- Py_DECREF (emptytuple );
1734
- if (!ret )
1723
+ if (kwnames != NULL && !_PyArg_ParseStackAndKeywords (args + nargs , 0 , kwnames , _parser ,
1724
+ & keyfunc , & defaultval )) {
1735
1725
return NULL ;
1726
+ }
1736
1727
1728
+ const int positional = nargs > 1 ; // False iff nargs == 1
1737
1729
if (positional && defaultval != NULL ) {
1738
1730
PyErr_Format (PyExc_TypeError ,
1739
1731
"Cannot specify a default for %s() with multiple "
1740
1732
"positional arguments" , name );
1741
1733
return NULL ;
1742
1734
}
1743
1735
1744
- it = PyObject_GetIter (v );
1745
- if (it == NULL ) {
1746
- return NULL ;
1736
+ if (!positional ) {
1737
+ it = PyObject_GetIter (args [0 ]);
1738
+ if (it == NULL ) {
1739
+ return NULL ;
1740
+ }
1747
1741
}
1748
1742
1749
1743
if (keyfunc == Py_None ) {
@@ -1752,7 +1746,14 @@ min_max(PyObject *args, PyObject *kwds, int op)
1752
1746
1753
1747
maxitem = NULL ; /* the result */
1754
1748
maxval = NULL ; /* the value associated with the result */
1755
- while (( item = PyIter_Next (it ) )) {
1749
+ int i = 0 ;
1750
+ while (positional ?
1751
+ ((i < nargs ) && (item = args [i ++ ]))
1752
+ : !!(item = PyIter_Next (it ))) {
1753
+ if (positional ) {
1754
+ Py_INCREF (item );
1755
+ }
1756
+
1756
1757
/* get the value from the key function */
1757
1758
if (keyfunc != NULL ) {
1758
1759
val = PyObject_CallOneArg (keyfunc , item );
@@ -1801,7 +1802,9 @@ min_max(PyObject *args, PyObject *kwds, int op)
1801
1802
}
1802
1803
else
1803
1804
Py_DECREF (maxval );
1804
- Py_DECREF (it );
1805
+ if (!positional ) {
1806
+ Py_DECREF (it );
1807
+ }
1805
1808
return maxitem ;
1806
1809
1807
1810
Fail_it_item_and_val :
@@ -1811,15 +1814,17 @@ min_max(PyObject *args, PyObject *kwds, int op)
1811
1814
Fail_it :
1812
1815
Py_XDECREF (maxval );
1813
1816
Py_XDECREF (maxitem );
1814
- Py_DECREF (it );
1817
+ if (!positional ) {
1818
+ Py_DECREF (it );
1819
+ }
1815
1820
return NULL ;
1816
1821
}
1817
1822
1818
1823
/* AC: cannot convert yet, waiting for *args support */
1819
1824
static PyObject *
1820
- builtin_min (PyObject * self , PyObject * args , PyObject * kwds )
1825
+ builtin_min (PyObject * self , PyObject * const * args , Py_ssize_t nargs , PyObject * kwnames )
1821
1826
{
1822
- return min_max (args , kwds , Py_LT );
1827
+ return min_max (args , nargs , kwnames , Py_LT );
1823
1828
}
1824
1829
1825
1830
PyDoc_STRVAR (min_doc ,
@@ -1834,9 +1839,9 @@ With two or more arguments, return the smallest argument.");
1834
1839
1835
1840
/* AC: cannot convert yet, waiting for *args support */
1836
1841
static PyObject *
1837
- builtin_max (PyObject * self , PyObject * args , PyObject * kwds )
1842
+ builtin_max (PyObject * self , PyObject * const * args , Py_ssize_t nargs , PyObject * kwnames )
1838
1843
{
1839
- return min_max (args , kwds , Py_GT );
1844
+ return min_max (args , nargs , kwnames , Py_GT );
1840
1845
}
1841
1846
1842
1847
PyDoc_STRVAR (max_doc ,
@@ -2954,8 +2959,8 @@ static PyMethodDef builtin_methods[] = {
2954
2959
BUILTIN_AITER_METHODDEF
2955
2960
BUILTIN_LEN_METHODDEF
2956
2961
BUILTIN_LOCALS_METHODDEF
2957
- {"max" , (PyCFunction )(void (* )(void ))builtin_max , METH_VARARGS | METH_KEYWORDS , max_doc },
2958
- {"min" , (PyCFunction )(void (* )(void ))builtin_min , METH_VARARGS | METH_KEYWORDS , min_doc },
2962
+ {"max" , (PyCFunction )(void (* )(void ))builtin_max , METH_FASTCALL | METH_KEYWORDS , max_doc },
2963
+ {"min" , (PyCFunction )(void (* )(void ))builtin_min , METH_FASTCALL | METH_KEYWORDS , min_doc },
2959
2964
{"next" , (PyCFunction )(void (* )(void ))builtin_next , METH_FASTCALL , next_doc },
2960
2965
BUILTIN_ANEXT_METHODDEF
2961
2966
BUILTIN_OCT_METHODDEF
0 commit comments