@@ -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-
700650static PyObject *
701651listextend (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