Skip to content

Commit e240327

Browse files
committed
gh-129559: Add bytearray.resize()
Add `bytearray.resize()` which wraps `PyByteArray_Resize`
1 parent cf4c4ec commit e240327

File tree

5 files changed

+104
-2
lines changed

5 files changed

+104
-2
lines changed

Doc/library/stdtypes.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2841,6 +2841,13 @@ objects.
28412841
optional *sep* and *bytes_per_sep* parameters to insert separators
28422842
between bytes in the hex output.
28432843

2844+
.. method:: resize(size)
2845+
2846+
Resize the :class:`bytearray` to contain size bytes with a NULL byte
2847+
following.
2848+
2849+
.. versionadded:: next
2850+
28442851
Since bytearray objects are sequences of integers (akin to a list), for a
28452852
bytearray object *b*, ``b[0]`` will be an integer, while ``b[0:1]`` will be
28462853
a bytearray object of length 1. (This contrasts with text strings, where

Lib/test/test_bytes.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1359,6 +1359,33 @@ def by(s):
13591359
b = by("Hello, world")
13601360
self.assertEqual(re.findall(br"\w+", b), [by("Hello"), by("world")])
13611361

1362+
def test_resize(self):
1363+
ba = bytearray(b'abcdef')
1364+
self.assertIsNone(ba.resize(3))
1365+
self.assertEqual(ba, bytearray(b'abc'))
1366+
self.assertIsNone(ba.resize(10))
1367+
self.assertEqual(len(ba), 10)
1368+
self.assertEqual(ba[:3], bytearray(b'abc'))
1369+
self.assertIsNone(ba.resize(2**20))
1370+
self.assertEqual(len(ba), 2**20)
1371+
self.assertEqual(ba[:3], bytearray(b'abc'))
1372+
self.assertIsNone(ba.resize(0))
1373+
self.assertEqual(ba, bytearray())
1374+
1375+
ba = ByteArraySubclass(b'abcdef')
1376+
self.assertIsNone(ba.resize(3))
1377+
self.assertEqual(ba, bytearray(b'abc'))
1378+
1379+
# Check arguments
1380+
self.assertRaises(TypeError, lambda: bytearray().resize())
1381+
self.assertRaises(TypeError, lambda: bytearray().resize(10, 10))
1382+
1383+
self.assertRaises(BufferError, lambda: bytearray().resize(-1))
1384+
self.assertRaises(BufferError, lambda: bytearray().resize(-200))
1385+
self.assertRaises(MemoryError, lambda: bytearray().resize(sys.maxsize))
1386+
self.assertRaises(MemoryError, lambda: bytearray(1000).resize(sys.maxsize))
1387+
1388+
13621389
def test_setitem(self):
13631390
def setitem_as_mapping(b, i, val):
13641391
b[i] = val
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Add :meth:`bytearray.resize` method to :class:`bytearray` wrapping
2+
:c:func:`PyByteArray_Resize` so :class:`bytearray` can be efficiently
3+
resized in place.

Objects/bytearrayobject.c

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,12 @@ PyByteArray_Resize(PyObject *self, Py_ssize_t requested_size)
184184
assert(self != NULL);
185185
assert(PyByteArray_Check(self));
186186
assert(logical_offset <= alloc);
187-
assert(requested_size >= 0);
187+
188+
if (requested_size < 0) {
189+
PyErr_Format(PyExc_BufferError,
190+
"Can only resize to positive sizes, got %zd.", requested_size);
191+
return -1;
192+
}
188193

189194
if (requested_size == Py_SIZE(self)) {
190195
return 0;
@@ -1388,6 +1393,26 @@ bytearray_removesuffix_impl(PyByteArrayObject *self, Py_buffer *suffix)
13881393
}
13891394

13901395

1396+
/*[clinic input]
1397+
bytearray.resize
1398+
size: Py_ssize_t
1399+
New size to resize to..
1400+
/
1401+
Resize the internal buffer of bytearray to len.
1402+
[clinic start generated code]*/
1403+
1404+
static PyObject *
1405+
bytearray_resize_impl(PyByteArrayObject *self, Py_ssize_t size)
1406+
/*[clinic end generated code: output=f73524922990b2d9 input=75fd4d17c4aa47d3]*/
1407+
{
1408+
int result = PyByteArray_Resize((PyObject *)self, size);
1409+
if (result == -1) {
1410+
return NULL;
1411+
}
1412+
Py_RETURN_NONE;
1413+
}
1414+
1415+
13911416
/*[clinic input]
13921417
bytearray.translate
13931418
@@ -2361,6 +2386,7 @@ static PyMethodDef bytearray_methods[] = {
23612386
BYTEARRAY_REPLACE_METHODDEF
23622387
BYTEARRAY_REMOVEPREFIX_METHODDEF
23632388
BYTEARRAY_REMOVESUFFIX_METHODDEF
2389+
BYTEARRAY_RESIZE_METHODDEF
23642390
BYTEARRAY_REVERSE_METHODDEF
23652391
BYTEARRAY_RFIND_METHODDEF
23662392
BYTEARRAY_RINDEX_METHODDEF

Objects/clinic/bytearrayobject.c.h

Lines changed: 40 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)