georg.brandl
2008-07-16 23:15:31 UTC
Author: georg.brandl
Date: Thu Jul 17 01:15:30 2008
New Revision: 65043
Log:
Merged revisions 65041 via svnmerge from
svn+ssh://pythondev at 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".
........
Modified:
python/branches/py3k/ (props changed)
python/branches/py3k/Lib/test/test_bytes.py
python/branches/py3k/Objects/bytearrayobject.c
Modified: python/branches/py3k/Lib/test/test_bytes.py
==============================================================================
--- python/branches/py3k/Lib/test/test_bytes.py (original)
+++ python/branches/py3k/Lib/test/test_bytes.py Thu Jul 17 01:15:30 2008
@@ -17,6 +17,12 @@
import test.string_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):
@@ -53,15 +59,11 @@
self.assertEqual(list(b), ints)
def test_from_index(self):
- class C:
- def __init__(self, i=0):
- self.i = i
- def __index__(self):
- return self.i
- b = self.type2test([C(), C(1), C(254), C(255)])
+ b = self.type2test([Indexable(), Indexable(1), Indexable(254),
+ Indexable(255)])
self.assertEqual(list(b), [0, 1, 254, 255])
- self.assertRaises(ValueError, bytearray, [C(-1)])
- self.assertRaises(ValueError, bytearray, [C(256)])
+ self.assertRaises(ValueError, bytearray, [Indexable(-1)])
+ self.assertRaises(ValueError, bytearray, [Indexable(256)])
def test_from_ssize(self):
self.assertEqual(bytearray(0), b'')
@@ -506,12 +508,7 @@
self.assertEqual(b, bytearray([1, 100, 3]))
b[-1] = 200
self.assertEqual(b, bytearray([1, 100, 200]))
- class C:
- def __init__(self, i=0):
- self.i = i
- def __index__(self):
- return self.i
- b[0] = C(10)
+ b[0] = Indexable(10)
self.assertEqual(b, bytearray([10, 100, 200]))
try:
b[3] = 0
@@ -529,7 +526,7 @@
except ValueError:
pass
try:
- b[0] = C(-1)
+ b[0] = Indexable(-1)
self.fail("Didn't raise ValueError")
except ValueError:
pass
@@ -665,6 +662,9 @@
self.assertRaises(ValueError, a.extend, [0, 1, 2, 256])
self.assertRaises(ValueError, a.extend, [0, 1, 2, -1])
self.assertEqual(len(a), 0)
+ a = bytearray(b'')
+ a.extend([Indexable(ord('a'))])
+ self.assertEqual(a, b'a')
def test_remove(self):
b = bytearray(b'hello')
@@ -680,6 +680,8 @@
b.remove(ord('h'))
self.assertEqual(b, b'e')
self.assertRaises(TypeError, lambda: b.remove(b'e'))
+ b.remove(Indexable(ord('e')))
+ self.assertEqual(b, b'')
def test_pop(self):
b = bytearray(b'world')
@@ -701,6 +703,9 @@
b.append(ord('A'))
self.assertEqual(len(b), 1)
self.assertRaises(TypeError, lambda: b.append(b'o'))
+ b = bytearray()
+ b.append(Indexable(ord('A')))
+ self.assertEqual(b, b'A')
def test_insert(self):
b = bytearray(b'msssspp')
@@ -710,6 +715,9 @@
b.insert(1000, ord('i'))
self.assertEqual(b, b'mississippi')
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):
a, b, c = bytearray(b"x").partition(b"y")
Modified: python/branches/py3k/Objects/bytearrayobject.c
==============================================================================
--- python/branches/py3k/Objects/bytearrayobject.c (original)
+++ python/branches/py3k/Objects/bytearrayobject.c Thu Jul 17 01:15:30 2008
@@ -36,12 +36,19 @@
if (PyLong_Check(arg)) {
face_value = PyLong_AsLong(arg);
- if (face_value < 0 || face_value >= 256) {
- PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
+ } else {
+ PyObject *index = PyNumber_Index(arg);
+ if (index == NULL) {
+ PyErr_Format(PyExc_TypeError, "an integer is required");
return 0;
}
- } else {
- PyErr_Format(PyExc_TypeError, "an integer is required");
+ face_value = PyLong_AsLong(index);
+ 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;
}
@@ -358,10 +365,10 @@
}
static PyObject *
-bytes_subscript(PyByteArrayObject *self, PyObject *item)
+bytes_subscript(PyByteArrayObject *self, PyObject *index)
{
- if (PyIndex_Check(item)) {
- Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+ if (PyIndex_Check(index)) {
+ Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
if (i == -1 && PyErr_Occurred())
return NULL;
@@ -375,9 +382,9 @@
}
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;
- if (PySlice_GetIndicesEx((PySliceObject *)item,
+ if (PySlice_GetIndicesEx((PySliceObject *)index,
PyByteArray_GET_SIZE(self),
&start, &stop, &step, &slicelength) < 0) {
return NULL;
@@ -501,7 +508,7 @@
static int
bytes_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value)
{
- Py_ssize_t ival;
+ int ival;
if (i < 0)
i += Py_SIZE(self);
@@ -514,27 +521,21 @@
if (value == NULL)
return bytes_setslice(self, i, i+1, NULL);
- ival = PyNumber_AsSsize_t(value, PyExc_ValueError);
- if (ival == -1 && PyErr_Occurred())
- return -1;
-
- if (ival < 0 || ival >= 256) {
- PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
+ if (!_getbytevalue(value, &ival))
return -1;
- }
self->ob_bytes[i] = ival;
return 0;
}
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;
char *bytes;
- if (PyIndex_Check(item)) {
- Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+ if (PyIndex_Check(index)) {
+ Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
if (i == -1 && PyErr_Occurred())
return -1;
@@ -555,20 +556,15 @@
slicelen = 1;
}
else {
- Py_ssize_t ival = PyNumber_AsSsize_t(values, PyExc_ValueError);
- if (ival == -1 && PyErr_Occurred())
- return -1;
- if (ival < 0 || ival >= 256) {
- PyErr_SetString(PyExc_ValueError,
- "byte must be in range(0, 256)");
+ int ival;
+ if (!_getbytevalue(values, &ival))
return -1;
- }
self->ob_bytes[i] = (char)ival;
return 0;
}
}
- else if (PySlice_Check(item)) {
- if (PySlice_GetIndicesEx((PySliceObject *)item,
+ else if (PySlice_Check(index)) {
+ if (PySlice_GetIndicesEx((PySliceObject *)index,
PyByteArray_GET_SIZE(self),
&start, &stop, &step, &slicelen) < 0) {
return -1;
@@ -589,7 +585,7 @@
values = PyByteArray_FromObject(values);
if (values == NULL)
return -1;
- err = bytes_ass_subscript(self, item, values);
+ err = bytes_ass_subscript(self, index, values);
Py_DECREF(values);
return err;
}
@@ -789,7 +785,7 @@
/* Run the iterator to exhaustion */
for (;;) {
PyObject *item;
- Py_ssize_t value;
+ int rc, value;
/* Get the next item */
item = iternext(it);
@@ -803,18 +799,11 @@
}
/* Interpret it as an int (__index__) */
- value = PyNumber_AsSsize_t(item, PyExc_ValueError);
+ rc = _getbytevalue(item, &value);
Py_DECREF(item);
- if (value == -1 && PyErr_Occurred())
+ if (!rc)
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 */
if (Py_SIZE(self) < self->ob_alloc)
Py_SIZE(self)++;
@@ -2517,10 +2506,11 @@
static PyObject *
bytes_insert(PyByteArrayObject *self, PyObject *args)
{
- int value;
+ PyObject *value;
+ int ival;
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;
if (n == PY_SSIZE_T_MAX) {
@@ -2528,11 +2518,8 @@
"cannot add more objects to bytes");
return NULL;
}
- if (value < 0 || value >= 256) {
- PyErr_SetString(PyExc_ValueError,
- "byte must be in range(0, 256)");
+ if (!_getbytevalue(value, &ival))
return NULL;
- }
if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
return NULL;
@@ -2544,7 +2531,7 @@
if (where > n)
where = n;
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;
}
Date: Thu Jul 17 01:15:30 2008
New Revision: 65043
Log:
Merged revisions 65041 via svnmerge from
svn+ssh://pythondev at 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".
........
Modified:
python/branches/py3k/ (props changed)
python/branches/py3k/Lib/test/test_bytes.py
python/branches/py3k/Objects/bytearrayobject.c
Modified: python/branches/py3k/Lib/test/test_bytes.py
==============================================================================
--- python/branches/py3k/Lib/test/test_bytes.py (original)
+++ python/branches/py3k/Lib/test/test_bytes.py Thu Jul 17 01:15:30 2008
@@ -17,6 +17,12 @@
import test.string_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):
@@ -53,15 +59,11 @@
self.assertEqual(list(b), ints)
def test_from_index(self):
- class C:
- def __init__(self, i=0):
- self.i = i
- def __index__(self):
- return self.i
- b = self.type2test([C(), C(1), C(254), C(255)])
+ b = self.type2test([Indexable(), Indexable(1), Indexable(254),
+ Indexable(255)])
self.assertEqual(list(b), [0, 1, 254, 255])
- self.assertRaises(ValueError, bytearray, [C(-1)])
- self.assertRaises(ValueError, bytearray, [C(256)])
+ self.assertRaises(ValueError, bytearray, [Indexable(-1)])
+ self.assertRaises(ValueError, bytearray, [Indexable(256)])
def test_from_ssize(self):
self.assertEqual(bytearray(0), b'')
@@ -506,12 +508,7 @@
self.assertEqual(b, bytearray([1, 100, 3]))
b[-1] = 200
self.assertEqual(b, bytearray([1, 100, 200]))
- class C:
- def __init__(self, i=0):
- self.i = i
- def __index__(self):
- return self.i
- b[0] = C(10)
+ b[0] = Indexable(10)
self.assertEqual(b, bytearray([10, 100, 200]))
try:
b[3] = 0
@@ -529,7 +526,7 @@
except ValueError:
pass
try:
- b[0] = C(-1)
+ b[0] = Indexable(-1)
self.fail("Didn't raise ValueError")
except ValueError:
pass
@@ -665,6 +662,9 @@
self.assertRaises(ValueError, a.extend, [0, 1, 2, 256])
self.assertRaises(ValueError, a.extend, [0, 1, 2, -1])
self.assertEqual(len(a), 0)
+ a = bytearray(b'')
+ a.extend([Indexable(ord('a'))])
+ self.assertEqual(a, b'a')
def test_remove(self):
b = bytearray(b'hello')
@@ -680,6 +680,8 @@
b.remove(ord('h'))
self.assertEqual(b, b'e')
self.assertRaises(TypeError, lambda: b.remove(b'e'))
+ b.remove(Indexable(ord('e')))
+ self.assertEqual(b, b'')
def test_pop(self):
b = bytearray(b'world')
@@ -701,6 +703,9 @@
b.append(ord('A'))
self.assertEqual(len(b), 1)
self.assertRaises(TypeError, lambda: b.append(b'o'))
+ b = bytearray()
+ b.append(Indexable(ord('A')))
+ self.assertEqual(b, b'A')
def test_insert(self):
b = bytearray(b'msssspp')
@@ -710,6 +715,9 @@
b.insert(1000, ord('i'))
self.assertEqual(b, b'mississippi')
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):
a, b, c = bytearray(b"x").partition(b"y")
Modified: python/branches/py3k/Objects/bytearrayobject.c
==============================================================================
--- python/branches/py3k/Objects/bytearrayobject.c (original)
+++ python/branches/py3k/Objects/bytearrayobject.c Thu Jul 17 01:15:30 2008
@@ -36,12 +36,19 @@
if (PyLong_Check(arg)) {
face_value = PyLong_AsLong(arg);
- if (face_value < 0 || face_value >= 256) {
- PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
+ } else {
+ PyObject *index = PyNumber_Index(arg);
+ if (index == NULL) {
+ PyErr_Format(PyExc_TypeError, "an integer is required");
return 0;
}
- } else {
- PyErr_Format(PyExc_TypeError, "an integer is required");
+ face_value = PyLong_AsLong(index);
+ 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;
}
@@ -358,10 +365,10 @@
}
static PyObject *
-bytes_subscript(PyByteArrayObject *self, PyObject *item)
+bytes_subscript(PyByteArrayObject *self, PyObject *index)
{
- if (PyIndex_Check(item)) {
- Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+ if (PyIndex_Check(index)) {
+ Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
if (i == -1 && PyErr_Occurred())
return NULL;
@@ -375,9 +382,9 @@
}
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;
- if (PySlice_GetIndicesEx((PySliceObject *)item,
+ if (PySlice_GetIndicesEx((PySliceObject *)index,
PyByteArray_GET_SIZE(self),
&start, &stop, &step, &slicelength) < 0) {
return NULL;
@@ -501,7 +508,7 @@
static int
bytes_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value)
{
- Py_ssize_t ival;
+ int ival;
if (i < 0)
i += Py_SIZE(self);
@@ -514,27 +521,21 @@
if (value == NULL)
return bytes_setslice(self, i, i+1, NULL);
- ival = PyNumber_AsSsize_t(value, PyExc_ValueError);
- if (ival == -1 && PyErr_Occurred())
- return -1;
-
- if (ival < 0 || ival >= 256) {
- PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
+ if (!_getbytevalue(value, &ival))
return -1;
- }
self->ob_bytes[i] = ival;
return 0;
}
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;
char *bytes;
- if (PyIndex_Check(item)) {
- Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+ if (PyIndex_Check(index)) {
+ Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
if (i == -1 && PyErr_Occurred())
return -1;
@@ -555,20 +556,15 @@
slicelen = 1;
}
else {
- Py_ssize_t ival = PyNumber_AsSsize_t(values, PyExc_ValueError);
- if (ival == -1 && PyErr_Occurred())
- return -1;
- if (ival < 0 || ival >= 256) {
- PyErr_SetString(PyExc_ValueError,
- "byte must be in range(0, 256)");
+ int ival;
+ if (!_getbytevalue(values, &ival))
return -1;
- }
self->ob_bytes[i] = (char)ival;
return 0;
}
}
- else if (PySlice_Check(item)) {
- if (PySlice_GetIndicesEx((PySliceObject *)item,
+ else if (PySlice_Check(index)) {
+ if (PySlice_GetIndicesEx((PySliceObject *)index,
PyByteArray_GET_SIZE(self),
&start, &stop, &step, &slicelen) < 0) {
return -1;
@@ -589,7 +585,7 @@
values = PyByteArray_FromObject(values);
if (values == NULL)
return -1;
- err = bytes_ass_subscript(self, item, values);
+ err = bytes_ass_subscript(self, index, values);
Py_DECREF(values);
return err;
}
@@ -789,7 +785,7 @@
/* Run the iterator to exhaustion */
for (;;) {
PyObject *item;
- Py_ssize_t value;
+ int rc, value;
/* Get the next item */
item = iternext(it);
@@ -803,18 +799,11 @@
}
/* Interpret it as an int (__index__) */
- value = PyNumber_AsSsize_t(item, PyExc_ValueError);
+ rc = _getbytevalue(item, &value);
Py_DECREF(item);
- if (value == -1 && PyErr_Occurred())
+ if (!rc)
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 */
if (Py_SIZE(self) < self->ob_alloc)
Py_SIZE(self)++;
@@ -2517,10 +2506,11 @@
static PyObject *
bytes_insert(PyByteArrayObject *self, PyObject *args)
{
- int value;
+ PyObject *value;
+ int ival;
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;
if (n == PY_SSIZE_T_MAX) {
@@ -2528,11 +2518,8 @@
"cannot add more objects to bytes");
return NULL;
}
- if (value < 0 || value >= 256) {
- PyErr_SetString(PyExc_ValueError,
- "byte must be in range(0, 256)");
+ if (!_getbytevalue(value, &ival))
return NULL;
- }
if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
return NULL;
@@ -2544,7 +2531,7 @@
if (where > n)
where = n;
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;
}