@@ -381,7 +381,7 @@ builtin_compile(PyObject *self, PyObject *args)
381381 int supplied_flags = 0 ;
382382 PyCompilerFlags cf ;
383383
384- if (!PyArg_ParseTuple (args , "sss|ii:compile" , & str , & filename ,
384+ if (!PyArg_ParseTuple (args , "sss|ii:compile" , & str , & filename ,
385385 & startstr , & supplied_flags , & dont_inherit ))
386386 return NULL ;
387387
@@ -1128,7 +1128,7 @@ min_max(PyObject *args, int op)
11281128 v = args ;
11291129 else if (!PyArg_ParseTuple (args , "O:min/max" , & v ))
11301130 return NULL ;
1131-
1131+
11321132 it = PyObject_GetIter (v );
11331133 if (it == NULL )
11341134 return NULL ;
@@ -1704,9 +1704,10 @@ static PyObject*
17041704builtin_zip (PyObject * self , PyObject * args )
17051705{
17061706 PyObject * ret ;
1707- int itemsize = PySequence_Length (args );
1707+ const int itemsize = PySequence_Length (args );
17081708 int i ;
17091709 PyObject * itlist ; /* tuple of iterators */
1710+ int len ; /* guess at result length */
17101711
17111712 if (itemsize < 1 ) {
17121713 PyErr_SetString (PyExc_TypeError ,
@@ -1716,8 +1717,21 @@ builtin_zip(PyObject *self, PyObject *args)
17161717 /* args must be a tuple */
17171718 assert (PyTuple_Check (args ));
17181719
1720+ /* Guess at result length: the shortest of the input lengths. */
1721+ len = -1 ; /* unknown */
1722+ for (i = 0 ; i < itemsize ; ++ i ) {
1723+ PyObject * item = PyTuple_GET_ITEM (args , i );
1724+ int thislen = PySequence_Length (item );
1725+ if (thislen < 0 )
1726+ PyErr_Clear ();
1727+ else if (len < 0 || thislen < len )
1728+ len = thislen ;
1729+ }
1730+
17191731 /* allocate result list */
1720- if ((ret = PyList_New (0 )) == NULL )
1732+ if (len < 0 )
1733+ len = 10 ; /* arbitrary */
1734+ if ((ret = PyList_New (len )) == NULL )
17211735 return NULL ;
17221736
17231737 /* obtain iterators */
@@ -1738,14 +1752,14 @@ builtin_zip(PyObject *self, PyObject *args)
17381752 }
17391753
17401754 /* build result into ret list */
1741- for (;; ) {
1742- int status ;
1755+ for (i = 0 ; ; ++ i ) {
1756+ int j ;
17431757 PyObject * next = PyTuple_New (itemsize );
17441758 if (!next )
17451759 goto Fail_ret_itlist ;
17461760
1747- for (i = 0 ; i < itemsize ; i ++ ) {
1748- PyObject * it = PyTuple_GET_ITEM (itlist , i );
1761+ for (j = 0 ; j < itemsize ; j ++ ) {
1762+ PyObject * it = PyTuple_GET_ITEM (itlist , j );
17491763 PyObject * item = PyIter_Next (it );
17501764 if (!item ) {
17511765 if (PyErr_Occurred ()) {
@@ -1754,16 +1768,29 @@ builtin_zip(PyObject *self, PyObject *args)
17541768 }
17551769 Py_DECREF (next );
17561770 Py_DECREF (itlist );
1757- return ret ;
1771+ goto Done ;
17581772 }
1759- PyTuple_SET_ITEM (next , i , item );
1773+ PyTuple_SET_ITEM (next , j , item );
17601774 }
17611775
1762- status = PyList_Append (ret , next );
1763- Py_DECREF (next );
1764- if (status < 0 )
1765- goto Fail_ret_itlist ;
1776+ if (i < len )
1777+ PyList_SET_ITEM (ret , i , next );
1778+ else {
1779+ int status = PyList_Append (ret , next );
1780+ Py_DECREF (next );
1781+ ++ len ;
1782+ if (status < 0 )
1783+ goto Fail_ret_itlist ;
1784+ }
1785+ }
1786+
1787+ Done :
1788+ if (ret != NULL && i < len ) {
1789+ /* The list is too big. */
1790+ if (PyList_SetSlice (ret , i , len , NULL ) < 0 )
1791+ return NULL ;
17661792 }
1793+ return ret ;
17671794
17681795Fail_ret_itlist :
17691796 Py_DECREF (itlist );
@@ -1864,7 +1891,7 @@ _PyBuiltin_Init(void)
18641891 SETBUILTIN ("complex" , & PyComplex_Type );
18651892#endif
18661893 SETBUILTIN ("dict" , & PyDict_Type );
1867- SETBUILTIN ("enumerate" , & PyEnum_Type );
1894+ SETBUILTIN ("enumerate" , & PyEnum_Type );
18681895 SETBUILTIN ("float" , & PyFloat_Type );
18691896 SETBUILTIN ("property" , & PyProperty_Type );
18701897 SETBUILTIN ("int" , & PyInt_Type );
0 commit comments