Protobuf: [Python] json_format.Parse unable to parse messages with `oneof`

Created on 15 Apr 2018  路  2Comments  路  Source: protocolbuffers/protobuf

(using 1.11.0 grpcio*)

syntax = "proto3";

message ReportData {
// ...
  oneof result {
    MyTestResults mytest = 100;
    // other kinds of tests to be added in the future
  }
}

message MyTestResults {
  repeated MyTestResult results = 1;

  enum Result {
    UNKNOWN = 0;
    POSITIVE = 1;
    NEGATIVE = 2;
  }

  Result result = 2;
}
In [1]: import report_pb2

In [3]: negative = report_pb2.ReportData()

In [4]: negative.mytest.CopyFrom(report_pb2.MyTestResults(result=report_pb2.MyTestResults.NEGATIVE))

In [6]: from google.protobuf import json_format as jf

In [7]: jf.Parse(jf.MessageToJson(negative), report_pb2.ReportData)
AttributeError: type object 'ReportData' has no attribute 'mytest'

In [8]: jf.ParseDict(jf.MessageToDict(negative), report_pb2.ReportData)
AttributeError: type object 'ReportData' has no attribute 'mytest'

In [9]: negative
Out[9]:
mytest {
  result: NEGATIVE
}
python

Most helpful comment

You should create a new message before parse:
new_message = report_pb2.ReportData()
jf.Parse(jf.MessageToJson(negative), new_message)

Closing this issue. Feel free to reopen if you still have questions

All 2 comments

text_format has a similar malady:

In [12]: from google.protobuf import text_format as tf

In [13]: tf.MessageToString(negative)
Out[13]: 'mytest {\n  result: NEGATIVE\n}\n'

In [14]: tf.Parse(tf.MessageToString(negative), report_pb2.ReportData)
    708         # Note that we ignore the case if the same field was set before, and we
    709         # apply _allow_multiple_scalars to non-scalar fields as well.
--> 710         which_oneof = message.WhichOneof(field.containing_oneof.name)
    711         if which_oneof is not None and which_oneof != field.name:
    712           raise tokenizer.ParseErrorPreviousToken(

TypeError: descriptor 'WhichOneof' requires a 'google.protobuf.pyext._message.CMessage' object but received a 'str'

Am I holding it wrong?

You should create a new message before parse:
new_message = report_pb2.ReportData()
jf.Parse(jf.MessageToJson(negative), new_message)

Closing this issue. Feel free to reopen if you still have questions

Was this page helpful?
0 / 5 - 0 ratings