Skip to content

[mypyc] Add primitives for bytearray len, indexing, item assignment and slicing - #22408

Open
Jahongir-Qurbonov wants to merge 2 commits into
python:masterfrom
Jahongir-Qurbonov:mypyc-bytearray-ops
Open

Jahongir-Qurbonov wants to merge 2 commits into
python:masterfrom
Jahongir-Qurbonov:mypyc-bytearray-ops

Conversation

@Jahongir-Qurbonov

@Jahongir-Qurbonov Jahongir-Qurbonov commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor

Add primitives for these bytearray operations:

  • len(b): reads ob_size directly, as for bytes, list and tuple
  • b[i]
  • b[i] = x
  • b[i:j]: covers b[i:] and b[:j] too, and always returns a bytearray

The C implementations are in bytearray_extra_ops.c.

Indexing, item assignment and slicing take the fast path only for exact bytearray objects with short int arguments. Other cases fall back to the generic implementation, which preserves:

  • subclass overrides of __getitem__ and __setitem__ (the result of slicing a subclass is checked to be a bytearray, as before)
  • CPython's error messages for very large indexes

Item assignment checks the value before the index, as CPython does.

On free-threaded builds, the item array is accessed while holding the object's critical section, because a bytearray can be resized concurrently.

Tests compare each operation against a generic call through Any. They cover:

  • the results, the exception types and the messages
  • every index around the bounds
  • large positive and negative ints
  • subclasses with and without overrides

They pass on Python 3.10, 3.13, 3.14 and 3.14t (free-threaded).

b[i] += x still goes through the generic path, because index assignment targets are typed as object (the existing TODO in AssignmentTargetIndex).

Micro-benchmark (2000 × 1024 operations on a 1024-byte bytearray, the same module compiled before and after this change, Python 3.13):

Operation Before After
len(b) 0.0051s 0.0020s
b[i] 0.0280s 0.0050s
b[i] = x 0.0319s 0.0045s
b[i:i + 8] 0.1273s 0.0454s

Part of mypyc/mypyc#644.

…nd slicing

Add fast paths for len(b), b[i], b[i] = x and b[i:j] when b is a
bytearray. The C implementations live in bytearray_extra_ops.c.

Indexing, item assignment and slicing only use the fast path for exact
bytearray objects with short int arguments, and otherwise fall back to
the generic implementation, so subclass overrides and error messages for
very large indexes are preserved. On free-threaded builds the item array
is accessed while holding the object's lock, since a bytearray can be
resized concurrently.

Part of mypyc/mypyc#644.
A subclass may override __getitem__ to return something other than a
bytearray. Also make the subclass tests use bytearray as the static type, so
that they exercise the primitives.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant