I’m trying to dynamically create objects from discovery of pb2 generated protobuf files and assign appropriate values to their fields. If the field types are simple, this is straightforward - e.g. for TYPE_BOOL, setattr(obj, “field_name”, True) works fine - but if the field is TYPE_MESSAGE, making an instance of that field and using setattr(obj, “field_name”, instance) results in an error:
Assignment not allowed to composite field "task" in protocol message object.
from python2.7/site-packages/google/protobuf/internal/python_message.py", line 736, in setter
sample code: dummy/test_dummy.proto
============================
syntax = "proto3";
message task {
int32 id = 1;
string msg = 2;
}
message task_info {
task task = 1;
}
from this I used protoc to generate a test_dummy_pb2.py
For example, I want to create a task_info object, so by exploring the imported pb2 module, I find the task_info descriptor and create an instance of it. I see that its field ‘task’ is of TYPE_MESSAGE so I create an instance of that as well and call setattr(task_instance, “id”, 1) and setattr(task_instance, “msg”, “some message”) to populate it, and then go back and call setattr(task_info_instance, “task”, task_instance). Here I get the error: Assignment not allowed to composite field "task" in protocol message object.
programatically I can import this module and assign values well enough, for example in the python shell:
>> import importlib
>> oobj = importlib.import_module("dummy.dummy.test_dummy_pb2", package=None)
>> obj = getattr(oobj, "task_info")
>> task_info_instance = obj()
>> task_info_instance.task.msg = "some message"
>> print task_info_instance
task {
id: 1
msg: "some message"
}
But dynamically I can’t explicitly assign it like that. I would need something like a setattr() function that can set an object’s composite object field. I’m hoping that someone can shed some light on this for me.