aboutsummaryrefslogtreecommitdiff
path: root/python/google/protobuf/internal/containers.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/google/protobuf/internal/containers.py')
-rwxr-xr-xpython/google/protobuf/internal/containers.py33
1 files changed, 26 insertions, 7 deletions
diff --git a/python/google/protobuf/internal/containers.py b/python/google/protobuf/internal/containers.py
index 97cdd848..c6a3692a 100755
--- a/python/google/protobuf/internal/containers.py
+++ b/python/google/protobuf/internal/containers.py
@@ -275,7 +275,7 @@ class RepeatedScalarFieldContainer(BaseContainer):
new_values = [self._type_checker.CheckValue(elem) for elem in elem_seq_iter]
if new_values:
self._values.extend(new_values)
- self._message_listener.Modified()
+ self._message_listener.Modified()
def MergeFrom(self, other):
"""Appends the contents of another repeated field of the same type to this
@@ -436,9 +436,11 @@ class ScalarMap(MutableMapping):
"""Simple, type-checked, dict-like container for holding repeated scalars."""
# Disallows assignment to other attributes.
- __slots__ = ['_key_checker', '_value_checker', '_values', '_message_listener']
+ __slots__ = ['_key_checker', '_value_checker', '_values', '_message_listener',
+ '_entry_descriptor']
- def __init__(self, message_listener, key_checker, value_checker):
+ def __init__(self, message_listener, key_checker, value_checker,
+ entry_descriptor):
"""
Args:
message_listener: A MessageListener implementation.
@@ -448,10 +450,12 @@ class ScalarMap(MutableMapping):
inserted into this container.
value_checker: A type_checkers.ValueChecker instance to run on values
inserted into this container.
+ entry_descriptor: The MessageDescriptor of a map entry: key and value.
"""
self._message_listener = message_listener
self._key_checker = key_checker
self._value_checker = value_checker
+ self._entry_descriptor = entry_descriptor
self._values = {}
def __getitem__(self, key):
@@ -513,6 +517,9 @@ class ScalarMap(MutableMapping):
self._values.clear()
self._message_listener.Modified()
+ def GetEntryClass(self):
+ return self._entry_descriptor._concrete_class
+
class MessageMap(MutableMapping):
@@ -520,9 +527,10 @@ class MessageMap(MutableMapping):
# Disallows assignment to other attributes.
__slots__ = ['_key_checker', '_values', '_message_listener',
- '_message_descriptor']
+ '_message_descriptor', '_entry_descriptor']
- def __init__(self, message_listener, message_descriptor, key_checker):
+ def __init__(self, message_listener, message_descriptor, key_checker,
+ entry_descriptor):
"""
Args:
message_listener: A MessageListener implementation.
@@ -532,17 +540,19 @@ class MessageMap(MutableMapping):
inserted into this container.
value_checker: A type_checkers.ValueChecker instance to run on values
inserted into this container.
+ entry_descriptor: The MessageDescriptor of a map entry: key and value.
"""
self._message_listener = message_listener
self._message_descriptor = message_descriptor
self._key_checker = key_checker
+ self._entry_descriptor = entry_descriptor
self._values = {}
def __getitem__(self, key):
+ key = self._key_checker.CheckValue(key)
try:
return self._values[key]
except KeyError:
- key = self._key_checker.CheckValue(key)
new_element = self._message_descriptor._concrete_class()
new_element._SetListener(self._message_listener)
self._values[key] = new_element
@@ -574,12 +584,14 @@ class MessageMap(MutableMapping):
return default
def __contains__(self, item):
+ item = self._key_checker.CheckValue(item)
return item in self._values
def __setitem__(self, key, value):
raise ValueError('May not set values directly, call my_map[key].foo = 5')
def __delitem__(self, key):
+ key = self._key_checker.CheckValue(key)
del self._values[key]
self._message_listener.Modified()
@@ -594,7 +606,11 @@ class MessageMap(MutableMapping):
def MergeFrom(self, other):
for key in other:
- self[key].MergeFrom(other[key])
+ # According to documentation: "When parsing from the wire or when merging,
+ # if there are duplicate map keys the last key seen is used".
+ if key in self:
+ del self[key]
+ self[key].CopyFrom(other[key])
# self._message_listener.Modified() not required here, because
# mutations to submessages already propagate.
@@ -609,3 +625,6 @@ class MessageMap(MutableMapping):
def clear(self):
self._values.clear()
self._message_listener.Modified()
+
+ def GetEntryClass(self):
+ return self._entry_descriptor._concrete_class