New issue 278 by muzuiget: SerializeToString fail if nested types all field
is empty
http://code.google.com/p/protobuf/issues/detail?id=278
version protobuf-2.4.0a, python2.6 ubuntu 10.10 install from source tarball
with easy_install.
If define a proto file as below
$cat test.proto
message Child {
repeated int32 a = 1;
repeated int32 b = 2;
}
message Partent {
required Child child = 1;
}
generate a python class file, run code as below
$ cat test1.py
import test_pb2
p = test_pb2.Partent()
print p
p.SerializeToString()
$ python test1.py
Traceback (most recent call last):
File "test1.py", line 4, in <module>
p.SerializeToString()
File "/usr/local/lib/python2.6/dist-packages/protobuf-2.4.0a-py2.6.egg/google/protobuf/internal/python_message.py",
line 730, in SerializeToString
','.join(self.FindInitializationErrors()))
google.protobuf.message.EncodeError: Message is missing required fields:
child
Because both child.a and child.b are empty, it cause child empty. A
solution is change the Child tag to "optional".
I don't know it is a feature or bug. But if I run
$ cat test2.py
import test_pb2
p = test_pb2.Partent()
print p
print p.child.a
p.child.a.append(1)
p.child.a.remove(1)
print p
print p.child.a
p.SerializeToString()
$ python test2.py
[]
child {
}
[]
After append and remove, child.a and child.b sitll empty, but this time
child is not empty, SerializeToString success.
Comment #1 on issue 278 by liuj...@google.com: SerializeToString fail if
nested types all field is empty
http://code.google.com/p/protobuf/issues/detail?id=278
The "has" bit in python is set lazily. in your case, the "child" message is
initialized when the append() is called. A following remove() won't delete
the message.
If you want to allow the "child" to be the default instance, you can do one
of the following:
* change it to optional
* use SerializePartialToString()
* call p.child.SetInParent() # not recommended.
Note: if you do need the required field to be empty, you should consider
changing it to optional, which is a better design.