bpo-39829: Fix __len__() is called twice in list() constructor (GH-31816)

This commit is contained in:
Crowthebird 2022-03-14 09:23:59 +08:00 committed by GitHub
parent 690490e4de
commit 2153daf0a0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 14 additions and 18 deletions

View file

@ -1336,6 +1336,7 @@ William Park
Claude Paroz Claude Paroz
Heikki Partanen Heikki Partanen
Harri Pasanen Harri Pasanen
Jeremiah Gabriel Pascual
Gaël Pasgrimaud Gaël Pasgrimaud
Feanil Patel Feanil Patel
Ashish Nitin Patil Ashish Nitin Patil
@ -1864,7 +1865,6 @@ Kurt Vile
Norman Vine Norman Vine
Pauli Virtanen Pauli Virtanen
Frank Visser Frank Visser
Jeremiah Vivian (Pascual)
Johannes Vogel Johannes Vogel
Michael Vogt Michael Vogt
Radu Voicilas Radu Voicilas

View file

@ -0,0 +1 @@
Removed the ``__len__()`` call when initializing a list and moved initializing to ``list_extend``. Patch by Jeremiah Pascual.

View file

@ -865,7 +865,6 @@ list_extend(PyListObject *self, PyObject *iterable)
PyObject *it; /* iter(v) */ PyObject *it; /* iter(v) */
Py_ssize_t m; /* size of self */ Py_ssize_t m; /* size of self */
Py_ssize_t n; /* guess for size of iterable */ Py_ssize_t n; /* guess for size of iterable */
Py_ssize_t mn; /* m + n */
Py_ssize_t i; Py_ssize_t i;
PyObject *(*iternext)(PyObject *); PyObject *(*iternext)(PyObject *);
@ -889,7 +888,13 @@ list_extend(PyListObject *self, PyObject *iterable)
/* It should not be possible to allocate a list large enough to cause /* It should not be possible to allocate a list large enough to cause
an overflow on any relevant platform */ an overflow on any relevant platform */
assert(m < PY_SSIZE_T_MAX - n); assert(m < PY_SSIZE_T_MAX - n);
if (list_resize(self, m + n) < 0) { if (self->ob_item == NULL) {
if (list_preallocate_exact(self, n) < 0) {
return NULL;
}
Py_SET_SIZE(self, n);
}
else if (list_resize(self, m + n) < 0) {
Py_DECREF(iterable); Py_DECREF(iterable);
return NULL; return NULL;
} }
@ -928,10 +933,13 @@ list_extend(PyListObject *self, PyObject *iterable)
* eventually run out of memory during the loop. * eventually run out of memory during the loop.
*/ */
} }
else if (self->ob_item == NULL) {
if (n && list_preallocate_exact(self, n) < 0)
goto error;
}
else { else {
mn = m + n;
/* Make room. */ /* Make room. */
if (list_resize(self, mn) < 0) if (list_resize(self, m + n) < 0)
goto error; goto error;
/* Make the list sane again. */ /* Make the list sane again. */
Py_SET_SIZE(self, m); Py_SET_SIZE(self, m);
@ -2814,19 +2822,6 @@ list___init___impl(PyListObject *self, PyObject *iterable)
(void)_list_clear(self); (void)_list_clear(self);
} }
if (iterable != NULL) { if (iterable != NULL) {
if (_PyObject_HasLen(iterable)) {
Py_ssize_t iter_len = PyObject_Size(iterable);
if (iter_len == -1) {
if (!PyErr_ExceptionMatches(PyExc_TypeError)) {
return -1;
}
PyErr_Clear();
}
if (iter_len > 0 && self->ob_item == NULL
&& list_preallocate_exact(self, iter_len)) {
return -1;
}
}
PyObject *rv = list_extend(self, iterable); PyObject *rv = list_extend(self, iterable);
if (rv == NULL) if (rv == NULL)
return -1; return -1;