On Wednesday, 12 April 2017 18:15:00 UTC+3, Tom Lichtenberg wrote:
>
> The original intention was to be able to do this with dynamically 
> discovered messages for which you have the as set of *_pb2.py objects but 
> don't know in advance which one you'll need to instantiate and set the 
> fields for
>
> assuming your **args contains keys and values for all of the required 
> fields in the protobuf object, you can use importlib to load the protobuf 
> message from the module, and use setattr to set each key-value pair
>
> obj = getattr(importlib.import_module(class_name), message_name)
> for descriptor in obj.DESCRIPTOR.fields:
>     print descriptor.name
>     setattr(obj, descriptor.name, args[descriptor.name])
>
>
>
> if the message contains fields that are themselves messages 
> (type=TYPE_MESSAGE) you need to instantiate the embedded message object 
> first and assign that created object to its corresponding key in the args 
> dict
>
> you'd need to do this for embedded messages all the way down - so you need 
> to fully parse the object, discover all the embedded messages, and build 
> your object from the bottom up
>
>
> On Friday, March 3, 2017 at 1:09:09 PM UTC-8, Tom Lichtenberg wrote:
>>
>> 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.id = 1
>> >> 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.
>>
>
if it's still interested for you AFAIK syntax = 2 required for dynamic 
protobufs

-- 
You received this message because you are subscribed to the Google Groups 
"Protocol Buffers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to protobuf+unsubscr...@googlegroups.com.
To post to this group, send email to protobuf@googlegroups.com.
Visit this group at https://groups.google.com/group/protobuf.
For more options, visit https://groups.google.com/d/optout.

Reply via email to