Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access Protocol Buffers custom option in python?

I'm following instructions from Google Developers guide in order to create custom message option. I have used their example but I've received an error:

Traceback (most recent call last):
  File "test_my_opt.py", line 2, in <module>
    value = my_proto_file_pb2.MyMessage.DESCRIPTOR.GetOptions().Extensions[my_proto_file_pb2.my_option]
  File "(...)\google\protobuf\internal\python_message.py", line 1167, in __getitem__
    _VerifyExtensionHandle(self._extended_message, extension_handle)
  File "(...)\google\protobuf\internal\python_message.py", line 170, in _VerifyExtensionHandle
    message.DESCRIPTOR.full_name))
KeyError: 'Extension "my_option" extends message type "google.protobuf.MessageOptions", but this message is of type "google.protobuf.MessageOptions".'

I simply used following code:

import my_proto_file_pb2
value = my_proto_file_pb2.MyMessage.DESCRIPTOR.GetOptions().Extensions[my_proto_file_pb2.my_option]

And this proto file:

import "beans-protobuf/proto/src/descriptor.proto";

extend google.protobuf.MessageOptions {
  optional string my_option = 51234;
}

message MyMessage {
  option (my_option) = "Hello world!";
}

Everything like in guide... so how should I access this option without error?

like image 501
andrzejdoro Avatar asked Aug 04 '26 19:08

andrzejdoro


1 Answers

import "beans-protobuf/proto/src/descriptor.proto";

I think this is the problem. The correct import statement for descriptor.proto is:

import "google/protobuf/descriptor.proto";

The path string is important because you need to be extending the original definitions of the descriptor types, not some copy of them. google/protobuf/descriptor.proto becomes the module google.protobuf.descriptor_pb2 in Python, and the Protobuf library expects that any custom options are extensions to the types in there. But you are actually extending beans-protobuf/proto/src/descriptor.proto, which becomes beans_protobuf.proto.src.descriptor_pb2 in Python, which is a completely different module! Hence, the protobuf library gets confused and doesn't think these extensions are applicable to protobuf descriptors.

I think if you just change the import statement, everything should work. When protobuf is correctly installed, google/protobuf/descriptor.proto should always work as an import -- there's no need to provide your own copy of the file.

like image 198
Kenton Varda Avatar answered Aug 06 '26 09:08

Kenton Varda