Assign a Python object to a protobuf message, based on the Python type (in recursive fashion). Lists become repeated fields/messages, dicts become messages, and other types are assigned directly. For convenience, repeated fields whose values are not lists are converted to single-element
(proto, name, val)
| 54 | |
| 55 | |
| 56 | def assign_proto(proto, name, val): |
| 57 | """Assign a Python object to a protobuf message, based on the Python |
| 58 | type (in recursive fashion). Lists become repeated fields/messages, dicts |
| 59 | become messages, and other types are assigned directly. For convenience, |
| 60 | repeated fields whose values are not lists are converted to single-element |
| 61 | lists; e.g., `my_repeated_int_field=3` is converted to |
| 62 | `my_repeated_int_field=[3]`.""" |
| 63 | |
| 64 | is_repeated_field = hasattr(getattr(proto, name), 'extend') |
| 65 | if is_repeated_field and not isinstance(val, list): |
| 66 | val = [val] |
| 67 | if isinstance(val, list): |
| 68 | if isinstance(val[0], dict): |
| 69 | for item in val: |
| 70 | proto_item = getattr(proto, name).add() |
| 71 | for k, v in six.iteritems(item): |
| 72 | assign_proto(proto_item, k, v) |
| 73 | else: |
| 74 | getattr(proto, name).extend(val) |
| 75 | elif isinstance(val, dict): |
| 76 | for k, v in six.iteritems(val): |
| 77 | assign_proto(getattr(proto, name), k, v) |
| 78 | else: |
| 79 | setattr(proto, name, val) |
| 80 | |
| 81 | |
| 82 | class Top(object): |