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

Skip to content

Commit 49f9bd1

Browse files
committed
SF feature request #686323: Minor array module enhancements
array.extend() now accepts iterable arguments implements as a series of appends. Besides being a user convenience and matching the behavior for lists, this the saves memory and cycles that would be used to create a temporary array object.
1 parent 6e2ee86 commit 49f9bd1

4 files changed

Lines changed: 51 additions & 14 deletions

File tree

Doc/lib/libarray.tex

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,13 @@ \section{\module{array} ---
104104
Return the number of occurences of \var{x} in the array.
105105
\end{methoddesc}
106106

107-
\begin{methoddesc}[array]{extend}{a}
108-
Append array items from \var{a} to the end of the array. The two
109-
arrays must have \emph{exactly} the same type code; if not,
110-
\exception{TypeError} will be raised.
107+
\begin{methoddesc}[array]{extend}{iterable}
108+
Append items from \var{iterable} to the end of the array. If
109+
\var{iterable} is another array, it must have \emph{exactly} the same
110+
type code; if not, \exception{TypeError} will be raised. If
111+
\var{iterable} is not an array, it must be iterable and its
112+
elements must be the right type to be appended to the array.
113+
\versionchanged[Formerly, the argument could only be another array]{2.4}
111114
\end{methoddesc}
112115

113116
\begin{methoddesc}[array]{fromfile}{f, n}

Lib/test/test_array.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -592,6 +592,13 @@ def test_extend(self):
592592
b = array.array(self.badtypecode())
593593
self.assertRaises(TypeError, a.extend, b)
594594

595+
a = array.array(self.typecode, self.example)
596+
a.extend(self.example[::-1])
597+
self.assertEqual(
598+
a,
599+
array.array(self.typecode, self.example+self.example[::-1])
600+
)
601+
595602
def test_coveritertraverse(self):
596603
try:
597604
import gc

Misc/NEWS

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,9 @@ Extension modules
182182

183183
- array objects now support the copy module. Also, their resizing
184184
scheme has been updated the same as for list objects. The improves
185-
performance for append() operations.
185+
the performance (speed and memory usage) of append() operations.
186+
Also, array.extend() now accepts any iterable argument for repeated
187+
appends without needing to create another temporary array.
186188

187189
- cStringIO.writelines() now accepts any iterable argument and writes
188190
the lines one at a time rather than joining them and writing once.

Modules/arraymodule.c

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -775,16 +775,35 @@ setarrayitem(PyObject *a, int i, PyObject *v)
775775
}
776776

777777
static int
778-
array_do_extend(arrayobject *self, PyObject *bb)
778+
array_iter_extend(arrayobject *self, PyObject *bb)
779779
{
780-
int size;
780+
PyObject *it, *v;
781781

782-
if (!array_Check(bb)) {
783-
PyErr_Format(PyExc_TypeError,
784-
"can only extend array with array (not \"%.200s\")",
785-
bb->ob_type->tp_name);
782+
it = PyObject_GetIter(bb);
783+
if (it == NULL)
786784
return -1;
785+
786+
while ((v = PyIter_Next(it)) != NULL) {
787+
if (ins1(self, (int) self->ob_size, v) != 0) {
788+
Py_DECREF(v);
789+
Py_DECREF(it);
790+
return -1;
791+
}
792+
Py_DECREF(v);
787793
}
794+
Py_DECREF(it);
795+
if (PyErr_Occurred())
796+
return -1;
797+
return 0;
798+
}
799+
800+
static int
801+
array_do_extend(arrayobject *self, PyObject *bb)
802+
{
803+
int size;
804+
805+
if (!array_Check(bb))
806+
return array_iter_extend(self, bb);
788807
#define b ((arrayobject *)bb)
789808
if (self->ob_descr != b->ob_descr) {
790809
PyErr_SetString(PyExc_TypeError,
@@ -810,6 +829,12 @@ array_do_extend(arrayobject *self, PyObject *bb)
810829
static PyObject *
811830
array_inplace_concat(arrayobject *self, PyObject *bb)
812831
{
832+
if (!array_Check(bb)) {
833+
PyErr_Format(PyExc_TypeError,
834+
"can only extend array with array (not \"%.200s\")",
835+
bb->ob_type->tp_name);
836+
return NULL;
837+
}
813838
if (array_do_extend(self, bb) == -1)
814839
return NULL;
815840
Py_INCREF(self);
@@ -990,9 +1015,9 @@ array_extend(arrayobject *self, PyObject *bb)
9901015
}
9911016

9921017
PyDoc_STRVAR(extend_doc,
993-
"extend(array)\n\
1018+
"extend(array or iterable)\n\
9941019
\n\
995-
Append array items to the end of the array.");
1020+
Append items to the end of the array.");
9961021

9971022
static PyObject *
9981023
array_insert(arrayobject *self, PyObject *args)
@@ -1881,7 +1906,7 @@ append() -- append a new item to the end of the array\n\
18811906
buffer_info() -- return information giving the current memory info\n\
18821907
byteswap() -- byteswap all the items of the array\n\
18831908
count() -- return number of occurences of an object\n\
1884-
extend() -- extend array by appending array elements\n\
1909+
extend() -- extend array by appending multiple elements from an iterable\n\
18851910
fromfile() -- read items from a file object\n\
18861911
fromlist() -- append items from the list\n\
18871912
fromstring() -- append items from the string\n\

0 commit comments

Comments
 (0)