Skip to content

Commit 9962ea7

Browse files
committed
Issue #5109: array.array constructor will now use fast code when
initial data is provided in an array object with correct type.
1 parent 3e10637 commit 9962ea7

3 files changed

Lines changed: 28 additions & 5 deletions

File tree

Lib/test/test_array.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,11 @@ def test_tofrombytes(self):
398398
if a.itemsize>1:
399399
self.assertRaises(ValueError, b.frombytes, b"x")
400400

401+
def test_fromarray(self):
402+
a = array.array(self.typecode, self.example)
403+
b = array.array(self.typecode, a)
404+
self.assertEqual(a, b)
405+
401406
def test_repr(self):
402407
a = array.array(self.typecode, 2*self.example)
403408
self.assertEqual(a, eval(repr(a), {"array": array.array}))
@@ -1113,6 +1118,11 @@ def __getitem__(self, i):
11131118

11141119
self.assertRaises(AttributeError, setattr, a, "color", "blue")
11151120

1121+
def test_frombytearray(self):
1122+
a = array.array('b', range(10))
1123+
b = array.array(self.typecode, a)
1124+
self.assertEqual(a, b)
1125+
11161126
class SignedNumberTest(NumberTest):
11171127
example = [-1, 0, 1, 42, 0x7f]
11181128
smallerexample = [-1, 0, 1, 42, 0x7e]

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -955,6 +955,9 @@ Library
955955
Extension Modules
956956
-----------------
957957

958+
- Issue #5109: array.array constructor will now use fast code when
959+
initial data is provided in an array object with correct type.
960+
958961
- Issue #6317: Now winsound.PlaySound only accepts unicode.
959962

960963
- Issue #6317: Now winsound.PlaySound can accept non ascii filename.

Modules/arraymodule.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2405,7 +2405,9 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
24052405
|| PyByteArray_Check(initial)
24062406
|| PyBytes_Check(initial)
24072407
|| PyTuple_Check(initial)
2408-
|| ((c=='u') && PyUnicode_Check(initial)))) {
2408+
|| ((c=='u') && PyUnicode_Check(initial))
2409+
|| (array_Check(initial)
2410+
&& c == ((arrayobject*)initial)->ob_descr->typecode))) {
24092411
it = PyObject_GetIter(initial);
24102412
if (it == NULL)
24112413
return NULL;
@@ -2421,17 +2423,20 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
24212423
PyObject *a;
24222424
Py_ssize_t len;
24232425

2424-
if (initial == NULL || !(PyList_Check(initial)
2425-
|| PyTuple_Check(initial)))
2426+
if (initial == NULL)
24262427
len = 0;
2428+
else if (PyList_Check(initial))
2429+
len = PyList_GET_SIZE(initial);
2430+
else if (PyTuple_Check(initial) || array_Check(initial))
2431+
len = Py_SIZE(initial);
24272432
else
2428-
len = PySequence_Size(initial);
2433+
len = 0;
24292434

24302435
a = newarrayobject(type, len, descr);
24312436
if (a == NULL)
24322437
return NULL;
24332438

2434-
if (len > 0) {
2439+
if (len > 0 && !array_Check(initial)) {
24352440
Py_ssize_t i;
24362441
for (i = 0; i < len; i++) {
24372442
PyObject *v =
@@ -2482,6 +2487,11 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
24822487
self->allocated = Py_SIZE(self);
24832488
}
24842489
}
2490+
else if (initial != NULL && array_Check(initial)) {
2491+
arrayobject *self = (arrayobject *)a;
2492+
arrayobject *other = (arrayobject *)initial;
2493+
memcpy(self->ob_item, other->ob_item, len * other->ob_descr->itemsize);
2494+
}
24852495
if (it != NULL) {
24862496
if (array_iter_extend((arrayobject *)a, it) == -1) {
24872497
Py_DECREF(it);

0 commit comments

Comments
 (0)