Skip to content

Commit 009aeb6

Browse files
bpo-39829: Fix __len__() is called twice in list() constructor (GH-31816)
(cherry picked from commit 2153daf) This patch fixes gh-87740 too. Co-authored-by: Crowthebird <[email protected]>
1 parent add8820 commit 009aeb6

File tree

3 files changed

+14
-17
lines changed

3 files changed

+14
-17
lines changed

Misc/ACKS

+1
Original file line numberDiff line numberDiff line change
@@ -1332,6 +1332,7 @@ William Park
13321332
Claude Paroz
13331333
Heikki Partanen
13341334
Harri Pasanen
1335+
Jeremiah Gabriel Pascual
13351336
Gaël Pasgrimaud
13361337
Feanil Patel
13371338
Ashish Nitin Patil
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Removed the ``__len__()`` call when initializing a list and moved initializing to ``list_extend``. Patch by Jeremiah Pascual.

Objects/listobject.c

+12-17
Original file line numberDiff line numberDiff line change
@@ -863,7 +863,6 @@ list_extend(PyListObject *self, PyObject *iterable)
863863
PyObject *it; /* iter(v) */
864864
Py_ssize_t m; /* size of self */
865865
Py_ssize_t n; /* guess for size of iterable */
866-
Py_ssize_t mn; /* m + n */
867866
Py_ssize_t i;
868867
PyObject *(*iternext)(PyObject *);
869868

@@ -887,7 +886,13 @@ list_extend(PyListObject *self, PyObject *iterable)
887886
/* It should not be possible to allocate a list large enough to cause
888887
an overflow on any relevant platform */
889888
assert(m < PY_SSIZE_T_MAX - n);
890-
if (list_resize(self, m + n) < 0) {
889+
if (self->ob_item == NULL) {
890+
if (list_preallocate_exact(self, n) < 0) {
891+
return NULL;
892+
}
893+
Py_SET_SIZE(self, n);
894+
}
895+
else if (list_resize(self, m + n) < 0) {
891896
Py_DECREF(iterable);
892897
return NULL;
893898
}
@@ -926,10 +931,13 @@ list_extend(PyListObject *self, PyObject *iterable)
926931
* eventually run out of memory during the loop.
927932
*/
928933
}
934+
else if (self->ob_item == NULL) {
935+
if (n && list_preallocate_exact(self, n) < 0)
936+
goto error;
937+
}
929938
else {
930-
mn = m + n;
931939
/* Make room. */
932-
if (list_resize(self, mn) < 0)
940+
if (list_resize(self, m + n) < 0)
933941
goto error;
934942
/* Make the list sane again. */
935943
Py_SET_SIZE(self, m);
@@ -2717,19 +2725,6 @@ list___init___impl(PyListObject *self, PyObject *iterable)
27172725
(void)_list_clear(self);
27182726
}
27192727
if (iterable != NULL) {
2720-
if (_PyObject_HasLen(iterable)) {
2721-
Py_ssize_t iter_len = PyObject_Size(iterable);
2722-
if (iter_len == -1) {
2723-
if (!PyErr_ExceptionMatches(PyExc_TypeError)) {
2724-
return -1;
2725-
}
2726-
PyErr_Clear();
2727-
}
2728-
if (iter_len > 0 && self->ob_item == NULL
2729-
&& list_preallocate_exact(self, iter_len)) {
2730-
return -1;
2731-
}
2732-
}
27332728
PyObject *rv = list_extend(self, iterable);
27342729
if (rv == NULL)
27352730
return -1;

0 commit comments

Comments
 (0)