Issue 278 in protobuf: SerializeToString fail if nested types all field is empty

328 views
Skip to first unread message

prot...@googlecode.com

unread,
Apr 25, 2011, 11:24:18 PM4/25/11
to prot...@googlegroups.com
Status: New
Owner: liuj...@google.com
Labels: Type-Defect Priority-Medium

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.


prot...@googlecode.com

unread,
Apr 26, 2011, 3:09:29 AM4/26/11
to prot...@googlegroups.com
Updates:
Status: WorkingAsIntended

Comment #1 on issue 278 by liuj...@google.com: SerializeToString fail if

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.

Reply all
Reply to author
Forward
0 new messages