Merged revisions 67291 via svnmerge from

svn+ssh://pythondev@svn.python.org/python/trunk

........
  r67291 | benjamin.peterson | 2008-11-19 15:49:09 -0600 (Wed, 19 Nov 2008) | 5 lines

  make sure that bytearray methods return a new bytearray even if there is no change

  Fixes #4348
  Reviewed by Brett
........
This commit is contained in:
Benjamin Peterson 2008-11-19 22:05:53 +00:00
parent 6df732777c
commit 866eba940f
3 changed files with 16 additions and 21 deletions

View File

@ -721,6 +721,16 @@ class ByteArrayTest(BaseBytesTest):
b.insert(0, Indexable(ord('A'))) b.insert(0, Indexable(ord('A')))
self.assertEqual(b, b'A') self.assertEqual(b, b'A')
def test_copied(self):
# Issue 4348. Make sure that operations that don't mutate the array
# copy the bytes.
b = bytearray(b'abc')
#self.assertFalse(b is b.replace(b'abc', b'cde', 0))
t = bytearray([i for i in range(256)])
x = bytearray(b'')
self.assertFalse(x is x.translate(t))
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")
self.assertEqual(b, b"") self.assertEqual(b, b"")

View File

@ -12,6 +12,9 @@ What's New in Python 2.6.1 alpha 1
Core and Builtins Core and Builtins
----------------- -----------------
- Issue #4348: Some bytearray methods returned that didn't cause any change to
the bytearray, returned the same bytearray instead of a copy.
- Issue #4317: Fixed a crash in the imageop.rgb2rgb8() function. - Issue #4317: Fixed a crash in the imageop.rgb2rgb8() function.
- Issue #4230: If ``__getattr__`` is a descriptor, it now functions correctly. - Issue #4230: If ``__getattr__`` is a descriptor, it now functions correctly.

View File

@ -1423,7 +1423,7 @@ bytes_translate(PyByteArrayObject *self, PyObject *args)
{ {
register char *input, *output; register char *input, *output;
register const char *table; register const char *table;
register Py_ssize_t i, c, changed = 0; register Py_ssize_t i, c;
PyObject *input_obj = (PyObject*)self; PyObject *input_obj = (PyObject*)self;
const char *output_start; const char *output_start;
Py_ssize_t inlen; Py_ssize_t inlen;
@ -1469,14 +1469,8 @@ bytes_translate(PyByteArrayObject *self, PyObject *args)
/* If no deletions are required, use faster code */ /* If no deletions are required, use faster code */
for (i = inlen; --i >= 0; ) { for (i = inlen; --i >= 0; ) {
c = Py_CHARMASK(*input++); c = Py_CHARMASK(*input++);
if (Py_CHARMASK((*output++ = table[c])) != c) *output++ = table[c];
changed = 1;
} }
if (changed || !PyByteArray_CheckExact(input_obj))
goto done;
Py_DECREF(result);
Py_INCREF(input_obj);
result = input_obj;
goto done; goto done;
} }
@ -1491,13 +1485,6 @@ bytes_translate(PyByteArrayObject *self, PyObject *args)
if (trans_table[c] != -1) if (trans_table[c] != -1)
if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c) if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c)
continue; continue;
changed = 1;
}
if (!changed && PyByteArray_CheckExact(input_obj)) {
Py_DECREF(result);
Py_INCREF(input_obj);
result = input_obj;
goto done;
} }
/* Fix the size of the resulting string */ /* Fix the size of the resulting string */
if (inlen > 0) if (inlen > 0)
@ -1526,15 +1513,10 @@ done:
!memcmp(target+offset+1, pattern+1, length-2) ) !memcmp(target+offset+1, pattern+1, length-2) )
/* Bytes ops must return a string. */ /* Bytes ops must return a string, create a copy */
/* If the object is subclass of bytes, create a copy */
Py_LOCAL(PyByteArrayObject *) Py_LOCAL(PyByteArrayObject *)
return_self(PyByteArrayObject *self) return_self(PyByteArrayObject *self)
{ {
if (PyByteArray_CheckExact(self)) {
Py_INCREF(self);
return (PyByteArrayObject *)self;
}
return (PyByteArrayObject *)PyByteArray_FromStringAndSize( return (PyByteArrayObject *)PyByteArray_FromStringAndSize(
PyByteArray_AS_STRING(self), PyByteArray_AS_STRING(self),
PyByteArray_GET_SIZE(self)); PyByteArray_GET_SIZE(self));