Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 70d172d

Browse files
committed
Get rid of listextend_internal() and explain why the special case
'a.extend(a)' isn't so special anyway.
1 parent 70ec0b4 commit 70d172d

1 file changed

Lines changed: 25 additions & 51 deletions

File tree

Objects/listobject.c

Lines changed: 25 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -647,56 +647,6 @@ listappend(PyListObject *self, PyObject *v)
647647
return ins(self, (int) self->ob_size, v);
648648
}
649649

650-
static int
651-
listextend_internal(PyListObject *self, PyObject *b)
652-
{
653-
int selflen = PyList_GET_SIZE(self);
654-
int blen;
655-
register int i;
656-
PyObject **src, **dest;
657-
658-
blen = PyObject_Size(b);
659-
if (blen == 0) {
660-
/* short circuit when b is empty */
661-
Py_DECREF(b);
662-
return 0;
663-
}
664-
665-
if (self == (PyListObject*)b) {
666-
/* as in list_ass_slice() we must special case the
667-
* situation: a.extend(a)
668-
*
669-
* XXX: I think this way ought to be faster than using
670-
* list_slice() the way list_ass_slice() does.
671-
*/
672-
Py_DECREF(b);
673-
b = PyList_New(selflen);
674-
if (!b)
675-
return -1;
676-
for (i = 0; i < selflen; i++) {
677-
PyObject *o = PyList_GET_ITEM(self, i);
678-
Py_INCREF(o);
679-
PyList_SET_ITEM(b, i, o);
680-
}
681-
}
682-
683-
if (list_resize(self, selflen + blen) == -1) {
684-
Py_DECREF(b);
685-
return -1;
686-
}
687-
688-
/* populate the end of self with b's items */
689-
src = PySequence_Fast_ITEMS(b);
690-
dest = self->ob_item + selflen;
691-
for (i = 0; i < blen; i++) {
692-
PyObject *o = src[i];
693-
Py_INCREF(o);
694-
dest[i] = o;
695-
}
696-
Py_DECREF(b);
697-
return 0;
698-
}
699-
700650
static PyObject *
701651
listextend(PyListObject *self, PyObject *b)
702652
{
@@ -712,11 +662,35 @@ listextend(PyListObject *self, PyObject *b)
712662
2) extending self to self requires making a copy first
713663
*/
714664
if (PyList_CheckExact(b) || PyTuple_CheckExact(b) || (PyObject *)self == b) {
665+
PyObject **src, **dest;
715666
b = PySequence_Fast(b, "argument must be iterable");
716667
if (!b)
717668
return NULL;
718-
if (listextend_internal(self, b) < 0)
669+
n = PySequence_Fast_GET_SIZE(b);
670+
if (n == 0) {
671+
/* short circuit when b is empty */
672+
Py_DECREF(b);
673+
Py_RETURN_NONE;
674+
}
675+
m = self->ob_size;
676+
if (list_resize(self, m + n) == -1) {
677+
Py_DECREF(b);
719678
return NULL;
679+
}
680+
/* note that we may still have self == b here for the
681+
* situation a.extend(a), but the following code works
682+
* in that case too. Just make sure to resize self
683+
* before calling PySequence_Fast_ITEMS.
684+
*/
685+
/* populate the end of self with b's items */
686+
src = PySequence_Fast_ITEMS(b);
687+
dest = self->ob_item + m;
688+
for (i = 0; i < n; i++) {
689+
PyObject *o = src[i];
690+
Py_INCREF(o);
691+
dest[i] = o;
692+
}
693+
Py_DECREF(b);
720694
Py_RETURN_NONE;
721695
}
722696

0 commit comments

Comments
 (0)