Merged revisions 65041 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk ........ r65041 | georg.brandl | 2008-07-17 00:57:41 +0200 (Thu, 17 Jul 2008) | 3 lines #3156: fix consistency in what type bytearray methods accept as items. Also rename confusing "item" parameters to "index". ........
This commit is contained in:
parent
01ca04cc49
commit
9a54d7c350
@ -17,6 +17,12 @@ import test.support
|
|||||||
import test.string_tests
|
import test.string_tests
|
||||||
import test.buffer_tests
|
import test.buffer_tests
|
||||||
|
|
||||||
|
class Indexable:
|
||||||
|
def __init__(self, value=0):
|
||||||
|
self.value = value
|
||||||
|
def __index__(self):
|
||||||
|
return self.value
|
||||||
|
|
||||||
|
|
||||||
class BaseBytesTest(unittest.TestCase):
|
class BaseBytesTest(unittest.TestCase):
|
||||||
|
|
||||||
@ -53,15 +59,11 @@ class BaseBytesTest(unittest.TestCase):
|
|||||||
self.assertEqual(list(b), ints)
|
self.assertEqual(list(b), ints)
|
||||||
|
|
||||||
def test_from_index(self):
|
def test_from_index(self):
|
||||||
class C:
|
b = self.type2test([Indexable(), Indexable(1), Indexable(254),
|
||||||
def __init__(self, i=0):
|
Indexable(255)])
|
||||||
self.i = i
|
|
||||||
def __index__(self):
|
|
||||||
return self.i
|
|
||||||
b = self.type2test([C(), C(1), C(254), C(255)])
|
|
||||||
self.assertEqual(list(b), [0, 1, 254, 255])
|
self.assertEqual(list(b), [0, 1, 254, 255])
|
||||||
self.assertRaises(ValueError, bytearray, [C(-1)])
|
self.assertRaises(ValueError, bytearray, [Indexable(-1)])
|
||||||
self.assertRaises(ValueError, bytearray, [C(256)])
|
self.assertRaises(ValueError, bytearray, [Indexable(256)])
|
||||||
|
|
||||||
def test_from_ssize(self):
|
def test_from_ssize(self):
|
||||||
self.assertEqual(bytearray(0), b'')
|
self.assertEqual(bytearray(0), b'')
|
||||||
@ -506,12 +508,7 @@ class ByteArrayTest(BaseBytesTest):
|
|||||||
self.assertEqual(b, bytearray([1, 100, 3]))
|
self.assertEqual(b, bytearray([1, 100, 3]))
|
||||||
b[-1] = 200
|
b[-1] = 200
|
||||||
self.assertEqual(b, bytearray([1, 100, 200]))
|
self.assertEqual(b, bytearray([1, 100, 200]))
|
||||||
class C:
|
b[0] = Indexable(10)
|
||||||
def __init__(self, i=0):
|
|
||||||
self.i = i
|
|
||||||
def __index__(self):
|
|
||||||
return self.i
|
|
||||||
b[0] = C(10)
|
|
||||||
self.assertEqual(b, bytearray([10, 100, 200]))
|
self.assertEqual(b, bytearray([10, 100, 200]))
|
||||||
try:
|
try:
|
||||||
b[3] = 0
|
b[3] = 0
|
||||||
@ -529,7 +526,7 @@ class ByteArrayTest(BaseBytesTest):
|
|||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
b[0] = C(-1)
|
b[0] = Indexable(-1)
|
||||||
self.fail("Didn't raise ValueError")
|
self.fail("Didn't raise ValueError")
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
@ -665,6 +662,9 @@ class ByteArrayTest(BaseBytesTest):
|
|||||||
self.assertRaises(ValueError, a.extend, [0, 1, 2, 256])
|
self.assertRaises(ValueError, a.extend, [0, 1, 2, 256])
|
||||||
self.assertRaises(ValueError, a.extend, [0, 1, 2, -1])
|
self.assertRaises(ValueError, a.extend, [0, 1, 2, -1])
|
||||||
self.assertEqual(len(a), 0)
|
self.assertEqual(len(a), 0)
|
||||||
|
a = bytearray(b'')
|
||||||
|
a.extend([Indexable(ord('a'))])
|
||||||
|
self.assertEqual(a, b'a')
|
||||||
|
|
||||||
def test_remove(self):
|
def test_remove(self):
|
||||||
b = bytearray(b'hello')
|
b = bytearray(b'hello')
|
||||||
@ -680,6 +680,8 @@ class ByteArrayTest(BaseBytesTest):
|
|||||||
b.remove(ord('h'))
|
b.remove(ord('h'))
|
||||||
self.assertEqual(b, b'e')
|
self.assertEqual(b, b'e')
|
||||||
self.assertRaises(TypeError, lambda: b.remove(b'e'))
|
self.assertRaises(TypeError, lambda: b.remove(b'e'))
|
||||||
|
b.remove(Indexable(ord('e')))
|
||||||
|
self.assertEqual(b, b'')
|
||||||
|
|
||||||
def test_pop(self):
|
def test_pop(self):
|
||||||
b = bytearray(b'world')
|
b = bytearray(b'world')
|
||||||
@ -701,6 +703,9 @@ class ByteArrayTest(BaseBytesTest):
|
|||||||
b.append(ord('A'))
|
b.append(ord('A'))
|
||||||
self.assertEqual(len(b), 1)
|
self.assertEqual(len(b), 1)
|
||||||
self.assertRaises(TypeError, lambda: b.append(b'o'))
|
self.assertRaises(TypeError, lambda: b.append(b'o'))
|
||||||
|
b = bytearray()
|
||||||
|
b.append(Indexable(ord('A')))
|
||||||
|
self.assertEqual(b, b'A')
|
||||||
|
|
||||||
def test_insert(self):
|
def test_insert(self):
|
||||||
b = bytearray(b'msssspp')
|
b = bytearray(b'msssspp')
|
||||||
@ -710,6 +715,9 @@ class ByteArrayTest(BaseBytesTest):
|
|||||||
b.insert(1000, ord('i'))
|
b.insert(1000, ord('i'))
|
||||||
self.assertEqual(b, b'mississippi')
|
self.assertEqual(b, b'mississippi')
|
||||||
self.assertRaises(TypeError, lambda: b.insert(0, b'1'))
|
self.assertRaises(TypeError, lambda: b.insert(0, b'1'))
|
||||||
|
b = bytearray()
|
||||||
|
b.insert(0, Indexable(ord('A')))
|
||||||
|
self.assertEqual(b, b'A')
|
||||||
|
|
||||||
def test_partition_bytearray_doesnt_share_nullstring(self):
|
def test_partition_bytearray_doesnt_share_nullstring(self):
|
||||||
a, b, c = bytearray(b"x").partition(b"y")
|
a, b, c = bytearray(b"x").partition(b"y")
|
||||||
|
@ -36,12 +36,19 @@ _getbytevalue(PyObject* arg, int *value)
|
|||||||
|
|
||||||
if (PyLong_Check(arg)) {
|
if (PyLong_Check(arg)) {
|
||||||
face_value = PyLong_AsLong(arg);
|
face_value = PyLong_AsLong(arg);
|
||||||
if (face_value < 0 || face_value >= 256) {
|
} else {
|
||||||
PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
|
PyObject *index = PyNumber_Index(arg);
|
||||||
|
if (index == NULL) {
|
||||||
|
PyErr_Format(PyExc_TypeError, "an integer is required");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else {
|
face_value = PyLong_AsLong(index);
|
||||||
PyErr_Format(PyExc_TypeError, "an integer is required");
|
Py_DECREF(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (face_value < 0 || face_value >= 256) {
|
||||||
|
/* this includes the OverflowError in case the long is too large */
|
||||||
|
PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -358,10 +365,10 @@ bytes_getitem(PyByteArrayObject *self, Py_ssize_t i)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
bytes_subscript(PyByteArrayObject *self, PyObject *item)
|
bytes_subscript(PyByteArrayObject *self, PyObject *index)
|
||||||
{
|
{
|
||||||
if (PyIndex_Check(item)) {
|
if (PyIndex_Check(index)) {
|
||||||
Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
|
Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
|
||||||
|
|
||||||
if (i == -1 && PyErr_Occurred())
|
if (i == -1 && PyErr_Occurred())
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -375,9 +382,9 @@ bytes_subscript(PyByteArrayObject *self, PyObject *item)
|
|||||||
}
|
}
|
||||||
return PyLong_FromLong((unsigned char)(self->ob_bytes[i]));
|
return PyLong_FromLong((unsigned char)(self->ob_bytes[i]));
|
||||||
}
|
}
|
||||||
else if (PySlice_Check(item)) {
|
else if (PySlice_Check(index)) {
|
||||||
Py_ssize_t start, stop, step, slicelength, cur, i;
|
Py_ssize_t start, stop, step, slicelength, cur, i;
|
||||||
if (PySlice_GetIndicesEx((PySliceObject *)item,
|
if (PySlice_GetIndicesEx((PySliceObject *)index,
|
||||||
PyByteArray_GET_SIZE(self),
|
PyByteArray_GET_SIZE(self),
|
||||||
&start, &stop, &step, &slicelength) < 0) {
|
&start, &stop, &step, &slicelength) < 0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -501,7 +508,7 @@ bytes_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi,
|
|||||||
static int
|
static int
|
||||||
bytes_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value)
|
bytes_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value)
|
||||||
{
|
{
|
||||||
Py_ssize_t ival;
|
int ival;
|
||||||
|
|
||||||
if (i < 0)
|
if (i < 0)
|
||||||
i += Py_SIZE(self);
|
i += Py_SIZE(self);
|
||||||
@ -514,27 +521,21 @@ bytes_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value)
|
|||||||
if (value == NULL)
|
if (value == NULL)
|
||||||
return bytes_setslice(self, i, i+1, NULL);
|
return bytes_setslice(self, i, i+1, NULL);
|
||||||
|
|
||||||
ival = PyNumber_AsSsize_t(value, PyExc_ValueError);
|
if (!_getbytevalue(value, &ival))
|
||||||
if (ival == -1 && PyErr_Occurred())
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (ival < 0 || ival >= 256) {
|
|
||||||
PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
self->ob_bytes[i] = ival;
|
self->ob_bytes[i] = ival;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
bytes_ass_subscript(PyByteArrayObject *self, PyObject *item, PyObject *values)
|
bytes_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *values)
|
||||||
{
|
{
|
||||||
Py_ssize_t start, stop, step, slicelen, needed;
|
Py_ssize_t start, stop, step, slicelen, needed;
|
||||||
char *bytes;
|
char *bytes;
|
||||||
|
|
||||||
if (PyIndex_Check(item)) {
|
if (PyIndex_Check(index)) {
|
||||||
Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
|
Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
|
||||||
|
|
||||||
if (i == -1 && PyErr_Occurred())
|
if (i == -1 && PyErr_Occurred())
|
||||||
return -1;
|
return -1;
|
||||||
@ -555,20 +556,15 @@ bytes_ass_subscript(PyByteArrayObject *self, PyObject *item, PyObject *values)
|
|||||||
slicelen = 1;
|
slicelen = 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Py_ssize_t ival = PyNumber_AsSsize_t(values, PyExc_ValueError);
|
int ival;
|
||||||
if (ival == -1 && PyErr_Occurred())
|
if (!_getbytevalue(values, &ival))
|
||||||
return -1;
|
return -1;
|
||||||
if (ival < 0 || ival >= 256) {
|
|
||||||
PyErr_SetString(PyExc_ValueError,
|
|
||||||
"byte must be in range(0, 256)");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
self->ob_bytes[i] = (char)ival;
|
self->ob_bytes[i] = (char)ival;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (PySlice_Check(item)) {
|
else if (PySlice_Check(index)) {
|
||||||
if (PySlice_GetIndicesEx((PySliceObject *)item,
|
if (PySlice_GetIndicesEx((PySliceObject *)index,
|
||||||
PyByteArray_GET_SIZE(self),
|
PyByteArray_GET_SIZE(self),
|
||||||
&start, &stop, &step, &slicelen) < 0) {
|
&start, &stop, &step, &slicelen) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
@ -589,7 +585,7 @@ bytes_ass_subscript(PyByteArrayObject *self, PyObject *item, PyObject *values)
|
|||||||
values = PyByteArray_FromObject(values);
|
values = PyByteArray_FromObject(values);
|
||||||
if (values == NULL)
|
if (values == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
err = bytes_ass_subscript(self, item, values);
|
err = bytes_ass_subscript(self, index, values);
|
||||||
Py_DECREF(values);
|
Py_DECREF(values);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -789,7 +785,7 @@ bytes_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
|
|||||||
/* Run the iterator to exhaustion */
|
/* Run the iterator to exhaustion */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
PyObject *item;
|
PyObject *item;
|
||||||
Py_ssize_t value;
|
int rc, value;
|
||||||
|
|
||||||
/* Get the next item */
|
/* Get the next item */
|
||||||
item = iternext(it);
|
item = iternext(it);
|
||||||
@ -803,18 +799,11 @@ bytes_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Interpret it as an int (__index__) */
|
/* Interpret it as an int (__index__) */
|
||||||
value = PyNumber_AsSsize_t(item, PyExc_ValueError);
|
rc = _getbytevalue(item, &value);
|
||||||
Py_DECREF(item);
|
Py_DECREF(item);
|
||||||
if (value == -1 && PyErr_Occurred())
|
if (!rc)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
/* Range check */
|
|
||||||
if (value < 0 || value >= 256) {
|
|
||||||
PyErr_SetString(PyExc_ValueError,
|
|
||||||
"bytes must be in range(0, 256)");
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Append the byte */
|
/* Append the byte */
|
||||||
if (Py_SIZE(self) < self->ob_alloc)
|
if (Py_SIZE(self) < self->ob_alloc)
|
||||||
Py_SIZE(self)++;
|
Py_SIZE(self)++;
|
||||||
@ -2517,10 +2506,11 @@ Insert a single item into the bytearray before the given index.");
|
|||||||
static PyObject *
|
static PyObject *
|
||||||
bytes_insert(PyByteArrayObject *self, PyObject *args)
|
bytes_insert(PyByteArrayObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
int value;
|
PyObject *value;
|
||||||
|
int ival;
|
||||||
Py_ssize_t where, n = Py_SIZE(self);
|
Py_ssize_t where, n = Py_SIZE(self);
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "ni:insert", &where, &value))
|
if (!PyArg_ParseTuple(args, "nO:insert", &where, &value))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (n == PY_SSIZE_T_MAX) {
|
if (n == PY_SSIZE_T_MAX) {
|
||||||
@ -2528,11 +2518,8 @@ bytes_insert(PyByteArrayObject *self, PyObject *args)
|
|||||||
"cannot add more objects to bytes");
|
"cannot add more objects to bytes");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (value < 0 || value >= 256) {
|
if (!_getbytevalue(value, &ival))
|
||||||
PyErr_SetString(PyExc_ValueError,
|
|
||||||
"byte must be in range(0, 256)");
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
|
if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -2544,7 +2531,7 @@ bytes_insert(PyByteArrayObject *self, PyObject *args)
|
|||||||
if (where > n)
|
if (where > n)
|
||||||
where = n;
|
where = n;
|
||||||
memmove(self->ob_bytes + where + 1, self->ob_bytes + where, n - where);
|
memmove(self->ob_bytes + where + 1, self->ob_bytes + where, n - where);
|
||||||
self->ob_bytes[where] = value;
|
self->ob_bytes[where] = ival;
|
||||||
|
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user