@@ -1747,45 +1747,47 @@ builtin_locals_impl(PyObject *module)
1747
1747
1748
1748
1749
1749
static PyObject *
1750
- min_max (PyObject * args , PyObject * kwds , int op )
1750
+ min_max (PyObject * const * args , Py_ssize_t nargs , PyObject * kwnames , int op )
1751
1751
{
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 ;
1758
1767
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 );
1766
1770
return NULL ;
1767
1771
}
1768
1772
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 )) {
1777
1775
return NULL ;
1776
+ }
1778
1777
1778
+ const int positional = nargs > 1 ; // False iff nargs == 1
1779
1779
if (positional && defaultval != NULL ) {
1780
1780
PyErr_Format (PyExc_TypeError ,
1781
1781
"Cannot specify a default for %s() with multiple "
1782
1782
"positional arguments" , name );
1783
1783
return NULL ;
1784
1784
}
1785
1785
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
+ }
1789
1791
}
1790
1792
1791
1793
if (keyfunc == Py_None ) {
@@ -1794,7 +1796,24 @@ min_max(PyObject *args, PyObject *kwds, int op)
1794
1796
1795
1797
maxitem = NULL ; /* the result */
1796
1798
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
+
1798
1817
/* get the value from the key function */
1799
1818
if (keyfunc != NULL ) {
1800
1819
val = PyObject_CallOneArg (keyfunc , item );
@@ -1828,8 +1847,6 @@ min_max(PyObject *args, PyObject *kwds, int op)
1828
1847
}
1829
1848
}
1830
1849
}
1831
- if (PyErr_Occurred ())
1832
- goto Fail_it ;
1833
1850
if (maxval == NULL ) {
1834
1851
assert (maxitem == NULL );
1835
1852
if (defaultval != NULL ) {
@@ -1841,7 +1858,7 @@ min_max(PyObject *args, PyObject *kwds, int op)
1841
1858
}
1842
1859
else
1843
1860
Py_DECREF (maxval );
1844
- Py_DECREF (it );
1861
+ Py_XDECREF (it );
1845
1862
return maxitem ;
1846
1863
1847
1864
Fail_it_item_and_val :
@@ -1851,15 +1868,15 @@ min_max(PyObject *args, PyObject *kwds, int op)
1851
1868
Fail_it :
1852
1869
Py_XDECREF (maxval );
1853
1870
Py_XDECREF (maxitem );
1854
- Py_DECREF (it );
1871
+ Py_XDECREF (it );
1855
1872
return NULL ;
1856
1873
}
1857
1874
1858
1875
/* AC: cannot convert yet, waiting for *args support */
1859
1876
static PyObject *
1860
- builtin_min (PyObject * self , PyObject * args , PyObject * kwds )
1877
+ builtin_min (PyObject * self , PyObject * const * args , Py_ssize_t nargs , PyObject * kwnames )
1861
1878
{
1862
- return min_max (args , kwds , Py_LT );
1879
+ return min_max (args , nargs , kwnames , Py_LT );
1863
1880
}
1864
1881
1865
1882
PyDoc_STRVAR (min_doc ,
@@ -1874,9 +1891,9 @@ With two or more arguments, return the smallest argument.");
1874
1891
1875
1892
/* AC: cannot convert yet, waiting for *args support */
1876
1893
static PyObject *
1877
- builtin_max (PyObject * self , PyObject * args , PyObject * kwds )
1894
+ builtin_max (PyObject * self , PyObject * const * args , Py_ssize_t nargs , PyObject * kwnames )
1878
1895
{
1879
- return min_max (args , kwds , Py_GT );
1896
+ return min_max (args , nargs , kwnames , Py_GT );
1880
1897
}
1881
1898
1882
1899
PyDoc_STRVAR (max_doc ,
@@ -3042,8 +3059,8 @@ static PyMethodDef builtin_methods[] = {
3042
3059
BUILTIN_AITER_METHODDEF
3043
3060
BUILTIN_LEN_METHODDEF
3044
3061
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 },
3047
3064
BUILTIN_NEXT_METHODDEF
3048
3065
BUILTIN_ANEXT_METHODDEF
3049
3066
BUILTIN_OCT_METHODDEF
0 commit comments