Python Generated Code explains most use-cases of protobuf map fields in Python but not how to copy one map to another.
Given simple map
message Src {
map<string, string> properties = 1;
...
}
message Dst {
map<string, string> properties = 1;
...
}
You cannot assign a value to an embedded message field, so there's no doing:
# Will not work.
dst = Dst()
dst.properties = src.properties
Nor is there an implementation of CopyFrom since map is not itself a message, it's a field within a message.
# Will not work.
dst = Dst()
dst.properties.CopyFrom(src.properties)
I also can't copy the entire message since I only want the map.
# Copies unwanted fields!
dst = Dst()
dst.CopyFrom(src)
I hope I don't have to iterate over all keys and assign one-by-one!
# Iterate over map keys
for key in src.properties:
dst.properties[key] = src.properties[key]
Map fields in python protobuf generated code operate pretty similarly to python dicts, so you can use .update() to copy over:
dst.properties.update(src.properties)
If the maps' values are simple types, dst.properties.update(src.properties)
should work. However, if you have a map with Message-type values, e.g.:
message Prop {
optional string value = 1;
optional bool is_public = 2;
}
message Src {
map<string, Prop> properties = 1;
...
}
message Dst {
map<string, Prop> properties = 1;
...
}
then .update
(or any type of direct assignment) will throw:
ValueError: Direct assignment of submessage not allowed
Instead, you'll have to do something like:
for k, v in src.properties.items():
dst.properties[k].CopyFrom(v)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With