[Python-3000-checkins] r65043 - in python/branches/py3k: Lib/test/test_bytes.py Objects/bytearrayobject.c

georg.brandl python-3000-checkins at python.org
Thu Jul 17 01:15:31 CEST 2008


Author: georg.brandl
Date: Thu Jul 17 01:15:30 2008
New Revision: 65043

Log:
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".
........


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;
 }


More information about the Python-3000-checkins mailing list