Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

gh-129559: Addbytearray.resize()#129560

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
gpshead merged 24 commits intopython:mainfromcmaloney:resize_pr
Feb 5, 2025
Merged
Show file tree
Hide file tree
Changes from15 commits
Commits
Show all changes
24 commits
Select commitHold shift + click to select a range
e240327
gh-129559: Add `bytearray.resize()`
cmaloneyFeb 1, 2025
925fcbd
Add versionchanged note to c-api around len behavior
cmaloneyFeb 1, 2025
29c04ad
Add argument formatting to stdtypes.rst
cmaloneyFeb 1, 2025
d15ef67
Add buffer error to c api test
cmaloneyFeb 2, 2025
d199032
Remove case that no longer crashes
cmaloneyFeb 2, 2025
18829a2
Fix versionchanged
cmaloneyFeb 2, 2025
df779e2
Fix doc warnings
cmaloneyFeb 2, 2025
facc91f
Fix requested size check range
cmaloneyFeb 2, 2025
d8b9faf
0 is a fine size
cmaloneyFeb 2, 2025
7429cf4
Fix grammar
cmaloneyFeb 2, 2025
c183116
Add NULL byte tests, include set bytes in docs
cmaloneyFeb 2, 2025
dd46a85
Update Doc/library/stdtypes.rst
cmaloneyFeb 2, 2025
69bbdc1
Always null new bytes
cmaloneyFeb 2, 2025
ec4aa3d
Apply suggestions from code review
cmaloneyFeb 4, 2025
336299a
Update Objects/bytearrayobject.c
cmaloneyFeb 4, 2025
1a0e157
tweak docs, fixup return exception
cmaloneyFeb 4, 2025
cf89ec1
Update test_resize_forbidden to use bytearray.resize
cmaloneyFeb 4, 2025
ddc7b09
doc tweaks
cmaloneyFeb 5, 2025
a49374b
Fix indentation of equivalent code
cmaloneyFeb 5, 2025
298d052
Fix doctest
cmaloneyFeb 5, 2025
2f6b0a3
Apply suggestions from code review
cmaloneyFeb 5, 2025
bf00f33
Update doctest per review
cmaloneyFeb 5, 2025
8df7b02
Fix whitespace in test_bytes
cmaloneyFeb 5, 2025
43e46dd
Merge branch 'main' into resize_pr
cmaloneyFeb 5, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletionDoc/c-api/bytearray.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -73,7 +73,11 @@ Direct API functions

.. c:function:: int PyByteArray_Resize(PyObject *bytearray, Py_ssize_t len)

Resize the internal buffer of *bytearray* to *len*.
Resize the internal buffer of *bytearray* to *len*. Failure is a ``-1`` return with an exception set.

.. versionchanged:: next
A negative *len* will now result in a failure.


Macros
^^^^^^
Expand Down
7 changes: 7 additions & 0 deletionsDoc/library/stdtypes.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -2841,6 +2841,13 @@ objects.
optional *sep* and *bytes_per_sep* parameters to insert separators
between bytes in the hex output.

.. method:: resize(size)

Resize the :class:`bytearray` to contain *size* bytes.
If :class:`bytearray` needs to grow, all new bytes will be set to null bytes.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Also describe the "obvious-to-us" behavior of what happens when it shrinks: the data at the end is truncated, the remaining data should be equivalent to a[:size] slice.

... and consider if the Python version should also support negative size to mean the same thing it would in a slice notation.
if (size < 0): size = max(0, len(self) + size) ?

Copy link
ContributorAuthor

@cmaloneycmaloneyFeb 5, 2025
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

👍 for the truncation.

I don't like negative, because the function operates in absolute buffer size, and requesting a negative buffer size sounds like a bug I'd write and I'd prefer an exception / exit rather than debug the symptom "my buffer shrank".

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

my original equivalent to is wrong, which make it look like a delta, current doc one I'm validating:

iflen(self)>size:delself[size:]else:self+=b'\0'* (size-len(self))


.. versionadded:: next

Since bytearray objects are sequences of integers (akin to a list), for a
bytearray object *b*, ``b[0]`` will be an integer, while ``b[0:1]`` will be
a bytearray object of length 1. (This contrasts with text strings, where
Expand Down
32 changes: 32 additions & 0 deletionsLib/test/test_bytes.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -1359,6 +1359,38 @@ def by(s):
b = by("Hello, world")
self.assertEqual(re.findall(br"\w+", b), [by("Hello"), by("world")])

def test_resize(self):
ba = bytearray(b'abcdef')
self.assertIsNone(ba.resize(3))
self.assertEqual(ba, bytearray(b'abc'))
self.assertIsNone(ba.resize(10))
self.assertEqual(len(ba), 10)
# Bytes beyond set values must be cleared.
self.assertEqual(ba, bytearray(b'abc\0\0\0\0\0\0\0'))
ba[3:10] = b'defghij'
self.assertEqual(ba, bytearray(b'abcdefghij'))
self.assertIsNone(ba.resize(2**20))
self.assertEqual(len(ba), 2**20)
self.assertEqual(ba, bytearray(b'abcdefghij' + b'\0' * (2 ** 20 - 10)))
self.assertIsNone(ba.resize(0))
self.assertEqual(ba, bytearray())
self.assertIsNone(ba.resize(10))
self.assertEqual(ba, bytearray(b'\0' * 10))

ba = ByteArraySubclass(b'abcdef')
self.assertIsNone(ba.resize(3))
self.assertEqual(ba, bytearray(b'abc'))

# Check arguments
self.assertRaises(TypeError, lambda: bytearray().resize())
self.assertRaises(TypeError, bytearray().resize, 10, 10)

self.assertRaises(BufferError, lambda: bytearray().resize(-1))
self.assertRaises(BufferError, lambda: bytearray().resize(-200))
self.assertRaises(MemoryError, lambda: bytearray().resize(sys.maxsize))
self.assertRaises(MemoryError, lambda: bytearray(1000).resize(sys.maxsize))


def test_setitem(self):
def setitem_as_mapping(b, i, val):
b[i] = val
Expand Down
3 changes: 2 additions & 1 deletionLib/test/test_capi/test_bytearray.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -151,10 +151,11 @@ def test_resize(self):
self.assertEqual(resize(ba, 3), 0)
self.assertEqual(ba, bytearray(b'abc'))

self.assertRaises(BufferError, resize, bytearray(), -1)
self.assertRaises(BufferError, resize, bytearray(), -200)
self.assertRaises(MemoryError, resize, bytearray(), PY_SSIZE_T_MAX)
self.assertRaises(MemoryError, resize, bytearray(1000), PY_SSIZE_T_MAX)

# CRASHES resize(bytearray(b'abc'), -1)
# CRASHES resize(b'abc', 0)
# CRASHES resize(object(), 0)
# CRASHES resize(NULL, 0)
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
Add:meth:`bytearray.resize` method to:class:`bytearray` wrapping
:c:func:`PyByteArray_Resize` so:class:`bytearray` can be efficiently
resized in place.
33 changes: 32 additions & 1 deletionObjects/bytearrayobject.c
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -184,7 +184,12 @@ PyByteArray_Resize(PyObject *self, Py_ssize_t requested_size)
assert(self != NULL);
assert(PyByteArray_Check(self));
assert(logical_offset <= alloc);
assert(requested_size >= 0);

if (requested_size < 0) {
PyErr_Format(PyExc_ValueError,
"Can only resize to positive sizes, got %zd", requested_size);
return -1;
}

if (requested_size == Py_SIZE(self)) {
return 0;
Expand DownExpand Up@@ -1388,6 +1393,31 @@ bytearray_removesuffix_impl(PyByteArrayObject *self, Py_buffer *suffix)
}


/*[clinic input]
bytearray.resize
size: Py_ssize_t
New size to resize to..
/
Resize the internal buffer of bytearray to len.
[clinic start generated code]*/

static PyObject *
bytearray_resize_impl(PyByteArrayObject *self, Py_ssize_t size)
/*[clinic end generated code: output=f73524922990b2d9 input=75fd4d17c4aa47d3]*/
{
Py_ssize_t start_size = PyByteArray_GET_SIZE(self);
int result = PyByteArray_Resize((PyObject *)self, size);
if (result < 0) {
return NULL;
}
// Set new bytes to provide consistent / safer behavior in Python version.
if (size > start_size) {
memset(PyByteArray_AS_STRING(self) + start_size, 0, size - start_size);
}
Py_RETURN_NONE;
}


/*[clinic input]
bytearray.translate

Expand DownExpand Up@@ -2361,6 +2391,7 @@ static PyMethodDef bytearray_methods[] = {
BYTEARRAY_REPLACE_METHODDEF
BYTEARRAY_REMOVEPREFIX_METHODDEF
BYTEARRAY_REMOVESUFFIX_METHODDEF
BYTEARRAY_RESIZE_METHODDEF
BYTEARRAY_REVERSE_METHODDEF
BYTEARRAY_RFIND_METHODDEF
BYTEARRAY_RINDEX_METHODDEF
Expand Down
41 changes: 40 additions & 1 deletionObjects/clinic/bytearrayobject.c.h
View file
Open in desktop

Some generated files are not rendered by default. Learn more abouthow customized files appear on GitHub.

Loading

[8]ページ先頭

©2009-2025 Movatter.jp