Currently dbus_to_python converts a dbus.Array with signature y to a python list and not a bytearray so struct.unpack doesn't work? e.g.
from bluezero import dbus_tools
import dbus
import struct
x = dbus.Array([1,2,3,4,5,6,7,8], signature='y')
# x = dbus.Array([1, 2, 3, 4, 5, 6, 7, 8], signature=dbus.Signature('y'))
y = dbus_tools.dbus_to_python(x)
# y = [1, 2, 3, 4, 5, 6, 7, 8]
z = struct.unpack('<II', y)
Traceback (most recent call last):
File "/usr/lib/python3.8/code.py", line 90, in runcode
exec(code, self.locals)
File "<input>", line 1, in <module>
TypeError: a bytes-like object is required, not 'list'
It would be more accurate to say that there is a bug in dbus_to_python and it is not doing the conversion correctly. There is probably some debate to be had if it should return bytes or bytearray.
For reference:
python3's bytes and bytearray classes both hold arrays of bytes, where each byte can take on a value between 0 and 255. The primary difference is that a bytes object is immutable, meaning that oncce created, you cannot modify its elements. By contrast, a bytearray object allows you to modify its elements.
Initially I'm favouring bytearray but I'm interested in other opinions.
This would result in the code going from:
elif isinstance(data, dbus.Array):
data = [dbus_to_python(value) for value in data]
to
elif isinstance(data, dbus.Array):
if data.signature == dbus.Signature('y'):
data = bytearray(data)
else:
data = [dbus_to_python(value) for value in data]
Rerunning the above example after making that change I get:
from bluezero import dbus_tools
import dbus
import struct
x = dbus.Array([1,2,3,4,5,6,7,8], signature='y')
# x= dbus.Array([1, 2, 3, 4, 5, 6, 7, 8], signature=dbus.Signature('y'))
y = dbus_tools.dbus_to_python(x)
# y = bytearray(b'\x01\x02\x03\x04\x05\x06\x07\x08')
z = struct.unpack('<II', y)
# z = (67305985, 134678021)
Currently
dbus_to_python
converts adbus.Array
with signaturey
to a python list and not abytearray
sostruct.unpack
doesn't work? e.g.It would be more accurate to say that there is a bug in
dbus_to_python
and it is not doing the conversion correctly. There is probably some debate to be had if it should returnbytes
orbytearray
. For reference:Initially I'm favouring
bytearray
but I'm interested in other opinions.This would result in the code going from:
to
Rerunning the above example after making that change I get:
Originally posted by @ukBaz in https://github.com/ukBaz/python-bluezero/issues/334#issuecomment-860014808