From 830c85d0bacc2366af8b75becca021e00e976298 Mon Sep 17 00:00:00 2001 From: Alexander Belopolsky Date: Tue, 11 Jan 2011 22:16:24 +0000 Subject: [PATCH] Merged revisions 87942 via svnmerge from svn+ssh://pythondev@svn.python.org/python/branches/py3k ........ r87942 | alexander.belopolsky | 2011-01-11 16:44:00 -0500 (Tue, 11 Jan 2011) | 3 lines Issue #5109: array.array constructor will now use fast code when initial data is provided in an array object with correct type. ........ --- Lib/test/test_array.py | 10 ++++++++++ Misc/NEWS | 3 +++ Modules/arraymodule.c | 21 ++++++++++++++++----- 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/Lib/test/test_array.py b/Lib/test/test_array.py index 4d56f5455986..d92205baa930 100755 --- a/Lib/test/test_array.py +++ b/Lib/test/test_array.py @@ -239,6 +239,11 @@ class BaseTest(unittest.TestCase): if a.itemsize>1: self.assertRaises(ValueError, b.fromstring, "x") + def test_fromarray(self): + a = array.array(self.typecode, self.example) + b = array.array(self.typecode, a) + self.assertEqual(a, b) + def test_repr(self): a = array.array(self.typecode, 2*self.example) self.assertEqual(a, eval(repr(a), {"array": array.array})) @@ -958,6 +963,11 @@ class NumberTest(BaseTest): self.assertRaises(AttributeError, setattr, a, "color", "blue") + def test_frombytearray(self): + a = array.array('b', range(10)) + b = array.array(self.typecode, a) + self.assertEqual(a, b) + class SignedNumberTest(NumberTest): example = [-1, 0, 1, 42, 0x7f] smallerexample = [-1, 0, 1, 42, 0x7e] diff --git a/Misc/NEWS b/Misc/NEWS index ab47022b8019..f3e3c1f13ea8 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -973,6 +973,9 @@ Library Extension Modules ----------------- +- Issue #5109: array.array constructor will now use fast code when + initial data is provided in an array object with correct type. + - Issue #7384: If the system readline library is linked against ncurses, the curses module must be linked against ncurses as well. Otherwise it is not safe to load both the readline and curses modules in an application. diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index 1602e4883df6..ba07e0228671 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -1925,7 +1925,10 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (!(initial == NULL || PyList_Check(initial) || PyString_Check(initial) || PyTuple_Check(initial) - || (c == 'u' && PyUnicode_Check(initial)))) { + || PyTuple_Check(initial) + || ((c=='u') && PyUnicode_Check(initial)) + || (array_Check(initial) + && c == ((arrayobject*)initial)->ob_descr->typecode))) { it = PyObject_GetIter(initial); if (it == NULL) return NULL; @@ -1941,17 +1944,20 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds) PyObject *a; Py_ssize_t len; - if (initial == NULL || !(PyList_Check(initial) - || PyTuple_Check(initial))) + if (initial == NULL) len = 0; + else if (PyList_Check(initial)) + len = PyList_GET_SIZE(initial); + else if (PyTuple_Check(initial) || array_Check(initial)) + len = Py_SIZE(initial); else - len = PySequence_Size(initial); + len = 0; a = newarrayobject(type, len, descr); if (a == NULL) return NULL; - if (len > 0) { + if (len > 0 && !array_Check(initial)) { Py_ssize_t i; for (i = 0; i < len; i++) { PyObject *v = @@ -2001,6 +2007,11 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds) } #endif } + else if (initial != NULL && array_Check(initial)) { + arrayobject *self = (arrayobject *)a; + arrayobject *other = (arrayobject *)initial; + memcpy(self->ob_item, other->ob_item, len * other->ob_descr->itemsize); + } if (it != NULL) { if (array_iter_extend((arrayobject *)a, it) == -1) { Py_DECREF(it); -- 2.47.3