@@ -1766,45 +1766,39 @@ builtin_locals_impl(PyObject *module)
1766
1766
1767
1767
1768
1768
static PyObject *
1769
- min_max (PyObject * args , PyObject * kwds , int op )
1769
+ min_max (PyObject * const * args , Py_ssize_t nargs , PyObject * kwnames , int op )
1770
1770
{
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 ;
1777
1778
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 );
1785
1781
return NULL ;
1786
1782
}
1787
1783
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 )) {
1796
1786
return NULL ;
1787
+ }
1797
1788
1789
+ const int positional = nargs > 1 ; // False iff nargs == 1
1798
1790
if (positional && defaultval != NULL ) {
1799
1791
PyErr_Format (PyExc_TypeError ,
1800
1792
"Cannot specify a default for %s() with multiple "
1801
1793
"positional arguments" , name );
1802
1794
return NULL ;
1803
1795
}
1804
1796
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
+ }
1808
1802
}
1809
1803
1810
1804
if (keyfunc == Py_None ) {
@@ -1813,7 +1807,24 @@ min_max(PyObject *args, PyObject *kwds, int op)
1813
1807
1814
1808
maxitem = NULL ; /* the result */
1815
1809
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
+
1817
1828
/* get the value from the key function */
1818
1829
if (keyfunc != NULL ) {
1819
1830
val = PyObject_CallOneArg (keyfunc , item );
@@ -1847,8 +1858,6 @@ min_max(PyObject *args, PyObject *kwds, int op)
1847
1858
}
1848
1859
}
1849
1860
}
1850
- if (PyErr_Occurred ())
1851
- goto Fail_it ;
1852
1861
if (maxval == NULL ) {
1853
1862
assert (maxitem == NULL );
1854
1863
if (defaultval != NULL ) {
@@ -1860,7 +1869,7 @@ min_max(PyObject *args, PyObject *kwds, int op)
1860
1869
}
1861
1870
else
1862
1871
Py_DECREF (maxval );
1863
- Py_DECREF (it );
1872
+ Py_XDECREF (it );
1864
1873
return maxitem ;
1865
1874
1866
1875
Fail_it_item_and_val :
@@ -1870,15 +1879,15 @@ min_max(PyObject *args, PyObject *kwds, int op)
1870
1879
Fail_it :
1871
1880
Py_XDECREF (maxval );
1872
1881
Py_XDECREF (maxitem );
1873
- Py_DECREF (it );
1882
+ Py_XDECREF (it );
1874
1883
return NULL ;
1875
1884
}
1876
1885
1877
1886
/* AC: cannot convert yet, waiting for *args support */
1878
1887
static PyObject *
1879
- builtin_min (PyObject * self , PyObject * args , PyObject * kwds )
1888
+ builtin_min (PyObject * self , PyObject * const * args , Py_ssize_t nargs , PyObject * kwnames )
1880
1889
{
1881
- return min_max (args , kwds , Py_LT );
1890
+ return min_max (args , nargs , kwnames , Py_LT );
1882
1891
}
1883
1892
1884
1893
PyDoc_STRVAR (min_doc ,
@@ -1893,9 +1902,9 @@ With two or more positional arguments, return the smallest argument.");
1893
1902
1894
1903
/* AC: cannot convert yet, waiting for *args support */
1895
1904
static PyObject *
1896
- builtin_max (PyObject * self , PyObject * args , PyObject * kwds )
1905
+ builtin_max (PyObject * self , PyObject * const * args , Py_ssize_t nargs , PyObject * kwnames )
1897
1906
{
1898
- return min_max (args , kwds , Py_GT );
1907
+ return min_max (args , nargs , kwnames , Py_GT );
1899
1908
}
1900
1909
1901
1910
PyDoc_STRVAR (max_doc ,
@@ -3054,8 +3063,8 @@ static PyMethodDef builtin_methods[] = {
3054
3063
BUILTIN_AITER_METHODDEF
3055
3064
BUILTIN_LEN_METHODDEF
3056
3065
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 },
3059
3068
{"next" , _PyCFunction_CAST (builtin_next ), METH_FASTCALL , next_doc },
3060
3069
BUILTIN_ANEXT_METHODDEF
3061
3070
BUILTIN_OCT_METHODDEF
0 commit comments