@@ -1524,6 +1524,32 @@ def test_take_bytes(self):
15241524 self .assertRaises (BufferError , ba .take_bytes )
15251525 self .assertEqual (ba .take_bytes (), b'abc' )
15261526
1527+ @support .cpython_only # tests an implementation detail
1528+ def test_take_bytes_optimization (self ):
1529+ # Validate optimization around taking lots of little chunks out of a
1530+ # much bigger buffer. Save work by only copying a little rather than
1531+ # moving a lot.
1532+ ba = bytearray (b'abcdef' + b'0' * 1000 )
1533+ start_alloc = ba .__alloc__ ()
1534+
1535+ # Take two bytes at a time, checking alloc doesn't change.
1536+ self .assertEqual (ba .take_bytes (2 ), b'ab' )
1537+ self .assertEqual (ba .__alloc__ (), start_alloc )
1538+ self .assertEqual (len (ba ), 4 + 1000 )
1539+ self .assertEqual (ba .take_bytes (2 ), b'cd' )
1540+ self .assertEqual (ba .__alloc__ (), start_alloc )
1541+ self .assertEqual (len (ba ), 2 + 1000 )
1542+ self .assertEqual (ba .take_bytes (2 ), b'ef' )
1543+ self .assertEqual (ba .__alloc__ (), start_alloc )
1544+ self .assertEqual (len (ba ), 0 + 1000 )
1545+ self .assertEqual (ba .__alloc__ (), start_alloc )
1546+
1547+ # Take over half, alloc shrinks to exact size.
1548+ self .assertEqual (ba .take_bytes (501 ), b'0' * 501 )
1549+ self .assertEqual (len (ba ), 499 )
1550+ bytes_header_size = sys .getsizeof (b'' )
1551+ self .assertEqual (ba .__alloc__ (), 499 + bytes_header_size )
1552+
15271553 def test_setitem (self ):
15281554 def setitem_as_mapping (b , i , val ):
15291555 b [i ] = val
0 commit comments