c-types Structure and equality with bytes/bytearray
Eryk Sun
eryksun at gmail.com
Thu Apr 29 17:56:14 EDT 2021
On 4/26/21, Michael Hull <mikehulluk at gmail.com> wrote:
>
> my understanding was that `bytes` and `bytearray` would normally
> be expected to work quite interchangeably with each other?
bytearray.__eq__() is more flexible:
>>> i = Int16(first=65, second=66)
>>> bytearray(i).__eq__(i)
True
>>> i.__eq__(bytearray(i))
NotImplemented
>>> i.__eq__(bytes(i))
NotImplemented
>>> bytes(i).__eq__(i)
NotImplemented
When in doubt, read the source code. In bytearray_richcompare() in
Objects/bytearrayobject.c, the comparison begins by using the buffer
protocol to get comparable byte strings. ctypes data types support the
buffer protocol, so this works well. On the other hand,
bytes_richcompare() in Objects/bytesobject.c does not use the buffer
protocol but instead requires the other object to be a bytes object.
In Python 3.3+, you can force the comparison to use the buffer
protocol via memoryview(). For example:
>>> memoryview(i).cast('B') == bytes(i)
True
>>> memoryview(i).cast('B') == bytearray(i)
True
The cast() to "B" (unsigned char) is required because views of ctypes
data objects include their format:
>>> memoryview(i).format
'T{<b:first:<b:second:}'
>>> memoryview(i).cast('B').format
'B'
More information about the Python-list
mailing list