- 
          
 - 
                Notifications
    
You must be signed in to change notification settings  - Fork 33.3k
 
          gh-139871: Add bytearray.take_bytes([n]) to efficiently extract bytes
          #140128
        
          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 our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 4 commits
daf8e02
              39b2d15
              86faf1d
              a9328f4
              e9f5ca9
              4784957
              db19def
              451c302
              bab7151
              cb2377c
              20175f8
              e485595
              b5535d0
              7c6e8a8
              4e27d13
              9887dad
              6e4b910
              b6f8403
              28cb8c5
              f03b895
              a45f3c2
              c8943e3
              5bffb7e
              583ea4b
              8ee14e6
              d70e369
              97be818
              99e49ef
              f4b62d9
              48afb62
              8c81e03
              313e78c
              c028e2b
              a69b338
              2a95118
              9680e8a
              02882af
              b67d10c
              6db8822
              File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| 
          
            
          
           | 
    @@ -3173,6 +3173,97 @@ objects. | |
| 
     | 
||
| .. versionadded:: 3.14 | ||
| 
     | 
||
| .. method:: take_bytes(n=None, /) | ||
| 
     | 
||
| Take the first *n* bytes as an immutable :class:`bytes`. Defaults to all | ||
| bytes. | ||
| 
     | 
||
| If *n* is negative indexes from the end and takes the first :func:`len` | ||
| minus *n* bytes. If *n* is out of bounds raises :exc:`IndexError`. | ||
| 
     | 
||
| Taking less than the full length will leave remaining bytes in the | ||
| :class:`bytearray` which requires a copy. If the remaining bytes should be | ||
| discarded use :func:`~bytearray.resize` or :keyword:`del` to truncate | ||
| then :func:`~bytearray.take_bytes` without a size. | ||
| 
     | 
||
| .. impl-detail:: | ||
| 
     | 
||
| CPython implements this as a zero-copy operation making it a very | ||
| efficient way to make a :class:`bytes` from a :class:`bytearray`. | ||
| 
     | 
||
| .. list-table:: Suggested Replacements | ||
                
       | 
||
| :header-rows: 1 | ||
| 
     | 
||
| * - Description | ||
| - Old | ||
| - New | ||
| 
     | 
||
| * - Return :class:`bytes` after working with :class:`bytearray` | ||
| - .. code:: python | ||
| 
     | 
||
| 
     | 
||
| def read() -> bytes: | ||
| buffer = bytearray(1024) | ||
| ... | ||
| return bytes(buffer) | ||
| - .. code:: python | ||
| 
     | 
||
| def read() -> bytes: | ||
| buffer = bytearray(1024) | ||
| ... | ||
| return buffer.take_bytes() | ||
| 
     | 
||
| * - Empty a buffer getting the bytes | ||
| - .. code:: python | ||
| 
     | 
||
| buffer = bytearray(1024) | ||
| ... | ||
| data = bytes(buffer) | ||
| buffer.clear() | ||
| - .. code:: python | ||
| 
     | 
||
| buffer = bytearray(1024) | ||
| ... | ||
| data = buffer.take_bytes() | ||
| assert len(buffer) == 0 | ||
                
      
                  cmaloney marked this conversation as resolved.
               
              
                Outdated
          
            Show resolved
            Hide resolved
         | 
||
| 
     | 
||
| * - Split a buffer at a specific separator | ||
| - .. code:: python | ||
| 
     | 
||
| buffer = bytearray(b'abc\ndef') | ||
| n = buffer.find(b'\n') | ||
| data = bytes(buffer[:n + 1]) | ||
| del buffer[:n + 1] | ||
| assert buffer == bytearray(b'def') | ||
| 
     | 
||
| - .. code:: python | ||
| 
     | 
||
| buffer = bytearray(b'abc\ndef') | ||
| n = buffer.find(b'\n') | ||
| data = buffer.take_bytes(n + 1) | ||
| assert buffer == bytearray(b'def') | ||
| 
     | 
||
| * - Split a buffer at a specific separator; discard after the separator | ||
| - .. code:: python | ||
| 
     | 
||
| buffer = bytearray(b'abc\ndef') | ||
| n = buffer.find(b'\n') | ||
| data = bytes(buffer[:n]) | ||
| buffer.clear() | ||
| assert data == b'abc' | ||
| assert len(buffer) == 0 | ||
| 
     | 
||
| - .. code:: python | ||
| 
     | 
||
| buffer = bytearray(b'abc\ndef') | ||
| n = buffer.find(b'\n') | ||
| buffer.resize(n) | ||
| data = buffer.take_bytes() | ||
| assert data == b'abc' | ||
| assert len(buffer) == 0 | ||
| 
     | 
||
| .. 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 | ||
| 
          
            
          
           | 
    ||
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1 @@ | ||
| Update :class:`bytearray` to use a :class:`bytes` under the hood as its buffer which enables optimizations. | ||
                
      
                  cmaloney marked this conversation as resolved.
               
              
                Outdated
          
            Show resolved
            Hide resolved
         | 
||
Uh oh!
There was an error while loading. Please reload this page.