Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5df8a8a

Browse files
committed
Issue #19087: Improve bytearray allocation in order to allow cheap popping of data at the front (slice deletion).
1 parent dcd01b4 commit 5df8a8a

5 files changed

Lines changed: 182 additions & 151 deletions

File tree

Include/bytearrayobject.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,11 @@ extern "C" {
2222
#ifndef Py_LIMITED_API
2323
typedef struct {
2424
PyObject_VAR_HEAD
25+
Py_ssize_t ob_alloc; /* How many bytes allocated in ob_buffer */
26+
char *ob_bytes; /* Physical backing buffer */
27+
char *ob_start; /* Logical start inside ob_bytes */
2528
/* XXX(nnorwitz): should ob_exports be Py_ssize_t? */
26-
int ob_exports; /* how many buffer exports */
27-
Py_ssize_t ob_alloc; /* How many bytes allocated */
28-
char *ob_bytes;
29+
int ob_exports; /* How many buffer exports */
2930
} PyByteArrayObject;
3031
#endif
3132

@@ -49,8 +50,8 @@ PyAPI_FUNC(int) PyByteArray_Resize(PyObject *, Py_ssize_t);
4950
#ifndef Py_LIMITED_API
5051
#define PyByteArray_AS_STRING(self) \
5152
(assert(PyByteArray_Check(self)), \
52-
Py_SIZE(self) ? ((PyByteArrayObject *)(self))->ob_bytes : _PyByteArray_empty_string)
53-
#define PyByteArray_GET_SIZE(self) (assert(PyByteArray_Check(self)),Py_SIZE(self))
53+
Py_SIZE(self) ? ((PyByteArrayObject *)(self))->ob_start : _PyByteArray_empty_string)
54+
#define PyByteArray_GET_SIZE(self) (assert(PyByteArray_Check(self)), Py_SIZE(self))
5455

5556
PyAPI_DATA(char) _PyByteArray_empty_string[];
5657
#endif

Lib/test/test_bytes.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -909,6 +909,15 @@ def test_setslice(self):
909909
with self.assertRaises(ValueError):
910910
b[3:4] = elem
911911

912+
def test_setslice_extend(self):
913+
# Exercise the resizing logic (see issue #19087)
914+
b = bytearray(range(100))
915+
self.assertEqual(list(b), list(range(100)))
916+
del b[:10]
917+
self.assertEqual(list(b), list(range(10, 100)))
918+
b.extend(range(100, 110))
919+
self.assertEqual(list(b), list(range(10, 110)))
920+
912921
def test_extended_set_del_slice(self):
913922
indices = (0, None, 1, 3, 19, 300, 1<<333, -1, -2, -31, -300)
914923
for start in indices:

Lib/test/test_sys.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -721,7 +721,7 @@ def test_objecttypes(self):
721721
samples = [b'', b'u'*100000]
722722
for sample in samples:
723723
x = bytearray(sample)
724-
check(x, vsize('inP') + x.__alloc__())
724+
check(x, vsize('n2Pi') + x.__alloc__())
725725
# bytearray_iterator
726726
check(iter(bytearray()), size('nP'))
727727
# cell

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ Projected release date: 2013-10-20
1010
Core and Builtins
1111
-----------------
1212

13+
- Issue #19087: Improve bytearray allocation in order to allow cheap popping
14+
of data at the front (slice deletion).
15+
1316
- Issue #19014: memoryview.cast() is now allowed on zero-length views.
1417

1518
- Issue #18690: memoryview is now automatically registered with

0 commit comments

Comments
 (0)