From 77d9d68812411191f3ca9437382734381dbde0df Mon Sep 17 00:00:00 2001 From: Crowthebird <78076854+thatbirdguythatuknownot@users.noreply.github.com> Date: Mon, 14 Mar 2022 09:23:59 +0800 Subject: [PATCH] bpo-39829: Fix `__len__()` is called twice in list() constructor (GH-31816) (cherry picked from commit 2153daf0a02a598ed5df93f2f224c1ab2a2cca0d) Co-authored-by: Crowthebird <78076854+thatbirdguythatuknownot@users.noreply.github.com> --- Misc/ACKS | 1 + .../2022-03-11-09-39-01.bpo-39829.mlW3Su.rst | 1 + Objects/listobject.c | 29 ++++++++----------- 3 files changed, 14 insertions(+), 17 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-03-11-09-39-01.bpo-39829.mlW3Su.rst diff --git a/Misc/ACKS b/Misc/ACKS index 889bf8aeaea1ac..b83f99956de0b1 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1332,6 +1332,7 @@ William Park Claude Paroz Heikki Partanen Harri Pasanen +Jeremiah Gabriel Pascual Gaƫl Pasgrimaud Feanil Patel Ashish Nitin Patil diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-11-09-39-01.bpo-39829.mlW3Su.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-11-09-39-01.bpo-39829.mlW3Su.rst new file mode 100644 index 00000000000000..1f3d945188a32a --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-11-09-39-01.bpo-39829.mlW3Su.rst @@ -0,0 +1 @@ +Removed the ``__len__()`` call when initializing a list and moved initializing to ``list_extend``. Patch by Jeremiah Pascual. diff --git a/Objects/listobject.c b/Objects/listobject.c index d3bc5766df7a0b..7f37b7386051d0 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -863,7 +863,6 @@ list_extend(PyListObject *self, PyObject *iterable) PyObject *it; /* iter(v) */ Py_ssize_t m; /* size of self */ Py_ssize_t n; /* guess for size of iterable */ - Py_ssize_t mn; /* m + n */ Py_ssize_t i; PyObject *(*iternext)(PyObject *); @@ -887,7 +886,13 @@ list_extend(PyListObject *self, PyObject *iterable) /* It should not be possible to allocate a list large enough to cause an overflow on any relevant platform */ 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); return NULL; } @@ -926,10 +931,13 @@ list_extend(PyListObject *self, PyObject *iterable) * 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 { - mn = m + n; /* Make room. */ - if (list_resize(self, mn) < 0) + if (list_resize(self, m + n) < 0) goto error; /* Make the list sane again. */ Py_SET_SIZE(self, m); @@ -2717,19 +2725,6 @@ list___init___impl(PyListObject *self, PyObject *iterable) (void)_list_clear(self); } 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); if (rv == NULL) return -1;
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: