Skip to content

Commit b54ca0f

Browse files
committed
Revert initial version
This reverts commit c961d61.
1 parent c961d61 commit b54ca0f

3 files changed

Lines changed: 13 additions & 78 deletions

File tree

Lib/test/test_bytes.py

Lines changed: 0 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1860,54 +1860,6 @@ def g():
18601860
alloc = b.__alloc__()
18611861
self.assertGreater(alloc, len(b))
18621862

1863-
def test_reinit_small_buffer(self):
1864-
# gh-153419: reinitializing a bytearray whose buffer allocation is
1865-
# exactly one byte used to fail a debug assertion
1866-
b = bytearray(1)
1867-
b.__init__()
1868-
self.assertEqual(b, bytearray())
1869-
1870-
def test_reinit_empty_buffer(self):
1871-
# gh-153419: Calling __init__ on a bytearray that has an active
1872-
# export should only be allowed if the bytearray is unchanged.
1873-
b = bytearray()
1874-
with memoryview(b):
1875-
self.assertRaises(BufferError, b.__init__, b"abc")
1876-
self.assertRaises(BufferError, b.__init__, "abc", "ascii")
1877-
self.assertRaises(BufferError, b.__init__, 3)
1878-
b.__init__()
1879-
b.__init__(b"")
1880-
b.__init__("", "ascii")
1881-
self.assertEqual(b, bytearray())
1882-
1883-
def test_reinit_nonempty_buffer(self):
1884-
# gh-153419: If a buffer is non-empty and has an active export
1885-
# calling __init__ on it should always fail, even if the
1886-
# new value ends up the same as the old one. This is purely for
1887-
# practical reasons rather than a design goal.
1888-
b = bytearray(b"abc")
1889-
with memoryview(b):
1890-
self.assertRaises(BufferError, b.__init__)
1891-
self.assertRaises(BufferError, b.__init__, b"xy")
1892-
self.assertRaises(BufferError, b.__init__, b"abc")
1893-
1894-
def test_new_without_init(self):
1895-
# gh-153419: a bytearray must be fully initialized by __new__
1896-
# alone to ensure that the underlying buffer is always valid.
1897-
b = bytearray.__new__(bytearray)
1898-
self.assertEqual(b, bytearray())
1899-
b.append(1)
1900-
self.assertEqual(b, bytearray(b"\x01"))
1901-
1902-
class B(bytearray):
1903-
def __init__(self, *args):
1904-
pass # does not call super().__init__()
1905-
1906-
b = B(b"ignored")
1907-
self.assertEqual(b, bytearray())
1908-
b.extend(b"abc")
1909-
self.assertEqual(b, bytearray(b"abc"))
1910-
19111863
def test_extend(self):
19121864
orig = b'hello'
19131865
a = bytearray(orig)

Misc/NEWS.d/next/Core_and_Builtins/2026-07-10-10-53-11.gh-issue-153419.QI9uwG.rst

Lines changed: 0 additions & 2 deletions
This file was deleted.

Objects/bytearrayobject.c

Lines changed: 13 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -236,14 +236,6 @@ bytearray_resize_lock_held(PyObject *self, Py_ssize_t requested_size)
236236
return -1;
237237
}
238238

239-
if (requested_size == 0) {
240-
/* Resizing to zero just resets to the empty constant (#153419) */
241-
Py_XSETREF(obj->ob_bytes_object,
242-
Py_GetConstant(Py_CONSTANT_EMPTY_BYTES));
243-
bytearray_reinit_from_bytes(obj, 0, 0);
244-
return 0;
245-
}
246-
247239
if (size + logical_offset <= alloc) {
248240
/* Current buffer is large enough to host the requested size,
249241
decide on a strategy. */
@@ -910,19 +902,6 @@ bytearray_ass_subscript(PyObject *op, PyObject *index, PyObject *values)
910902
return ret;
911903
}
912904

913-
static PyObject *
914-
bytearray_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
915-
{
916-
PyObject *self = PyType_GenericNew(type, args, kwds);
917-
if (self == NULL) {
918-
return NULL;
919-
}
920-
PyByteArrayObject *obj = _PyByteArray_CAST(self);
921-
obj->ob_bytes_object = Py_GetConstant(Py_CONSTANT_EMPTY_BYTES);
922-
bytearray_reinit_from_bytes(obj, 0, 0);
923-
return self;
924-
}
925-
926905
/*[clinic input]
927906
bytearray.__init__
928907
@@ -941,13 +920,22 @@ bytearray___init___impl(PyByteArrayObject *self, PyObject *arg,
941920
PyObject *it;
942921
PyObject *(*iternext)(PyObject *);
943922

923+
/* First __init__; set ob_bytes_object so ob_bytes is always non-null. */
924+
if (self->ob_bytes_object == NULL) {
925+
self->ob_bytes_object = Py_GetConstant(Py_CONSTANT_EMPTY_BYTES);
926+
bytearray_reinit_from_bytes(self, 0, 0);
927+
self->ob_exports = 0;
928+
}
929+
944930
if (Py_SIZE(self) != 0) {
945-
/* Empty previous contents if possible (yes, do this first of all!). */
931+
/* Empty previous contents (yes, do this first of all!) */
946932
if (PyByteArray_Resize((PyObject *)self, 0) < 0)
947933
return -1;
948934
}
949935

936+
/* Should be caused by first init or the resize to 0. */
950937
assert(self->ob_bytes_object == Py_GetConstantBorrowed(Py_CONSTANT_EMPTY_BYTES));
938+
assert(self->ob_exports == 0);
951939

952940
/* Make a quick exit if no first argument */
953941
if (arg == NULL) {
@@ -975,11 +963,8 @@ bytearray___init___impl(PyByteArrayObject *self, PyObject *arg,
975963
}
976964
assert(PyBytes_Check(encoded));
977965

978-
/* Most encodes return a new unique bytes, just use it as buffer.
979-
If there are active exports, let `iconcat` handle raising the
980-
error when encoded is not empty */
981-
if (self->ob_exports == 0
982-
&& _PyObject_IsUniquelyReferenced(encoded)
966+
/* Most encodes return a new unique bytes, just use it as buffer. */
967+
if (_PyObject_IsUniquelyReferenced(encoded)
983968
&& PyBytes_CheckExact(encoded))
984969
{
985970
Py_ssize_t size = Py_SIZE(encoded);
@@ -2952,7 +2937,7 @@ PyTypeObject PyByteArray_Type = {
29522937
0, /* tp_dictoffset */
29532938
bytearray___init__, /* tp_init */
29542939
PyType_GenericAlloc, /* tp_alloc */
2955-
bytearray_new, /* tp_new */
2940+
PyType_GenericNew, /* tp_new */
29562941
PyObject_Free, /* tp_free */
29572942
.tp_version_tag = _Py_TYPE_VERSION_BYTEARRAY,
29582943
};

0 commit comments

Comments
 (0)