31 """Contains container classes to represent different protocol buffer types.
33 This file defines container classes which represent categories of protocol
34 buffer field types which need extra maintenance. Currently these categories
36 - Repeated scalar fields - These are all repeated fields which aren't
37 composite (e.g. they are of simple types like int32, string, etc).
38 - Repeated composite fields - Repeated fields which are composite. This
39 includes groups and nested messages.
42 __author__ =
'petar@google.com (Petar Petrov)'
47 import collections.abc
as collections_abc
49 import collections
as collections_abc
51 if sys.version_info[0] < 3:
75 def get(self, key, default=None):
98 yield (key, self[key])
104 return [(key, self[key])
for key
in self]
107 return [self[key]
for key
in self]
113 if not isinstance(other, collections_abc.Mapping):
114 return NotImplemented
115 return dict(self.
items()) == dict(other.items())
118 return not (self == other)
125 def pop(self, key, default=__marker):
138 key =
next(iter(self))
139 except StopIteration:
154 raise TypeError(
"update() takes at most 2 positional "
155 "arguments ({} given)".format(
len(args)))
157 raise TypeError(
"update() takes at least 1 argument (0 given)")
159 other = args[1]
if len(args) >= 2
else ()
161 if isinstance(other, Mapping):
163 self[key] = other[key]
164 elif hasattr(other,
"keys"):
165 for key
in other.keys():
166 self[key] = other[key]
168 for key, value
in other:
170 for key, value
in kwds.items():
180 collections_abc.Mapping.register(Mapping)
181 collections_abc.MutableMapping.register(MutableMapping)
186 MutableMapping = collections_abc.MutableMapping
191 """Base container class."""
194 __slots__ = [
'_message_listener',
'_values']
199 message_listener: A MessageListener implementation.
200 The RepeatedScalarFieldContainer will call this object's
201 Modified() method when it is modified.
207 """Retrieves item by the specified key."""
211 """Returns the number of elements in the container."""
215 """Checks if another instance isn't equal to this one."""
217 return not self == other
220 raise TypeError(
'unhashable object')
225 def sort(self, *args, **kwargs):
229 if 'sort_function' in kwargs:
230 kwargs[
'cmp'] = kwargs.pop(
'sort_function')
233 collections_abc.MutableSequence.register(BaseContainer)
238 """Simple, type-checked, list-like container for holding repeated scalars."""
241 __slots__ = [
'_type_checker']
243 def __init__(self, message_listener, type_checker):
246 message_listener: A MessageListener implementation.
247 The RepeatedScalarFieldContainer will call this object's
248 Modified() method when it is modified.
249 type_checker: A type_checkers.ValueChecker instance to run on elements
250 inserted into this container.
252 super(RepeatedScalarFieldContainer, self).
__init__(message_listener)
256 """Appends an item to the list. Similar to list.append()."""
262 """Inserts the item at the specified position. Similar to list.insert()."""
268 """Extends by appending the given iterable. Similar to list.extend()."""
273 elem_seq_iter = iter(elem_seq)
281 new_values = [self.
_type_checker.CheckValue(elem)
for elem
in elem_seq_iter]
287 """Appends the contents of another repeated field of the same type to this
288 one. We do not check the types of the individual fields.
294 """Removes an item from the list. Similar to list.remove()."""
299 """Removes and returns an item at a given index. Similar to list.pop()."""
305 """Sets the item on the specified position."""
306 if isinstance(key, slice):
307 if key.step
is not None:
308 raise ValueError(
'Extended slices not supported')
315 """Retrieves the subset of items from between the specified indices."""
316 return self.
_values[start:stop]
319 """Sets the subset of items from between the specified indices."""
323 self.
_values[start:stop] = new_values
327 """Deletes the item at the specified position."""
332 """Deletes the subset of items from between the specified indices."""
337 """Compares the current instance with another one."""
341 if isinstance(other, self.__class__):
342 return other._values == self.
_values
349 """Simple, list-like container for holding repeated composite fields."""
352 __slots__ = [
'_message_descriptor']
354 def __init__(self, message_listener, message_descriptor):
356 Note that we pass in a descriptor instead of the generated directly,
357 since at the time we construct a _RepeatedCompositeFieldContainer we
358 haven't yet necessarily initialized the type that will be contained in the
362 message_listener: A MessageListener implementation.
363 The RepeatedCompositeFieldContainer will call this object's
364 Modified() method when it is modified.
365 message_descriptor: A Descriptor instance describing the protocol type
366 that should be present in this container. We'll use the
367 _concrete_class field of this descriptor when the client calls add().
369 super(RepeatedCompositeFieldContainer, self).
__init__(message_listener)
373 """Adds a new element at the end of the list and returns it. Keyword
374 arguments may be used to initialize the element.
384 """Appends one element by copying the message."""
387 new_element.CopyFrom(value)
393 """Inserts the item at the specified position by copying."""
396 new_element.CopyFrom(value)
402 """Extends by appending the given sequence of elements of the same type
403 as this one, copying each individual message.
408 for message
in elem_seq:
409 new_element = message_class()
410 new_element._SetListener(listener)
411 new_element.MergeFrom(message)
412 values.append(new_element)
416 """Appends the contents of another repeated field of the same type to this
417 one, copying each individual message.
419 self.
extend(other._values)
422 """Removes an item from the list. Similar to list.remove()."""
427 """Removes and returns an item at a given index. Similar to list.pop()."""
433 """Retrieves the subset of items from between the specified indices."""
434 return self.
_values[start:stop]
437 """Deletes the item at the specified position."""
442 """Deletes the subset of items from between the specified indices."""
447 """Compares the current instance with another one."""
450 if not isinstance(other, self.__class__):
451 raise TypeError(
'Can only compare repeated composite fields against '
452 'other repeated composite fields.')
458 """Simple, type-checked, dict-like container for holding repeated scalars."""
461 __slots__ = [
'_key_checker',
'_value_checker',
'_values',
'_message_listener',
464 def __init__(self, message_listener, key_checker, value_checker,
468 message_listener: A MessageListener implementation.
469 The ScalarMap will call this object's Modified() method when it
471 key_checker: A type_checkers.ValueChecker instance to run on keys
472 inserted into this container.
473 value_checker: A type_checkers.ValueChecker instance to run on values
474 inserted into this container.
475 entry_descriptor: The MessageDescriptor of a map entry: key and value.
501 def get(self, key, default=None):
510 self.
_values[checked_key] = checked_value
535 original[
None] =
None
548 """Simple, type-checked, dict-like container for with submessage values."""
551 __slots__ = [
'_key_checker',
'_values',
'_message_listener',
552 '_message_descriptor',
'_entry_descriptor']
554 def __init__(self, message_listener, message_descriptor, key_checker,
558 message_listener: A MessageListener implementation.
559 The ScalarMap will call this object's Modified() method when it
561 key_checker: A type_checkers.ValueChecker instance to run on keys
562 inserted into this container.
563 value_checker: A type_checkers.ValueChecker instance to run on values
564 inserted into this container.
565 entry_descriptor: The MessageDescriptor of a map entry: key and value.
580 self.
_values[key] = new_element
586 """get_or_create() is an alias for getitem (ie. map[key]).
589 key: The key to get or create in the map.
591 This is useful in cases where you want to be explicit that the call is
592 mutating the map. This can avoid lint errors for statements like this
593 that otherwise would appear to be pointless statements:
602 def get(self, key, default=None):
613 raise ValueError(
'May not set values directly, call my_map[key].foo = 5')
644 original[
None] =
None
657 """A parsed unknown field."""
660 __slots__ = [
'_field_number',
'_wire_type',
'_data']
678 self.
_data == other._data)
690 raise ValueError(
'UnknownField does not exist. '
691 'The parent message might be cleared.')
693 raise ValueError(
'UnknownField does not exist. '
694 'The parent message might be cleared.')
717 """UnknownField container"""
720 __slots__ = [
'_values']
727 raise ValueError(
'UnknownFields does not exist. '
728 'The parent message might be cleared.')
732 if index < 0
or index >= size:
733 raise IndexError(
'index %d out of range'.index)
742 raise ValueError(
'UnknownFields does not exist. '
743 'The parent message might be cleared.')
746 def _add(self, field_number, wire_type, data):
748 self.
_values.append(unknown_field)
752 for i
in range(
len(self)):
759 self.
_values.extend(other._values)
771 other_values = sorted(other._values)
772 return values == other_values
777 if isinstance(value._data, UnknownFieldSet):