2
votes

I am receiving these errors only in Raspberry Pis: "TypeError: unhashable type: 'bytearray'"

  • Python 3.5.3
  • Raspbian Stretch 9.1
  • The following packages: grpcio (1.6.3) grpcio-reflection (1.6.3) grpcio-tools (1.6.3)

test.proto (very simple):

syntax = "proto3";

package bug;

message Foo
{
    string field1 = 1;
}

and the Python code:

from test_pb2 import Foo

EXPECTED = bytearray(b'\n\x04AAAA')
foo = Foo()
foo.field1 = 'AAAA'
print(foo)

data = foo.SerializeToString()
print(data)
assert (data == EXPECTED)

foo.ParseFromString(EXPECTED)
assert (foo.field1 == 'AAAA')

The deserialization only fails in Raspberry Pi (Ubuntu is fine):

field1: "AAAA"

Traceback (most recent call last): File "/home/pi/.local/lib/python3.5/site-packages/google/protobuf/internal/python_message.py", line 1069, in MergeFromString if self._InternalParse(serialized, 0, length) != length: File "/home/pi/.local/lib/python3.5/site-packages/google/protobuf/internal/python_message.py", line 1092, in InternalParse field_decoder, field_desc = decoders_by_tag.get(tag_bytes, (None, None)) TypeError: unhashable type: 'bytearray'

During handling of the above exception, another exception occurred:

Traceback (most recent call last): File "test.py", line 13, in foo.ParseFromString(REF) File "/home/pi/.local/lib/python3.5/site-packages/google/protobuf/message.py", line 185, in ParseFromString self.MergeFromString(serialized) File "/home/pi/.local/lib/python3.5/site-packages/google/protobuf/internal/python_message.py", line 1075, in MergeFromString raise message_mod.DecodeError('Truncated message.') google.protobuf.message.DecodeError: Truncated message.

1

1 Answers

1
votes

I managed to fix the problem in the Raspberry Pi.

The issue was that when running in the Pi deserialize fails for bytearray, however, if the data is passed as bytes things work well.

So my current workaround is to do something like:

foo.ParseFromString( bytes(EXPECTED) )

I am still not sure why the same problem does not happen in desktops. What I have noticed is that when debugging in desktops, foo.ParseFromString is shown as <built-in method ParseFromString of Foo object at 0x7fedcc0b3fa8> so I suppose that there is some native optimization in desktops that is not available when running in the Pi.

When I have a little more time I will try to investigate a little more on how protobuf is deployed. Maybe in the meantime someone can share some details.