bytearray.copy()
Genuinely independent, unlike list.copy. Because the elements are plain ints rather than objects, the shallow-copy caveat that haunts lists simply does not apply here.
Common call
snapshot = buf.copy()
Returns
a new bytearray with the same bytes
Replaces
bytearray(buf) and buf[:]
Watch out
assignment does NOT copy — b = a shares the same buffer
bytearray.copy()
→ bytearray
Demo
Live evaluation
Try:
Inputs
sstrbuffer (as text)
Output
bytearray(bytes('abc', 'utf-8')).copy()
bytearray(b'abc')
The output looks identical to the input, because a copy holds the same bytes — the point is what the display cannot show. The result is a DIFFERENT object, so appending to one leaves the other untouched. That matters because plain assignment does not copy: b = a gives two names for one buffer, and mutating through either is visible through both.
Common patterns
Snapshot before mutating
Keeps the original intact while you edit.
original = buf.copy() buf.extend(patch)
Hand out a private buffer
Callers can mutate their copy without touching your state.
def get_buffer(self): return self._buf.copy()
Copy before a destructive parse
Parsers that consume the buffer should not consume the caller's.
work = data.copy() while work: frame = work.pop(0)
Examples
1. Same contents
bytearray(b'abc').copy()
Returns
bytearray(b'abc')2. Different object
a = bytearray(b'abc')
a.copy() is a
Returns
False3. Independent
a = bytearray(b'ab')
c = a.copy()
c.append(99)
a
Returns
bytearray(b'ab')4. Assignment shares
a = bytearray(b'ab')
c = a
c.append(99)
a
Returns
bytearray(b'abc')5. Empty
bytearray().copy()
Returns
bytearray(b'')6. Same as slicing
bytearray(b'abc')[:]
Returns
bytearray(b'abc')Pitfalls
1. Assignment does not copy
The mistake copy exists to prevent. b = a gives a second name for the same buffer, so mutating through either is visible through both — and the bug usually surfaces far from the assignment.
Shared buffer
a = bytearray(b'ab') c = a c.append(99) a
bytearray(b'abc')
Copy explicitly
c = a.copy() c.append(99) a
bytearray(b'ab')
2. A copy of a bytearray is still mutable
copy does not freeze anything. Handing one out still lets the caller change it — if you want a genuinely read-only snapshot, convert to bytes.
Still writable
snap = buf.copy() snap[0] = 99
succeeds
Freeze it
snap = bytes(buf) snap[0] = 99
TypeError
3. Python 3.3 and newer only
copy arrived after the type itself. Older code uses bytearray(buf) or buf[:], both of which still work and are equally correct.
Fails on 3.2
buf.copy()
AttributeError: 'bytearray' object has no attribute 'copy'
Portable form
bytearray(buf)
a copy, on any version
When to use
Use it
- Snapshotting a buffer before mutating it
- Returning an internal buffer callers may safely modify
- Feeding a destructive parser without consuming the original
Reach for something else
- You want an immutable snapshot → bytes(buf)
- Nothing will mutate either side → sharing is cheaper
- A zero-copy read-only view is enough → memoryview(buf).toreadonly()
Notes
Complexity
O(n) — the bytes are copied
Return
A new bytearray; always a distinct object, even when empty
CPython impl
Objects/bytearrayobject.c :: bytearray_copy
Memory
Allocates a second buffer the same size as the first
Thread-safe
The copy itself is safe; a concurrently mutated source gives a torn snapshot
FAQ
Technically yes, but it makes no difference. A bytearray holds plain integers rather than references to objects, so there is no inner structure to share — the copy is fully independent in practice.
a = bytearray(b"ab") c = a.copy() c.append(99) a # unchanged
History
3.0
bytearray introduced as the mutable counterpart to bytes.
3.3
copy and clear added, matching the list interface.