i need send protobuf descriptor server can used serialize/deserialize objects containing nested types. wrote quick example demonstrating problem:
test.proto:
message { message b { required string data = 1; } repeated b bs = 1; } test.py:
from descriptor_pb2 import descriptorproto google.protobuf import descriptor,reflection,message test_pb2 import * = a() b = a.bs.add() b.data = "stuff" d1 = a.descriptor dp1 = descriptorproto() d1.copytoproto(dp1) # dp1 serialized, sent on network, deserialized d2 = descriptor.makedescriptor(dp1) ## code fixes problem #for desc in dp1.nested_type: # d2.nested_types.append( descriptor.makedescriptor(desc) ) #d2.nested_types_by_name = dict((t.name, t) t in d2.nested_types) # #for f in dp1.field: # d2.fields_by_number[f.number].message_type = d2.nested_types_by_name[f.type_name.split('.')[-1]] # ## line cannot run on server side #d2.fields[0].message_type._concrete_class = d1.fields[0].message_type._concrete_class reflection.parsemessage(d1, a.serializetostring()) reflection.parsemessage(d2, a.serializetostring()) when run code, error on last line:
traceback (most recent call last): file "test.py", line 29, in <module> reflection.parsemessage(d2, a.serializetostring()) file "build\bdist.win32\egg\google\protobuf\reflection.py", line 168, in parsemessage new_msg.parsefromstring(byte_str) file "build\bdist.win32\egg\google\protobuf\message.py", line 182, in parsefromstring self.mergefromstring(serialized) file "build\bdist.win32\egg\google\protobuf\internal\python_message.py", line 795, in mergefromstring if self._internalparse(serialized, 0, length) != length: file "build\bdist.win32\egg\google\protobuf\internal\python_message.py", line 827, in internalparse pos = field_decoder(buffer, new_pos, end, self, field_dict) file "build\bdist.win32\egg\google\protobuf\internal\decoder.py", line 523, in decoderepeatedfield if value.add()._internalparse(buffer, pos, new_pos) != new_pos: file "build\bdist.win32\egg\google\protobuf\internal\containers.py", line 216, in add new_element = self._message_descriptor._concrete_class(**kwargs) attributeerror: 'nonetype' object has no attribute '_concrete_class' i figured out error occurring because descriptor.makedescriptor() not copy nested types when copies deserialized descriptorproto, wrote code in comment block compensate it. however, last line uses reference class in original descriptor, cannot on server.
i've spent countless hours trying figure problem out, , crucial part of system. appreciated.
Comments
Post a Comment