In protobuf 3 I can't get the fields in the message which are not empty. ListFields method doesn't work like it is described in the documentation. This problem appears when value in field equals default value. So, for example, I can't get boolean field through ListFields method if the value of field is False or integer field is 0 and so on. In protobuf 2 ListFields method works correct. Following example illustrates problem:
Protofile:
syntax = "proto3";
message TestMethodResponse{
int32 integer = 1;
string string = 2;
bool boolean = 3;
string empty = 4;
string nonempty = 5;
}
Python example:
import testservice_pb2
req = testservice_pb2.TestMethodResponse(
integer=1,
string='string',
boolean=True,
nonempty='nonempty'
)
print 'All is well:'
print [f[0].name for f in req.ListFields()]
req = testservice_pb2.TestMethodResponse(
integer=0,
string='',
boolean=False,
nonempty='nonempty'
)
print "Something's wrong:"
print [f[0].name for f in req.ListFields()]
Output:
>>> All is well:
>>> ['integer', 'string', 'boolean', 'nonempty']
>>> Something's wrong:
>>> ['nonempty']
This is working as intended. In proto3, a field with default value is equivalent to an unset field. That's why ListFields() doesn't include fields whose value is set to default.
Thank you for your reply. It is very strange behavior in proto3. Because It has no opportunity to distinguish between a field which are not set and a field whose value is set to default. In this case I think that the description of HasField and ListFields is not fully correct for proto3. The behavior of these methods is important for me and I will use proto2 for my aim. Thanks.
I have the same problem with proto3 and this strange behaviour. I am not able to distinguish between a field which is not set and a field where the default value has been assigned.
I want to check if the user has set the value and eventually to return back an error, asking the user to insert it. I am basically trying to implement required behaviour in my stack and outside the protobuffer but this seems apparently impossible.
This is really a strange behaviour! What is the work around in proto3 if I need to distinguish between a field that is not set and a field which has the value of default value !?
@farzadpanahi you can refer to the open source project 'protobuf_to_dict'
https://github.com/kaporzhu/protobuf-to-dict/blob/master/src/protobuf_to_dict.py
For googlers: This is what I was looking for:
https://stackoverflow.com/questions/24639562/getting-all-field-names-from-a-protocol-buffer/34921093
Most helpful comment
I have the same problem with proto3 and this strange behaviour. I am not able to distinguish between a field which is not set and a field where the default value has been assigned.
I want to check if the user has set the value and eventually to return back an error, asking the user to insert it. I am basically trying to implement required behaviour in my stack and outside the protobuffer but this seems apparently impossible.