python enum values option

2,052 views
Skip to first unread message

Vsevolod Zadubrovsky

unread,
Nov 9, 2010, 7:12:16 AM11/9/10
to Protocol Buffers
Hi, I'm stuck with getting the enum value option in Python. The proto
file is:

import "descriptor.proto";

extend google.protobuf.EnumValueOptions {
optional string verbose_enum_value_option = 50005;
}

enum ErrorType {
OK = 1 [(verbose_enum_value_option) = "OK"];
SOME_ERROR = 2 [(verbose_enum_value_option) = "Some Error verbose
message"];
}

message Request {
required bool success = 1;
optional ErrorType error = 2;
}

When I receive the Request message, I can access the 'error' field,
and its type is int, that's actually ok. But how can I get the
verbose_enum_value_option of 'error' field value ?

Thanks

p.s. The goal is to keep error types and their verbose error messages
in one place, available for every service in our project, so the error
messages would've been identical.

Kenton Varda

unread,
Nov 9, 2010, 5:50:36 PM11/9/10
to Vsevolod Zadubrovsky, Protocol Buffers
You need to use the descriptor for the enum type.  Unfortunately this interface isn't very well fleshed-out in Python.  I think you'd have to write something like:

Request.DESCRIPTOR.fields_by_name['error'].enum_type.values_by_number[message.error].options.Extensions[verbose_enum_value_option]

I haven't checked that that's exactly correct, but it gives you an idea.  We should probably improve this.


--
You received this message because you are subscribed to the Google Groups "Protocol Buffers" group.
To post to this group, send email to prot...@googlegroups.com.
To unsubscribe from this group, send email to protobuf+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/protobuf?hl=en.


Vsevolod Zadubrovsky

unread,
Nov 10, 2010, 3:42:24 AM11/10/10
to Protocol Buffers
It seems to me, it doesn't work at all.

I got this:
>(Pdb) import ooo
>(Pdb) vals_by_nums = req.DESCRIPTOR.fields_by_name['error'].enum_type.values_by_number[req.error]
>(Pdb) options = vals_by_nums.GetOptions()
>(Pdb) options.Extensions[ooo.verbose_enum_value_option]
*** KeyError: 'Extension "verbose_enum_value_option" extends message
type "google.protobuf.EnumValueOptions", but this message is of type
"google.protobuf.EnumValueOptions".'

I've checked the source code, and it looks like raised from here
(google.protobuf.reflection, line 224):

if extension_handle.containing_type is not message.DESCRIPTOR:
raise KeyError('Extension "%s" extends message type "%s", but this
'
'message is of type "%s".' %
(extension_handle.full_name,
extension_handle.containing_type.full_name,
message.DESCRIPTOR.full_name))

Any ideas ? may be it is already solved in trunk version?

Thanks

On Nov 10, 1:50 am, Kenton Varda <ken...@google.com> wrote:
> You need to use the descriptor for the enum type.  Unfortunately this
> interface isn't very well fleshed-out in Python.  I think you'd have to
> write something like:
>
> Request.DESCRIPTOR.fields_by_name['error'].enum_type.values_by_number[message.error].options.Extensions[verbose_enum_value_option]
>
> I haven't checked that that's exactly correct, but it gives you an idea.  We
> should probably improve this.
>
> On Tue, Nov 9, 2010 at 4:12 AM, Vsevolod Zadubrovsky
> <zadubrov...@gmail.com>wrote:
>
> > Hi, I'm stuck with getting the enum value option in Python. The proto
> > file is:
>
> > import "descriptor.proto";
>
> > extend google.protobuf.EnumValueOptions {
> >  optional string verbose_enum_value_option = 50005;
> > }
>
> > enum ErrorType {
> >        OK = 1 [(verbose_enum_value_option) = "OK"];
> >        SOME_ERROR = 2 [(verbose_enum_value_option) = "Some Error verbose
> > message"];
> > }
>
> > message Request {
> >  required bool success = 1;
> >  optional ErrorType error = 2;
> > }
>
> > When I receive the Request message, I can access the 'error' field,
> > and its type is int, that's actually ok. But how can I get the
> > verbose_enum_value_option of 'error' field value ?
>
> > Thanks
>
> > p.s. The goal is to keep error types and their verbose error messages
> > in one place, available for every service in our project, so the error
> > messages would've been identical.
>
> > --
> > You received this message because you are subscribed to the Google Groups
> > "Protocol Buffers" group.
> > To post to this group, send email to prot...@googlegroups.com.
> > To unsubscribe from this group, send email to
> > protobuf+u...@googlegroups.com<protobuf%2Bunsu...@googlegroups.com>
> > .

Kenton Varda

unread,
Nov 16, 2010, 10:31:24 PM11/16/10
to Vsevolod Zadubrovsky, Protocol Buffers
That is strange.  Can you provide a minimal but complete program that reproduces this problem, so I can look at it?

To unsubscribe from this group, send email to protobuf+u...@googlegroups.com.

Kenton Varda

unread,
Nov 23, 2010, 10:54:21 PM11/23/10
to Vsevolod Zadubrovsky, Protocol Buffers
I see, the problem is that you've created a copy of descriptor.proto and are extending that rather than extending the original file.

To correctly extend descriptor.proto, you need to import it like:
  import "google/protobuf/descriptor.proto";

The path name is important, because it determines which module your generated code imports and extends.  You want it to import google.protobuf.descriptor_pb2 (which is included in the protobuf library), not your own local copy of descriptor_pb2.

Note that when you install protocol buffers, a copy of descriptor.proto is placed in $PREFIX/include/google/protobuf (where $PREFIX is usually /usr or /usr/local).  So you should invoke protoc like:

  protoc -I. -I/usr/include ooo.proto

This way ooo.proto will be able to import google/protobuf/descriptor.proto, which protoc will find in /usr/include.

On Thu, Nov 18, 2010 at 4:32 AM, Vsevolod Zadubrovsky <zadub...@gmail.com> wrote:
Kenton,

I didn't find how to attach file in the group discussion, so am replying to you directly.
In attach you will find the source proto file, the generated *pb2.py files, and the test program enum_test.py
I used: google protobuf 2.3.0 and proto compiler 2.3.0 win32 from here: http://code.google.com/p/protobuf/downloads/list

The test output is:

E:\projects\gpb>python enum_test.py
serialized request☺►☻:
Traceback (most recent call last):
  File "enum_test.py", line 13, in <module> ext = opts.Extensions[proto.verbose_enum_value_option]
  File "C:\Python27\lib\site-packages\protobuf-2.3.0-py2.7.egg\google\protobuf\reflection.py", line 1068, in __getitem__
    _VerifyExtensionHandle(self._extended_message, extension_handle)
  File "C:\Python27\lib\site-packages\protobuf-2.3.0-py2.7.egg\google\protobuf\reflection.py", line 229, in _VerifyExtensionHandle
    message.DESCRIPTOR.full_name))

KeyError: 'Extension "verbose_enum_value_option" extends message type "google.protobuf.EnumValueOptions", but this message is of type "google.protobuf.EnumValueOptions".'

Thnk you very much for support

2010/11/17 Kenton Varda <ken...@google.com>
Reply all
Reply to author
Forward
0 new messages