Repository navigation
fix: encode and decode binary frames on bitstring 4 and 5 - #310
Conversation
bitstring 5 removed BitStream and ConstBitStream and reversed the argument order of BitArray.insert(). serialization.py imported BitStream at module load, and the dependency is bitstring>=4.1.1, so a fresh install on Python 3.11 or later took bitstring 5 and nothing that imports hivemind_bus_client.client could start (ImportError: cannot import name 'BitStream'). The decoder now reads through a small cursor over Bits slices, which behave the same in both major versions, and the encoder pads with prepend() instead of insert(). The wire format is unchanged: the cross-platform vectors pass on both versions. The new tests run the codec in a child interpreter with BitStream removed and the old insert() order refused, so they fail on the previous code under bitstring 4 as well as 5. The existing tests that built frames with BitStream or the old insert() order use the shared API. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Merge Risk: ⚪ Minimal · up to This change restores import compatibility with bitstring 5 while keeping the wire format unchanged. No actionable merge-blocking risk was identified. Pre-merge checks |
|
|
Ready for review. bitstring 5.0.0 (released 2026-10-11) removed This replaces the |
bitstring 5 removed
BitStreamandConstBitStreamand reversed the argument order ofBitArray.insert().serialization.pyimportsBitStreamat module load, and the declared dependency isbitstring>=4.1.1. So a fresh install on Python 3.11 or later resolves bitstring 5, and importinghivemind_bus_client.clientfails withImportError: cannot import name 'BitStream'. That covers hivemind-core and every satellite. Python 3.10 still resolves bitstring 4, because bitstring 5 requires 3.11.The decoder used
BitStreamonly as a read cursor: read N bits, check the position, take the rest. It now reads through a small_FrameReaderoverBitsslices. Slicing behaves the same in bitstring 4 and 5, and the reader raises bitstring'sReadErroron an over-read asBitStream.readdid, so the existing error mapping toMalformedBinaryFrameis untouched. bitstring 5's own replacement,Reader, does not exist in bitstring 4, so it cannot serve both. The encoder's left padding usesprepend(), which takes the same argument in both versions, instead ofinsert()in a loop. The BINARY payload type check acceptsBits, which coversBitArrayand bitstring 4'sBitStream.The wire format does not change. The cross-platform vectors and the rest of the suite pass unchanged on bitstring 4.4.0 and on 5.0.0 (1088 passed, 4 skipped on each, Python 3.12). The CI matrix covers both, because 3.10 resolves bitstring 4 and 3.11 to 3.14 resolve 5.
tests/test_bitstring_major_versions.pyruns the codec in a child interpreter whereBitStreamandConstBitStreamare removed and the oldinsert()order is refused, whatever bitstring is installed. It round-trips BUS frames (compressed or not, versioned or not) and a BINARY frame, and checks that a truncated frame is malformed. With the source change reverted, it fails on bitstring 4.4.0 with theBitStreamImportError, not only on 5. It also covers the reader's bounds and the padding layout. Existing tests that built frames withBitStream,bytes=or the oldinsert()order now use the API both versions share.Downstream, packages that depend on this one have been capping
bitstring<5until a release carries this change.🤖 Generated with Claude Code
Summary by CodeRabbit