@@ -213,6 +213,9 @@ bytearray_resize_lock_held(PyObject *self, Py_ssize_t requested_size)
213213{
214214 _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED (self );
215215 PyByteArrayObject * obj = ((PyByteArrayObject * )self );
216+
217+ assert (obj -> ob_bytes_object != NULL );
218+
216219 /* All computations are done unsigned to avoid integer overflows
217220 (see issue #22335). */
218221 size_t alloc = (size_t ) obj -> ob_alloc ;
@@ -236,6 +239,14 @@ bytearray_resize_lock_held(PyObject *self, Py_ssize_t requested_size)
236239 return -1 ;
237240 }
238241
242+ /* Resize to 0 resets to empty bytes (see issue #153419). */
243+ if (requested_size == 0 ) {
244+ Py_SETREF (obj -> ob_bytes_object ,
245+ Py_GetConstant (Py_CONSTANT_EMPTY_BYTES ));
246+ bytearray_reinit_from_bytes (obj , 0 , 0 );
247+ return 0 ;
248+ }
249+
239250 if (size + logical_offset <= alloc ) {
240251 /* Current buffer is large enough to host the requested size,
241252 decide on a strategy. */
@@ -902,6 +913,20 @@ bytearray_ass_subscript(PyObject *op, PyObject *index, PyObject *values)
902913 return ret ;
903914}
904915
916+ static PyObject *
917+ bytearray_new (PyTypeObject * type , PyObject * args , PyObject * kwds )
918+ {
919+ PyObject * op = PyType_GenericNew (type , args , kwds );
920+ if (op == NULL ) {
921+ return NULL ;
922+ }
923+ PyByteArrayObject * self = _PyByteArray_CAST (op );
924+ self -> ob_bytes_object = Py_GetConstant (Py_CONSTANT_EMPTY_BYTES );
925+ bytearray_reinit_from_bytes (self , 0 , 0 );
926+ self -> ob_exports = 0 ;
927+ return op ;
928+ }
929+
905930/*[clinic input]
906931bytearray.__init__
907932
@@ -920,20 +945,16 @@ bytearray___init___impl(PyByteArrayObject *self, PyObject *arg,
920945 PyObject * it ;
921946 PyObject * (* iternext )(PyObject * );
922947
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 ;
948+ /* Disallow any __init__ call if the object is not resizable (has exports)
949+ to make the handling of non-null `source` init values simpler. */
950+ if (!_canresize (self )) {
951+ return -1 ;
928952 }
929953
930- if (Py_SIZE (self ) != 0 ) {
931- /* Empty previous contents (yes, do this first of all!) */
932- if (PyByteArray_Resize ((PyObject * )self , 0 ) < 0 )
933- return -1 ;
954+ /* Empty any previous contents (do this first of all!). */
955+ if (PyByteArray_Resize ((PyObject * )self , 0 ) < 0 ) {
956+ return -1 ;
934957 }
935-
936- /* Should be caused by first init or the resize to 0. */
937958 assert (self -> ob_bytes_object == Py_GetConstantBorrowed (Py_CONSTANT_EMPTY_BYTES ));
938959 assert (self -> ob_exports == 0 );
939960
@@ -1609,6 +1630,9 @@ bytearray_take_bytes_impl(PyByteArrayObject *self, PyObject *n)
16091630 }
16101631
16111632 if (_PyBytes_Resize (& self -> ob_bytes_object , to_take ) == -1 ) {
1633+ assert (self -> ob_bytes_object == NULL );
1634+ self -> ob_bytes_object = Py_GetConstant (Py_CONSTANT_EMPTY_BYTES );
1635+ bytearray_reinit_from_bytes (self , 0 , 0 );
16121636 Py_DECREF (remaining );
16131637 return NULL ;
16141638 }
@@ -2939,7 +2963,7 @@ PyTypeObject PyByteArray_Type = {
29392963 0 , /* tp_dictoffset */
29402964 bytearray___init__ , /* tp_init */
29412965 PyType_GenericAlloc , /* tp_alloc */
2942- PyType_GenericNew , /* tp_new */
2966+ bytearray_new , /* tp_new */
29432967 PyObject_Free , /* tp_free */
29442968 .tp_version_tag = _Py_TYPE_VERSION_BYTEARRAY ,
29452969};
0 commit comments