]> granicus.if.org Git - python/commitdiff
Merged revisions 87942 via svnmerge from
authorAlexander Belopolsky <alexander.belopolsky@gmail.com>
Tue, 11 Jan 2011 22:16:24 +0000 (22:16 +0000)
committerAlexander Belopolsky <alexander.belopolsky@gmail.com>
Tue, 11 Jan 2011 22:16:24 +0000 (22:16 +0000)
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
Misc/NEWS
Modules/arraymodule.c

index 4d56f5455986befd2179e4c0ce5dd0b68633d24c..d92205baa9305b282a5b3baab13f17a7c93841bd 100755 (executable)
@@ -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]
index ab47022b80196544993f6984227972344ed567a2..f3e3c1f13ea819c1630619bef1794ee5aa891c8b 100644 (file)
--- 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.
index 1602e4883df6cd8391e60300b21f3261217337ea..ba07e02286716e26843ecb0972564f7e5404c97f 100644 (file)
@@ -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);