python - Error when deserializing protobuf descriptor containing nested types -


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