# HG changeset patch # Parent eeb7a0d882f7edcae9580a9de8de8039b09d82ca diff -r eeb7a0d882f7 Lib/test/test_array.py --- a/Lib/test/test_array.py Thu Jul 01 09:32:02 2010 +0200 +++ b/Lib/test/test_array.py Thu Jul 01 14:07:55 2010 +0200 @@ -362,9 +362,11 @@ self.assertRaises(TypeError, b.fromstring) self.assertRaises(TypeError, b.fromstring, 42) b.fromstring(a.tostring()) + c = array.array(self.typecode, bytearray(a.tostring())) self.assertEqual(a, b) + self.assertEqual(a, c) if a.itemsize>1: - self.assertRaises(ValueError, b.fromstring, "x") + self.assertRaises(ValueError, b.fromstring, b"x") def test_repr(self): a = array.array(self.typecode, 2*self.example) @@ -1099,6 +1101,23 @@ upper = int(pow(2, a.itemsize * 8)) - 1 self.check_overflow(lower, upper) + def test_bytes_extend(self): + s = bytes(self.example) + + a = array.array(self.typecode, self.example) + a.extend(s) + self.assertEqual( + a, + array.array(self.typecode, self.example+self.example) + ) + + a = array.array(self.typecode, self.example) + a.extend(bytearray(reversed(s))) + self.assertEqual( + a, + array.array(self.typecode, self.example+self.example[::-1]) + ) + class ByteTest(SignedNumberTest): typecode = 'b' diff -r eeb7a0d882f7 Modules/arraymodule.c --- a/Modules/arraymodule.c Thu Jul 01 09:32:02 2010 +0200 +++ b/Modules/arraymodule.c Thu Jul 01 14:07:55 2010 +0200 @@ -1335,28 +1335,39 @@ static PyObject * array_fromstring(arrayobject *self, PyObject *args) { - char *str; + Py_buffer buffer; Py_ssize_t n; int itemsize = self->ob_descr->itemsize; - if (!PyArg_ParseTuple(args, "s#:fromstring", &str, &n)) + if (!PyArg_ParseTuple(args, "y*:fromstring", &buffer)) return NULL; + if (buffer.itemsize != 1) { + PyBuffer_Release(&buffer); + PyErr_SetString(PyExc_TypeError, "string/buffer of bytes required."); + return NULL; + } + n = buffer.len; if (n % itemsize != 0) { + PyBuffer_Release(&buffer); PyErr_SetString(PyExc_ValueError, "string length not a multiple of item size"); return NULL; } n = n / itemsize; if (n > 0) { - Py_ssize_t old_size = Py_SIZE(self); + Py_ssize_t old_size = Py_SIZE(self); if ((n > PY_SSIZE_T_MAX - old_size) || ((old_size + n) > PY_SSIZE_T_MAX / itemsize)) { + PyBuffer_Release(&buffer); return PyErr_NoMemory(); } - if (array_resize(self, old_size + n) == -1) + if (array_resize(self, old_size + n) == -1) { + PyBuffer_Release(&buffer); return NULL; + } memcpy(self->ob_item + old_size * itemsize, - str, n * itemsize); + buffer.buf, n * itemsize); } + PyBuffer_Release(&buffer); Py_INCREF(Py_None); return Py_None; }