Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

reserved keyword is used in protobuf in Python

In general, I have a protobuf definition which used a Python keyword "from". It works in Java/C#/C++, but when comes to Python, I could not assign value to it.

Here is the detail of my problem.

I have a protobuf definition like below:

message Foo
{
    required int64 from = 10
    ...
}

Since the field "from" is a keyword in Python, after I generated the python code, I could not compile the code as below:

foo = Foo()
foo.from = 1234

Then, I tried to use setattr() to set the attribute:

setattr(foo, 'from', 1234)

That gives me a Protobuf exception:

AttributeError: Assignment not allowed to composite field "from" in protocol message object.

I could not change the definition at this moment because it has been used widely in the system. Any help would be appreciated if I can workaround to use the "from" attribute in Python.

Below is the ProtoBuf generated code:

import sys


_FOO = _descriptor.Descriptor(
  name='Foo',
  full_name='com.kerneljoy.Foo',
  filename=None,
  file=DESCRIPTOR,
  containing_type=None,
  fields=[
    _descriptor.FieldDescriptor(
      name='from', full_name='com.kerneljoy.Foo.from', index=0,
      number=10, type=3, cpp_type=2, label=2,
      has_default_value=False, default_value=0,
      message_type=None, enum_type=None, containing_type=None,
      is_extension=False, extension_scope=None,
      options=None),
  ],
  extensions=[
  ],
  nested_types=[],
  enum_types=[
  ],
  options=None,
  is_extendable=False,
  extension_ranges=[],
  oneofs=[
  ],
  serialized_start=28,
  serialized_end=47,
)

DESCRIPTOR.message_types_by_name['Foo'] = _FOO

Foo = _reflection.GeneratedProtocolMessageType('Foo', (_message.Message,), dict(
  DESCRIPTOR = _FOO,
  __module__ = 'Foo_pb2'
  # @@protoc_insertion_point(class_scope:com.kerneljoy.Foo)
  ))
_sym_db.RegisterMessage(Foo)
like image 709
kerneljoy Avatar asked May 09 '15 17:05

kerneljoy


1 Answers

After couple attempts, I found the setattr() and getattr() can workaround this. Because in my production code, the 'from' refers to another protobuff definition. So the solution here is as below:

foo = Foo()
object = getattr(foo, 'from')
object.bar = 'value'
object.bar2 = 'value2'
like image 152
kerneljoy Avatar answered Oct 19 '22 13:10

kerneljoy