From 741fc41f070cc59574db6436a2b53e6213c3a1f6 Mon Sep 17 00:00:00 2001 From: S Groesz Date: Mon, 24 Aug 2026 18:27:58 -0500 Subject: [PATCH] fix: Bits.__getitem__/__setitem__ ignore msb_last (rtl) as documented list() always used MSB-first bit order regardless of the msb_last constructor flag, so indexing/slicing on an instance built with msb_last=True silently behaved identically to the default -- the documented "swap bit order for indexing and slicing" never happened. __setitem__ needed a matching fix: since __setvalue() always expects a MSB-first list, a mutated LSB-first list from list() has to be reversed back before being passed in. Found while wiring bits.Bits into progpib's GPIB status-byte handling (IEEE-488.2 bit numbering is LSB-first, e.g. RQS = bit 6). Co-Authored-By: Claude Sonnet 5 --- src/bits.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/bits.py b/src/bits.py index b34d5be..4c9a5c8 100644 --- a/src/bits.py +++ b/src/bits.py @@ -605,6 +605,9 @@ class Bits: l = self.list() # str->int->bool->int : accept bool, str, int, return either "0" or "1" l[index] = Bit(value) + if self.__r_to_l: + # list() returned LSB-first order; __setvalue expects MSB-first + l = l[::-1] self.__setvalue(l) def __get__(self, instance, owner): @@ -911,10 +914,15 @@ class Bits: """ self.__r_to_l = bool(msb_last) - def list(self, pad=True, reverse=False): + def list(self, pad=True, reverse=None): """ Return self as list(of Bit) + reverse: True/False to force bit order for this call; None (the + default) uses self.rtl, so indexing/slicing on an instance + constructed with msb_last=True is LSB-first as documented. """ + if reverse is None: + reverse = self.__r_to_l ret = [] bits = self.bin(pad=pad, reverse=reverse) for b in bits: