Protocol message classes are almost always generated by the protocol
-compiler.
-These generated types subclass Message and implement the methods
-shown below.
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field AdminMessage.confirm_set_channel
var confirm_set_radio
-
Getter for confirm_set_radio.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field AdminMessage.confirm_set_radio
var exit_simulator
-
Getter for exit_simulator.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field AdminMessage.exit_simulator
var get_channel_request
-
Getter for get_channel_request.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field AdminMessage.get_channel_request
var get_channel_response
-
Getter for get_channel_response.
-
-
-Expand source code
-
-
def getter(self):
- field_value = self._fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
-
- # Atomically check if another thread has preempted us and, if not, swap
- # in the new object we just created. If someone has preempted us, we
- # take that object and discard ours.
- # WARNING: We are relying on setdefault() being atomic. This is true
- # in CPython but we haven't investigated others. This warning appears
- # in several other locations in this file.
- field_value = self._fields.setdefault(field, field_value)
- return field_value
-
+
Field AdminMessage.get_channel_response
var get_radio_request
-
Getter for get_radio_request.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field AdminMessage.get_radio_request
var get_radio_response
-
Getter for get_radio_response.
-
-
-Expand source code
-
-
def getter(self):
- field_value = self._fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
-
- # Atomically check if another thread has preempted us and, if not, swap
- # in the new object we just created. If someone has preempted us, we
- # take that object and discard ours.
- # WARNING: We are relying on setdefault() being atomic. This is true
- # in CPython but we haven't investigated others. This warning appears
- # in several other locations in this file.
- field_value = self._fields.setdefault(field, field_value)
- return field_value
-
+
Field AdminMessage.get_radio_response
var reboot_seconds
-
Getter for reboot_seconds.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field AdminMessage.reboot_seconds
var set_channel
-
Getter for set_channel.
-
-
-Expand source code
-
-
def getter(self):
- field_value = self._fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
-
- # Atomically check if another thread has preempted us and, if not, swap
- # in the new object we just created. If someone has preempted us, we
- # take that object and discard ours.
- # WARNING: We are relying on setdefault() being atomic. This is true
- # in CPython but we haven't investigated others. This warning appears
- # in several other locations in this file.
- field_value = self._fields.setdefault(field, field_value)
- return field_value
-
+
Field AdminMessage.set_channel
var set_owner
-
Getter for set_owner.
-
-
-Expand source code
-
-
def getter(self):
- field_value = self._fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
-
- # Atomically check if another thread has preempted us and, if not, swap
- # in the new object we just created. If someone has preempted us, we
- # take that object and discard ours.
- # WARNING: We are relying on setdefault() being atomic. This is true
- # in CPython but we haven't investigated others. This warning appears
- # in several other locations in this file.
- field_value = self._fields.setdefault(field, field_value)
- return field_value
-
+
Field AdminMessage.set_owner
var set_radio
-
Getter for set_radio.
-
-
-Expand source code
-
-
def getter(self):
- field_value = self._fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
-
- # Atomically check if another thread has preempted us and, if not, swap
- # in the new object we just created. If someone has preempted us, we
- # take that object and discard ours.
- # WARNING: We are relying on setdefault() being atomic. This is true
- # in CPython but we haven't investigated others. This warning appears
- # in several other locations in this file.
- field_value = self._fields.setdefault(field, field_value)
- return field_value
-
-
-
-
Methods
-
-
-def ByteSize(self)
-
-
-
-
-
-Expand source code
-
-
def ByteSize(self):
- if not self._cached_byte_size_dirty:
- return self._cached_byte_size
-
- size = 0
- descriptor = self.DESCRIPTOR
- if descriptor.GetOptions().map_entry:
- # Fields of map entry should always be serialized.
- size = descriptor.fields_by_name['key']._sizer(self.key)
- size += descriptor.fields_by_name['value']._sizer(self.value)
- else:
- for field_descriptor, field_value in self.ListFields():
- size += field_descriptor._sizer(field_value)
- for tag_bytes, value_bytes in self._unknown_fields:
- size += len(tag_bytes) + len(value_bytes)
-
- self._cached_byte_size = size
- self._cached_byte_size_dirty = False
- self._listener_for_children.dirty = False
- return size
def ClearField(self, field_name):
- try:
- field = message_descriptor.fields_by_name[field_name]
- except KeyError:
- try:
- field = message_descriptor.oneofs_by_name[field_name]
- if field in self._oneofs:
- field = self._oneofs[field]
- else:
- return
- except KeyError:
- raise ValueError('Protocol message %s has no "%s" field.' %
- (message_descriptor.name, field_name))
-
- if field in self._fields:
- # To match the C++ implementation, we need to invalidate iterators
- # for map fields when ClearField() happens.
- if hasattr(self._fields[field], 'InvalidateIterators'):
- self._fields[field].InvalidateIterators()
-
- # Note: If the field is a sub-message, its listener will still point
- # at us. That's fine, because the worst than can happen is that it
- # will call _Modified() and invalidate our byte size. Big deal.
- del self._fields[field]
-
- if self._oneofs.get(field.containing_oneof, None) is field:
- del self._oneofs[field.containing_oneof]
-
- # Always call _Modified() -- even if nothing was changed, this is
- # a mutating method, and thus calling it should cause the field to become
- # present in the parent message.
- self._Modified()
-
-
-
-def DiscardUnknownFields(self)
-
-
-
-
-
-Expand source code
-
-
def _DiscardUnknownFields(self):
- self._unknown_fields = []
- self._unknown_field_set = None # pylint: disable=protected-access
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if _IsMapField(field):
- if _IsMessageMapField(field):
- for key in value:
- value[key].DiscardUnknownFields()
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
- for sub_message in value:
- sub_message.DiscardUnknownFields()
- else:
- value.DiscardUnknownFields()
-
-
-
-def FindInitializationErrors(self)
-
-
-
Finds required fields which are not initialized.
-
Returns
-
A list of strings.
-Each string is a path to an uninitialized field from
-the top-level message, e.g. "foo.bar[5].baz".
-
-
-Expand source code
-
-
def FindInitializationErrors(self):
- """Finds required fields which are not initialized.
-
- Returns:
- A list of strings. Each string is a path to an uninitialized field from
- the top-level message, e.g. "foo.bar[5].baz".
- """
-
- errors = [] # simplify things
-
- for field in required_fields:
- if not self.HasField(field.name):
- errors.append(field.name)
-
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.is_extension:
- name = '(%s)' % field.full_name
- else:
- name = field.name
-
- if _IsMapField(field):
- if _IsMessageMapField(field):
- for key in value:
- element = value[key]
- prefix = '%s[%s].' % (name, key)
- sub_errors = element.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
- else:
- # ScalarMaps can't have any initialization errors.
- pass
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
- for i in range(len(value)):
- element = value[i]
- prefix = '%s[%d].' % (name, i)
- sub_errors = element.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
- else:
- prefix = name + '.'
- sub_errors = value.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
-
- return errors
-
-
-
-def HasField(self, field_name)
-
-
-
-
-
-Expand source code
-
-
def HasField(self, field_name):
- try:
- field = hassable_fields[field_name]
- except KeyError:
- raise ValueError(error_msg % (message_descriptor.full_name, field_name))
-
- if isinstance(field, descriptor_mod.OneofDescriptor):
- try:
- return HasField(self, self._oneofs[field].name)
- except KeyError:
- return False
- else:
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- value = self._fields.get(field)
- return value is not None and value._is_present_in_parent
- else:
- return field in self._fields
-
-
-
-def IsInitialized(self, errors=None)
-
-
-
Checks if all required fields of a message are set.
-
Args
-
-
errors
-
A list which, if provided, will be populated with the field
-paths of all missing required fields.
-
-
Returns
-
True iff the specified message has all required fields set.
-
-
-Expand source code
-
-
def IsInitialized(self, errors=None):
- """Checks if all required fields of a message are set.
-
- Args:
- errors: A list which, if provided, will be populated with the field
- paths of all missing required fields.
-
- Returns:
- True iff the specified message has all required fields set.
- """
-
- # Performance is critical so we avoid HasField() and ListFields().
-
- for field in required_fields:
- if (field not in self._fields or
- (field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE and
- not self._fields[field]._is_present_in_parent)):
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- for field, value in list(self._fields.items()): # dict can change size!
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.label == _FieldDescriptor.LABEL_REPEATED:
- if (field.message_type.has_options and
- field.message_type.GetOptions().map_entry):
- continue
- for element in value:
- if not element.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
- elif value._is_present_in_parent and not value.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- return True
-
-
-
-def ListFields(self)
-
-
-
-
-
-Expand source code
-
-
def ListFields(self):
- all_fields = [item for item in self._fields.items() if _IsPresent(item)]
- all_fields.sort(key = lambda item: item[0].number)
- return all_fields
-
-
-
-def MergeFrom(self, msg)
-
-
-
-
-
-Expand source code
-
-
def MergeFrom(self, msg):
- if not isinstance(msg, cls):
- raise TypeError(
- 'Parameter to MergeFrom() must be instance of same class: '
- 'expected %s got %s.' % (_FullyQualifiedClassName(cls),
- _FullyQualifiedClassName(msg.__class__)))
-
- assert msg is not self
- self._Modified()
-
- fields = self._fields
-
- for field, value in msg._fields.items():
- if field.label == LABEL_REPEATED:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- elif field.cpp_type == CPPTYPE_MESSAGE:
- if value._is_present_in_parent:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- else:
- self._fields[field] = value
- if field.containing_oneof:
- self._UpdateOneofState(field)
-
- if msg._unknown_fields:
- if not self._unknown_fields:
- self._unknown_fields = []
- self._unknown_fields.extend(msg._unknown_fields)
- # pylint: disable=protected-access
- if self._unknown_field_set is None:
- self._unknown_field_set = containers.UnknownFieldSet()
- self._unknown_field_set._extend(msg._unknown_field_set)
-
-
-
-def MergeFromString(self, serialized)
-
-
-
-
-
-Expand source code
-
-
def MergeFromString(self, serialized):
- serialized = memoryview(serialized)
- length = len(serialized)
- try:
- if self._InternalParse(serialized, 0, length) != length:
- # The only reason _InternalParse would return early is if it
- # encountered an end-group tag.
- raise message_mod.DecodeError('Unexpected end-group tag.')
- except (IndexError, TypeError):
- # Now ord(buf[p:p+1]) == ord('') gets TypeError.
- raise message_mod.DecodeError('Truncated message.')
- except struct.error as e:
- raise message_mod.DecodeError(e)
- return length # Return this for legacy reasons.
def SerializeToString(self, **kwargs):
- # Check if the message has all of its required fields set.
- if not self.IsInitialized():
- raise message_mod.EncodeError(
- 'Message %s is missing required fields: %s' % (
- self.DESCRIPTOR.full_name, ','.join(self.FindInitializationErrors())))
- return self.SerializePartialToString(**kwargs)
-
-
-
-def SetInParent(self)
-
-
-
Sets the _cached_byte_size_dirty bit to true,
-and propagates this to our listener iff this was a state change.
-
-
-Expand source code
-
-
def Modified(self):
- """Sets the _cached_byte_size_dirty bit to true,
- and propagates this to our listener iff this was a state change.
- """
-
- # Note: Some callers check _cached_byte_size_dirty before calling
- # _Modified() as an extra optimization. So, if this method is ever
- # changed such that it does stuff even when _cached_byte_size_dirty is
- # already true, the callers need to be updated.
- if not self._cached_byte_size_dirty:
- self._cached_byte_size_dirty = True
- self._listener_for_children.dirty = True
- self._is_present_in_parent = True
- self._listener.Modified()
Returns the name of the currently set field inside a oneof, or None.
-
-
-Expand source code
-
-
def WhichOneof(self, oneof_name):
- """Returns the name of the currently set field inside a oneof, or None."""
- try:
- field = message_descriptor.oneofs_by_name[oneof_name]
- except KeyError:
- raise ValueError(
- 'Protocol message has no oneof "%s" field.' % oneof_name)
-
- nested_field = self._oneofs.get(field, None)
- if nested_field is not None and self.HasField(nested_field.name):
- return nested_field.name
- else:
- return None
-
+
Field AdminMessage.set_radio
@@ -995,35 +306,7 @@ and propagates this to our listener iff this was a state change.
Protocol message classes are almost always generated by the protocol
-compiler.
-These generated types subclass Message and implement the methods
-shown below.
def getter(self):
- field_value = self._fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
-
- # Atomically check if another thread has preempted us and, if not, swap
- # in the new object we just created. If someone has preempted us, we
- # take that object and discard ours.
- # WARNING: We are relying on setdefault() being atomic. This is true
- # in CPython but we haven't investigated others. This warning appears
- # in several other locations in this file.
- field_value = self._fields.setdefault(field, field_value)
- return field_value
-
-
-
-
Methods
-
-
-def ByteSize(self)
-
-
-
-
-
-Expand source code
-
-
def ByteSize(self):
- if not self._cached_byte_size_dirty:
- return self._cached_byte_size
-
- size = 0
- descriptor = self.DESCRIPTOR
- if descriptor.GetOptions().map_entry:
- # Fields of map entry should always be serialized.
- size = descriptor.fields_by_name['key']._sizer(self.key)
- size += descriptor.fields_by_name['value']._sizer(self.value)
- else:
- for field_descriptor, field_value in self.ListFields():
- size += field_descriptor._sizer(field_value)
- for tag_bytes, value_bytes in self._unknown_fields:
- size += len(tag_bytes) + len(value_bytes)
-
- self._cached_byte_size = size
- self._cached_byte_size_dirty = False
- self._listener_for_children.dirty = False
- return size
def ClearField(self, field_name):
- try:
- field = message_descriptor.fields_by_name[field_name]
- except KeyError:
- try:
- field = message_descriptor.oneofs_by_name[field_name]
- if field in self._oneofs:
- field = self._oneofs[field]
- else:
- return
- except KeyError:
- raise ValueError('Protocol message %s has no "%s" field.' %
- (message_descriptor.name, field_name))
-
- if field in self._fields:
- # To match the C++ implementation, we need to invalidate iterators
- # for map fields when ClearField() happens.
- if hasattr(self._fields[field], 'InvalidateIterators'):
- self._fields[field].InvalidateIterators()
-
- # Note: If the field is a sub-message, its listener will still point
- # at us. That's fine, because the worst than can happen is that it
- # will call _Modified() and invalidate our byte size. Big deal.
- del self._fields[field]
-
- if self._oneofs.get(field.containing_oneof, None) is field:
- del self._oneofs[field.containing_oneof]
-
- # Always call _Modified() -- even if nothing was changed, this is
- # a mutating method, and thus calling it should cause the field to become
- # present in the parent message.
- self._Modified()
-
-
-
-def DiscardUnknownFields(self)
-
-
-
-
-
-Expand source code
-
-
def _DiscardUnknownFields(self):
- self._unknown_fields = []
- self._unknown_field_set = None # pylint: disable=protected-access
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if _IsMapField(field):
- if _IsMessageMapField(field):
- for key in value:
- value[key].DiscardUnknownFields()
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
- for sub_message in value:
- sub_message.DiscardUnknownFields()
- else:
- value.DiscardUnknownFields()
-
-
-
-def FindInitializationErrors(self)
-
-
-
Finds required fields which are not initialized.
-
Returns
-
A list of strings.
-Each string is a path to an uninitialized field from
-the top-level message, e.g. "foo.bar[5].baz".
-
-
-Expand source code
-
-
def FindInitializationErrors(self):
- """Finds required fields which are not initialized.
-
- Returns:
- A list of strings. Each string is a path to an uninitialized field from
- the top-level message, e.g. "foo.bar[5].baz".
- """
-
- errors = [] # simplify things
-
- for field in required_fields:
- if not self.HasField(field.name):
- errors.append(field.name)
-
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.is_extension:
- name = '(%s)' % field.full_name
- else:
- name = field.name
-
- if _IsMapField(field):
- if _IsMessageMapField(field):
- for key in value:
- element = value[key]
- prefix = '%s[%s].' % (name, key)
- sub_errors = element.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
- else:
- # ScalarMaps can't have any initialization errors.
- pass
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
- for i in range(len(value)):
- element = value[i]
- prefix = '%s[%d].' % (name, i)
- sub_errors = element.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
- else:
- prefix = name + '.'
- sub_errors = value.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
-
- return errors
-
-
-
-def HasField(self, field_name)
-
-
-
-
-
-Expand source code
-
-
def HasField(self, field_name):
- try:
- field = hassable_fields[field_name]
- except KeyError:
- raise ValueError(error_msg % (message_descriptor.full_name, field_name))
-
- if isinstance(field, descriptor_mod.OneofDescriptor):
- try:
- return HasField(self, self._oneofs[field].name)
- except KeyError:
- return False
- else:
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- value = self._fields.get(field)
- return value is not None and value._is_present_in_parent
- else:
- return field in self._fields
-
-
-
-def IsInitialized(self, errors=None)
-
-
-
Checks if all required fields of a message are set.
-
Args
-
-
errors
-
A list which, if provided, will be populated with the field
-paths of all missing required fields.
-
-
Returns
-
True iff the specified message has all required fields set.
-
-
-Expand source code
-
-
def IsInitialized(self, errors=None):
- """Checks if all required fields of a message are set.
-
- Args:
- errors: A list which, if provided, will be populated with the field
- paths of all missing required fields.
-
- Returns:
- True iff the specified message has all required fields set.
- """
-
- # Performance is critical so we avoid HasField() and ListFields().
-
- for field in required_fields:
- if (field not in self._fields or
- (field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE and
- not self._fields[field]._is_present_in_parent)):
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- for field, value in list(self._fields.items()): # dict can change size!
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.label == _FieldDescriptor.LABEL_REPEATED:
- if (field.message_type.has_options and
- field.message_type.GetOptions().map_entry):
- continue
- for element in value:
- if not element.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
- elif value._is_present_in_parent and not value.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- return True
-
-
-
-def ListFields(self)
-
-
-
-
-
-Expand source code
-
-
def ListFields(self):
- all_fields = [item for item in self._fields.items() if _IsPresent(item)]
- all_fields.sort(key = lambda item: item[0].number)
- return all_fields
-
-
-
-def MergeFrom(self, msg)
-
-
-
-
-
-Expand source code
-
-
def MergeFrom(self, msg):
- if not isinstance(msg, cls):
- raise TypeError(
- 'Parameter to MergeFrom() must be instance of same class: '
- 'expected %s got %s.' % (_FullyQualifiedClassName(cls),
- _FullyQualifiedClassName(msg.__class__)))
-
- assert msg is not self
- self._Modified()
-
- fields = self._fields
-
- for field, value in msg._fields.items():
- if field.label == LABEL_REPEATED:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- elif field.cpp_type == CPPTYPE_MESSAGE:
- if value._is_present_in_parent:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- else:
- self._fields[field] = value
- if field.containing_oneof:
- self._UpdateOneofState(field)
-
- if msg._unknown_fields:
- if not self._unknown_fields:
- self._unknown_fields = []
- self._unknown_fields.extend(msg._unknown_fields)
- # pylint: disable=protected-access
- if self._unknown_field_set is None:
- self._unknown_field_set = containers.UnknownFieldSet()
- self._unknown_field_set._extend(msg._unknown_field_set)
-
-
-
-def MergeFromString(self, serialized)
-
-
-
-
-
-Expand source code
-
-
def MergeFromString(self, serialized):
- serialized = memoryview(serialized)
- length = len(serialized)
- try:
- if self._InternalParse(serialized, 0, length) != length:
- # The only reason _InternalParse would return early is if it
- # encountered an end-group tag.
- raise message_mod.DecodeError('Unexpected end-group tag.')
- except (IndexError, TypeError):
- # Now ord(buf[p:p+1]) == ord('') gets TypeError.
- raise message_mod.DecodeError('Truncated message.')
- except struct.error as e:
- raise message_mod.DecodeError(e)
- return length # Return this for legacy reasons.
def SerializeToString(self, **kwargs):
- # Check if the message has all of its required fields set.
- if not self.IsInitialized():
- raise message_mod.EncodeError(
- 'Message %s is missing required fields: %s' % (
- self.DESCRIPTOR.full_name, ','.join(self.FindInitializationErrors())))
- return self.SerializePartialToString(**kwargs)
-
-
-
-def SetInParent(self)
-
-
-
Sets the _cached_byte_size_dirty bit to true,
-and propagates this to our listener iff this was a state change.
-
-
-Expand source code
-
-
def Modified(self):
- """Sets the _cached_byte_size_dirty bit to true,
- and propagates this to our listener iff this was a state change.
- """
-
- # Note: Some callers check _cached_byte_size_dirty before calling
- # _Modified() as an extra optimization. So, if this method is ever
- # changed such that it does stuff even when _cached_byte_size_dirty is
- # already true, the callers need to be updated.
- if not self._cached_byte_size_dirty:
- self._cached_byte_size_dirty = True
- self._listener_for_children.dirty = True
- self._is_present_in_parent = True
- self._listener.Modified()
Returns the name of the currently set field inside a oneof, or None.
-
-
-Expand source code
-
-
def WhichOneof(self, oneof_name):
- """Returns the name of the currently set field inside a oneof, or None."""
- try:
- field = message_descriptor.oneofs_by_name[oneof_name]
- except KeyError:
- raise ValueError(
- 'Protocol message has no oneof "%s" field.' % oneof_name)
-
- nested_field = self._oneofs.get(field, None)
- if nested_field is not None and self.HasField(nested_field.name):
- return nested_field.name
- else:
- return None
-
+
Field ChannelSet.settings
@@ -673,25 +154,7 @@ and propagates this to our listener iff this was a state change.
Protocol message classes are almost always generated by the protocol
-compiler.
-These generated types subclass Message and implement the methods
-shown below.
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field Channel.index
var role
-
Getter for role.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field Channel.role
var settings
-
Getter for settings.
-
-
-Expand source code
-
-
def getter(self):
- field_value = self._fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
-
- # Atomically check if another thread has preempted us and, if not, swap
- # in the new object we just created. If someone has preempted us, we
- # take that object and discard ours.
- # WARNING: We are relying on setdefault() being atomic. This is true
- # in CPython but we haven't investigated others. This warning appears
- # in several other locations in this file.
- field_value = self._fields.setdefault(field, field_value)
- return field_value
-
-
-
-
Methods
-
-
-def ByteSize(self)
-
-
-
-
-
-Expand source code
-
-
def ByteSize(self):
- if not self._cached_byte_size_dirty:
- return self._cached_byte_size
-
- size = 0
- descriptor = self.DESCRIPTOR
- if descriptor.GetOptions().map_entry:
- # Fields of map entry should always be serialized.
- size = descriptor.fields_by_name['key']._sizer(self.key)
- size += descriptor.fields_by_name['value']._sizer(self.value)
- else:
- for field_descriptor, field_value in self.ListFields():
- size += field_descriptor._sizer(field_value)
- for tag_bytes, value_bytes in self._unknown_fields:
- size += len(tag_bytes) + len(value_bytes)
-
- self._cached_byte_size = size
- self._cached_byte_size_dirty = False
- self._listener_for_children.dirty = False
- return size
def ClearField(self, field_name):
- try:
- field = message_descriptor.fields_by_name[field_name]
- except KeyError:
- try:
- field = message_descriptor.oneofs_by_name[field_name]
- if field in self._oneofs:
- field = self._oneofs[field]
- else:
- return
- except KeyError:
- raise ValueError('Protocol message %s has no "%s" field.' %
- (message_descriptor.name, field_name))
-
- if field in self._fields:
- # To match the C++ implementation, we need to invalidate iterators
- # for map fields when ClearField() happens.
- if hasattr(self._fields[field], 'InvalidateIterators'):
- self._fields[field].InvalidateIterators()
-
- # Note: If the field is a sub-message, its listener will still point
- # at us. That's fine, because the worst than can happen is that it
- # will call _Modified() and invalidate our byte size. Big deal.
- del self._fields[field]
-
- if self._oneofs.get(field.containing_oneof, None) is field:
- del self._oneofs[field.containing_oneof]
-
- # Always call _Modified() -- even if nothing was changed, this is
- # a mutating method, and thus calling it should cause the field to become
- # present in the parent message.
- self._Modified()
-
-
-
-def DiscardUnknownFields(self)
-
-
-
-
-
-Expand source code
-
-
def _DiscardUnknownFields(self):
- self._unknown_fields = []
- self._unknown_field_set = None # pylint: disable=protected-access
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if _IsMapField(field):
- if _IsMessageMapField(field):
- for key in value:
- value[key].DiscardUnknownFields()
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
- for sub_message in value:
- sub_message.DiscardUnknownFields()
- else:
- value.DiscardUnknownFields()
-
-
-
-def FindInitializationErrors(self)
-
-
-
Finds required fields which are not initialized.
-
Returns
-
A list of strings.
-Each string is a path to an uninitialized field from
-the top-level message, e.g. "foo.bar[5].baz".
-
-
-Expand source code
-
-
def FindInitializationErrors(self):
- """Finds required fields which are not initialized.
-
- Returns:
- A list of strings. Each string is a path to an uninitialized field from
- the top-level message, e.g. "foo.bar[5].baz".
- """
-
- errors = [] # simplify things
-
- for field in required_fields:
- if not self.HasField(field.name):
- errors.append(field.name)
-
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.is_extension:
- name = '(%s)' % field.full_name
- else:
- name = field.name
-
- if _IsMapField(field):
- if _IsMessageMapField(field):
- for key in value:
- element = value[key]
- prefix = '%s[%s].' % (name, key)
- sub_errors = element.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
- else:
- # ScalarMaps can't have any initialization errors.
- pass
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
- for i in range(len(value)):
- element = value[i]
- prefix = '%s[%d].' % (name, i)
- sub_errors = element.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
- else:
- prefix = name + '.'
- sub_errors = value.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
-
- return errors
-
-
-
-def HasField(self, field_name)
-
-
-
-
-
-Expand source code
-
-
def HasField(self, field_name):
- try:
- field = hassable_fields[field_name]
- except KeyError:
- raise ValueError(error_msg % (message_descriptor.full_name, field_name))
-
- if isinstance(field, descriptor_mod.OneofDescriptor):
- try:
- return HasField(self, self._oneofs[field].name)
- except KeyError:
- return False
- else:
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- value = self._fields.get(field)
- return value is not None and value._is_present_in_parent
- else:
- return field in self._fields
-
-
-
-def IsInitialized(self, errors=None)
-
-
-
Checks if all required fields of a message are set.
-
Args
-
-
errors
-
A list which, if provided, will be populated with the field
-paths of all missing required fields.
-
-
Returns
-
True iff the specified message has all required fields set.
-
-
-Expand source code
-
-
def IsInitialized(self, errors=None):
- """Checks if all required fields of a message are set.
-
- Args:
- errors: A list which, if provided, will be populated with the field
- paths of all missing required fields.
-
- Returns:
- True iff the specified message has all required fields set.
- """
-
- # Performance is critical so we avoid HasField() and ListFields().
-
- for field in required_fields:
- if (field not in self._fields or
- (field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE and
- not self._fields[field]._is_present_in_parent)):
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- for field, value in list(self._fields.items()): # dict can change size!
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.label == _FieldDescriptor.LABEL_REPEATED:
- if (field.message_type.has_options and
- field.message_type.GetOptions().map_entry):
- continue
- for element in value:
- if not element.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
- elif value._is_present_in_parent and not value.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- return True
-
-
-
-def ListFields(self)
-
-
-
-
-
-Expand source code
-
-
def ListFields(self):
- all_fields = [item for item in self._fields.items() if _IsPresent(item)]
- all_fields.sort(key = lambda item: item[0].number)
- return all_fields
-
-
-
-def MergeFrom(self, msg)
-
-
-
-
-
-Expand source code
-
-
def MergeFrom(self, msg):
- if not isinstance(msg, cls):
- raise TypeError(
- 'Parameter to MergeFrom() must be instance of same class: '
- 'expected %s got %s.' % (_FullyQualifiedClassName(cls),
- _FullyQualifiedClassName(msg.__class__)))
-
- assert msg is not self
- self._Modified()
-
- fields = self._fields
-
- for field, value in msg._fields.items():
- if field.label == LABEL_REPEATED:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- elif field.cpp_type == CPPTYPE_MESSAGE:
- if value._is_present_in_parent:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- else:
- self._fields[field] = value
- if field.containing_oneof:
- self._UpdateOneofState(field)
-
- if msg._unknown_fields:
- if not self._unknown_fields:
- self._unknown_fields = []
- self._unknown_fields.extend(msg._unknown_fields)
- # pylint: disable=protected-access
- if self._unknown_field_set is None:
- self._unknown_field_set = containers.UnknownFieldSet()
- self._unknown_field_set._extend(msg._unknown_field_set)
-
-
-
-def MergeFromString(self, serialized)
-
-
-
-
-
-Expand source code
-
-
def MergeFromString(self, serialized):
- serialized = memoryview(serialized)
- length = len(serialized)
- try:
- if self._InternalParse(serialized, 0, length) != length:
- # The only reason _InternalParse would return early is if it
- # encountered an end-group tag.
- raise message_mod.DecodeError('Unexpected end-group tag.')
- except (IndexError, TypeError):
- # Now ord(buf[p:p+1]) == ord('') gets TypeError.
- raise message_mod.DecodeError('Truncated message.')
- except struct.error as e:
- raise message_mod.DecodeError(e)
- return length # Return this for legacy reasons.
def SerializeToString(self, **kwargs):
- # Check if the message has all of its required fields set.
- if not self.IsInitialized():
- raise message_mod.EncodeError(
- 'Message %s is missing required fields: %s' % (
- self.DESCRIPTOR.full_name, ','.join(self.FindInitializationErrors())))
- return self.SerializePartialToString(**kwargs)
-
-
-
-def SetInParent(self)
-
-
-
Sets the _cached_byte_size_dirty bit to true,
-and propagates this to our listener iff this was a state change.
-
-
-Expand source code
-
-
def Modified(self):
- """Sets the _cached_byte_size_dirty bit to true,
- and propagates this to our listener iff this was a state change.
- """
-
- # Note: Some callers check _cached_byte_size_dirty before calling
- # _Modified() as an extra optimization. So, if this method is ever
- # changed such that it does stuff even when _cached_byte_size_dirty is
- # already true, the callers need to be updated.
- if not self._cached_byte_size_dirty:
- self._cached_byte_size_dirty = True
- self._listener_for_children.dirty = True
- self._is_present_in_parent = True
- self._listener.Modified()
Returns the name of the currently set field inside a oneof, or None.
-
-
-Expand source code
-
-
def WhichOneof(self, oneof_name):
- """Returns the name of the currently set field inside a oneof, or None."""
- try:
- field = message_descriptor.oneofs_by_name[oneof_name]
- except KeyError:
- raise ValueError(
- 'Protocol message has no oneof "%s" field.' % oneof_name)
-
- nested_field = self._oneofs.get(field, None)
- if nested_field is not None and self.HasField(nested_field.name):
- return nested_field.name
- else:
- return None
-
+
Field Channel.settings
class ChannelSettings
-(**kwargs)
+(*args, **kwargs)
-
Abstract base class for protocol messages.
-
Protocol message classes are almost always generated by the protocol
-compiler.
-These generated types subclass Message and implement the methods
-shown below.
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field ChannelSettings.bandwidth
var channel_num
-
Getter for channel_num.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field ChannelSettings.channel_num
var coding_rate
-
Getter for coding_rate.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field ChannelSettings.coding_rate
var downlink_enabled
-
Getter for downlink_enabled.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field ChannelSettings.downlink_enabled
var id
-
Getter for id.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field ChannelSettings.id
var modem_config
-
Getter for modem_config.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field ChannelSettings.modem_config
var name
-
Getter for name.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field ChannelSettings.name
var psk
-
Getter for psk.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field ChannelSettings.psk
var spread_factor
-
Getter for spread_factor.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field ChannelSettings.spread_factor
var tx_power
-
Getter for tx_power.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field ChannelSettings.tx_power
var uplink_enabled
-
Getter for uplink_enabled.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
-
-
-
Methods
-
-
-def ByteSize(self)
-
-
-
-
-
-Expand source code
-
-
def ByteSize(self):
- if not self._cached_byte_size_dirty:
- return self._cached_byte_size
-
- size = 0
- descriptor = self.DESCRIPTOR
- if descriptor.GetOptions().map_entry:
- # Fields of map entry should always be serialized.
- size = descriptor.fields_by_name['key']._sizer(self.key)
- size += descriptor.fields_by_name['value']._sizer(self.value)
- else:
- for field_descriptor, field_value in self.ListFields():
- size += field_descriptor._sizer(field_value)
- for tag_bytes, value_bytes in self._unknown_fields:
- size += len(tag_bytes) + len(value_bytes)
-
- self._cached_byte_size = size
- self._cached_byte_size_dirty = False
- self._listener_for_children.dirty = False
- return size
def ClearField(self, field_name):
- try:
- field = message_descriptor.fields_by_name[field_name]
- except KeyError:
- try:
- field = message_descriptor.oneofs_by_name[field_name]
- if field in self._oneofs:
- field = self._oneofs[field]
- else:
- return
- except KeyError:
- raise ValueError('Protocol message %s has no "%s" field.' %
- (message_descriptor.name, field_name))
-
- if field in self._fields:
- # To match the C++ implementation, we need to invalidate iterators
- # for map fields when ClearField() happens.
- if hasattr(self._fields[field], 'InvalidateIterators'):
- self._fields[field].InvalidateIterators()
-
- # Note: If the field is a sub-message, its listener will still point
- # at us. That's fine, because the worst than can happen is that it
- # will call _Modified() and invalidate our byte size. Big deal.
- del self._fields[field]
-
- if self._oneofs.get(field.containing_oneof, None) is field:
- del self._oneofs[field.containing_oneof]
-
- # Always call _Modified() -- even if nothing was changed, this is
- # a mutating method, and thus calling it should cause the field to become
- # present in the parent message.
- self._Modified()
-
-
-
-def DiscardUnknownFields(self)
-
-
-
-
-
-Expand source code
-
-
def _DiscardUnknownFields(self):
- self._unknown_fields = []
- self._unknown_field_set = None # pylint: disable=protected-access
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if _IsMapField(field):
- if _IsMessageMapField(field):
- for key in value:
- value[key].DiscardUnknownFields()
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
- for sub_message in value:
- sub_message.DiscardUnknownFields()
- else:
- value.DiscardUnknownFields()
-
-
-
-def FindInitializationErrors(self)
-
-
-
Finds required fields which are not initialized.
-
Returns
-
A list of strings.
-Each string is a path to an uninitialized field from
-the top-level message, e.g. "foo.bar[5].baz".
-
-
-Expand source code
-
-
def FindInitializationErrors(self):
- """Finds required fields which are not initialized.
-
- Returns:
- A list of strings. Each string is a path to an uninitialized field from
- the top-level message, e.g. "foo.bar[5].baz".
- """
-
- errors = [] # simplify things
-
- for field in required_fields:
- if not self.HasField(field.name):
- errors.append(field.name)
-
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.is_extension:
- name = '(%s)' % field.full_name
- else:
- name = field.name
-
- if _IsMapField(field):
- if _IsMessageMapField(field):
- for key in value:
- element = value[key]
- prefix = '%s[%s].' % (name, key)
- sub_errors = element.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
- else:
- # ScalarMaps can't have any initialization errors.
- pass
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
- for i in range(len(value)):
- element = value[i]
- prefix = '%s[%d].' % (name, i)
- sub_errors = element.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
- else:
- prefix = name + '.'
- sub_errors = value.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
-
- return errors
-
-
-
-def HasField(self, field_name)
-
-
-
-
-
-Expand source code
-
-
def HasField(self, field_name):
- try:
- field = hassable_fields[field_name]
- except KeyError:
- raise ValueError(error_msg % (message_descriptor.full_name, field_name))
-
- if isinstance(field, descriptor_mod.OneofDescriptor):
- try:
- return HasField(self, self._oneofs[field].name)
- except KeyError:
- return False
- else:
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- value = self._fields.get(field)
- return value is not None and value._is_present_in_parent
- else:
- return field in self._fields
-
-
-
-def IsInitialized(self, errors=None)
-
-
-
Checks if all required fields of a message are set.
-
Args
-
-
errors
-
A list which, if provided, will be populated with the field
-paths of all missing required fields.
-
-
Returns
-
True iff the specified message has all required fields set.
-
-
-Expand source code
-
-
def IsInitialized(self, errors=None):
- """Checks if all required fields of a message are set.
-
- Args:
- errors: A list which, if provided, will be populated with the field
- paths of all missing required fields.
-
- Returns:
- True iff the specified message has all required fields set.
- """
-
- # Performance is critical so we avoid HasField() and ListFields().
-
- for field in required_fields:
- if (field not in self._fields or
- (field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE and
- not self._fields[field]._is_present_in_parent)):
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- for field, value in list(self._fields.items()): # dict can change size!
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.label == _FieldDescriptor.LABEL_REPEATED:
- if (field.message_type.has_options and
- field.message_type.GetOptions().map_entry):
- continue
- for element in value:
- if not element.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
- elif value._is_present_in_parent and not value.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- return True
-
-
-
-def ListFields(self)
-
-
-
-
-
-Expand source code
-
-
def ListFields(self):
- all_fields = [item for item in self._fields.items() if _IsPresent(item)]
- all_fields.sort(key = lambda item: item[0].number)
- return all_fields
-
-
-
-def MergeFrom(self, msg)
-
-
-
-
-
-Expand source code
-
-
def MergeFrom(self, msg):
- if not isinstance(msg, cls):
- raise TypeError(
- 'Parameter to MergeFrom() must be instance of same class: '
- 'expected %s got %s.' % (_FullyQualifiedClassName(cls),
- _FullyQualifiedClassName(msg.__class__)))
-
- assert msg is not self
- self._Modified()
-
- fields = self._fields
-
- for field, value in msg._fields.items():
- if field.label == LABEL_REPEATED:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- elif field.cpp_type == CPPTYPE_MESSAGE:
- if value._is_present_in_parent:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- else:
- self._fields[field] = value
- if field.containing_oneof:
- self._UpdateOneofState(field)
-
- if msg._unknown_fields:
- if not self._unknown_fields:
- self._unknown_fields = []
- self._unknown_fields.extend(msg._unknown_fields)
- # pylint: disable=protected-access
- if self._unknown_field_set is None:
- self._unknown_field_set = containers.UnknownFieldSet()
- self._unknown_field_set._extend(msg._unknown_field_set)
-
-
-
-def MergeFromString(self, serialized)
-
-
-
-
-
-Expand source code
-
-
def MergeFromString(self, serialized):
- serialized = memoryview(serialized)
- length = len(serialized)
- try:
- if self._InternalParse(serialized, 0, length) != length:
- # The only reason _InternalParse would return early is if it
- # encountered an end-group tag.
- raise message_mod.DecodeError('Unexpected end-group tag.')
- except (IndexError, TypeError):
- # Now ord(buf[p:p+1]) == ord('') gets TypeError.
- raise message_mod.DecodeError('Truncated message.')
- except struct.error as e:
- raise message_mod.DecodeError(e)
- return length # Return this for legacy reasons.
def SerializeToString(self, **kwargs):
- # Check if the message has all of its required fields set.
- if not self.IsInitialized():
- raise message_mod.EncodeError(
- 'Message %s is missing required fields: %s' % (
- self.DESCRIPTOR.full_name, ','.join(self.FindInitializationErrors())))
- return self.SerializePartialToString(**kwargs)
-
-
-
-def SetInParent(self)
-
-
-
Sets the _cached_byte_size_dirty bit to true,
-and propagates this to our listener iff this was a state change.
-
-
-Expand source code
-
-
def Modified(self):
- """Sets the _cached_byte_size_dirty bit to true,
- and propagates this to our listener iff this was a state change.
- """
-
- # Note: Some callers check _cached_byte_size_dirty before calling
- # _Modified() as an extra optimization. So, if this method is ever
- # changed such that it does stuff even when _cached_byte_size_dirty is
- # already true, the callers need to be updated.
- if not self._cached_byte_size_dirty:
- self._cached_byte_size_dirty = True
- self._listener_for_children.dirty = True
- self._is_present_in_parent = True
- self._listener.Modified()
Returns the name of the currently set field inside a oneof, or None.
-
-
-Expand source code
-
-
def WhichOneof(self, oneof_name):
- """Returns the name of the currently set field inside a oneof, or None."""
- try:
- field = message_descriptor.oneofs_by_name[oneof_name]
- except KeyError:
- raise ValueError(
- 'Protocol message has no oneof "%s" field.' % oneof_name)
-
- nested_field = self._oneofs.get(field, None)
- if nested_field is not None and self.HasField(nested_field.name):
- return nested_field.name
- else:
- return None
-
+
Field ChannelSettings.uplink_enabled
@@ -1646,32 +462,12 @@ and propagates this to our listener iff this was a state change.
Protocol message classes are almost always generated by the protocol
-compiler.
-These generated types subclass Message and implement the methods
-shown below.
def getter(self):
- field_value = self._fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
-
- # Atomically check if another thread has preempted us and, if not, swap
- # in the new object we just created. If someone has preempted us, we
- # take that object and discard ours.
- # WARNING: We are relying on setdefault() being atomic. This is true
- # in CPython but we haven't investigated others. This warning appears
- # in several other locations in this file.
- field_value = self._fields.setdefault(field, field_value)
- return field_value
-
-
-
-
Methods
-
-
-def ByteSize(self)
-
-
-
-
-
-Expand source code
-
-
def ByteSize(self):
- if not self._cached_byte_size_dirty:
- return self._cached_byte_size
-
- size = 0
- descriptor = self.DESCRIPTOR
- if descriptor.GetOptions().map_entry:
- # Fields of map entry should always be serialized.
- size = descriptor.fields_by_name['key']._sizer(self.key)
- size += descriptor.fields_by_name['value']._sizer(self.value)
- else:
- for field_descriptor, field_value in self.ListFields():
- size += field_descriptor._sizer(field_value)
- for tag_bytes, value_bytes in self._unknown_fields:
- size += len(tag_bytes) + len(value_bytes)
-
- self._cached_byte_size = size
- self._cached_byte_size_dirty = False
- self._listener_for_children.dirty = False
- return size
def ClearField(self, field_name):
- try:
- field = message_descriptor.fields_by_name[field_name]
- except KeyError:
- try:
- field = message_descriptor.oneofs_by_name[field_name]
- if field in self._oneofs:
- field = self._oneofs[field]
- else:
- return
- except KeyError:
- raise ValueError('Protocol message %s has no "%s" field.' %
- (message_descriptor.name, field_name))
-
- if field in self._fields:
- # To match the C++ implementation, we need to invalidate iterators
- # for map fields when ClearField() happens.
- if hasattr(self._fields[field], 'InvalidateIterators'):
- self._fields[field].InvalidateIterators()
-
- # Note: If the field is a sub-message, its listener will still point
- # at us. That's fine, because the worst than can happen is that it
- # will call _Modified() and invalidate our byte size. Big deal.
- del self._fields[field]
-
- if self._oneofs.get(field.containing_oneof, None) is field:
- del self._oneofs[field.containing_oneof]
-
- # Always call _Modified() -- even if nothing was changed, this is
- # a mutating method, and thus calling it should cause the field to become
- # present in the parent message.
- self._Modified()
-
-
-
-def DiscardUnknownFields(self)
-
-
-
-
-
-Expand source code
-
-
def _DiscardUnknownFields(self):
- self._unknown_fields = []
- self._unknown_field_set = None # pylint: disable=protected-access
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if _IsMapField(field):
- if _IsMessageMapField(field):
- for key in value:
- value[key].DiscardUnknownFields()
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
- for sub_message in value:
- sub_message.DiscardUnknownFields()
- else:
- value.DiscardUnknownFields()
-
-
-
-def FindInitializationErrors(self)
-
-
-
Finds required fields which are not initialized.
-
Returns
-
A list of strings.
-Each string is a path to an uninitialized field from
-the top-level message, e.g. "foo.bar[5].baz".
-
-
-Expand source code
-
-
def FindInitializationErrors(self):
- """Finds required fields which are not initialized.
-
- Returns:
- A list of strings. Each string is a path to an uninitialized field from
- the top-level message, e.g. "foo.bar[5].baz".
- """
-
- errors = [] # simplify things
-
- for field in required_fields:
- if not self.HasField(field.name):
- errors.append(field.name)
-
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.is_extension:
- name = '(%s)' % field.full_name
- else:
- name = field.name
-
- if _IsMapField(field):
- if _IsMessageMapField(field):
- for key in value:
- element = value[key]
- prefix = '%s[%s].' % (name, key)
- sub_errors = element.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
- else:
- # ScalarMaps can't have any initialization errors.
- pass
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
- for i in range(len(value)):
- element = value[i]
- prefix = '%s[%d].' % (name, i)
- sub_errors = element.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
- else:
- prefix = name + '.'
- sub_errors = value.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
-
- return errors
-
-
-
-def HasField(self, field_name)
-
-
-
-
-
-Expand source code
-
-
def HasField(self, field_name):
- try:
- field = hassable_fields[field_name]
- except KeyError:
- raise ValueError(error_msg % (message_descriptor.full_name, field_name))
-
- if isinstance(field, descriptor_mod.OneofDescriptor):
- try:
- return HasField(self, self._oneofs[field].name)
- except KeyError:
- return False
- else:
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- value = self._fields.get(field)
- return value is not None and value._is_present_in_parent
- else:
- return field in self._fields
-
-
-
-def IsInitialized(self, errors=None)
-
-
-
Checks if all required fields of a message are set.
-
Args
-
-
errors
-
A list which, if provided, will be populated with the field
-paths of all missing required fields.
-
-
Returns
-
True iff the specified message has all required fields set.
-
-
-Expand source code
-
-
def IsInitialized(self, errors=None):
- """Checks if all required fields of a message are set.
-
- Args:
- errors: A list which, if provided, will be populated with the field
- paths of all missing required fields.
-
- Returns:
- True iff the specified message has all required fields set.
- """
-
- # Performance is critical so we avoid HasField() and ListFields().
-
- for field in required_fields:
- if (field not in self._fields or
- (field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE and
- not self._fields[field]._is_present_in_parent)):
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- for field, value in list(self._fields.items()): # dict can change size!
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.label == _FieldDescriptor.LABEL_REPEATED:
- if (field.message_type.has_options and
- field.message_type.GetOptions().map_entry):
- continue
- for element in value:
- if not element.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
- elif value._is_present_in_parent and not value.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- return True
-
-
-
-def ListFields(self)
-
-
-
-
-
-Expand source code
-
-
def ListFields(self):
- all_fields = [item for item in self._fields.items() if _IsPresent(item)]
- all_fields.sort(key = lambda item: item[0].number)
- return all_fields
-
-
-
-def MergeFrom(self, msg)
-
-
-
-
-
-Expand source code
-
-
def MergeFrom(self, msg):
- if not isinstance(msg, cls):
- raise TypeError(
- 'Parameter to MergeFrom() must be instance of same class: '
- 'expected %s got %s.' % (_FullyQualifiedClassName(cls),
- _FullyQualifiedClassName(msg.__class__)))
-
- assert msg is not self
- self._Modified()
-
- fields = self._fields
-
- for field, value in msg._fields.items():
- if field.label == LABEL_REPEATED:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- elif field.cpp_type == CPPTYPE_MESSAGE:
- if value._is_present_in_parent:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- else:
- self._fields[field] = value
- if field.containing_oneof:
- self._UpdateOneofState(field)
-
- if msg._unknown_fields:
- if not self._unknown_fields:
- self._unknown_fields = []
- self._unknown_fields.extend(msg._unknown_fields)
- # pylint: disable=protected-access
- if self._unknown_field_set is None:
- self._unknown_field_set = containers.UnknownFieldSet()
- self._unknown_field_set._extend(msg._unknown_field_set)
-
-
-
-def MergeFromString(self, serialized)
-
-
-
-
-
-Expand source code
-
-
def MergeFromString(self, serialized):
- serialized = memoryview(serialized)
- length = len(serialized)
- try:
- if self._InternalParse(serialized, 0, length) != length:
- # The only reason _InternalParse would return early is if it
- # encountered an end-group tag.
- raise message_mod.DecodeError('Unexpected end-group tag.')
- except (IndexError, TypeError):
- # Now ord(buf[p:p+1]) == ord('') gets TypeError.
- raise message_mod.DecodeError('Truncated message.')
- except struct.error as e:
- raise message_mod.DecodeError(e)
- return length # Return this for legacy reasons.
def SerializeToString(self, **kwargs):
- # Check if the message has all of its required fields set.
- if not self.IsInitialized():
- raise message_mod.EncodeError(
- 'Message %s is missing required fields: %s' % (
- self.DESCRIPTOR.full_name, ','.join(self.FindInitializationErrors())))
- return self.SerializePartialToString(**kwargs)
-
-
-
-def SetInParent(self)
-
-
-
Sets the _cached_byte_size_dirty bit to true,
-and propagates this to our listener iff this was a state change.
-
-
-Expand source code
-
-
def Modified(self):
- """Sets the _cached_byte_size_dirty bit to true,
- and propagates this to our listener iff this was a state change.
- """
-
- # Note: Some callers check _cached_byte_size_dirty before calling
- # _Modified() as an extra optimization. So, if this method is ever
- # changed such that it does stuff even when _cached_byte_size_dirty is
- # already true, the callers need to be updated.
- if not self._cached_byte_size_dirty:
- self._cached_byte_size_dirty = True
- self._listener_for_children.dirty = True
- self._is_present_in_parent = True
- self._listener.Modified()
Returns the name of the currently set field inside a oneof, or None.
-
-
-Expand source code
-
-
def WhichOneof(self, oneof_name):
- """Returns the name of the currently set field inside a oneof, or None."""
- try:
- field = message_descriptor.oneofs_by_name[oneof_name]
- except KeyError:
- raise ValueError(
- 'Protocol message has no oneof "%s" field.' % oneof_name)
-
- nested_field = self._oneofs.get(field, None)
- if nested_field is not None and self.HasField(nested_field.name):
- return nested_field.name
- else:
- return None
-
+
Field ChannelFile.channels
class DeviceState
-(**kwargs)
+(*args, **kwargs)
-
Abstract base class for protocol messages.
-
Protocol message classes are almost always generated by the protocol
-compiler.
-These generated types subclass Message and implement the methods
-shown below.
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field DeviceState.did_gps_reset
var legacyRadio
-
Getter for legacyRadio.
-
-
-Expand source code
-
-
def getter(self):
- field_value = self._fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
-
- # Atomically check if another thread has preempted us and, if not, swap
- # in the new object we just created. If someone has preempted us, we
- # take that object and discard ours.
- # WARNING: We are relying on setdefault() being atomic. This is true
- # in CPython but we haven't investigated others. This warning appears
- # in several other locations in this file.
- field_value = self._fields.setdefault(field, field_value)
- return field_value
-
+
Field DeviceState.legacyRadio
var my_node
-
Getter for my_node.
-
-
-Expand source code
-
-
def getter(self):
- field_value = self._fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
-
- # Atomically check if another thread has preempted us and, if not, swap
- # in the new object we just created. If someone has preempted us, we
- # take that object and discard ours.
- # WARNING: We are relying on setdefault() being atomic. This is true
- # in CPython but we haven't investigated others. This warning appears
- # in several other locations in this file.
- field_value = self._fields.setdefault(field, field_value)
- return field_value
-
+
Field DeviceState.my_node
var no_save
-
Getter for no_save.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field DeviceState.no_save
var node_db
-
Getter for node_db.
-
-
-Expand source code
-
-
def getter(self):
- field_value = self._fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
-
- # Atomically check if another thread has preempted us and, if not, swap
- # in the new object we just created. If someone has preempted us, we
- # take that object and discard ours.
- # WARNING: We are relying on setdefault() being atomic. This is true
- # in CPython but we haven't investigated others. This warning appears
- # in several other locations in this file.
- field_value = self._fields.setdefault(field, field_value)
- return field_value
-
+
Field DeviceState.node_db
var owner
-
Getter for owner.
-
-
-Expand source code
-
-
def getter(self):
- field_value = self._fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
-
- # Atomically check if another thread has preempted us and, if not, swap
- # in the new object we just created. If someone has preempted us, we
- # take that object and discard ours.
- # WARNING: We are relying on setdefault() being atomic. This is true
- # in CPython but we haven't investigated others. This warning appears
- # in several other locations in this file.
- field_value = self._fields.setdefault(field, field_value)
- return field_value
-
+
Field DeviceState.owner
var receive_queue
-
Getter for receive_queue.
-
-
-Expand source code
-
-
def getter(self):
- field_value = self._fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
-
- # Atomically check if another thread has preempted us and, if not, swap
- # in the new object we just created. If someone has preempted us, we
- # take that object and discard ours.
- # WARNING: We are relying on setdefault() being atomic. This is true
- # in CPython but we haven't investigated others. This warning appears
- # in several other locations in this file.
- field_value = self._fields.setdefault(field, field_value)
- return field_value
-
+
Field DeviceState.receive_queue
var rx_text_message
-
Getter for rx_text_message.
-
-
-Expand source code
-
-
def getter(self):
- field_value = self._fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
-
- # Atomically check if another thread has preempted us and, if not, swap
- # in the new object we just created. If someone has preempted us, we
- # take that object and discard ours.
- # WARNING: We are relying on setdefault() being atomic. This is true
- # in CPython but we haven't investigated others. This warning appears
- # in several other locations in this file.
- field_value = self._fields.setdefault(field, field_value)
- return field_value
-
+
Field DeviceState.rx_text_message
var version
-
Getter for version.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
-
-
-
Methods
-
-
-def ByteSize(self)
-
-
-
-
-
-Expand source code
-
-
def ByteSize(self):
- if not self._cached_byte_size_dirty:
- return self._cached_byte_size
-
- size = 0
- descriptor = self.DESCRIPTOR
- if descriptor.GetOptions().map_entry:
- # Fields of map entry should always be serialized.
- size = descriptor.fields_by_name['key']._sizer(self.key)
- size += descriptor.fields_by_name['value']._sizer(self.value)
- else:
- for field_descriptor, field_value in self.ListFields():
- size += field_descriptor._sizer(field_value)
- for tag_bytes, value_bytes in self._unknown_fields:
- size += len(tag_bytes) + len(value_bytes)
-
- self._cached_byte_size = size
- self._cached_byte_size_dirty = False
- self._listener_for_children.dirty = False
- return size
def ClearField(self, field_name):
- try:
- field = message_descriptor.fields_by_name[field_name]
- except KeyError:
- try:
- field = message_descriptor.oneofs_by_name[field_name]
- if field in self._oneofs:
- field = self._oneofs[field]
- else:
- return
- except KeyError:
- raise ValueError('Protocol message %s has no "%s" field.' %
- (message_descriptor.name, field_name))
-
- if field in self._fields:
- # To match the C++ implementation, we need to invalidate iterators
- # for map fields when ClearField() happens.
- if hasattr(self._fields[field], 'InvalidateIterators'):
- self._fields[field].InvalidateIterators()
-
- # Note: If the field is a sub-message, its listener will still point
- # at us. That's fine, because the worst than can happen is that it
- # will call _Modified() and invalidate our byte size. Big deal.
- del self._fields[field]
-
- if self._oneofs.get(field.containing_oneof, None) is field:
- del self._oneofs[field.containing_oneof]
-
- # Always call _Modified() -- even if nothing was changed, this is
- # a mutating method, and thus calling it should cause the field to become
- # present in the parent message.
- self._Modified()
-
-
-
-def DiscardUnknownFields(self)
-
-
-
-
-
-Expand source code
-
-
def _DiscardUnknownFields(self):
- self._unknown_fields = []
- self._unknown_field_set = None # pylint: disable=protected-access
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if _IsMapField(field):
- if _IsMessageMapField(field):
- for key in value:
- value[key].DiscardUnknownFields()
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
- for sub_message in value:
- sub_message.DiscardUnknownFields()
- else:
- value.DiscardUnknownFields()
-
-
-
-def FindInitializationErrors(self)
-
-
-
Finds required fields which are not initialized.
-
Returns
-
A list of strings.
-Each string is a path to an uninitialized field from
-the top-level message, e.g. "foo.bar[5].baz".
-
-
-Expand source code
-
-
def FindInitializationErrors(self):
- """Finds required fields which are not initialized.
-
- Returns:
- A list of strings. Each string is a path to an uninitialized field from
- the top-level message, e.g. "foo.bar[5].baz".
- """
-
- errors = [] # simplify things
-
- for field in required_fields:
- if not self.HasField(field.name):
- errors.append(field.name)
-
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.is_extension:
- name = '(%s)' % field.full_name
- else:
- name = field.name
-
- if _IsMapField(field):
- if _IsMessageMapField(field):
- for key in value:
- element = value[key]
- prefix = '%s[%s].' % (name, key)
- sub_errors = element.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
- else:
- # ScalarMaps can't have any initialization errors.
- pass
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
- for i in range(len(value)):
- element = value[i]
- prefix = '%s[%d].' % (name, i)
- sub_errors = element.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
- else:
- prefix = name + '.'
- sub_errors = value.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
-
- return errors
-
-
-
-def HasField(self, field_name)
-
-
-
-
-
-Expand source code
-
-
def HasField(self, field_name):
- try:
- field = hassable_fields[field_name]
- except KeyError:
- raise ValueError(error_msg % (message_descriptor.full_name, field_name))
-
- if isinstance(field, descriptor_mod.OneofDescriptor):
- try:
- return HasField(self, self._oneofs[field].name)
- except KeyError:
- return False
- else:
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- value = self._fields.get(field)
- return value is not None and value._is_present_in_parent
- else:
- return field in self._fields
-
-
-
-def IsInitialized(self, errors=None)
-
-
-
Checks if all required fields of a message are set.
-
Args
-
-
errors
-
A list which, if provided, will be populated with the field
-paths of all missing required fields.
-
-
Returns
-
True iff the specified message has all required fields set.
-
-
-Expand source code
-
-
def IsInitialized(self, errors=None):
- """Checks if all required fields of a message are set.
-
- Args:
- errors: A list which, if provided, will be populated with the field
- paths of all missing required fields.
-
- Returns:
- True iff the specified message has all required fields set.
- """
-
- # Performance is critical so we avoid HasField() and ListFields().
-
- for field in required_fields:
- if (field not in self._fields or
- (field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE and
- not self._fields[field]._is_present_in_parent)):
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- for field, value in list(self._fields.items()): # dict can change size!
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.label == _FieldDescriptor.LABEL_REPEATED:
- if (field.message_type.has_options and
- field.message_type.GetOptions().map_entry):
- continue
- for element in value:
- if not element.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
- elif value._is_present_in_parent and not value.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- return True
-
-
-
-def ListFields(self)
-
-
-
-
-
-Expand source code
-
-
def ListFields(self):
- all_fields = [item for item in self._fields.items() if _IsPresent(item)]
- all_fields.sort(key = lambda item: item[0].number)
- return all_fields
-
-
-
-def MergeFrom(self, msg)
-
-
-
-
-
-Expand source code
-
-
def MergeFrom(self, msg):
- if not isinstance(msg, cls):
- raise TypeError(
- 'Parameter to MergeFrom() must be instance of same class: '
- 'expected %s got %s.' % (_FullyQualifiedClassName(cls),
- _FullyQualifiedClassName(msg.__class__)))
-
- assert msg is not self
- self._Modified()
-
- fields = self._fields
-
- for field, value in msg._fields.items():
- if field.label == LABEL_REPEATED:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- elif field.cpp_type == CPPTYPE_MESSAGE:
- if value._is_present_in_parent:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- else:
- self._fields[field] = value
- if field.containing_oneof:
- self._UpdateOneofState(field)
-
- if msg._unknown_fields:
- if not self._unknown_fields:
- self._unknown_fields = []
- self._unknown_fields.extend(msg._unknown_fields)
- # pylint: disable=protected-access
- if self._unknown_field_set is None:
- self._unknown_field_set = containers.UnknownFieldSet()
- self._unknown_field_set._extend(msg._unknown_field_set)
-
-
-
-def MergeFromString(self, serialized)
-
-
-
-
-
-Expand source code
-
-
def MergeFromString(self, serialized):
- serialized = memoryview(serialized)
- length = len(serialized)
- try:
- if self._InternalParse(serialized, 0, length) != length:
- # The only reason _InternalParse would return early is if it
- # encountered an end-group tag.
- raise message_mod.DecodeError('Unexpected end-group tag.')
- except (IndexError, TypeError):
- # Now ord(buf[p:p+1]) == ord('') gets TypeError.
- raise message_mod.DecodeError('Truncated message.')
- except struct.error as e:
- raise message_mod.DecodeError(e)
- return length # Return this for legacy reasons.
def SerializeToString(self, **kwargs):
- # Check if the message has all of its required fields set.
- if not self.IsInitialized():
- raise message_mod.EncodeError(
- 'Message %s is missing required fields: %s' % (
- self.DESCRIPTOR.full_name, ','.join(self.FindInitializationErrors())))
- return self.SerializePartialToString(**kwargs)
-
-
-
-def SetInParent(self)
-
-
-
Sets the _cached_byte_size_dirty bit to true,
-and propagates this to our listener iff this was a state change.
-
-
-Expand source code
-
-
def Modified(self):
- """Sets the _cached_byte_size_dirty bit to true,
- and propagates this to our listener iff this was a state change.
- """
-
- # Note: Some callers check _cached_byte_size_dirty before calling
- # _Modified() as an extra optimization. So, if this method is ever
- # changed such that it does stuff even when _cached_byte_size_dirty is
- # already true, the callers need to be updated.
- if not self._cached_byte_size_dirty:
- self._cached_byte_size_dirty = True
- self._listener_for_children.dirty = True
- self._is_present_in_parent = True
- self._listener.Modified()
Returns the name of the currently set field inside a oneof, or None.
-
-
-Expand source code
-
-
def WhichOneof(self, oneof_name):
- """Returns the name of the currently set field inside a oneof, or None."""
- try:
- field = message_descriptor.oneofs_by_name[oneof_name]
- except KeyError:
- raise ValueError(
- 'Protocol message has no oneof "%s" field.' % oneof_name)
-
- nested_field = self._oneofs.get(field, None)
- if nested_field is not None and self.HasField(nested_field.name):
- return nested_field.name
- else:
- return None
-
+
Field DeviceState.version
class LegacyRadioConfig
-(**kwargs)
+(*args, **kwargs)
-
Abstract base class for protocol messages.
-
Protocol message classes are almost always generated by the protocol
-compiler.
-These generated types subclass Message and implement the methods
-shown below.
+
A ProtocolMessage
Ancestors
+
google.protobuf.pyext._message.CMessage
google.protobuf.message.Message
Class variables
@@ -1590,534 +395,14 @@ shown below.
var LegacyPreferences
-
Abstract base class for protocol messages.
-
Protocol message classes are almost always generated by the protocol
-compiler.
-These generated types subclass Message and implement the methods
-shown below.
def getter(self):
- field_value = self._fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
-
- # Atomically check if another thread has preempted us and, if not, swap
- # in the new object we just created. If someone has preempted us, we
- # take that object and discard ours.
- # WARNING: We are relying on setdefault() being atomic. This is true
- # in CPython but we haven't investigated others. This warning appears
- # in several other locations in this file.
- field_value = self._fields.setdefault(field, field_value)
- return field_value
-
-
-
-
Methods
-
-
-def ByteSize(self)
-
-
-
-
-
-Expand source code
-
-
def ByteSize(self):
- if not self._cached_byte_size_dirty:
- return self._cached_byte_size
-
- size = 0
- descriptor = self.DESCRIPTOR
- if descriptor.GetOptions().map_entry:
- # Fields of map entry should always be serialized.
- size = descriptor.fields_by_name['key']._sizer(self.key)
- size += descriptor.fields_by_name['value']._sizer(self.value)
- else:
- for field_descriptor, field_value in self.ListFields():
- size += field_descriptor._sizer(field_value)
- for tag_bytes, value_bytes in self._unknown_fields:
- size += len(tag_bytes) + len(value_bytes)
-
- self._cached_byte_size = size
- self._cached_byte_size_dirty = False
- self._listener_for_children.dirty = False
- return size
def ClearField(self, field_name):
- try:
- field = message_descriptor.fields_by_name[field_name]
- except KeyError:
- try:
- field = message_descriptor.oneofs_by_name[field_name]
- if field in self._oneofs:
- field = self._oneofs[field]
- else:
- return
- except KeyError:
- raise ValueError('Protocol message %s has no "%s" field.' %
- (message_descriptor.name, field_name))
-
- if field in self._fields:
- # To match the C++ implementation, we need to invalidate iterators
- # for map fields when ClearField() happens.
- if hasattr(self._fields[field], 'InvalidateIterators'):
- self._fields[field].InvalidateIterators()
-
- # Note: If the field is a sub-message, its listener will still point
- # at us. That's fine, because the worst than can happen is that it
- # will call _Modified() and invalidate our byte size. Big deal.
- del self._fields[field]
-
- if self._oneofs.get(field.containing_oneof, None) is field:
- del self._oneofs[field.containing_oneof]
-
- # Always call _Modified() -- even if nothing was changed, this is
- # a mutating method, and thus calling it should cause the field to become
- # present in the parent message.
- self._Modified()
-
-
-
-def DiscardUnknownFields(self)
-
-
-
-
-
-Expand source code
-
-
def _DiscardUnknownFields(self):
- self._unknown_fields = []
- self._unknown_field_set = None # pylint: disable=protected-access
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if _IsMapField(field):
- if _IsMessageMapField(field):
- for key in value:
- value[key].DiscardUnknownFields()
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
- for sub_message in value:
- sub_message.DiscardUnknownFields()
- else:
- value.DiscardUnknownFields()
-
-
-
-def FindInitializationErrors(self)
-
-
-
Finds required fields which are not initialized.
-
Returns
-
A list of strings.
-Each string is a path to an uninitialized field from
-the top-level message, e.g. "foo.bar[5].baz".
-
-
-Expand source code
-
-
def FindInitializationErrors(self):
- """Finds required fields which are not initialized.
-
- Returns:
- A list of strings. Each string is a path to an uninitialized field from
- the top-level message, e.g. "foo.bar[5].baz".
- """
-
- errors = [] # simplify things
-
- for field in required_fields:
- if not self.HasField(field.name):
- errors.append(field.name)
-
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.is_extension:
- name = '(%s)' % field.full_name
- else:
- name = field.name
-
- if _IsMapField(field):
- if _IsMessageMapField(field):
- for key in value:
- element = value[key]
- prefix = '%s[%s].' % (name, key)
- sub_errors = element.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
- else:
- # ScalarMaps can't have any initialization errors.
- pass
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
- for i in range(len(value)):
- element = value[i]
- prefix = '%s[%d].' % (name, i)
- sub_errors = element.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
- else:
- prefix = name + '.'
- sub_errors = value.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
-
- return errors
-
-
-
-def HasField(self, field_name)
-
-
-
-
-
-Expand source code
-
-
def HasField(self, field_name):
- try:
- field = hassable_fields[field_name]
- except KeyError:
- raise ValueError(error_msg % (message_descriptor.full_name, field_name))
-
- if isinstance(field, descriptor_mod.OneofDescriptor):
- try:
- return HasField(self, self._oneofs[field].name)
- except KeyError:
- return False
- else:
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- value = self._fields.get(field)
- return value is not None and value._is_present_in_parent
- else:
- return field in self._fields
-
-
-
-def IsInitialized(self, errors=None)
-
-
-
Checks if all required fields of a message are set.
-
Args
-
-
errors
-
A list which, if provided, will be populated with the field
-paths of all missing required fields.
-
-
Returns
-
True iff the specified message has all required fields set.
-
-
-Expand source code
-
-
def IsInitialized(self, errors=None):
- """Checks if all required fields of a message are set.
-
- Args:
- errors: A list which, if provided, will be populated with the field
- paths of all missing required fields.
-
- Returns:
- True iff the specified message has all required fields set.
- """
-
- # Performance is critical so we avoid HasField() and ListFields().
-
- for field in required_fields:
- if (field not in self._fields or
- (field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE and
- not self._fields[field]._is_present_in_parent)):
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- for field, value in list(self._fields.items()): # dict can change size!
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.label == _FieldDescriptor.LABEL_REPEATED:
- if (field.message_type.has_options and
- field.message_type.GetOptions().map_entry):
- continue
- for element in value:
- if not element.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
- elif value._is_present_in_parent and not value.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- return True
-
-
-
-def ListFields(self)
-
-
-
-
-
-Expand source code
-
-
def ListFields(self):
- all_fields = [item for item in self._fields.items() if _IsPresent(item)]
- all_fields.sort(key = lambda item: item[0].number)
- return all_fields
-
-
-
-def MergeFrom(self, msg)
-
-
-
-
-
-Expand source code
-
-
def MergeFrom(self, msg):
- if not isinstance(msg, cls):
- raise TypeError(
- 'Parameter to MergeFrom() must be instance of same class: '
- 'expected %s got %s.' % (_FullyQualifiedClassName(cls),
- _FullyQualifiedClassName(msg.__class__)))
-
- assert msg is not self
- self._Modified()
-
- fields = self._fields
-
- for field, value in msg._fields.items():
- if field.label == LABEL_REPEATED:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- elif field.cpp_type == CPPTYPE_MESSAGE:
- if value._is_present_in_parent:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- else:
- self._fields[field] = value
- if field.containing_oneof:
- self._UpdateOneofState(field)
-
- if msg._unknown_fields:
- if not self._unknown_fields:
- self._unknown_fields = []
- self._unknown_fields.extend(msg._unknown_fields)
- # pylint: disable=protected-access
- if self._unknown_field_set is None:
- self._unknown_field_set = containers.UnknownFieldSet()
- self._unknown_field_set._extend(msg._unknown_field_set)
-
-
-
-def MergeFromString(self, serialized)
-
-
-
-
-
-Expand source code
-
-
def MergeFromString(self, serialized):
- serialized = memoryview(serialized)
- length = len(serialized)
- try:
- if self._InternalParse(serialized, 0, length) != length:
- # The only reason _InternalParse would return early is if it
- # encountered an end-group tag.
- raise message_mod.DecodeError('Unexpected end-group tag.')
- except (IndexError, TypeError):
- # Now ord(buf[p:p+1]) == ord('') gets TypeError.
- raise message_mod.DecodeError('Truncated message.')
- except struct.error as e:
- raise message_mod.DecodeError(e)
- return length # Return this for legacy reasons.
def SerializeToString(self, **kwargs):
- # Check if the message has all of its required fields set.
- if not self.IsInitialized():
- raise message_mod.EncodeError(
- 'Message %s is missing required fields: %s' % (
- self.DESCRIPTOR.full_name, ','.join(self.FindInitializationErrors())))
- return self.SerializePartialToString(**kwargs)
-
-
-
-def SetInParent(self)
-
-
-
Sets the _cached_byte_size_dirty bit to true,
-and propagates this to our listener iff this was a state change.
-
-
-Expand source code
-
-
def Modified(self):
- """Sets the _cached_byte_size_dirty bit to true,
- and propagates this to our listener iff this was a state change.
- """
-
- # Note: Some callers check _cached_byte_size_dirty before calling
- # _Modified() as an extra optimization. So, if this method is ever
- # changed such that it does stuff even when _cached_byte_size_dirty is
- # already true, the callers need to be updated.
- if not self._cached_byte_size_dirty:
- self._cached_byte_size_dirty = True
- self._listener_for_children.dirty = True
- self._is_present_in_parent = True
- self._listener.Modified()
Returns the name of the currently set field inside a oneof, or None.
-
-
-Expand source code
-
-
def WhichOneof(self, oneof_name):
- """Returns the name of the currently set field inside a oneof, or None."""
- try:
- field = message_descriptor.oneofs_by_name[oneof_name]
- except KeyError:
- raise ValueError(
- 'Protocol message has no oneof "%s" field.' % oneof_name)
-
- nested_field = self._oneofs.get(field, None)
- if nested_field is not None and self.HasField(nested_field.name):
- return nested_field.name
- else:
- return None
-
+
Field LegacyRadioConfig.preferences
@@ -2140,58 +425,14 @@ and propagates this to our listener iff this was a state change.
class EnvironmentalMeasurement
-(**kwargs)
+(*args, **kwargs)
-
Abstract base class for protocol messages.
-
Protocol message classes are almost always generated by the protocol
-compiler.
-These generated types subclass Message and implement the methods
-shown below.
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field EnvironmentalMeasurement.barometric_pressure
var relative_humidity
-
Getter for relative_humidity.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field EnvironmentalMeasurement.relative_humidity
var temperature
-
Getter for temperature.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
-
-
-
Methods
-
-
-def ByteSize(self)
-
-
-
-
-
-Expand source code
-
-
def ByteSize(self):
- if not self._cached_byte_size_dirty:
- return self._cached_byte_size
-
- size = 0
- descriptor = self.DESCRIPTOR
- if descriptor.GetOptions().map_entry:
- # Fields of map entry should always be serialized.
- size = descriptor.fields_by_name['key']._sizer(self.key)
- size += descriptor.fields_by_name['value']._sizer(self.value)
- else:
- for field_descriptor, field_value in self.ListFields():
- size += field_descriptor._sizer(field_value)
- for tag_bytes, value_bytes in self._unknown_fields:
- size += len(tag_bytes) + len(value_bytes)
-
- self._cached_byte_size = size
- self._cached_byte_size_dirty = False
- self._listener_for_children.dirty = False
- return size
def ClearField(self, field_name):
- try:
- field = message_descriptor.fields_by_name[field_name]
- except KeyError:
- try:
- field = message_descriptor.oneofs_by_name[field_name]
- if field in self._oneofs:
- field = self._oneofs[field]
- else:
- return
- except KeyError:
- raise ValueError('Protocol message %s has no "%s" field.' %
- (message_descriptor.name, field_name))
-
- if field in self._fields:
- # To match the C++ implementation, we need to invalidate iterators
- # for map fields when ClearField() happens.
- if hasattr(self._fields[field], 'InvalidateIterators'):
- self._fields[field].InvalidateIterators()
-
- # Note: If the field is a sub-message, its listener will still point
- # at us. That's fine, because the worst than can happen is that it
- # will call _Modified() and invalidate our byte size. Big deal.
- del self._fields[field]
-
- if self._oneofs.get(field.containing_oneof, None) is field:
- del self._oneofs[field.containing_oneof]
-
- # Always call _Modified() -- even if nothing was changed, this is
- # a mutating method, and thus calling it should cause the field to become
- # present in the parent message.
- self._Modified()
-
-
-
-def DiscardUnknownFields(self)
-
-
-
-
-
-Expand source code
-
-
def _DiscardUnknownFields(self):
- self._unknown_fields = []
- self._unknown_field_set = None # pylint: disable=protected-access
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if _IsMapField(field):
- if _IsMessageMapField(field):
- for key in value:
- value[key].DiscardUnknownFields()
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
- for sub_message in value:
- sub_message.DiscardUnknownFields()
- else:
- value.DiscardUnknownFields()
-
-
-
-def FindInitializationErrors(self)
-
-
-
Finds required fields which are not initialized.
-
Returns
-
A list of strings.
-Each string is a path to an uninitialized field from
-the top-level message, e.g. "foo.bar[5].baz".
-
-
-Expand source code
-
-
def FindInitializationErrors(self):
- """Finds required fields which are not initialized.
-
- Returns:
- A list of strings. Each string is a path to an uninitialized field from
- the top-level message, e.g. "foo.bar[5].baz".
- """
-
- errors = [] # simplify things
-
- for field in required_fields:
- if not self.HasField(field.name):
- errors.append(field.name)
-
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.is_extension:
- name = '(%s)' % field.full_name
- else:
- name = field.name
-
- if _IsMapField(field):
- if _IsMessageMapField(field):
- for key in value:
- element = value[key]
- prefix = '%s[%s].' % (name, key)
- sub_errors = element.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
- else:
- # ScalarMaps can't have any initialization errors.
- pass
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
- for i in range(len(value)):
- element = value[i]
- prefix = '%s[%d].' % (name, i)
- sub_errors = element.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
- else:
- prefix = name + '.'
- sub_errors = value.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
-
- return errors
-
-
-
-def HasField(self, field_name)
-
-
-
-
-
-Expand source code
-
-
def HasField(self, field_name):
- try:
- field = hassable_fields[field_name]
- except KeyError:
- raise ValueError(error_msg % (message_descriptor.full_name, field_name))
-
- if isinstance(field, descriptor_mod.OneofDescriptor):
- try:
- return HasField(self, self._oneofs[field].name)
- except KeyError:
- return False
- else:
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- value = self._fields.get(field)
- return value is not None and value._is_present_in_parent
- else:
- return field in self._fields
-
-
-
-def IsInitialized(self, errors=None)
-
-
-
Checks if all required fields of a message are set.
-
Args
-
-
errors
-
A list which, if provided, will be populated with the field
-paths of all missing required fields.
-
-
Returns
-
True iff the specified message has all required fields set.
-
-
-Expand source code
-
-
def IsInitialized(self, errors=None):
- """Checks if all required fields of a message are set.
-
- Args:
- errors: A list which, if provided, will be populated with the field
- paths of all missing required fields.
-
- Returns:
- True iff the specified message has all required fields set.
- """
-
- # Performance is critical so we avoid HasField() and ListFields().
-
- for field in required_fields:
- if (field not in self._fields or
- (field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE and
- not self._fields[field]._is_present_in_parent)):
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- for field, value in list(self._fields.items()): # dict can change size!
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.label == _FieldDescriptor.LABEL_REPEATED:
- if (field.message_type.has_options and
- field.message_type.GetOptions().map_entry):
- continue
- for element in value:
- if not element.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
- elif value._is_present_in_parent and not value.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- return True
-
-
-
-def ListFields(self)
-
-
-
-
-
-Expand source code
-
-
def ListFields(self):
- all_fields = [item for item in self._fields.items() if _IsPresent(item)]
- all_fields.sort(key = lambda item: item[0].number)
- return all_fields
-
-
-
-def MergeFrom(self, msg)
-
-
-
-
-
-Expand source code
-
-
def MergeFrom(self, msg):
- if not isinstance(msg, cls):
- raise TypeError(
- 'Parameter to MergeFrom() must be instance of same class: '
- 'expected %s got %s.' % (_FullyQualifiedClassName(cls),
- _FullyQualifiedClassName(msg.__class__)))
-
- assert msg is not self
- self._Modified()
-
- fields = self._fields
-
- for field, value in msg._fields.items():
- if field.label == LABEL_REPEATED:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- elif field.cpp_type == CPPTYPE_MESSAGE:
- if value._is_present_in_parent:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- else:
- self._fields[field] = value
- if field.containing_oneof:
- self._UpdateOneofState(field)
-
- if msg._unknown_fields:
- if not self._unknown_fields:
- self._unknown_fields = []
- self._unknown_fields.extend(msg._unknown_fields)
- # pylint: disable=protected-access
- if self._unknown_field_set is None:
- self._unknown_field_set = containers.UnknownFieldSet()
- self._unknown_field_set._extend(msg._unknown_field_set)
-
-
-
-def MergeFromString(self, serialized)
-
-
-
-
-
-Expand source code
-
-
def MergeFromString(self, serialized):
- serialized = memoryview(serialized)
- length = len(serialized)
- try:
- if self._InternalParse(serialized, 0, length) != length:
- # The only reason _InternalParse would return early is if it
- # encountered an end-group tag.
- raise message_mod.DecodeError('Unexpected end-group tag.')
- except (IndexError, TypeError):
- # Now ord(buf[p:p+1]) == ord('') gets TypeError.
- raise message_mod.DecodeError('Truncated message.')
- except struct.error as e:
- raise message_mod.DecodeError(e)
- return length # Return this for legacy reasons.
def SerializeToString(self, **kwargs):
- # Check if the message has all of its required fields set.
- if not self.IsInitialized():
- raise message_mod.EncodeError(
- 'Message %s is missing required fields: %s' % (
- self.DESCRIPTOR.full_name, ','.join(self.FindInitializationErrors())))
- return self.SerializePartialToString(**kwargs)
-
-
-
-def SetInParent(self)
-
-
-
Sets the _cached_byte_size_dirty bit to true,
-and propagates this to our listener iff this was a state change.
-
-
-Expand source code
-
-
def Modified(self):
- """Sets the _cached_byte_size_dirty bit to true,
- and propagates this to our listener iff this was a state change.
- """
-
- # Note: Some callers check _cached_byte_size_dirty before calling
- # _Modified() as an extra optimization. So, if this method is ever
- # changed such that it does stuff even when _cached_byte_size_dirty is
- # already true, the callers need to be updated.
- if not self._cached_byte_size_dirty:
- self._cached_byte_size_dirty = True
- self._listener_for_children.dirty = True
- self._is_present_in_parent = True
- self._listener.Modified()
Returns the name of the currently set field inside a oneof, or None.
-
-
-Expand source code
-
-
def WhichOneof(self, oneof_name):
- """Returns the name of the currently set field inside a oneof, or None."""
- try:
- field = message_descriptor.oneofs_by_name[oneof_name]
- except KeyError:
- raise ValueError(
- 'Protocol message has no oneof "%s" field.' % oneof_name)
-
- nested_field = self._oneofs.get(field, None)
- if nested_field is not None and self.HasField(nested_field.name):
- return nested_field.name
- else:
- return None
-
+
Field EnvironmentalMeasurement.temperature
@@ -708,27 +173,7 @@ and propagates this to our listener iff this was a state change.
diff --git a/docs/meshtastic/index.html b/docs/meshtastic/index.html
index bfd2d02..cefec61 100644
--- a/docs/meshtastic/index.html
+++ b/docs/meshtastic/index.html
@@ -66,6 +66,7 @@ For ASCII these two strings will be the same, but for
unicode scripts they can be different.
Example Usage
import meshtastic
+import meshtastic.serial_interface
from pubsub import pub
def onReceive(packet, interface): # called when a packet arrives
@@ -78,7 +79,7 @@ def onConnection(interface, topic=pub.AUTO_TOPIC): # called when we (re)connect
pub.subscribe(onReceive, "meshtastic.receive")
pub.subscribe(onConnection, "meshtastic.connection.established")
# By default will try to find a meshtastic device, otherwise provide a device path like /dev/ttyUSB0
-interface = meshtastic.SerialInterface()
+interface = meshtastic.serial_interface.SerialInterface()
@@ -124,6 +125,7 @@ unicode scripts they can be different.
# Example Usage
```
import meshtastic
+import meshtastic.serial_interface
from pubsub import pub
def onReceive(packet, interface): # called when a packet arrives
@@ -136,7 +138,7 @@ def onConnection(interface, topic=pub.AUTO_TOPIC): # called when we (re)connect
pub.subscribe(onReceive, "meshtastic.receive")
pub.subscribe(onConnection, "meshtastic.connection.established")
# By default will try to find a meshtastic device, otherwise provide a device path like /dev/ttyUSB0
-interface = meshtastic.SerialInterface()
+interface = meshtastic.serial_interface.SerialInterface()
```
@@ -167,23 +169,23 @@ from .util import fixme, catchAndIgnore, stripnl, DeferredExecution, Timeout
from .node import Node
from . import mesh_pb2, portnums_pb2, apponly_pb2, admin_pb2, environmental_measurement_pb2, remote_hardware_pb2, channel_pb2, radioconfig_pb2, util
+# Note: To follow PEP224, comments should be after the module variable.
-"""A special ID that means the local node"""
LOCAL_ADDR = "^local"
+"""A special ID that means the local node"""
-# if using 8 bit nodenums this will be shortend on the target
BROADCAST_NUM = 0xffffffff
+"""if using 8 bit nodenums this will be shortend on the target"""
-"""A special ID that means broadcast"""
BROADCAST_ADDR = "^all"
+"""A special ID that means broadcast"""
-
+OUR_APP_VERSION = 20200
"""The numeric buildnumber (shared with android apps) specifying the
level of device code we are guaranteed to understand
format is Mmmss (where M is 1+the numeric major number. i.e. 20120 means 1.1.20
"""
-OUR_APP_VERSION = 20200
publishingThread = DeferredExecution("publishing")
@@ -242,10 +244,11 @@ def _onNodeInfoReceive(iface, asDict):
def _receiveInfoUpdate(iface, asDict):
- iface._getOrCreateByNum(asDict["from"])["lastReceived"] = asDict
- iface._getOrCreateByNum(asDict["from"])["lastHeard"] = asDict.get("rxTime")
- iface._getOrCreateByNum(asDict["from"])["snr"] = asDict.get("rxSnr")
- iface._getOrCreateByNum(asDict["from"])["hopLimit"] = asDict.get("hopLimit")
+ if "from" in asDict:
+ iface._getOrCreateByNum(asDict["from"])["lastReceived"] = asDict
+ iface._getOrCreateByNum(asDict["from"])["lastHeard"] = asDict.get("rxTime")
+ iface._getOrCreateByNum(asDict["from"])["snr"] = asDict.get("rxSnr")
+ iface._getOrCreateByNum(asDict["from"])["hopLimit"] = asDict.get("hopLimit")
"""Well known message payloads can register decoders for automatic protobuf parsing"""
@@ -368,13 +371,21 @@ messages and report back if successful.
var BROADCAST_ADDR
-
The numeric buildnumber (shared with android apps) specifying the
-level of device code we are guaranteed to understand
-
format is Mmmss (where M is 1+the numeric major number. i.e. 20120 means 1.1.20
+
A special ID that means broadcast
var BROADCAST_NUM
-
A special ID that means broadcast
+
if using 8 bit nodenums this will be shortend on the target
+
+
var LOCAL_ADDR
+
+
A special ID that means the local node
+
+
var OUR_APP_VERSION
+
+
The numeric buildnumber (shared with android apps) specifying the
+level of device code we are guaranteed to understand
+
format is Mmmss (where M is 1+the numeric major number. i.e. 20120 means 1.1.20
@@ -495,6 +506,8 @@ level of device code we are guaranteed to understand
"""Mesh Interface class
"""
import sys
import random
@@ -45,15 +45,11 @@ from pubsub import pub
from google.protobuf.json_format import MessageToJson
+import meshtastic.node
from . import portnums_pb2, mesh_pb2
from .util import stripnl, Timeout, our_exit
-from .node import Node
from .__init__ import LOCAL_ADDR, BROADCAST_NUM, BROADCAST_ADDR, ResponseHandler, publishingThread, OUR_APP_VERSION, protocols
-
-defaultHopLimit = 3
-
-
class MeshInterface:
"""Interface class for meshtastic devices
@@ -75,7 +71,7 @@ class MeshInterface:
self.nodes = None # FIXME
self.isConnected = threading.Event()
self.noProto = noProto
- self.localNode = Node(self, -1) # We fixup nodenum later
+ self.localNode = meshtastic.node.Node(self, -1) # We fixup nodenum later
self.myInfo = None # We don't have device info yet
self.responseHandlers = {} # A map from request ID to the handler
self.failure = None # If we've encountered a fatal exception it will be kept here
@@ -85,6 +81,9 @@ class MeshInterface:
self.currentPacketId = random.randint(0, 0xffffffff)
self.nodesByNum = None
self.configId = None
+ self.defaultHopLimit = 3
+ self.gotResponse = False # used in gpio read
+ self.mask = None # used in gpio read and gpio watch
def close(self):
"""Shutdown this interface"""
@@ -135,6 +134,7 @@ class MeshInterface:
rows = []
if self.nodes:
+ logging.debug(f'self.nodes:{self.nodes}')
for node in self.nodes.values():
if not includeSelf and node['num'] == self.localNode.nodeNum:
continue
@@ -180,7 +180,8 @@ class MeshInterface:
if nodeId == LOCAL_ADDR:
return self.localNode
else:
- n = Node(self, nodeId)
+ n = meshtastic.node.Node(self, nodeId)
+ logging.debug("About to requestConfig")
n.requestConfig()
if not n.waitForConfig():
our_exit("Error: Timed out waiting for node config")
@@ -190,7 +191,7 @@ class MeshInterface:
destinationId=BROADCAST_ADDR,
wantAck=False,
wantResponse=False,
- hopLimit=defaultHopLimit,
+ hopLimit=None,
onResponse=None,
channelIndex=0):
"""Send a utf8 string to some other node, if the node has a display it
@@ -212,6 +213,9 @@ class MeshInterface:
Returns the sent packet. The id field will be populated in this packet
and can be used to track future message acks/naks.
"""
+ if hopLimit is None:
+ hopLimit = self.defaultHopLimit
+
return self.sendData(text.encode("utf-8"), destinationId,
portNum=portnums_pb2.PortNum.TEXT_MESSAGE_APP,
wantAck=wantAck,
@@ -223,7 +227,7 @@ class MeshInterface:
def sendData(self, data, destinationId=BROADCAST_ADDR,
portNum=portnums_pb2.PortNum.PRIVATE_APP, wantAck=False,
wantResponse=False,
- hopLimit=defaultHopLimit,
+ hopLimit=None,
onResponse=None,
channelIndex=0):
"""Send a data packet to some other node
@@ -243,16 +247,22 @@ class MeshInterface:
onResponse -- A closure of the form funct(packet), that will be
called when a response packet arrives (or the transaction
is NAKed due to non receipt)
+ channelIndex - channel number to use
Returns the sent packet. The id field will be populated in this packet
and can be used to track future message acks/naks.
"""
+ if hopLimit is None:
+ hopLimit = self.defaultHopLimit
+
if getattr(data, "SerializeToString", None):
logging.debug(f"Serializing protobuf as data: {stripnl(data)}")
data = data.SerializeToString()
+ logging.debug(f"len(data): {len(data)}")
+ logging.debug(f"mesh_pb2.Constants.DATA_PAYLOAD_LEN: {mesh_pb2.Constants.DATA_PAYLOAD_LEN}")
if len(data) > mesh_pb2.Constants.DATA_PAYLOAD_LEN:
- Exception("Data payload too big")
+ raise Exception("Data payload too big")
if portNum == portnums_pb2.PortNum.UNKNOWN_APP: # we are now more strict wrt port numbers
our_exit("Warning: A non-zero port number must be specified")
@@ -285,16 +295,20 @@ class MeshInterface:
p = mesh_pb2.Position()
if latitude != 0.0:
p.latitude_i = int(latitude / 1e-7)
+ logging.debug(f'p.latitude_i:{p.latitude_i}')
if longitude != 0.0:
p.longitude_i = int(longitude / 1e-7)
+ logging.debug(f'p.longitude_i:{p.longitude_i}')
if altitude != 0:
p.altitude = int(altitude)
+ logging.debug(f'p.altitude:{p.altitude}')
if timeSec == 0:
timeSec = time.time() # returns unix timestamp in seconds
p.time = int(timeSec)
+ logging.debug(f'p.time:{p.time}')
return self.sendData(p, destinationId,
portNum=portnums_pb2.PortNum.POSITION_APP,
@@ -306,13 +320,15 @@ class MeshInterface:
def _sendPacket(self, meshPacket,
destinationId=BROADCAST_ADDR,
- wantAck=False, hopLimit=defaultHopLimit):
+ wantAck=False, hopLimit=None):
"""Send a MeshPacket to the specified node (or if unspecified, broadcast).
You probably don't want this - use sendData instead.
Returns the sent packet. The id field will be populated in this packet and
can be used to track future message acks/naks.
"""
+ if hopLimit is None:
+ hopLimit = self.defaultHopLimit
# We allow users to talk to the local node before we've completed the full connection flow...
if(self.myInfo is not None and destinationId != self.myInfo.my_node_num):
@@ -320,6 +336,7 @@ class MeshInterface:
toRadio = mesh_pb2.ToRadio()
+ nodeNum = 0
if destinationId is None:
our_exit("Warning: destinationId must not be None")
elif isinstance(destinationId, int):
@@ -327,15 +344,21 @@ class MeshInterface:
elif destinationId == BROADCAST_ADDR:
nodeNum = BROADCAST_NUM
elif destinationId == LOCAL_ADDR:
- nodeNum = self.myInfo.my_node_num
+ if self.myInfo:
+ nodeNum = self.myInfo.my_node_num
+ else:
+ our_exit("Warning: No myInfo found.")
# A simple hex style nodeid - we can parse this without needing the DB
elif destinationId.startswith("!"):
nodeNum = int(destinationId[1:], 16)
else:
- node = self.nodes.get(destinationId)
- if not node:
- our_exit(f"Warning: NodeId {destinationId} not found in DB")
- nodeNum = node['num']
+ if self.nodes:
+ node = self.nodes.get(destinationId)
+ if not node:
+ our_exit(f"Warning: NodeId {destinationId} not found in DB")
+ nodeNum = node['num']
+ else:
+ logging.warning("Warning: There were no self.nodes.")
meshPacket.to = nodeNum
meshPacket.want_ack = wantAck
@@ -347,8 +370,11 @@ class MeshInterface:
meshPacket.id = self._generatePacketId()
toRadio.packet.CopyFrom(meshPacket)
- #logging.debug(f"Sending packet: {stripnl(meshPacket)}")
- self._sendToRadio(toRadio)
+ if self.noProto:
+ logging.warning(f"Not sending packet because protocol use is disabled by noProto")
+ else:
+ logging.debug(f"Sending packet: {stripnl(meshPacket)}")
+ self._sendToRadio(toRadio)
return meshPacket
def waitForConfig(self):
@@ -361,6 +387,7 @@ class MeshInterface:
"""Get info about my node."""
if self.myInfo is None:
return None
+ logging.debug(f'self.nodesByNum:{self.nodesByNum}')
return self.nodesByNum.get(self.myInfo.my_node_num)
def getMyUser(self):
@@ -387,8 +414,9 @@ class MeshInterface:
def _waitConnected(self):
"""Block until the initial node db download is complete, or timeout
and raise an exception"""
- if not self.isConnected.wait(10.0): # timeout after 10 seconds
- raise Exception("Timed out waiting for connection completion")
+ if not self.noProto:
+ if not self.isConnected.wait(15.0): # timeout after x seconds
+ raise Exception("Timed out waiting for connection completion")
# If we failed while connecting, raise the connection to the client
if self.failure:
@@ -478,8 +506,9 @@ class MeshInterface:
Called by subclasses."""
fromRadio = mesh_pb2.FromRadio()
fromRadio.ParseFromString(fromRadioBytes)
+ logging.debug(f"in mesh_interface.py _handleFromRadio() fromRadioBytes: {fromRadioBytes}")
asDict = google.protobuf.json_format.MessageToDict(fromRadio)
- #logging.debug(f"Received from radio: {fromRadio}")
+ logging.debug(f"Received from radio: {fromRadio}")
if fromRadio.HasField("my_info"):
self.myInfo = fromRadio.my_info
self.localNode.nodeNum = self.myInfo.my_node_num
@@ -512,7 +541,8 @@ class MeshInterface:
self.nodesByNum[node["num"]] = node
if "user" in node: # Some nodes might not have user/ids assigned yet
- self.nodes[node["user"]["id"]] = node
+ if "id" in node["user"]:
+ self.nodes[node["user"]["id"]] = node
publishingThread.queueWork(lambda: pub.sendMessage("meshtastic.node.updated",
node=node, interface=self))
elif fromRadio.config_complete_id == self.configId:
@@ -572,16 +602,22 @@ class MeshInterface:
self.nodesByNum[nodeNum] = n
return n
- def _handlePacketFromRadio(self, meshPacket):
+ def _handlePacketFromRadio(self, meshPacket, hack=False):
"""Handle a MeshPacket that just arrived from the radio
+ hack - well, since we used 'from', which is a python keyword,
+ as an attribute to MeshPacket in protobufs,
+ there really is no way to do something like this:
+ meshPacket = mesh_pb2.MeshPacket()
+ meshPacket.from = 123
+ If hack is True, we can unit test this code.
+
Will publish one of the following events:
- meshtastic.receive.text(packet = MeshPacket dictionary)
- meshtastic.receive.position(packet = MeshPacket dictionary)
- meshtastic.receive.user(packet = MeshPacket dictionary)
- meshtastic.receive.data(packet = MeshPacket dictionary)
"""
-
asDict = google.protobuf.json_format.MessageToDict(meshPacket)
# We normally decompose the payload into a dictionary so that the client
@@ -590,10 +626,10 @@ class MeshInterface:
asDict["raw"] = meshPacket
# from might be missing if the nodenum was zero.
- if "from" not in asDict:
+ if not hack and "from" not in asDict:
asDict["from"] = 0
- logging.error(
- f"Device returned a packet we sent, ignoring: {stripnl(asDict)}")
+ logging.error(f"Device returned a packet we sent, ignoring: {stripnl(asDict)}")
+ print(f"Error: Device returned a packet we sent, ignoring: {stripnl(asDict)}")
return
if "to" not in asDict:
asDict["to"] = 0
@@ -621,9 +657,10 @@ class MeshInterface:
# UNKNOWN_APP is the default protobuf portnum value, and therefore if not
# set it will not be populated at all to make API usage easier, set
# it to prevent confusion
- if not "portnum" in decoded:
- decoded["portnum"] = portnums_pb2.PortNum.Name(
- portnums_pb2.PortNum.UNKNOWN_APP)
+ if "portnum" not in decoded:
+ new_portnum = portnums_pb2.PortNum.Name(portnums_pb2.PortNum.UNKNOWN_APP)
+ decoded["portnum"] = new_portnum
+ logging.warning(f"portnum was not in decoded. Setting to:{new_portnum}")
portnum = decoded["portnum"]
@@ -717,7 +754,7 @@ link - just be a dumb serial client.
self.nodes = None # FIXME
self.isConnected = threading.Event()
self.noProto = noProto
- self.localNode = Node(self, -1) # We fixup nodenum later
+ self.localNode = meshtastic.node.Node(self, -1) # We fixup nodenum later
self.myInfo = None # We don't have device info yet
self.responseHandlers = {} # A map from request ID to the handler
self.failure = None # If we've encountered a fatal exception it will be kept here
@@ -727,6 +764,9 @@ link - just be a dumb serial client.
self.currentPacketId = random.randint(0, 0xffffffff)
self.nodesByNum = None
self.configId = None
+ self.defaultHopLimit = 3
+ self.gotResponse = False # used in gpio read
+ self.mask = None # used in gpio read and gpio watch
def close(self):
"""Shutdown this interface"""
@@ -777,6 +817,7 @@ link - just be a dumb serial client.
rows = []
if self.nodes:
+ logging.debug(f'self.nodes:{self.nodes}')
for node in self.nodes.values():
if not includeSelf and node['num'] == self.localNode.nodeNum:
continue
@@ -822,7 +863,8 @@ link - just be a dumb serial client.
if nodeId == LOCAL_ADDR:
return self.localNode
else:
- n = Node(self, nodeId)
+ n = meshtastic.node.Node(self, nodeId)
+ logging.debug("About to requestConfig")
n.requestConfig()
if not n.waitForConfig():
our_exit("Error: Timed out waiting for node config")
@@ -832,7 +874,7 @@ link - just be a dumb serial client.
destinationId=BROADCAST_ADDR,
wantAck=False,
wantResponse=False,
- hopLimit=defaultHopLimit,
+ hopLimit=None,
onResponse=None,
channelIndex=0):
"""Send a utf8 string to some other node, if the node has a display it
@@ -854,6 +896,9 @@ link - just be a dumb serial client.
Returns the sent packet. The id field will be populated in this packet
and can be used to track future message acks/naks.
"""
+ if hopLimit is None:
+ hopLimit = self.defaultHopLimit
+
return self.sendData(text.encode("utf-8"), destinationId,
portNum=portnums_pb2.PortNum.TEXT_MESSAGE_APP,
wantAck=wantAck,
@@ -865,7 +910,7 @@ link - just be a dumb serial client.
def sendData(self, data, destinationId=BROADCAST_ADDR,
portNum=portnums_pb2.PortNum.PRIVATE_APP, wantAck=False,
wantResponse=False,
- hopLimit=defaultHopLimit,
+ hopLimit=None,
onResponse=None,
channelIndex=0):
"""Send a data packet to some other node
@@ -885,16 +930,22 @@ link - just be a dumb serial client.
onResponse -- A closure of the form funct(packet), that will be
called when a response packet arrives (or the transaction
is NAKed due to non receipt)
+ channelIndex - channel number to use
Returns the sent packet. The id field will be populated in this packet
and can be used to track future message acks/naks.
"""
+ if hopLimit is None:
+ hopLimit = self.defaultHopLimit
+
if getattr(data, "SerializeToString", None):
logging.debug(f"Serializing protobuf as data: {stripnl(data)}")
data = data.SerializeToString()
+ logging.debug(f"len(data): {len(data)}")
+ logging.debug(f"mesh_pb2.Constants.DATA_PAYLOAD_LEN: {mesh_pb2.Constants.DATA_PAYLOAD_LEN}")
if len(data) > mesh_pb2.Constants.DATA_PAYLOAD_LEN:
- Exception("Data payload too big")
+ raise Exception("Data payload too big")
if portNum == portnums_pb2.PortNum.UNKNOWN_APP: # we are now more strict wrt port numbers
our_exit("Warning: A non-zero port number must be specified")
@@ -927,16 +978,20 @@ link - just be a dumb serial client.
p = mesh_pb2.Position()
if latitude != 0.0:
p.latitude_i = int(latitude / 1e-7)
+ logging.debug(f'p.latitude_i:{p.latitude_i}')
if longitude != 0.0:
p.longitude_i = int(longitude / 1e-7)
+ logging.debug(f'p.longitude_i:{p.longitude_i}')
if altitude != 0:
p.altitude = int(altitude)
+ logging.debug(f'p.altitude:{p.altitude}')
if timeSec == 0:
timeSec = time.time() # returns unix timestamp in seconds
p.time = int(timeSec)
+ logging.debug(f'p.time:{p.time}')
return self.sendData(p, destinationId,
portNum=portnums_pb2.PortNum.POSITION_APP,
@@ -948,13 +1003,15 @@ link - just be a dumb serial client.
def _sendPacket(self, meshPacket,
destinationId=BROADCAST_ADDR,
- wantAck=False, hopLimit=defaultHopLimit):
+ wantAck=False, hopLimit=None):
"""Send a MeshPacket to the specified node (or if unspecified, broadcast).
You probably don't want this - use sendData instead.
Returns the sent packet. The id field will be populated in this packet and
can be used to track future message acks/naks.
"""
+ if hopLimit is None:
+ hopLimit = self.defaultHopLimit
# We allow users to talk to the local node before we've completed the full connection flow...
if(self.myInfo is not None and destinationId != self.myInfo.my_node_num):
@@ -962,6 +1019,7 @@ link - just be a dumb serial client.
toRadio = mesh_pb2.ToRadio()
+ nodeNum = 0
if destinationId is None:
our_exit("Warning: destinationId must not be None")
elif isinstance(destinationId, int):
@@ -969,15 +1027,21 @@ link - just be a dumb serial client.
elif destinationId == BROADCAST_ADDR:
nodeNum = BROADCAST_NUM
elif destinationId == LOCAL_ADDR:
- nodeNum = self.myInfo.my_node_num
+ if self.myInfo:
+ nodeNum = self.myInfo.my_node_num
+ else:
+ our_exit("Warning: No myInfo found.")
# A simple hex style nodeid - we can parse this without needing the DB
elif destinationId.startswith("!"):
nodeNum = int(destinationId[1:], 16)
else:
- node = self.nodes.get(destinationId)
- if not node:
- our_exit(f"Warning: NodeId {destinationId} not found in DB")
- nodeNum = node['num']
+ if self.nodes:
+ node = self.nodes.get(destinationId)
+ if not node:
+ our_exit(f"Warning: NodeId {destinationId} not found in DB")
+ nodeNum = node['num']
+ else:
+ logging.warning("Warning: There were no self.nodes.")
meshPacket.to = nodeNum
meshPacket.want_ack = wantAck
@@ -989,8 +1053,11 @@ link - just be a dumb serial client.
meshPacket.id = self._generatePacketId()
toRadio.packet.CopyFrom(meshPacket)
- #logging.debug(f"Sending packet: {stripnl(meshPacket)}")
- self._sendToRadio(toRadio)
+ if self.noProto:
+ logging.warning(f"Not sending packet because protocol use is disabled by noProto")
+ else:
+ logging.debug(f"Sending packet: {stripnl(meshPacket)}")
+ self._sendToRadio(toRadio)
return meshPacket
def waitForConfig(self):
@@ -1003,6 +1070,7 @@ link - just be a dumb serial client.
"""Get info about my node."""
if self.myInfo is None:
return None
+ logging.debug(f'self.nodesByNum:{self.nodesByNum}')
return self.nodesByNum.get(self.myInfo.my_node_num)
def getMyUser(self):
@@ -1029,8 +1097,9 @@ link - just be a dumb serial client.
def _waitConnected(self):
"""Block until the initial node db download is complete, or timeout
and raise an exception"""
- if not self.isConnected.wait(10.0): # timeout after 10 seconds
- raise Exception("Timed out waiting for connection completion")
+ if not self.noProto:
+ if not self.isConnected.wait(15.0): # timeout after x seconds
+ raise Exception("Timed out waiting for connection completion")
# If we failed while connecting, raise the connection to the client
if self.failure:
@@ -1120,8 +1189,9 @@ link - just be a dumb serial client.
Called by subclasses."""
fromRadio = mesh_pb2.FromRadio()
fromRadio.ParseFromString(fromRadioBytes)
+ logging.debug(f"in mesh_interface.py _handleFromRadio() fromRadioBytes: {fromRadioBytes}")
asDict = google.protobuf.json_format.MessageToDict(fromRadio)
- #logging.debug(f"Received from radio: {fromRadio}")
+ logging.debug(f"Received from radio: {fromRadio}")
if fromRadio.HasField("my_info"):
self.myInfo = fromRadio.my_info
self.localNode.nodeNum = self.myInfo.my_node_num
@@ -1154,7 +1224,8 @@ link - just be a dumb serial client.
self.nodesByNum[node["num"]] = node
if "user" in node: # Some nodes might not have user/ids assigned yet
- self.nodes[node["user"]["id"]] = node
+ if "id" in node["user"]:
+ self.nodes[node["user"]["id"]] = node
publishingThread.queueWork(lambda: pub.sendMessage("meshtastic.node.updated",
node=node, interface=self))
elif fromRadio.config_complete_id == self.configId:
@@ -1214,16 +1285,22 @@ link - just be a dumb serial client.
self.nodesByNum[nodeNum] = n
return n
- def _handlePacketFromRadio(self, meshPacket):
+ def _handlePacketFromRadio(self, meshPacket, hack=False):
"""Handle a MeshPacket that just arrived from the radio
+ hack - well, since we used 'from', which is a python keyword,
+ as an attribute to MeshPacket in protobufs,
+ there really is no way to do something like this:
+ meshPacket = mesh_pb2.MeshPacket()
+ meshPacket.from = 123
+ If hack is True, we can unit test this code.
+
Will publish one of the following events:
- meshtastic.receive.text(packet = MeshPacket dictionary)
- meshtastic.receive.position(packet = MeshPacket dictionary)
- meshtastic.receive.user(packet = MeshPacket dictionary)
- meshtastic.receive.data(packet = MeshPacket dictionary)
"""
-
asDict = google.protobuf.json_format.MessageToDict(meshPacket)
# We normally decompose the payload into a dictionary so that the client
@@ -1232,10 +1309,10 @@ link - just be a dumb serial client.
asDict["raw"] = meshPacket
# from might be missing if the nodenum was zero.
- if "from" not in asDict:
+ if not hack and "from" not in asDict:
asDict["from"] = 0
- logging.error(
- f"Device returned a packet we sent, ignoring: {stripnl(asDict)}")
+ logging.error(f"Device returned a packet we sent, ignoring: {stripnl(asDict)}")
+ print(f"Error: Device returned a packet we sent, ignoring: {stripnl(asDict)}")
return
if "to" not in asDict:
asDict["to"] = 0
@@ -1263,9 +1340,10 @@ link - just be a dumb serial client.
# UNKNOWN_APP is the default protobuf portnum value, and therefore if not
# set it will not be populated at all to make API usage easier, set
# it to prevent confusion
- if not "portnum" in decoded:
- decoded["portnum"] = portnums_pb2.PortNum.Name(
- portnums_pb2.PortNum.UNKNOWN_APP)
+ if "portnum" not in decoded:
+ new_portnum = portnums_pb2.PortNum.Name(portnums_pb2.PortNum.UNKNOWN_APP)
+ decoded["portnum"] = new_portnum
+ logging.warning(f"portnum was not in decoded. Setting to:{new_portnum}")
portnum = decoded["portnum"]
@@ -1364,6 +1442,7 @@ link - just be a dumb serial client.
"""Get info about my node."""
if self.myInfo is None:
return None
+ logging.debug(f'self.nodesByNum:{self.nodesByNum}')
return self.nodesByNum.get(self.myInfo.my_node_num)
@@ -1398,7 +1477,8 @@ link - just be a dumb serial client.
if nodeId == LOCAL_ADDR:
return self.localNode
else:
- n = Node(self, nodeId)
+ n = meshtastic.node.Node(self, nodeId)
+ logging.debug("About to requestConfig")
n.requestConfig()
if not n.waitForConfig():
our_exit("Error: Timed out waiting for node config")
@@ -1423,7 +1503,7 @@ link - just be a dumb serial client.
@@ -1441,7 +1521,8 @@ wantResponse – True if you want the service on the other
side to send an application layer response
onResponse – A closure of the form funct(packet), that will be
called when a response packet arrives (or the transaction
-is NAKed due to non receipt)
+is NAKed due to non receipt)
+channelIndex - channel number to use
Returns the sent packet. The id field will be populated in this packet
and can be used to track future message acks/naks.
@@ -1451,7 +1532,7 @@ and can be used to track future message acks/naks.
def sendData(self, data, destinationId=BROADCAST_ADDR,
portNum=portnums_pb2.PortNum.PRIVATE_APP, wantAck=False,
wantResponse=False,
- hopLimit=defaultHopLimit,
+ hopLimit=None,
onResponse=None,
channelIndex=0):
"""Send a data packet to some other node
@@ -1471,16 +1552,22 @@ and can be used to track future message acks/naks.
onResponse -- A closure of the form funct(packet), that will be
called when a response packet arrives (or the transaction
is NAKed due to non receipt)
+ channelIndex - channel number to use
Returns the sent packet. The id field will be populated in this packet
and can be used to track future message acks/naks.
"""
+ if hopLimit is None:
+ hopLimit = self.defaultHopLimit
+
if getattr(data, "SerializeToString", None):
logging.debug(f"Serializing protobuf as data: {stripnl(data)}")
data = data.SerializeToString()
+ logging.debug(f"len(data): {len(data)}")
+ logging.debug(f"mesh_pb2.Constants.DATA_PAYLOAD_LEN: {mesh_pb2.Constants.DATA_PAYLOAD_LEN}")
if len(data) > mesh_pb2.Constants.DATA_PAYLOAD_LEN:
- Exception("Data payload too big")
+ raise Exception("Data payload too big")
if portNum == portnums_pb2.PortNum.UNKNOWN_APP: # we are now more strict wrt port numbers
our_exit("Warning: A non-zero port number must be specified")
@@ -1528,16 +1615,20 @@ can be used to track future message acks/naks.
p = mesh_pb2.Position()
if latitude != 0.0:
p.latitude_i = int(latitude / 1e-7)
+ logging.debug(f'p.latitude_i:{p.latitude_i}')
if longitude != 0.0:
p.longitude_i = int(longitude / 1e-7)
+ logging.debug(f'p.longitude_i:{p.longitude_i}')
if altitude != 0:
p.altitude = int(altitude)
+ logging.debug(f'p.altitude:{p.altitude}')
if timeSec == 0:
timeSec = time.time() # returns unix timestamp in seconds
p.time = int(timeSec)
+ logging.debug(f'p.time:{p.time}')
return self.sendData(p, destinationId,
portNum=portnums_pb2.PortNum.POSITION_APP,
@@ -1546,7 +1637,7 @@ can be used to track future message acks/naks.
Send a utf8 string to some other node, if the node has a display it
@@ -1572,7 +1663,7 @@ and can be used to track future message acks/naks.
destinationId=BROADCAST_ADDR,
wantAck=False,
wantResponse=False,
- hopLimit=defaultHopLimit,
+ hopLimit=None,
onResponse=None,
channelIndex=0):
"""Send a utf8 string to some other node, if the node has a display it
@@ -1594,6 +1685,9 @@ and can be used to track future message acks/naks.
Returns the sent packet. The id field will be populated in this packet
and can be used to track future message acks/naks.
"""
+ if hopLimit is None:
+ hopLimit = self.defaultHopLimit
+
return self.sendData(text.encode("utf-8"), destinationId,
portNum=portnums_pb2.PortNum.TEXT_MESSAGE_APP,
wantAck=wantAck,
@@ -1653,6 +1747,7 @@ and can be used to track future message acks/naks.
rows = []
if self.nodes:
+ logging.debug(f'self.nodes:{self.nodes}')
for node in self.nodes.values():
if not includeSelf and node['num'] == self.localNode.nodeNum:
continue
diff --git a/docs/meshtastic/mesh_pb2.html b/docs/meshtastic/mesh_pb2.html
index 7645371..144e18d 100644
--- a/docs/meshtastic/mesh_pb2.html
+++ b/docs/meshtastic/mesh_pb2.html
@@ -1706,16 +1706,13 @@ _MYNODEINFO.fields_by_name['hw_model_deprecated']._options = None
class Data
-(**kwargs)
+(*args, **kwargs)
-
Abstract base class for protocol messages.
-
Protocol message classes are almost always generated by the protocol
-compiler.
-These generated types subclass Message and implement the methods
-shown below.
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field Data.dest
var payload
-
Getter for payload.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field Data.payload
var portnum
-
Getter for portnum.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field Data.portnum
var request_id
-
Getter for request_id.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field Data.request_id
var source
-
Getter for source.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field Data.source
var want_response
-
Getter for want_response.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
-
-
-
Methods
-
-
-def ByteSize(self)
-
-
-
-
-
-Expand source code
-
-
def ByteSize(self):
- if not self._cached_byte_size_dirty:
- return self._cached_byte_size
-
- size = 0
- descriptor = self.DESCRIPTOR
- if descriptor.GetOptions().map_entry:
- # Fields of map entry should always be serialized.
- size = descriptor.fields_by_name['key']._sizer(self.key)
- size += descriptor.fields_by_name['value']._sizer(self.value)
- else:
- for field_descriptor, field_value in self.ListFields():
- size += field_descriptor._sizer(field_value)
- for tag_bytes, value_bytes in self._unknown_fields:
- size += len(tag_bytes) + len(value_bytes)
-
- self._cached_byte_size = size
- self._cached_byte_size_dirty = False
- self._listener_for_children.dirty = False
- return size
def ClearField(self, field_name):
- try:
- field = message_descriptor.fields_by_name[field_name]
- except KeyError:
- try:
- field = message_descriptor.oneofs_by_name[field_name]
- if field in self._oneofs:
- field = self._oneofs[field]
- else:
- return
- except KeyError:
- raise ValueError('Protocol message %s has no "%s" field.' %
- (message_descriptor.name, field_name))
-
- if field in self._fields:
- # To match the C++ implementation, we need to invalidate iterators
- # for map fields when ClearField() happens.
- if hasattr(self._fields[field], 'InvalidateIterators'):
- self._fields[field].InvalidateIterators()
-
- # Note: If the field is a sub-message, its listener will still point
- # at us. That's fine, because the worst than can happen is that it
- # will call _Modified() and invalidate our byte size. Big deal.
- del self._fields[field]
-
- if self._oneofs.get(field.containing_oneof, None) is field:
- del self._oneofs[field.containing_oneof]
-
- # Always call _Modified() -- even if nothing was changed, this is
- # a mutating method, and thus calling it should cause the field to become
- # present in the parent message.
- self._Modified()
-
-
-
-def DiscardUnknownFields(self)
-
-
-
-
-
-Expand source code
-
-
def _DiscardUnknownFields(self):
- self._unknown_fields = []
- self._unknown_field_set = None # pylint: disable=protected-access
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if _IsMapField(field):
- if _IsMessageMapField(field):
- for key in value:
- value[key].DiscardUnknownFields()
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
- for sub_message in value:
- sub_message.DiscardUnknownFields()
- else:
- value.DiscardUnknownFields()
-
-
-
-def FindInitializationErrors(self)
-
-
-
Finds required fields which are not initialized.
-
Returns
-
A list of strings.
-Each string is a path to an uninitialized field from
-the top-level message, e.g. "foo.bar[5].baz".
-
-
-Expand source code
-
-
def FindInitializationErrors(self):
- """Finds required fields which are not initialized.
-
- Returns:
- A list of strings. Each string is a path to an uninitialized field from
- the top-level message, e.g. "foo.bar[5].baz".
- """
-
- errors = [] # simplify things
-
- for field in required_fields:
- if not self.HasField(field.name):
- errors.append(field.name)
-
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.is_extension:
- name = '(%s)' % field.full_name
- else:
- name = field.name
-
- if _IsMapField(field):
- if _IsMessageMapField(field):
- for key in value:
- element = value[key]
- prefix = '%s[%s].' % (name, key)
- sub_errors = element.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
- else:
- # ScalarMaps can't have any initialization errors.
- pass
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
- for i in range(len(value)):
- element = value[i]
- prefix = '%s[%d].' % (name, i)
- sub_errors = element.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
- else:
- prefix = name + '.'
- sub_errors = value.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
-
- return errors
-
-
-
-def HasField(self, field_name)
-
-
-
-
-
-Expand source code
-
-
def HasField(self, field_name):
- try:
- field = hassable_fields[field_name]
- except KeyError:
- raise ValueError(error_msg % (message_descriptor.full_name, field_name))
-
- if isinstance(field, descriptor_mod.OneofDescriptor):
- try:
- return HasField(self, self._oneofs[field].name)
- except KeyError:
- return False
- else:
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- value = self._fields.get(field)
- return value is not None and value._is_present_in_parent
- else:
- return field in self._fields
-
-
-
-def IsInitialized(self, errors=None)
-
-
-
Checks if all required fields of a message are set.
-
Args
-
-
errors
-
A list which, if provided, will be populated with the field
-paths of all missing required fields.
-
-
Returns
-
True iff the specified message has all required fields set.
-
-
-Expand source code
-
-
def IsInitialized(self, errors=None):
- """Checks if all required fields of a message are set.
-
- Args:
- errors: A list which, if provided, will be populated with the field
- paths of all missing required fields.
-
- Returns:
- True iff the specified message has all required fields set.
- """
-
- # Performance is critical so we avoid HasField() and ListFields().
-
- for field in required_fields:
- if (field not in self._fields or
- (field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE and
- not self._fields[field]._is_present_in_parent)):
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- for field, value in list(self._fields.items()): # dict can change size!
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.label == _FieldDescriptor.LABEL_REPEATED:
- if (field.message_type.has_options and
- field.message_type.GetOptions().map_entry):
- continue
- for element in value:
- if not element.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
- elif value._is_present_in_parent and not value.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- return True
-
-
-
-def ListFields(self)
-
-
-
-
-
-Expand source code
-
-
def ListFields(self):
- all_fields = [item for item in self._fields.items() if _IsPresent(item)]
- all_fields.sort(key = lambda item: item[0].number)
- return all_fields
-
-
-
-def MergeFrom(self, msg)
-
-
-
-
-
-Expand source code
-
-
def MergeFrom(self, msg):
- if not isinstance(msg, cls):
- raise TypeError(
- 'Parameter to MergeFrom() must be instance of same class: '
- 'expected %s got %s.' % (_FullyQualifiedClassName(cls),
- _FullyQualifiedClassName(msg.__class__)))
-
- assert msg is not self
- self._Modified()
-
- fields = self._fields
-
- for field, value in msg._fields.items():
- if field.label == LABEL_REPEATED:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- elif field.cpp_type == CPPTYPE_MESSAGE:
- if value._is_present_in_parent:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- else:
- self._fields[field] = value
- if field.containing_oneof:
- self._UpdateOneofState(field)
-
- if msg._unknown_fields:
- if not self._unknown_fields:
- self._unknown_fields = []
- self._unknown_fields.extend(msg._unknown_fields)
- # pylint: disable=protected-access
- if self._unknown_field_set is None:
- self._unknown_field_set = containers.UnknownFieldSet()
- self._unknown_field_set._extend(msg._unknown_field_set)
-
-
-
-def MergeFromString(self, serialized)
-
-
-
-
-
-Expand source code
-
-
def MergeFromString(self, serialized):
- serialized = memoryview(serialized)
- length = len(serialized)
- try:
- if self._InternalParse(serialized, 0, length) != length:
- # The only reason _InternalParse would return early is if it
- # encountered an end-group tag.
- raise message_mod.DecodeError('Unexpected end-group tag.')
- except (IndexError, TypeError):
- # Now ord(buf[p:p+1]) == ord('') gets TypeError.
- raise message_mod.DecodeError('Truncated message.')
- except struct.error as e:
- raise message_mod.DecodeError(e)
- return length # Return this for legacy reasons.
def SerializeToString(self, **kwargs):
- # Check if the message has all of its required fields set.
- if not self.IsInitialized():
- raise message_mod.EncodeError(
- 'Message %s is missing required fields: %s' % (
- self.DESCRIPTOR.full_name, ','.join(self.FindInitializationErrors())))
- return self.SerializePartialToString(**kwargs)
-
-
-
-def SetInParent(self)
-
-
-
Sets the _cached_byte_size_dirty bit to true,
-and propagates this to our listener iff this was a state change.
-
-
-Expand source code
-
-
def Modified(self):
- """Sets the _cached_byte_size_dirty bit to true,
- and propagates this to our listener iff this was a state change.
- """
-
- # Note: Some callers check _cached_byte_size_dirty before calling
- # _Modified() as an extra optimization. So, if this method is ever
- # changed such that it does stuff even when _cached_byte_size_dirty is
- # already true, the callers need to be updated.
- if not self._cached_byte_size_dirty:
- self._cached_byte_size_dirty = True
- self._listener_for_children.dirty = True
- self._is_present_in_parent = True
- self._listener.Modified()
Returns the name of the currently set field inside a oneof, or None.
-
-
-Expand source code
-
-
def WhichOneof(self, oneof_name):
- """Returns the name of the currently set field inside a oneof, or None."""
- try:
- field = message_descriptor.oneofs_by_name[oneof_name]
- except KeyError:
- raise ValueError(
- 'Protocol message has no oneof "%s" field.' % oneof_name)
-
- nested_field = self._oneofs.get(field, None)
- if nested_field is not None and self.HasField(nested_field.name):
- return nested_field.name
- else:
- return None
-
+
Field Data.want_response
class FromRadio
-(**kwargs)
+(*args, **kwargs)
-
Abstract base class for protocol messages.
-
Protocol message classes are almost always generated by the protocol
-compiler.
-These generated types subclass Message and implement the methods
-shown below.
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field FromRadio.config_complete_id
var log_record
-
Getter for log_record.
-
-
-Expand source code
-
-
def getter(self):
- field_value = self._fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
-
- # Atomically check if another thread has preempted us and, if not, swap
- # in the new object we just created. If someone has preempted us, we
- # take that object and discard ours.
- # WARNING: We are relying on setdefault() being atomic. This is true
- # in CPython but we haven't investigated others. This warning appears
- # in several other locations in this file.
- field_value = self._fields.setdefault(field, field_value)
- return field_value
-
+
Field FromRadio.log_record
var my_info
-
Getter for my_info.
-
-
-Expand source code
-
-
def getter(self):
- field_value = self._fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
-
- # Atomically check if another thread has preempted us and, if not, swap
- # in the new object we just created. If someone has preempted us, we
- # take that object and discard ours.
- # WARNING: We are relying on setdefault() being atomic. This is true
- # in CPython but we haven't investigated others. This warning appears
- # in several other locations in this file.
- field_value = self._fields.setdefault(field, field_value)
- return field_value
-
+
Field FromRadio.my_info
var node_info
-
Getter for node_info.
-
-
-Expand source code
-
-
def getter(self):
- field_value = self._fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
-
- # Atomically check if another thread has preempted us and, if not, swap
- # in the new object we just created. If someone has preempted us, we
- # take that object and discard ours.
- # WARNING: We are relying on setdefault() being atomic. This is true
- # in CPython but we haven't investigated others. This warning appears
- # in several other locations in this file.
- field_value = self._fields.setdefault(field, field_value)
- return field_value
-
+
Field FromRadio.node_info
var num
-
Getter for num.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field FromRadio.num
var packet
-
Getter for packet.
-
-
-Expand source code
-
-
def getter(self):
- field_value = self._fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
-
- # Atomically check if another thread has preempted us and, if not, swap
- # in the new object we just created. If someone has preempted us, we
- # take that object and discard ours.
- # WARNING: We are relying on setdefault() being atomic. This is true
- # in CPython but we haven't investigated others. This warning appears
- # in several other locations in this file.
- field_value = self._fields.setdefault(field, field_value)
- return field_value
-
+
Field FromRadio.packet
var rebooted
-
Getter for rebooted.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
-
-
-
Methods
-
-
-def ByteSize(self)
-
-
-
-
-
-Expand source code
-
-
def ByteSize(self):
- if not self._cached_byte_size_dirty:
- return self._cached_byte_size
-
- size = 0
- descriptor = self.DESCRIPTOR
- if descriptor.GetOptions().map_entry:
- # Fields of map entry should always be serialized.
- size = descriptor.fields_by_name['key']._sizer(self.key)
- size += descriptor.fields_by_name['value']._sizer(self.value)
- else:
- for field_descriptor, field_value in self.ListFields():
- size += field_descriptor._sizer(field_value)
- for tag_bytes, value_bytes in self._unknown_fields:
- size += len(tag_bytes) + len(value_bytes)
-
- self._cached_byte_size = size
- self._cached_byte_size_dirty = False
- self._listener_for_children.dirty = False
- return size
def ClearField(self, field_name):
- try:
- field = message_descriptor.fields_by_name[field_name]
- except KeyError:
- try:
- field = message_descriptor.oneofs_by_name[field_name]
- if field in self._oneofs:
- field = self._oneofs[field]
- else:
- return
- except KeyError:
- raise ValueError('Protocol message %s has no "%s" field.' %
- (message_descriptor.name, field_name))
-
- if field in self._fields:
- # To match the C++ implementation, we need to invalidate iterators
- # for map fields when ClearField() happens.
- if hasattr(self._fields[field], 'InvalidateIterators'):
- self._fields[field].InvalidateIterators()
-
- # Note: If the field is a sub-message, its listener will still point
- # at us. That's fine, because the worst than can happen is that it
- # will call _Modified() and invalidate our byte size. Big deal.
- del self._fields[field]
-
- if self._oneofs.get(field.containing_oneof, None) is field:
- del self._oneofs[field.containing_oneof]
-
- # Always call _Modified() -- even if nothing was changed, this is
- # a mutating method, and thus calling it should cause the field to become
- # present in the parent message.
- self._Modified()
-
-
-
-def DiscardUnknownFields(self)
-
-
-
-
-
-Expand source code
-
-
def _DiscardUnknownFields(self):
- self._unknown_fields = []
- self._unknown_field_set = None # pylint: disable=protected-access
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if _IsMapField(field):
- if _IsMessageMapField(field):
- for key in value:
- value[key].DiscardUnknownFields()
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
- for sub_message in value:
- sub_message.DiscardUnknownFields()
- else:
- value.DiscardUnknownFields()
-
-
-
-def FindInitializationErrors(self)
-
-
-
Finds required fields which are not initialized.
-
Returns
-
A list of strings.
-Each string is a path to an uninitialized field from
-the top-level message, e.g. "foo.bar[5].baz".
-
-
-Expand source code
-
-
def FindInitializationErrors(self):
- """Finds required fields which are not initialized.
-
- Returns:
- A list of strings. Each string is a path to an uninitialized field from
- the top-level message, e.g. "foo.bar[5].baz".
- """
-
- errors = [] # simplify things
-
- for field in required_fields:
- if not self.HasField(field.name):
- errors.append(field.name)
-
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.is_extension:
- name = '(%s)' % field.full_name
- else:
- name = field.name
-
- if _IsMapField(field):
- if _IsMessageMapField(field):
- for key in value:
- element = value[key]
- prefix = '%s[%s].' % (name, key)
- sub_errors = element.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
- else:
- # ScalarMaps can't have any initialization errors.
- pass
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
- for i in range(len(value)):
- element = value[i]
- prefix = '%s[%d].' % (name, i)
- sub_errors = element.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
- else:
- prefix = name + '.'
- sub_errors = value.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
-
- return errors
-
-
-
-def HasField(self, field_name)
-
-
-
-
-
-Expand source code
-
-
def HasField(self, field_name):
- try:
- field = hassable_fields[field_name]
- except KeyError:
- raise ValueError(error_msg % (message_descriptor.full_name, field_name))
-
- if isinstance(field, descriptor_mod.OneofDescriptor):
- try:
- return HasField(self, self._oneofs[field].name)
- except KeyError:
- return False
- else:
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- value = self._fields.get(field)
- return value is not None and value._is_present_in_parent
- else:
- return field in self._fields
-
-
-
-def IsInitialized(self, errors=None)
-
-
-
Checks if all required fields of a message are set.
-
Args
-
-
errors
-
A list which, if provided, will be populated with the field
-paths of all missing required fields.
-
-
Returns
-
True iff the specified message has all required fields set.
-
-
-Expand source code
-
-
def IsInitialized(self, errors=None):
- """Checks if all required fields of a message are set.
-
- Args:
- errors: A list which, if provided, will be populated with the field
- paths of all missing required fields.
-
- Returns:
- True iff the specified message has all required fields set.
- """
-
- # Performance is critical so we avoid HasField() and ListFields().
-
- for field in required_fields:
- if (field not in self._fields or
- (field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE and
- not self._fields[field]._is_present_in_parent)):
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- for field, value in list(self._fields.items()): # dict can change size!
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.label == _FieldDescriptor.LABEL_REPEATED:
- if (field.message_type.has_options and
- field.message_type.GetOptions().map_entry):
- continue
- for element in value:
- if not element.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
- elif value._is_present_in_parent and not value.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- return True
-
-
-
-def ListFields(self)
-
-
-
-
-
-Expand source code
-
-
def ListFields(self):
- all_fields = [item for item in self._fields.items() if _IsPresent(item)]
- all_fields.sort(key = lambda item: item[0].number)
- return all_fields
-
-
-
-def MergeFrom(self, msg)
-
-
-
-
-
-Expand source code
-
-
def MergeFrom(self, msg):
- if not isinstance(msg, cls):
- raise TypeError(
- 'Parameter to MergeFrom() must be instance of same class: '
- 'expected %s got %s.' % (_FullyQualifiedClassName(cls),
- _FullyQualifiedClassName(msg.__class__)))
-
- assert msg is not self
- self._Modified()
-
- fields = self._fields
-
- for field, value in msg._fields.items():
- if field.label == LABEL_REPEATED:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- elif field.cpp_type == CPPTYPE_MESSAGE:
- if value._is_present_in_parent:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- else:
- self._fields[field] = value
- if field.containing_oneof:
- self._UpdateOneofState(field)
-
- if msg._unknown_fields:
- if not self._unknown_fields:
- self._unknown_fields = []
- self._unknown_fields.extend(msg._unknown_fields)
- # pylint: disable=protected-access
- if self._unknown_field_set is None:
- self._unknown_field_set = containers.UnknownFieldSet()
- self._unknown_field_set._extend(msg._unknown_field_set)
-
-
-
-def MergeFromString(self, serialized)
-
-
-
-
-
-Expand source code
-
-
def MergeFromString(self, serialized):
- serialized = memoryview(serialized)
- length = len(serialized)
- try:
- if self._InternalParse(serialized, 0, length) != length:
- # The only reason _InternalParse would return early is if it
- # encountered an end-group tag.
- raise message_mod.DecodeError('Unexpected end-group tag.')
- except (IndexError, TypeError):
- # Now ord(buf[p:p+1]) == ord('') gets TypeError.
- raise message_mod.DecodeError('Truncated message.')
- except struct.error as e:
- raise message_mod.DecodeError(e)
- return length # Return this for legacy reasons.
def SerializeToString(self, **kwargs):
- # Check if the message has all of its required fields set.
- if not self.IsInitialized():
- raise message_mod.EncodeError(
- 'Message %s is missing required fields: %s' % (
- self.DESCRIPTOR.full_name, ','.join(self.FindInitializationErrors())))
- return self.SerializePartialToString(**kwargs)
-
-
-
-def SetInParent(self)
-
-
-
Sets the _cached_byte_size_dirty bit to true,
-and propagates this to our listener iff this was a state change.
-
-
-Expand source code
-
-
def Modified(self):
- """Sets the _cached_byte_size_dirty bit to true,
- and propagates this to our listener iff this was a state change.
- """
-
- # Note: Some callers check _cached_byte_size_dirty before calling
- # _Modified() as an extra optimization. So, if this method is ever
- # changed such that it does stuff even when _cached_byte_size_dirty is
- # already true, the callers need to be updated.
- if not self._cached_byte_size_dirty:
- self._cached_byte_size_dirty = True
- self._listener_for_children.dirty = True
- self._is_present_in_parent = True
- self._listener.Modified()
Returns the name of the currently set field inside a oneof, or None.
-
-
-Expand source code
-
-
def WhichOneof(self, oneof_name):
- """Returns the name of the currently set field inside a oneof, or None."""
- try:
- field = message_descriptor.oneofs_by_name[oneof_name]
- except KeyError:
- raise ValueError(
- 'Protocol message has no oneof "%s" field.' % oneof_name)
-
- nested_field = self._oneofs.get(field, None)
- if nested_field is not None and self.HasField(nested_field.name):
- return nested_field.name
- else:
- return None
-
+
Field FromRadio.rebooted
class LogRecord
-(**kwargs)
+(*args, **kwargs)
-
Abstract base class for protocol messages.
-
Protocol message classes are almost always generated by the protocol
-compiler.
-These generated types subclass Message and implement the methods
-shown below.
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field LogRecord.level
var message
-
Getter for message.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field LogRecord.message
var source
-
Getter for source.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field LogRecord.source
var time
-
Getter for time.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
-
-
-
Methods
-
-
-def ByteSize(self)
-
-
-
-
-
-Expand source code
-
-
def ByteSize(self):
- if not self._cached_byte_size_dirty:
- return self._cached_byte_size
-
- size = 0
- descriptor = self.DESCRIPTOR
- if descriptor.GetOptions().map_entry:
- # Fields of map entry should always be serialized.
- size = descriptor.fields_by_name['key']._sizer(self.key)
- size += descriptor.fields_by_name['value']._sizer(self.value)
- else:
- for field_descriptor, field_value in self.ListFields():
- size += field_descriptor._sizer(field_value)
- for tag_bytes, value_bytes in self._unknown_fields:
- size += len(tag_bytes) + len(value_bytes)
-
- self._cached_byte_size = size
- self._cached_byte_size_dirty = False
- self._listener_for_children.dirty = False
- return size
def ClearField(self, field_name):
- try:
- field = message_descriptor.fields_by_name[field_name]
- except KeyError:
- try:
- field = message_descriptor.oneofs_by_name[field_name]
- if field in self._oneofs:
- field = self._oneofs[field]
- else:
- return
- except KeyError:
- raise ValueError('Protocol message %s has no "%s" field.' %
- (message_descriptor.name, field_name))
-
- if field in self._fields:
- # To match the C++ implementation, we need to invalidate iterators
- # for map fields when ClearField() happens.
- if hasattr(self._fields[field], 'InvalidateIterators'):
- self._fields[field].InvalidateIterators()
-
- # Note: If the field is a sub-message, its listener will still point
- # at us. That's fine, because the worst than can happen is that it
- # will call _Modified() and invalidate our byte size. Big deal.
- del self._fields[field]
-
- if self._oneofs.get(field.containing_oneof, None) is field:
- del self._oneofs[field.containing_oneof]
-
- # Always call _Modified() -- even if nothing was changed, this is
- # a mutating method, and thus calling it should cause the field to become
- # present in the parent message.
- self._Modified()
-
-
-
-def DiscardUnknownFields(self)
-
-
-
-
-
-Expand source code
-
-
def _DiscardUnknownFields(self):
- self._unknown_fields = []
- self._unknown_field_set = None # pylint: disable=protected-access
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if _IsMapField(field):
- if _IsMessageMapField(field):
- for key in value:
- value[key].DiscardUnknownFields()
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
- for sub_message in value:
- sub_message.DiscardUnknownFields()
- else:
- value.DiscardUnknownFields()
-
-
-
-def FindInitializationErrors(self)
-
-
-
Finds required fields which are not initialized.
-
Returns
-
A list of strings.
-Each string is a path to an uninitialized field from
-the top-level message, e.g. "foo.bar[5].baz".
-
-
-Expand source code
-
-
def FindInitializationErrors(self):
- """Finds required fields which are not initialized.
-
- Returns:
- A list of strings. Each string is a path to an uninitialized field from
- the top-level message, e.g. "foo.bar[5].baz".
- """
-
- errors = [] # simplify things
-
- for field in required_fields:
- if not self.HasField(field.name):
- errors.append(field.name)
-
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.is_extension:
- name = '(%s)' % field.full_name
- else:
- name = field.name
-
- if _IsMapField(field):
- if _IsMessageMapField(field):
- for key in value:
- element = value[key]
- prefix = '%s[%s].' % (name, key)
- sub_errors = element.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
- else:
- # ScalarMaps can't have any initialization errors.
- pass
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
- for i in range(len(value)):
- element = value[i]
- prefix = '%s[%d].' % (name, i)
- sub_errors = element.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
- else:
- prefix = name + '.'
- sub_errors = value.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
-
- return errors
-
-
-
-def HasField(self, field_name)
-
-
-
-
-
-Expand source code
-
-
def HasField(self, field_name):
- try:
- field = hassable_fields[field_name]
- except KeyError:
- raise ValueError(error_msg % (message_descriptor.full_name, field_name))
-
- if isinstance(field, descriptor_mod.OneofDescriptor):
- try:
- return HasField(self, self._oneofs[field].name)
- except KeyError:
- return False
- else:
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- value = self._fields.get(field)
- return value is not None and value._is_present_in_parent
- else:
- return field in self._fields
-
-
-
-def IsInitialized(self, errors=None)
-
-
-
Checks if all required fields of a message are set.
-
Args
-
-
errors
-
A list which, if provided, will be populated with the field
-paths of all missing required fields.
-
-
Returns
-
True iff the specified message has all required fields set.
-
-
-Expand source code
-
-
def IsInitialized(self, errors=None):
- """Checks if all required fields of a message are set.
-
- Args:
- errors: A list which, if provided, will be populated with the field
- paths of all missing required fields.
-
- Returns:
- True iff the specified message has all required fields set.
- """
-
- # Performance is critical so we avoid HasField() and ListFields().
-
- for field in required_fields:
- if (field not in self._fields or
- (field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE and
- not self._fields[field]._is_present_in_parent)):
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- for field, value in list(self._fields.items()): # dict can change size!
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.label == _FieldDescriptor.LABEL_REPEATED:
- if (field.message_type.has_options and
- field.message_type.GetOptions().map_entry):
- continue
- for element in value:
- if not element.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
- elif value._is_present_in_parent and not value.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- return True
-
-
-
-def ListFields(self)
-
-
-
-
-
-Expand source code
-
-
def ListFields(self):
- all_fields = [item for item in self._fields.items() if _IsPresent(item)]
- all_fields.sort(key = lambda item: item[0].number)
- return all_fields
-
-
-
-def MergeFrom(self, msg)
-
-
-
-
-
-Expand source code
-
-
def MergeFrom(self, msg):
- if not isinstance(msg, cls):
- raise TypeError(
- 'Parameter to MergeFrom() must be instance of same class: '
- 'expected %s got %s.' % (_FullyQualifiedClassName(cls),
- _FullyQualifiedClassName(msg.__class__)))
-
- assert msg is not self
- self._Modified()
-
- fields = self._fields
-
- for field, value in msg._fields.items():
- if field.label == LABEL_REPEATED:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- elif field.cpp_type == CPPTYPE_MESSAGE:
- if value._is_present_in_parent:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- else:
- self._fields[field] = value
- if field.containing_oneof:
- self._UpdateOneofState(field)
-
- if msg._unknown_fields:
- if not self._unknown_fields:
- self._unknown_fields = []
- self._unknown_fields.extend(msg._unknown_fields)
- # pylint: disable=protected-access
- if self._unknown_field_set is None:
- self._unknown_field_set = containers.UnknownFieldSet()
- self._unknown_field_set._extend(msg._unknown_field_set)
-
-
-
-def MergeFromString(self, serialized)
-
-
-
-
-
-Expand source code
-
-
def MergeFromString(self, serialized):
- serialized = memoryview(serialized)
- length = len(serialized)
- try:
- if self._InternalParse(serialized, 0, length) != length:
- # The only reason _InternalParse would return early is if it
- # encountered an end-group tag.
- raise message_mod.DecodeError('Unexpected end-group tag.')
- except (IndexError, TypeError):
- # Now ord(buf[p:p+1]) == ord('') gets TypeError.
- raise message_mod.DecodeError('Truncated message.')
- except struct.error as e:
- raise message_mod.DecodeError(e)
- return length # Return this for legacy reasons.
def SerializeToString(self, **kwargs):
- # Check if the message has all of its required fields set.
- if not self.IsInitialized():
- raise message_mod.EncodeError(
- 'Message %s is missing required fields: %s' % (
- self.DESCRIPTOR.full_name, ','.join(self.FindInitializationErrors())))
- return self.SerializePartialToString(**kwargs)
-
-
-
-def SetInParent(self)
-
-
-
Sets the _cached_byte_size_dirty bit to true,
-and propagates this to our listener iff this was a state change.
-
-
-Expand source code
-
-
def Modified(self):
- """Sets the _cached_byte_size_dirty bit to true,
- and propagates this to our listener iff this was a state change.
- """
-
- # Note: Some callers check _cached_byte_size_dirty before calling
- # _Modified() as an extra optimization. So, if this method is ever
- # changed such that it does stuff even when _cached_byte_size_dirty is
- # already true, the callers need to be updated.
- if not self._cached_byte_size_dirty:
- self._cached_byte_size_dirty = True
- self._listener_for_children.dirty = True
- self._is_present_in_parent = True
- self._listener.Modified()
Returns the name of the currently set field inside a oneof, or None.
-
-
-Expand source code
-
-
def WhichOneof(self, oneof_name):
- """Returns the name of the currently set field inside a oneof, or None."""
- try:
- field = message_descriptor.oneofs_by_name[oneof_name]
- except KeyError:
- raise ValueError(
- 'Protocol message has no oneof "%s" field.' % oneof_name)
-
- nested_field = self._oneofs.get(field, None)
- if nested_field is not None and self.HasField(nested_field.name):
- return nested_field.name
- else:
- return None
-
+
Field LogRecord.time
class MeshPacket
-(**kwargs)
+(*args, **kwargs)
-
Abstract base class for protocol messages.
-
Protocol message classes are almost always generated by the protocol
-compiler.
-These generated types subclass Message and implement the methods
-shown below.
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field MeshPacket.channel
var decoded
-
Getter for decoded.
-
-
-Expand source code
-
-
def getter(self):
- field_value = self._fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
-
- # Atomically check if another thread has preempted us and, if not, swap
- # in the new object we just created. If someone has preempted us, we
- # take that object and discard ours.
- # WARNING: We are relying on setdefault() being atomic. This is true
- # in CPython but we haven't investigated others. This warning appears
- # in several other locations in this file.
- field_value = self._fields.setdefault(field, field_value)
- return field_value
-
+
Field MeshPacket.decoded
var encrypted
-
Getter for encrypted.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field MeshPacket.encrypted
var from
-
Getter for from.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field MeshPacket.from
var hop_limit
-
Getter for hop_limit.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field MeshPacket.hop_limit
var id
-
Getter for id.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field MeshPacket.id
var priority
-
Getter for priority.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field MeshPacket.priority
var rx_rssi
-
Getter for rx_rssi.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field MeshPacket.rx_rssi
var rx_snr
-
Getter for rx_snr.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field MeshPacket.rx_snr
var rx_time
-
Getter for rx_time.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field MeshPacket.rx_time
var to
-
Getter for to.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field MeshPacket.to
var want_ack
-
Getter for want_ack.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
-
-
-
Methods
-
-
-def ByteSize(self)
-
-
-
-
-
-Expand source code
-
-
def ByteSize(self):
- if not self._cached_byte_size_dirty:
- return self._cached_byte_size
-
- size = 0
- descriptor = self.DESCRIPTOR
- if descriptor.GetOptions().map_entry:
- # Fields of map entry should always be serialized.
- size = descriptor.fields_by_name['key']._sizer(self.key)
- size += descriptor.fields_by_name['value']._sizer(self.value)
- else:
- for field_descriptor, field_value in self.ListFields():
- size += field_descriptor._sizer(field_value)
- for tag_bytes, value_bytes in self._unknown_fields:
- size += len(tag_bytes) + len(value_bytes)
-
- self._cached_byte_size = size
- self._cached_byte_size_dirty = False
- self._listener_for_children.dirty = False
- return size
def ClearField(self, field_name):
- try:
- field = message_descriptor.fields_by_name[field_name]
- except KeyError:
- try:
- field = message_descriptor.oneofs_by_name[field_name]
- if field in self._oneofs:
- field = self._oneofs[field]
- else:
- return
- except KeyError:
- raise ValueError('Protocol message %s has no "%s" field.' %
- (message_descriptor.name, field_name))
-
- if field in self._fields:
- # To match the C++ implementation, we need to invalidate iterators
- # for map fields when ClearField() happens.
- if hasattr(self._fields[field], 'InvalidateIterators'):
- self._fields[field].InvalidateIterators()
-
- # Note: If the field is a sub-message, its listener will still point
- # at us. That's fine, because the worst than can happen is that it
- # will call _Modified() and invalidate our byte size. Big deal.
- del self._fields[field]
-
- if self._oneofs.get(field.containing_oneof, None) is field:
- del self._oneofs[field.containing_oneof]
-
- # Always call _Modified() -- even if nothing was changed, this is
- # a mutating method, and thus calling it should cause the field to become
- # present in the parent message.
- self._Modified()
-
-
-
-def DiscardUnknownFields(self)
-
-
-
-
-
-Expand source code
-
-
def _DiscardUnknownFields(self):
- self._unknown_fields = []
- self._unknown_field_set = None # pylint: disable=protected-access
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if _IsMapField(field):
- if _IsMessageMapField(field):
- for key in value:
- value[key].DiscardUnknownFields()
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
- for sub_message in value:
- sub_message.DiscardUnknownFields()
- else:
- value.DiscardUnknownFields()
-
-
-
-def FindInitializationErrors(self)
-
-
-
Finds required fields which are not initialized.
-
Returns
-
A list of strings.
-Each string is a path to an uninitialized field from
-the top-level message, e.g. "foo.bar[5].baz".
-
-
-Expand source code
-
-
def FindInitializationErrors(self):
- """Finds required fields which are not initialized.
-
- Returns:
- A list of strings. Each string is a path to an uninitialized field from
- the top-level message, e.g. "foo.bar[5].baz".
- """
-
- errors = [] # simplify things
-
- for field in required_fields:
- if not self.HasField(field.name):
- errors.append(field.name)
-
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.is_extension:
- name = '(%s)' % field.full_name
- else:
- name = field.name
-
- if _IsMapField(field):
- if _IsMessageMapField(field):
- for key in value:
- element = value[key]
- prefix = '%s[%s].' % (name, key)
- sub_errors = element.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
- else:
- # ScalarMaps can't have any initialization errors.
- pass
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
- for i in range(len(value)):
- element = value[i]
- prefix = '%s[%d].' % (name, i)
- sub_errors = element.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
- else:
- prefix = name + '.'
- sub_errors = value.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
-
- return errors
-
-
-
-def HasField(self, field_name)
-
-
-
-
-
-Expand source code
-
-
def HasField(self, field_name):
- try:
- field = hassable_fields[field_name]
- except KeyError:
- raise ValueError(error_msg % (message_descriptor.full_name, field_name))
-
- if isinstance(field, descriptor_mod.OneofDescriptor):
- try:
- return HasField(self, self._oneofs[field].name)
- except KeyError:
- return False
- else:
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- value = self._fields.get(field)
- return value is not None and value._is_present_in_parent
- else:
- return field in self._fields
-
-
-
-def IsInitialized(self, errors=None)
-
-
-
Checks if all required fields of a message are set.
-
Args
-
-
errors
-
A list which, if provided, will be populated with the field
-paths of all missing required fields.
-
-
Returns
-
True iff the specified message has all required fields set.
-
-
-Expand source code
-
-
def IsInitialized(self, errors=None):
- """Checks if all required fields of a message are set.
-
- Args:
- errors: A list which, if provided, will be populated with the field
- paths of all missing required fields.
-
- Returns:
- True iff the specified message has all required fields set.
- """
-
- # Performance is critical so we avoid HasField() and ListFields().
-
- for field in required_fields:
- if (field not in self._fields or
- (field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE and
- not self._fields[field]._is_present_in_parent)):
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- for field, value in list(self._fields.items()): # dict can change size!
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.label == _FieldDescriptor.LABEL_REPEATED:
- if (field.message_type.has_options and
- field.message_type.GetOptions().map_entry):
- continue
- for element in value:
- if not element.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
- elif value._is_present_in_parent and not value.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- return True
-
-
-
-def ListFields(self)
-
-
-
-
-
-Expand source code
-
-
def ListFields(self):
- all_fields = [item for item in self._fields.items() if _IsPresent(item)]
- all_fields.sort(key = lambda item: item[0].number)
- return all_fields
-
-
-
-def MergeFrom(self, msg)
-
-
-
-
-
-Expand source code
-
-
def MergeFrom(self, msg):
- if not isinstance(msg, cls):
- raise TypeError(
- 'Parameter to MergeFrom() must be instance of same class: '
- 'expected %s got %s.' % (_FullyQualifiedClassName(cls),
- _FullyQualifiedClassName(msg.__class__)))
-
- assert msg is not self
- self._Modified()
-
- fields = self._fields
-
- for field, value in msg._fields.items():
- if field.label == LABEL_REPEATED:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- elif field.cpp_type == CPPTYPE_MESSAGE:
- if value._is_present_in_parent:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- else:
- self._fields[field] = value
- if field.containing_oneof:
- self._UpdateOneofState(field)
-
- if msg._unknown_fields:
- if not self._unknown_fields:
- self._unknown_fields = []
- self._unknown_fields.extend(msg._unknown_fields)
- # pylint: disable=protected-access
- if self._unknown_field_set is None:
- self._unknown_field_set = containers.UnknownFieldSet()
- self._unknown_field_set._extend(msg._unknown_field_set)
-
-
-
-def MergeFromString(self, serialized)
-
-
-
-
-
-Expand source code
-
-
def MergeFromString(self, serialized):
- serialized = memoryview(serialized)
- length = len(serialized)
- try:
- if self._InternalParse(serialized, 0, length) != length:
- # The only reason _InternalParse would return early is if it
- # encountered an end-group tag.
- raise message_mod.DecodeError('Unexpected end-group tag.')
- except (IndexError, TypeError):
- # Now ord(buf[p:p+1]) == ord('') gets TypeError.
- raise message_mod.DecodeError('Truncated message.')
- except struct.error as e:
- raise message_mod.DecodeError(e)
- return length # Return this for legacy reasons.
def SerializeToString(self, **kwargs):
- # Check if the message has all of its required fields set.
- if not self.IsInitialized():
- raise message_mod.EncodeError(
- 'Message %s is missing required fields: %s' % (
- self.DESCRIPTOR.full_name, ','.join(self.FindInitializationErrors())))
- return self.SerializePartialToString(**kwargs)
-
-
-
-def SetInParent(self)
-
-
-
Sets the _cached_byte_size_dirty bit to true,
-and propagates this to our listener iff this was a state change.
-
-
-Expand source code
-
-
def Modified(self):
- """Sets the _cached_byte_size_dirty bit to true,
- and propagates this to our listener iff this was a state change.
- """
-
- # Note: Some callers check _cached_byte_size_dirty before calling
- # _Modified() as an extra optimization. So, if this method is ever
- # changed such that it does stuff even when _cached_byte_size_dirty is
- # already true, the callers need to be updated.
- if not self._cached_byte_size_dirty:
- self._cached_byte_size_dirty = True
- self._listener_for_children.dirty = True
- self._is_present_in_parent = True
- self._listener.Modified()
Returns the name of the currently set field inside a oneof, or None.
-
-
-Expand source code
-
-
def WhichOneof(self, oneof_name):
- """Returns the name of the currently set field inside a oneof, or None."""
- try:
- field = message_descriptor.oneofs_by_name[oneof_name]
- except KeyError:
- raise ValueError(
- 'Protocol message has no oneof "%s" field.' % oneof_name)
-
- nested_field = self._oneofs.get(field, None)
- if nested_field is not None and self.HasField(nested_field.name):
- return nested_field.name
- else:
- return None
-
+
Field MeshPacket.want_ack
class MyNodeInfo
-(**kwargs)
+(*args, **kwargs)
-
Abstract base class for protocol messages.
-
Protocol message classes are almost always generated by the protocol
-compiler.
-These generated types subclass Message and implement the methods
-shown below.
def getter(self):
- field_value = self._fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
-
- # Atomically check if another thread has preempted us and, if not, swap
- # in the new object we just created. If someone has preempted us, we
- # take that object and discard ours.
- # WARNING: We are relying on setdefault() being atomic. This is true
- # in CPython but we haven't investigated others. This warning appears
- # in several other locations in this file.
- field_value = self._fields.setdefault(field, field_value)
- return field_value
-
+
Field MyNodeInfo.air_period_rx
var air_period_tx
-
Getter for air_period_tx.
-
-
-Expand source code
-
-
def getter(self):
- field_value = self._fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
-
- # Atomically check if another thread has preempted us and, if not, swap
- # in the new object we just created. If someone has preempted us, we
- # take that object and discard ours.
- # WARNING: We are relying on setdefault() being atomic. This is true
- # in CPython but we haven't investigated others. This warning appears
- # in several other locations in this file.
- field_value = self._fields.setdefault(field, field_value)
- return field_value
-
+
Field MyNodeInfo.air_period_tx
var bitrate
-
Getter for bitrate.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field MyNodeInfo.bitrate
var error_address
-
Getter for error_address.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field MyNodeInfo.error_address
var error_code
-
Getter for error_code.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field MyNodeInfo.error_code
var error_count
-
Getter for error_count.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field MyNodeInfo.error_count
var firmware_version
-
Getter for firmware_version.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field MyNodeInfo.firmware_version
var has_gps
-
Getter for has_gps.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field MyNodeInfo.has_gps
var hw_model_deprecated
-
Getter for hw_model_deprecated.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field MyNodeInfo.hw_model_deprecated
var max_channels
-
Getter for max_channels.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field MyNodeInfo.max_channels
var message_timeout_msec
-
Getter for message_timeout_msec.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field MyNodeInfo.message_timeout_msec
var min_app_version
-
Getter for min_app_version.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field MyNodeInfo.min_app_version
var my_node_num
-
Getter for my_node_num.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field MyNodeInfo.my_node_num
var num_bands
-
Getter for num_bands.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field MyNodeInfo.num_bands
var reboot_count
-
Getter for reboot_count.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field MyNodeInfo.reboot_count
var region
-
Getter for region.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
-
-
-
Methods
-
-
-def ByteSize(self)
-
-
-
-
-
-Expand source code
-
-
def ByteSize(self):
- if not self._cached_byte_size_dirty:
- return self._cached_byte_size
-
- size = 0
- descriptor = self.DESCRIPTOR
- if descriptor.GetOptions().map_entry:
- # Fields of map entry should always be serialized.
- size = descriptor.fields_by_name['key']._sizer(self.key)
- size += descriptor.fields_by_name['value']._sizer(self.value)
- else:
- for field_descriptor, field_value in self.ListFields():
- size += field_descriptor._sizer(field_value)
- for tag_bytes, value_bytes in self._unknown_fields:
- size += len(tag_bytes) + len(value_bytes)
-
- self._cached_byte_size = size
- self._cached_byte_size_dirty = False
- self._listener_for_children.dirty = False
- return size
def ClearField(self, field_name):
- try:
- field = message_descriptor.fields_by_name[field_name]
- except KeyError:
- try:
- field = message_descriptor.oneofs_by_name[field_name]
- if field in self._oneofs:
- field = self._oneofs[field]
- else:
- return
- except KeyError:
- raise ValueError('Protocol message %s has no "%s" field.' %
- (message_descriptor.name, field_name))
-
- if field in self._fields:
- # To match the C++ implementation, we need to invalidate iterators
- # for map fields when ClearField() happens.
- if hasattr(self._fields[field], 'InvalidateIterators'):
- self._fields[field].InvalidateIterators()
-
- # Note: If the field is a sub-message, its listener will still point
- # at us. That's fine, because the worst than can happen is that it
- # will call _Modified() and invalidate our byte size. Big deal.
- del self._fields[field]
-
- if self._oneofs.get(field.containing_oneof, None) is field:
- del self._oneofs[field.containing_oneof]
-
- # Always call _Modified() -- even if nothing was changed, this is
- # a mutating method, and thus calling it should cause the field to become
- # present in the parent message.
- self._Modified()
-
-
-
-def DiscardUnknownFields(self)
-
-
-
-
-
-Expand source code
-
-
def _DiscardUnknownFields(self):
- self._unknown_fields = []
- self._unknown_field_set = None # pylint: disable=protected-access
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if _IsMapField(field):
- if _IsMessageMapField(field):
- for key in value:
- value[key].DiscardUnknownFields()
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
- for sub_message in value:
- sub_message.DiscardUnknownFields()
- else:
- value.DiscardUnknownFields()
-
-
-
-def FindInitializationErrors(self)
-
-
-
Finds required fields which are not initialized.
-
Returns
-
A list of strings.
-Each string is a path to an uninitialized field from
-the top-level message, e.g. "foo.bar[5].baz".
-
-
-Expand source code
-
-
def FindInitializationErrors(self):
- """Finds required fields which are not initialized.
-
- Returns:
- A list of strings. Each string is a path to an uninitialized field from
- the top-level message, e.g. "foo.bar[5].baz".
- """
-
- errors = [] # simplify things
-
- for field in required_fields:
- if not self.HasField(field.name):
- errors.append(field.name)
-
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.is_extension:
- name = '(%s)' % field.full_name
- else:
- name = field.name
-
- if _IsMapField(field):
- if _IsMessageMapField(field):
- for key in value:
- element = value[key]
- prefix = '%s[%s].' % (name, key)
- sub_errors = element.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
- else:
- # ScalarMaps can't have any initialization errors.
- pass
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
- for i in range(len(value)):
- element = value[i]
- prefix = '%s[%d].' % (name, i)
- sub_errors = element.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
- else:
- prefix = name + '.'
- sub_errors = value.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
-
- return errors
-
-
-
-def HasField(self, field_name)
-
-
-
-
-
-Expand source code
-
-
def HasField(self, field_name):
- try:
- field = hassable_fields[field_name]
- except KeyError:
- raise ValueError(error_msg % (message_descriptor.full_name, field_name))
-
- if isinstance(field, descriptor_mod.OneofDescriptor):
- try:
- return HasField(self, self._oneofs[field].name)
- except KeyError:
- return False
- else:
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- value = self._fields.get(field)
- return value is not None and value._is_present_in_parent
- else:
- return field in self._fields
-
-
-
-def IsInitialized(self, errors=None)
-
-
-
Checks if all required fields of a message are set.
-
Args
-
-
errors
-
A list which, if provided, will be populated with the field
-paths of all missing required fields.
-
-
Returns
-
True iff the specified message has all required fields set.
-
-
-Expand source code
-
-
def IsInitialized(self, errors=None):
- """Checks if all required fields of a message are set.
-
- Args:
- errors: A list which, if provided, will be populated with the field
- paths of all missing required fields.
-
- Returns:
- True iff the specified message has all required fields set.
- """
-
- # Performance is critical so we avoid HasField() and ListFields().
-
- for field in required_fields:
- if (field not in self._fields or
- (field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE and
- not self._fields[field]._is_present_in_parent)):
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- for field, value in list(self._fields.items()): # dict can change size!
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.label == _FieldDescriptor.LABEL_REPEATED:
- if (field.message_type.has_options and
- field.message_type.GetOptions().map_entry):
- continue
- for element in value:
- if not element.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
- elif value._is_present_in_parent and not value.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- return True
-
-
-
-def ListFields(self)
-
-
-
-
-
-Expand source code
-
-
def ListFields(self):
- all_fields = [item for item in self._fields.items() if _IsPresent(item)]
- all_fields.sort(key = lambda item: item[0].number)
- return all_fields
-
-
-
-def MergeFrom(self, msg)
-
-
-
-
-
-Expand source code
-
-
def MergeFrom(self, msg):
- if not isinstance(msg, cls):
- raise TypeError(
- 'Parameter to MergeFrom() must be instance of same class: '
- 'expected %s got %s.' % (_FullyQualifiedClassName(cls),
- _FullyQualifiedClassName(msg.__class__)))
-
- assert msg is not self
- self._Modified()
-
- fields = self._fields
-
- for field, value in msg._fields.items():
- if field.label == LABEL_REPEATED:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- elif field.cpp_type == CPPTYPE_MESSAGE:
- if value._is_present_in_parent:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- else:
- self._fields[field] = value
- if field.containing_oneof:
- self._UpdateOneofState(field)
-
- if msg._unknown_fields:
- if not self._unknown_fields:
- self._unknown_fields = []
- self._unknown_fields.extend(msg._unknown_fields)
- # pylint: disable=protected-access
- if self._unknown_field_set is None:
- self._unknown_field_set = containers.UnknownFieldSet()
- self._unknown_field_set._extend(msg._unknown_field_set)
-
-
-
-def MergeFromString(self, serialized)
-
-
-
-
-
-Expand source code
-
-
def MergeFromString(self, serialized):
- serialized = memoryview(serialized)
- length = len(serialized)
- try:
- if self._InternalParse(serialized, 0, length) != length:
- # The only reason _InternalParse would return early is if it
- # encountered an end-group tag.
- raise message_mod.DecodeError('Unexpected end-group tag.')
- except (IndexError, TypeError):
- # Now ord(buf[p:p+1]) == ord('') gets TypeError.
- raise message_mod.DecodeError('Truncated message.')
- except struct.error as e:
- raise message_mod.DecodeError(e)
- return length # Return this for legacy reasons.
def SerializeToString(self, **kwargs):
- # Check if the message has all of its required fields set.
- if not self.IsInitialized():
- raise message_mod.EncodeError(
- 'Message %s is missing required fields: %s' % (
- self.DESCRIPTOR.full_name, ','.join(self.FindInitializationErrors())))
- return self.SerializePartialToString(**kwargs)
-
-
-
-def SetInParent(self)
-
-
-
Sets the _cached_byte_size_dirty bit to true,
-and propagates this to our listener iff this was a state change.
-
-
-Expand source code
-
-
def Modified(self):
- """Sets the _cached_byte_size_dirty bit to true,
- and propagates this to our listener iff this was a state change.
- """
-
- # Note: Some callers check _cached_byte_size_dirty before calling
- # _Modified() as an extra optimization. So, if this method is ever
- # changed such that it does stuff even when _cached_byte_size_dirty is
- # already true, the callers need to be updated.
- if not self._cached_byte_size_dirty:
- self._cached_byte_size_dirty = True
- self._listener_for_children.dirty = True
- self._is_present_in_parent = True
- self._listener.Modified()
Returns the name of the currently set field inside a oneof, or None.
-
-
-Expand source code
-
-
def WhichOneof(self, oneof_name):
- """Returns the name of the currently set field inside a oneof, or None."""
- try:
- field = message_descriptor.oneofs_by_name[oneof_name]
- except KeyError:
- raise ValueError(
- 'Protocol message has no oneof "%s" field.' % oneof_name)
-
- nested_field = self._oneofs.get(field, None)
- if nested_field is not None and self.HasField(nested_field.name):
- return nested_field.name
- else:
- return None
-
+
Field MyNodeInfo.region
class NodeInfo
-(**kwargs)
+(*args, **kwargs)
-
Abstract base class for protocol messages.
-
Protocol message classes are almost always generated by the protocol
-compiler.
-These generated types subclass Message and implement the methods
-shown below.
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field NodeInfo.last_heard
var num
-
Getter for num.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field NodeInfo.num
var position
-
Getter for position.
-
-
-Expand source code
-
-
def getter(self):
- field_value = self._fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
-
- # Atomically check if another thread has preempted us and, if not, swap
- # in the new object we just created. If someone has preempted us, we
- # take that object and discard ours.
- # WARNING: We are relying on setdefault() being atomic. This is true
- # in CPython but we haven't investigated others. This warning appears
- # in several other locations in this file.
- field_value = self._fields.setdefault(field, field_value)
- return field_value
-
+
Field NodeInfo.position
var snr
-
Getter for snr.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field NodeInfo.snr
var user
-
Getter for user.
-
-
-Expand source code
-
-
def getter(self):
- field_value = self._fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
-
- # Atomically check if another thread has preempted us and, if not, swap
- # in the new object we just created. If someone has preempted us, we
- # take that object and discard ours.
- # WARNING: We are relying on setdefault() being atomic. This is true
- # in CPython but we haven't investigated others. This warning appears
- # in several other locations in this file.
- field_value = self._fields.setdefault(field, field_value)
- return field_value
-
-
-
-
Methods
-
-
-def ByteSize(self)
-
-
-
-
-
-Expand source code
-
-
def ByteSize(self):
- if not self._cached_byte_size_dirty:
- return self._cached_byte_size
-
- size = 0
- descriptor = self.DESCRIPTOR
- if descriptor.GetOptions().map_entry:
- # Fields of map entry should always be serialized.
- size = descriptor.fields_by_name['key']._sizer(self.key)
- size += descriptor.fields_by_name['value']._sizer(self.value)
- else:
- for field_descriptor, field_value in self.ListFields():
- size += field_descriptor._sizer(field_value)
- for tag_bytes, value_bytes in self._unknown_fields:
- size += len(tag_bytes) + len(value_bytes)
-
- self._cached_byte_size = size
- self._cached_byte_size_dirty = False
- self._listener_for_children.dirty = False
- return size
def ClearField(self, field_name):
- try:
- field = message_descriptor.fields_by_name[field_name]
- except KeyError:
- try:
- field = message_descriptor.oneofs_by_name[field_name]
- if field in self._oneofs:
- field = self._oneofs[field]
- else:
- return
- except KeyError:
- raise ValueError('Protocol message %s has no "%s" field.' %
- (message_descriptor.name, field_name))
-
- if field in self._fields:
- # To match the C++ implementation, we need to invalidate iterators
- # for map fields when ClearField() happens.
- if hasattr(self._fields[field], 'InvalidateIterators'):
- self._fields[field].InvalidateIterators()
-
- # Note: If the field is a sub-message, its listener will still point
- # at us. That's fine, because the worst than can happen is that it
- # will call _Modified() and invalidate our byte size. Big deal.
- del self._fields[field]
-
- if self._oneofs.get(field.containing_oneof, None) is field:
- del self._oneofs[field.containing_oneof]
-
- # Always call _Modified() -- even if nothing was changed, this is
- # a mutating method, and thus calling it should cause the field to become
- # present in the parent message.
- self._Modified()
-
-
-
-def DiscardUnknownFields(self)
-
-
-
-
-
-Expand source code
-
-
def _DiscardUnknownFields(self):
- self._unknown_fields = []
- self._unknown_field_set = None # pylint: disable=protected-access
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if _IsMapField(field):
- if _IsMessageMapField(field):
- for key in value:
- value[key].DiscardUnknownFields()
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
- for sub_message in value:
- sub_message.DiscardUnknownFields()
- else:
- value.DiscardUnknownFields()
-
-
-
-def FindInitializationErrors(self)
-
-
-
Finds required fields which are not initialized.
-
Returns
-
A list of strings.
-Each string is a path to an uninitialized field from
-the top-level message, e.g. "foo.bar[5].baz".
-
-
-Expand source code
-
-
def FindInitializationErrors(self):
- """Finds required fields which are not initialized.
-
- Returns:
- A list of strings. Each string is a path to an uninitialized field from
- the top-level message, e.g. "foo.bar[5].baz".
- """
-
- errors = [] # simplify things
-
- for field in required_fields:
- if not self.HasField(field.name):
- errors.append(field.name)
-
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.is_extension:
- name = '(%s)' % field.full_name
- else:
- name = field.name
-
- if _IsMapField(field):
- if _IsMessageMapField(field):
- for key in value:
- element = value[key]
- prefix = '%s[%s].' % (name, key)
- sub_errors = element.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
- else:
- # ScalarMaps can't have any initialization errors.
- pass
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
- for i in range(len(value)):
- element = value[i]
- prefix = '%s[%d].' % (name, i)
- sub_errors = element.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
- else:
- prefix = name + '.'
- sub_errors = value.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
-
- return errors
-
-
-
-def HasField(self, field_name)
-
-
-
-
-
-Expand source code
-
-
def HasField(self, field_name):
- try:
- field = hassable_fields[field_name]
- except KeyError:
- raise ValueError(error_msg % (message_descriptor.full_name, field_name))
-
- if isinstance(field, descriptor_mod.OneofDescriptor):
- try:
- return HasField(self, self._oneofs[field].name)
- except KeyError:
- return False
- else:
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- value = self._fields.get(field)
- return value is not None and value._is_present_in_parent
- else:
- return field in self._fields
-
-
-
-def IsInitialized(self, errors=None)
-
-
-
Checks if all required fields of a message are set.
-
Args
-
-
errors
-
A list which, if provided, will be populated with the field
-paths of all missing required fields.
-
-
Returns
-
True iff the specified message has all required fields set.
-
-
-Expand source code
-
-
def IsInitialized(self, errors=None):
- """Checks if all required fields of a message are set.
-
- Args:
- errors: A list which, if provided, will be populated with the field
- paths of all missing required fields.
-
- Returns:
- True iff the specified message has all required fields set.
- """
-
- # Performance is critical so we avoid HasField() and ListFields().
-
- for field in required_fields:
- if (field not in self._fields or
- (field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE and
- not self._fields[field]._is_present_in_parent)):
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- for field, value in list(self._fields.items()): # dict can change size!
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.label == _FieldDescriptor.LABEL_REPEATED:
- if (field.message_type.has_options and
- field.message_type.GetOptions().map_entry):
- continue
- for element in value:
- if not element.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
- elif value._is_present_in_parent and not value.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- return True
-
-
-
-def ListFields(self)
-
-
-
-
-
-Expand source code
-
-
def ListFields(self):
- all_fields = [item for item in self._fields.items() if _IsPresent(item)]
- all_fields.sort(key = lambda item: item[0].number)
- return all_fields
-
-
-
-def MergeFrom(self, msg)
-
-
-
-
-
-Expand source code
-
-
def MergeFrom(self, msg):
- if not isinstance(msg, cls):
- raise TypeError(
- 'Parameter to MergeFrom() must be instance of same class: '
- 'expected %s got %s.' % (_FullyQualifiedClassName(cls),
- _FullyQualifiedClassName(msg.__class__)))
-
- assert msg is not self
- self._Modified()
-
- fields = self._fields
-
- for field, value in msg._fields.items():
- if field.label == LABEL_REPEATED:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- elif field.cpp_type == CPPTYPE_MESSAGE:
- if value._is_present_in_parent:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- else:
- self._fields[field] = value
- if field.containing_oneof:
- self._UpdateOneofState(field)
-
- if msg._unknown_fields:
- if not self._unknown_fields:
- self._unknown_fields = []
- self._unknown_fields.extend(msg._unknown_fields)
- # pylint: disable=protected-access
- if self._unknown_field_set is None:
- self._unknown_field_set = containers.UnknownFieldSet()
- self._unknown_field_set._extend(msg._unknown_field_set)
-
-
-
-def MergeFromString(self, serialized)
-
-
-
-
-
-Expand source code
-
-
def MergeFromString(self, serialized):
- serialized = memoryview(serialized)
- length = len(serialized)
- try:
- if self._InternalParse(serialized, 0, length) != length:
- # The only reason _InternalParse would return early is if it
- # encountered an end-group tag.
- raise message_mod.DecodeError('Unexpected end-group tag.')
- except (IndexError, TypeError):
- # Now ord(buf[p:p+1]) == ord('') gets TypeError.
- raise message_mod.DecodeError('Truncated message.')
- except struct.error as e:
- raise message_mod.DecodeError(e)
- return length # Return this for legacy reasons.
def SerializeToString(self, **kwargs):
- # Check if the message has all of its required fields set.
- if not self.IsInitialized():
- raise message_mod.EncodeError(
- 'Message %s is missing required fields: %s' % (
- self.DESCRIPTOR.full_name, ','.join(self.FindInitializationErrors())))
- return self.SerializePartialToString(**kwargs)
-
-
-
-def SetInParent(self)
-
-
-
Sets the _cached_byte_size_dirty bit to true,
-and propagates this to our listener iff this was a state change.
-
-
-Expand source code
-
-
def Modified(self):
- """Sets the _cached_byte_size_dirty bit to true,
- and propagates this to our listener iff this was a state change.
- """
-
- # Note: Some callers check _cached_byte_size_dirty before calling
- # _Modified() as an extra optimization. So, if this method is ever
- # changed such that it does stuff even when _cached_byte_size_dirty is
- # already true, the callers need to be updated.
- if not self._cached_byte_size_dirty:
- self._cached_byte_size_dirty = True
- self._listener_for_children.dirty = True
- self._is_present_in_parent = True
- self._listener.Modified()
Returns the name of the currently set field inside a oneof, or None.
-
-
-Expand source code
-
-
def WhichOneof(self, oneof_name):
- """Returns the name of the currently set field inside a oneof, or None."""
- try:
- field = message_descriptor.oneofs_by_name[oneof_name]
- except KeyError:
- raise ValueError(
- 'Protocol message has no oneof "%s" field.' % oneof_name)
-
- nested_field = self._oneofs.get(field, None)
- if nested_field is not None and self.HasField(nested_field.name):
- return nested_field.name
- else:
- return None
-
+
Field NodeInfo.user
class Position
-(**kwargs)
+(*args, **kwargs)
-
Abstract base class for protocol messages.
-
Protocol message classes are almost always generated by the protocol
-compiler.
-These generated types subclass Message and implement the methods
-shown below.
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field Position.HDOP
var PDOP
-
Getter for PDOP.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field Position.PDOP
var VDOP
-
Getter for VDOP.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field Position.VDOP
var alt_geoid_sep
-
Getter for alt_geoid_sep.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field Position.alt_geoid_sep
var altitude
-
Getter for altitude.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field Position.altitude
var altitude_hae
-
Getter for altitude_hae.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field Position.altitude_hae
var altitude_source
-
Getter for altitude_source.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field Position.altitude_source
var battery_level
-
Getter for battery_level.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field Position.battery_level
var fix_quality
-
Getter for fix_quality.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field Position.fix_quality
var fix_type
-
Getter for fix_type.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field Position.fix_type
var gps_accuracy
-
Getter for gps_accuracy.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field Position.gps_accuracy
var ground_speed
-
Getter for ground_speed.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field Position.ground_speed
var ground_track
-
Getter for ground_track.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field Position.ground_track
var latitude_i
-
Getter for latitude_i.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field Position.latitude_i
var location_source
-
Getter for location_source.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field Position.location_source
var longitude_i
-
Getter for longitude_i.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field Position.longitude_i
var pos_next_update
-
Getter for pos_next_update.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field Position.pos_next_update
var pos_seq_number
-
Getter for pos_seq_number.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field Position.pos_seq_number
var pos_time_millis
-
Getter for pos_time_millis.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field Position.pos_time_millis
var pos_timestamp
-
Getter for pos_timestamp.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field Position.pos_timestamp
var sats_in_view
-
Getter for sats_in_view.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field Position.sats_in_view
var sensor_id
-
Getter for sensor_id.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field Position.sensor_id
var time
-
Getter for time.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
-
-
-
Methods
-
-
-def ByteSize(self)
-
-
-
-
-
-Expand source code
-
-
def ByteSize(self):
- if not self._cached_byte_size_dirty:
- return self._cached_byte_size
-
- size = 0
- descriptor = self.DESCRIPTOR
- if descriptor.GetOptions().map_entry:
- # Fields of map entry should always be serialized.
- size = descriptor.fields_by_name['key']._sizer(self.key)
- size += descriptor.fields_by_name['value']._sizer(self.value)
- else:
- for field_descriptor, field_value in self.ListFields():
- size += field_descriptor._sizer(field_value)
- for tag_bytes, value_bytes in self._unknown_fields:
- size += len(tag_bytes) + len(value_bytes)
-
- self._cached_byte_size = size
- self._cached_byte_size_dirty = False
- self._listener_for_children.dirty = False
- return size
def ClearField(self, field_name):
- try:
- field = message_descriptor.fields_by_name[field_name]
- except KeyError:
- try:
- field = message_descriptor.oneofs_by_name[field_name]
- if field in self._oneofs:
- field = self._oneofs[field]
- else:
- return
- except KeyError:
- raise ValueError('Protocol message %s has no "%s" field.' %
- (message_descriptor.name, field_name))
-
- if field in self._fields:
- # To match the C++ implementation, we need to invalidate iterators
- # for map fields when ClearField() happens.
- if hasattr(self._fields[field], 'InvalidateIterators'):
- self._fields[field].InvalidateIterators()
-
- # Note: If the field is a sub-message, its listener will still point
- # at us. That's fine, because the worst than can happen is that it
- # will call _Modified() and invalidate our byte size. Big deal.
- del self._fields[field]
-
- if self._oneofs.get(field.containing_oneof, None) is field:
- del self._oneofs[field.containing_oneof]
-
- # Always call _Modified() -- even if nothing was changed, this is
- # a mutating method, and thus calling it should cause the field to become
- # present in the parent message.
- self._Modified()
-
-
-
-def DiscardUnknownFields(self)
-
-
-
-
-
-Expand source code
-
-
def _DiscardUnknownFields(self):
- self._unknown_fields = []
- self._unknown_field_set = None # pylint: disable=protected-access
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if _IsMapField(field):
- if _IsMessageMapField(field):
- for key in value:
- value[key].DiscardUnknownFields()
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
- for sub_message in value:
- sub_message.DiscardUnknownFields()
- else:
- value.DiscardUnknownFields()
-
-
-
-def FindInitializationErrors(self)
-
-
-
Finds required fields which are not initialized.
-
Returns
-
A list of strings.
-Each string is a path to an uninitialized field from
-the top-level message, e.g. "foo.bar[5].baz".
-
-
-Expand source code
-
-
def FindInitializationErrors(self):
- """Finds required fields which are not initialized.
-
- Returns:
- A list of strings. Each string is a path to an uninitialized field from
- the top-level message, e.g. "foo.bar[5].baz".
- """
-
- errors = [] # simplify things
-
- for field in required_fields:
- if not self.HasField(field.name):
- errors.append(field.name)
-
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.is_extension:
- name = '(%s)' % field.full_name
- else:
- name = field.name
-
- if _IsMapField(field):
- if _IsMessageMapField(field):
- for key in value:
- element = value[key]
- prefix = '%s[%s].' % (name, key)
- sub_errors = element.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
- else:
- # ScalarMaps can't have any initialization errors.
- pass
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
- for i in range(len(value)):
- element = value[i]
- prefix = '%s[%d].' % (name, i)
- sub_errors = element.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
- else:
- prefix = name + '.'
- sub_errors = value.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
-
- return errors
-
-
-
-def HasField(self, field_name)
-
-
-
-
-
-Expand source code
-
-
def HasField(self, field_name):
- try:
- field = hassable_fields[field_name]
- except KeyError:
- raise ValueError(error_msg % (message_descriptor.full_name, field_name))
-
- if isinstance(field, descriptor_mod.OneofDescriptor):
- try:
- return HasField(self, self._oneofs[field].name)
- except KeyError:
- return False
- else:
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- value = self._fields.get(field)
- return value is not None and value._is_present_in_parent
- else:
- return field in self._fields
-
-
-
-def IsInitialized(self, errors=None)
-
-
-
Checks if all required fields of a message are set.
-
Args
-
-
errors
-
A list which, if provided, will be populated with the field
-paths of all missing required fields.
-
-
Returns
-
True iff the specified message has all required fields set.
-
-
-Expand source code
-
-
def IsInitialized(self, errors=None):
- """Checks if all required fields of a message are set.
-
- Args:
- errors: A list which, if provided, will be populated with the field
- paths of all missing required fields.
-
- Returns:
- True iff the specified message has all required fields set.
- """
-
- # Performance is critical so we avoid HasField() and ListFields().
-
- for field in required_fields:
- if (field not in self._fields or
- (field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE and
- not self._fields[field]._is_present_in_parent)):
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- for field, value in list(self._fields.items()): # dict can change size!
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.label == _FieldDescriptor.LABEL_REPEATED:
- if (field.message_type.has_options and
- field.message_type.GetOptions().map_entry):
- continue
- for element in value:
- if not element.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
- elif value._is_present_in_parent and not value.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- return True
-
-
-
-def ListFields(self)
-
-
-
-
-
-Expand source code
-
-
def ListFields(self):
- all_fields = [item for item in self._fields.items() if _IsPresent(item)]
- all_fields.sort(key = lambda item: item[0].number)
- return all_fields
-
-
-
-def MergeFrom(self, msg)
-
-
-
-
-
-Expand source code
-
-
def MergeFrom(self, msg):
- if not isinstance(msg, cls):
- raise TypeError(
- 'Parameter to MergeFrom() must be instance of same class: '
- 'expected %s got %s.' % (_FullyQualifiedClassName(cls),
- _FullyQualifiedClassName(msg.__class__)))
-
- assert msg is not self
- self._Modified()
-
- fields = self._fields
-
- for field, value in msg._fields.items():
- if field.label == LABEL_REPEATED:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- elif field.cpp_type == CPPTYPE_MESSAGE:
- if value._is_present_in_parent:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- else:
- self._fields[field] = value
- if field.containing_oneof:
- self._UpdateOneofState(field)
-
- if msg._unknown_fields:
- if not self._unknown_fields:
- self._unknown_fields = []
- self._unknown_fields.extend(msg._unknown_fields)
- # pylint: disable=protected-access
- if self._unknown_field_set is None:
- self._unknown_field_set = containers.UnknownFieldSet()
- self._unknown_field_set._extend(msg._unknown_field_set)
-
-
-
-def MergeFromString(self, serialized)
-
-
-
-
-
-Expand source code
-
-
def MergeFromString(self, serialized):
- serialized = memoryview(serialized)
- length = len(serialized)
- try:
- if self._InternalParse(serialized, 0, length) != length:
- # The only reason _InternalParse would return early is if it
- # encountered an end-group tag.
- raise message_mod.DecodeError('Unexpected end-group tag.')
- except (IndexError, TypeError):
- # Now ord(buf[p:p+1]) == ord('') gets TypeError.
- raise message_mod.DecodeError('Truncated message.')
- except struct.error as e:
- raise message_mod.DecodeError(e)
- return length # Return this for legacy reasons.
def SerializeToString(self, **kwargs):
- # Check if the message has all of its required fields set.
- if not self.IsInitialized():
- raise message_mod.EncodeError(
- 'Message %s is missing required fields: %s' % (
- self.DESCRIPTOR.full_name, ','.join(self.FindInitializationErrors())))
- return self.SerializePartialToString(**kwargs)
-
-
-
-def SetInParent(self)
-
-
-
Sets the _cached_byte_size_dirty bit to true,
-and propagates this to our listener iff this was a state change.
-
-
-Expand source code
-
-
def Modified(self):
- """Sets the _cached_byte_size_dirty bit to true,
- and propagates this to our listener iff this was a state change.
- """
-
- # Note: Some callers check _cached_byte_size_dirty before calling
- # _Modified() as an extra optimization. So, if this method is ever
- # changed such that it does stuff even when _cached_byte_size_dirty is
- # already true, the callers need to be updated.
- if not self._cached_byte_size_dirty:
- self._cached_byte_size_dirty = True
- self._listener_for_children.dirty = True
- self._is_present_in_parent = True
- self._listener.Modified()
Returns the name of the currently set field inside a oneof, or None.
-
-
-Expand source code
-
-
def WhichOneof(self, oneof_name):
- """Returns the name of the currently set field inside a oneof, or None."""
- try:
- field = message_descriptor.oneofs_by_name[oneof_name]
- except KeyError:
- raise ValueError(
- 'Protocol message has no oneof "%s" field.' % oneof_name)
-
- nested_field = self._oneofs.get(field, None)
- if nested_field is not None and self.HasField(nested_field.name):
- return nested_field.name
- else:
- return None
-
+
Field Position.time
class RouteDiscovery
-(**kwargs)
+(*args, **kwargs)
-
Abstract base class for protocol messages.
-
Protocol message classes are almost always generated by the protocol
-compiler.
-These generated types subclass Message and implement the methods
-shown below.
def getter(self):
- field_value = self._fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
-
- # Atomically check if another thread has preempted us and, if not, swap
- # in the new object we just created. If someone has preempted us, we
- # take that object and discard ours.
- # WARNING: We are relying on setdefault() being atomic. This is true
- # in CPython but we haven't investigated others. This warning appears
- # in several other locations in this file.
- field_value = self._fields.setdefault(field, field_value)
- return field_value
-
-
-
-
Methods
-
-
-def ByteSize(self)
-
-
-
-
-
-Expand source code
-
-
def ByteSize(self):
- if not self._cached_byte_size_dirty:
- return self._cached_byte_size
-
- size = 0
- descriptor = self.DESCRIPTOR
- if descriptor.GetOptions().map_entry:
- # Fields of map entry should always be serialized.
- size = descriptor.fields_by_name['key']._sizer(self.key)
- size += descriptor.fields_by_name['value']._sizer(self.value)
- else:
- for field_descriptor, field_value in self.ListFields():
- size += field_descriptor._sizer(field_value)
- for tag_bytes, value_bytes in self._unknown_fields:
- size += len(tag_bytes) + len(value_bytes)
-
- self._cached_byte_size = size
- self._cached_byte_size_dirty = False
- self._listener_for_children.dirty = False
- return size
def ClearField(self, field_name):
- try:
- field = message_descriptor.fields_by_name[field_name]
- except KeyError:
- try:
- field = message_descriptor.oneofs_by_name[field_name]
- if field in self._oneofs:
- field = self._oneofs[field]
- else:
- return
- except KeyError:
- raise ValueError('Protocol message %s has no "%s" field.' %
- (message_descriptor.name, field_name))
-
- if field in self._fields:
- # To match the C++ implementation, we need to invalidate iterators
- # for map fields when ClearField() happens.
- if hasattr(self._fields[field], 'InvalidateIterators'):
- self._fields[field].InvalidateIterators()
-
- # Note: If the field is a sub-message, its listener will still point
- # at us. That's fine, because the worst than can happen is that it
- # will call _Modified() and invalidate our byte size. Big deal.
- del self._fields[field]
-
- if self._oneofs.get(field.containing_oneof, None) is field:
- del self._oneofs[field.containing_oneof]
-
- # Always call _Modified() -- even if nothing was changed, this is
- # a mutating method, and thus calling it should cause the field to become
- # present in the parent message.
- self._Modified()
-
-
-
-def DiscardUnknownFields(self)
-
-
-
-
-
-Expand source code
-
-
def _DiscardUnknownFields(self):
- self._unknown_fields = []
- self._unknown_field_set = None # pylint: disable=protected-access
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if _IsMapField(field):
- if _IsMessageMapField(field):
- for key in value:
- value[key].DiscardUnknownFields()
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
- for sub_message in value:
- sub_message.DiscardUnknownFields()
- else:
- value.DiscardUnknownFields()
-
-
-
-def FindInitializationErrors(self)
-
-
-
Finds required fields which are not initialized.
-
Returns
-
A list of strings.
-Each string is a path to an uninitialized field from
-the top-level message, e.g. "foo.bar[5].baz".
-
-
-Expand source code
-
-
def FindInitializationErrors(self):
- """Finds required fields which are not initialized.
-
- Returns:
- A list of strings. Each string is a path to an uninitialized field from
- the top-level message, e.g. "foo.bar[5].baz".
- """
-
- errors = [] # simplify things
-
- for field in required_fields:
- if not self.HasField(field.name):
- errors.append(field.name)
-
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.is_extension:
- name = '(%s)' % field.full_name
- else:
- name = field.name
-
- if _IsMapField(field):
- if _IsMessageMapField(field):
- for key in value:
- element = value[key]
- prefix = '%s[%s].' % (name, key)
- sub_errors = element.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
- else:
- # ScalarMaps can't have any initialization errors.
- pass
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
- for i in range(len(value)):
- element = value[i]
- prefix = '%s[%d].' % (name, i)
- sub_errors = element.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
- else:
- prefix = name + '.'
- sub_errors = value.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
-
- return errors
-
-
-
-def HasField(self, field_name)
-
-
-
-
-
-Expand source code
-
-
def HasField(self, field_name):
- try:
- field = hassable_fields[field_name]
- except KeyError:
- raise ValueError(error_msg % (message_descriptor.full_name, field_name))
-
- if isinstance(field, descriptor_mod.OneofDescriptor):
- try:
- return HasField(self, self._oneofs[field].name)
- except KeyError:
- return False
- else:
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- value = self._fields.get(field)
- return value is not None and value._is_present_in_parent
- else:
- return field in self._fields
-
-
-
-def IsInitialized(self, errors=None)
-
-
-
Checks if all required fields of a message are set.
-
Args
-
-
errors
-
A list which, if provided, will be populated with the field
-paths of all missing required fields.
-
-
Returns
-
True iff the specified message has all required fields set.
-
-
-Expand source code
-
-
def IsInitialized(self, errors=None):
- """Checks if all required fields of a message are set.
-
- Args:
- errors: A list which, if provided, will be populated with the field
- paths of all missing required fields.
-
- Returns:
- True iff the specified message has all required fields set.
- """
-
- # Performance is critical so we avoid HasField() and ListFields().
-
- for field in required_fields:
- if (field not in self._fields or
- (field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE and
- not self._fields[field]._is_present_in_parent)):
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- for field, value in list(self._fields.items()): # dict can change size!
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.label == _FieldDescriptor.LABEL_REPEATED:
- if (field.message_type.has_options and
- field.message_type.GetOptions().map_entry):
- continue
- for element in value:
- if not element.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
- elif value._is_present_in_parent and not value.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- return True
-
-
-
-def ListFields(self)
-
-
-
-
-
-Expand source code
-
-
def ListFields(self):
- all_fields = [item for item in self._fields.items() if _IsPresent(item)]
- all_fields.sort(key = lambda item: item[0].number)
- return all_fields
-
-
-
-def MergeFrom(self, msg)
-
-
-
-
-
-Expand source code
-
-
def MergeFrom(self, msg):
- if not isinstance(msg, cls):
- raise TypeError(
- 'Parameter to MergeFrom() must be instance of same class: '
- 'expected %s got %s.' % (_FullyQualifiedClassName(cls),
- _FullyQualifiedClassName(msg.__class__)))
-
- assert msg is not self
- self._Modified()
-
- fields = self._fields
-
- for field, value in msg._fields.items():
- if field.label == LABEL_REPEATED:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- elif field.cpp_type == CPPTYPE_MESSAGE:
- if value._is_present_in_parent:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- else:
- self._fields[field] = value
- if field.containing_oneof:
- self._UpdateOneofState(field)
-
- if msg._unknown_fields:
- if not self._unknown_fields:
- self._unknown_fields = []
- self._unknown_fields.extend(msg._unknown_fields)
- # pylint: disable=protected-access
- if self._unknown_field_set is None:
- self._unknown_field_set = containers.UnknownFieldSet()
- self._unknown_field_set._extend(msg._unknown_field_set)
-
-
-
-def MergeFromString(self, serialized)
-
-
-
-
-
-Expand source code
-
-
def MergeFromString(self, serialized):
- serialized = memoryview(serialized)
- length = len(serialized)
- try:
- if self._InternalParse(serialized, 0, length) != length:
- # The only reason _InternalParse would return early is if it
- # encountered an end-group tag.
- raise message_mod.DecodeError('Unexpected end-group tag.')
- except (IndexError, TypeError):
- # Now ord(buf[p:p+1]) == ord('') gets TypeError.
- raise message_mod.DecodeError('Truncated message.')
- except struct.error as e:
- raise message_mod.DecodeError(e)
- return length # Return this for legacy reasons.
def SerializeToString(self, **kwargs):
- # Check if the message has all of its required fields set.
- if not self.IsInitialized():
- raise message_mod.EncodeError(
- 'Message %s is missing required fields: %s' % (
- self.DESCRIPTOR.full_name, ','.join(self.FindInitializationErrors())))
- return self.SerializePartialToString(**kwargs)
-
-
-
-def SetInParent(self)
-
-
-
Sets the _cached_byte_size_dirty bit to true,
-and propagates this to our listener iff this was a state change.
-
-
-Expand source code
-
-
def Modified(self):
- """Sets the _cached_byte_size_dirty bit to true,
- and propagates this to our listener iff this was a state change.
- """
-
- # Note: Some callers check _cached_byte_size_dirty before calling
- # _Modified() as an extra optimization. So, if this method is ever
- # changed such that it does stuff even when _cached_byte_size_dirty is
- # already true, the callers need to be updated.
- if not self._cached_byte_size_dirty:
- self._cached_byte_size_dirty = True
- self._listener_for_children.dirty = True
- self._is_present_in_parent = True
- self._listener.Modified()
Returns the name of the currently set field inside a oneof, or None.
-
-
-Expand source code
-
-
def WhichOneof(self, oneof_name):
- """Returns the name of the currently set field inside a oneof, or None."""
- try:
- field = message_descriptor.oneofs_by_name[oneof_name]
- except KeyError:
- raise ValueError(
- 'Protocol message has no oneof "%s" field.' % oneof_name)
-
- nested_field = self._oneofs.get(field, None)
- if nested_field is not None and self.HasField(nested_field.name):
- return nested_field.name
- else:
- return None
-
+
Field RouteDiscovery.route
class Routing
-(**kwargs)
+(*args, **kwargs)
-
Abstract base class for protocol messages.
-
Protocol message classes are almost always generated by the protocol
-compiler.
-These generated types subclass Message and implement the methods
-shown below.
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field Routing.error_reason
var route_reply
-
Getter for route_reply.
-
-
-Expand source code
-
-
def getter(self):
- field_value = self._fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
-
- # Atomically check if another thread has preempted us and, if not, swap
- # in the new object we just created. If someone has preempted us, we
- # take that object and discard ours.
- # WARNING: We are relying on setdefault() being atomic. This is true
- # in CPython but we haven't investigated others. This warning appears
- # in several other locations in this file.
- field_value = self._fields.setdefault(field, field_value)
- return field_value
-
+
Field Routing.route_reply
var route_request
-
Getter for route_request.
-
-
-Expand source code
-
-
def getter(self):
- field_value = self._fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
-
- # Atomically check if another thread has preempted us and, if not, swap
- # in the new object we just created. If someone has preempted us, we
- # take that object and discard ours.
- # WARNING: We are relying on setdefault() being atomic. This is true
- # in CPython but we haven't investigated others. This warning appears
- # in several other locations in this file.
- field_value = self._fields.setdefault(field, field_value)
- return field_value
-
-
-
-
Methods
-
-
-def ByteSize(self)
-
-
-
-
-
-Expand source code
-
-
def ByteSize(self):
- if not self._cached_byte_size_dirty:
- return self._cached_byte_size
-
- size = 0
- descriptor = self.DESCRIPTOR
- if descriptor.GetOptions().map_entry:
- # Fields of map entry should always be serialized.
- size = descriptor.fields_by_name['key']._sizer(self.key)
- size += descriptor.fields_by_name['value']._sizer(self.value)
- else:
- for field_descriptor, field_value in self.ListFields():
- size += field_descriptor._sizer(field_value)
- for tag_bytes, value_bytes in self._unknown_fields:
- size += len(tag_bytes) + len(value_bytes)
-
- self._cached_byte_size = size
- self._cached_byte_size_dirty = False
- self._listener_for_children.dirty = False
- return size
def ClearField(self, field_name):
- try:
- field = message_descriptor.fields_by_name[field_name]
- except KeyError:
- try:
- field = message_descriptor.oneofs_by_name[field_name]
- if field in self._oneofs:
- field = self._oneofs[field]
- else:
- return
- except KeyError:
- raise ValueError('Protocol message %s has no "%s" field.' %
- (message_descriptor.name, field_name))
-
- if field in self._fields:
- # To match the C++ implementation, we need to invalidate iterators
- # for map fields when ClearField() happens.
- if hasattr(self._fields[field], 'InvalidateIterators'):
- self._fields[field].InvalidateIterators()
-
- # Note: If the field is a sub-message, its listener will still point
- # at us. That's fine, because the worst than can happen is that it
- # will call _Modified() and invalidate our byte size. Big deal.
- del self._fields[field]
-
- if self._oneofs.get(field.containing_oneof, None) is field:
- del self._oneofs[field.containing_oneof]
-
- # Always call _Modified() -- even if nothing was changed, this is
- # a mutating method, and thus calling it should cause the field to become
- # present in the parent message.
- self._Modified()
-
-
-
-def DiscardUnknownFields(self)
-
-
-
-
-
-Expand source code
-
-
def _DiscardUnknownFields(self):
- self._unknown_fields = []
- self._unknown_field_set = None # pylint: disable=protected-access
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if _IsMapField(field):
- if _IsMessageMapField(field):
- for key in value:
- value[key].DiscardUnknownFields()
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
- for sub_message in value:
- sub_message.DiscardUnknownFields()
- else:
- value.DiscardUnknownFields()
-
-
-
-def FindInitializationErrors(self)
-
-
-
Finds required fields which are not initialized.
-
Returns
-
A list of strings.
-Each string is a path to an uninitialized field from
-the top-level message, e.g. "foo.bar[5].baz".
-
-
-Expand source code
-
-
def FindInitializationErrors(self):
- """Finds required fields which are not initialized.
-
- Returns:
- A list of strings. Each string is a path to an uninitialized field from
- the top-level message, e.g. "foo.bar[5].baz".
- """
-
- errors = [] # simplify things
-
- for field in required_fields:
- if not self.HasField(field.name):
- errors.append(field.name)
-
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.is_extension:
- name = '(%s)' % field.full_name
- else:
- name = field.name
-
- if _IsMapField(field):
- if _IsMessageMapField(field):
- for key in value:
- element = value[key]
- prefix = '%s[%s].' % (name, key)
- sub_errors = element.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
- else:
- # ScalarMaps can't have any initialization errors.
- pass
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
- for i in range(len(value)):
- element = value[i]
- prefix = '%s[%d].' % (name, i)
- sub_errors = element.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
- else:
- prefix = name + '.'
- sub_errors = value.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
-
- return errors
-
-
-
-def HasField(self, field_name)
-
-
-
-
-
-Expand source code
-
-
def HasField(self, field_name):
- try:
- field = hassable_fields[field_name]
- except KeyError:
- raise ValueError(error_msg % (message_descriptor.full_name, field_name))
-
- if isinstance(field, descriptor_mod.OneofDescriptor):
- try:
- return HasField(self, self._oneofs[field].name)
- except KeyError:
- return False
- else:
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- value = self._fields.get(field)
- return value is not None and value._is_present_in_parent
- else:
- return field in self._fields
-
-
-
-def IsInitialized(self, errors=None)
-
-
-
Checks if all required fields of a message are set.
-
Args
-
-
errors
-
A list which, if provided, will be populated with the field
-paths of all missing required fields.
-
-
Returns
-
True iff the specified message has all required fields set.
-
-
-Expand source code
-
-
def IsInitialized(self, errors=None):
- """Checks if all required fields of a message are set.
-
- Args:
- errors: A list which, if provided, will be populated with the field
- paths of all missing required fields.
-
- Returns:
- True iff the specified message has all required fields set.
- """
-
- # Performance is critical so we avoid HasField() and ListFields().
-
- for field in required_fields:
- if (field not in self._fields or
- (field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE and
- not self._fields[field]._is_present_in_parent)):
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- for field, value in list(self._fields.items()): # dict can change size!
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.label == _FieldDescriptor.LABEL_REPEATED:
- if (field.message_type.has_options and
- field.message_type.GetOptions().map_entry):
- continue
- for element in value:
- if not element.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
- elif value._is_present_in_parent and not value.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- return True
-
-
-
-def ListFields(self)
-
-
-
-
-
-Expand source code
-
-
def ListFields(self):
- all_fields = [item for item in self._fields.items() if _IsPresent(item)]
- all_fields.sort(key = lambda item: item[0].number)
- return all_fields
-
-
-
-def MergeFrom(self, msg)
-
-
-
-
-
-Expand source code
-
-
def MergeFrom(self, msg):
- if not isinstance(msg, cls):
- raise TypeError(
- 'Parameter to MergeFrom() must be instance of same class: '
- 'expected %s got %s.' % (_FullyQualifiedClassName(cls),
- _FullyQualifiedClassName(msg.__class__)))
-
- assert msg is not self
- self._Modified()
-
- fields = self._fields
-
- for field, value in msg._fields.items():
- if field.label == LABEL_REPEATED:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- elif field.cpp_type == CPPTYPE_MESSAGE:
- if value._is_present_in_parent:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- else:
- self._fields[field] = value
- if field.containing_oneof:
- self._UpdateOneofState(field)
-
- if msg._unknown_fields:
- if not self._unknown_fields:
- self._unknown_fields = []
- self._unknown_fields.extend(msg._unknown_fields)
- # pylint: disable=protected-access
- if self._unknown_field_set is None:
- self._unknown_field_set = containers.UnknownFieldSet()
- self._unknown_field_set._extend(msg._unknown_field_set)
-
-
-
-def MergeFromString(self, serialized)
-
-
-
-
-
-Expand source code
-
-
def MergeFromString(self, serialized):
- serialized = memoryview(serialized)
- length = len(serialized)
- try:
- if self._InternalParse(serialized, 0, length) != length:
- # The only reason _InternalParse would return early is if it
- # encountered an end-group tag.
- raise message_mod.DecodeError('Unexpected end-group tag.')
- except (IndexError, TypeError):
- # Now ord(buf[p:p+1]) == ord('') gets TypeError.
- raise message_mod.DecodeError('Truncated message.')
- except struct.error as e:
- raise message_mod.DecodeError(e)
- return length # Return this for legacy reasons.
def SerializeToString(self, **kwargs):
- # Check if the message has all of its required fields set.
- if not self.IsInitialized():
- raise message_mod.EncodeError(
- 'Message %s is missing required fields: %s' % (
- self.DESCRIPTOR.full_name, ','.join(self.FindInitializationErrors())))
- return self.SerializePartialToString(**kwargs)
-
-
-
-def SetInParent(self)
-
-
-
Sets the _cached_byte_size_dirty bit to true,
-and propagates this to our listener iff this was a state change.
-
-
-Expand source code
-
-
def Modified(self):
- """Sets the _cached_byte_size_dirty bit to true,
- and propagates this to our listener iff this was a state change.
- """
-
- # Note: Some callers check _cached_byte_size_dirty before calling
- # _Modified() as an extra optimization. So, if this method is ever
- # changed such that it does stuff even when _cached_byte_size_dirty is
- # already true, the callers need to be updated.
- if not self._cached_byte_size_dirty:
- self._cached_byte_size_dirty = True
- self._listener_for_children.dirty = True
- self._is_present_in_parent = True
- self._listener.Modified()
Returns the name of the currently set field inside a oneof, or None.
-
-
-Expand source code
-
-
def WhichOneof(self, oneof_name):
- """Returns the name of the currently set field inside a oneof, or None."""
- try:
- field = message_descriptor.oneofs_by_name[oneof_name]
- except KeyError:
- raise ValueError(
- 'Protocol message has no oneof "%s" field.' % oneof_name)
-
- nested_field = self._oneofs.get(field, None)
- if nested_field is not None and self.HasField(nested_field.name):
- return nested_field.name
- else:
- return None
-
+
Field Routing.route_request
class ToRadio
-(**kwargs)
+(*args, **kwargs)
-
Abstract base class for protocol messages.
-
Protocol message classes are almost always generated by the protocol
-compiler.
-These generated types subclass Message and implement the methods
-shown below.
+
A ProtocolMessage
Ancestors
+
google.protobuf.pyext._message.CMessage
google.protobuf.message.Message
Class variables
@@ -7971,1285 +2383,90 @@ shown below.
-
var DISCONNECT_FIELD_NUMBER
-
-
-
-
var PACKET_FIELD_NUMBER
-
-
-
-
var PEER_INFO_FIELD_NUMBER
-
-
-
var PeerInfo
-
Abstract base class for protocol messages.
-
Protocol message classes are almost always generated by the protocol
-compiler.
-These generated types subclass Message and implement the methods
-shown below.
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field ToRadio.disconnect
var packet
-
Getter for packet.
-
-
-Expand source code
-
-
def getter(self):
- field_value = self._fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
-
- # Atomically check if another thread has preempted us and, if not, swap
- # in the new object we just created. If someone has preempted us, we
- # take that object and discard ours.
- # WARNING: We are relying on setdefault() being atomic. This is true
- # in CPython but we haven't investigated others. This warning appears
- # in several other locations in this file.
- field_value = self._fields.setdefault(field, field_value)
- return field_value
-
+
Field ToRadio.packet
var peer_info
-
Getter for peer_info.
-
-
-Expand source code
-
-
def getter(self):
- field_value = self._fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
-
- # Atomically check if another thread has preempted us and, if not, swap
- # in the new object we just created. If someone has preempted us, we
- # take that object and discard ours.
- # WARNING: We are relying on setdefault() being atomic. This is true
- # in CPython but we haven't investigated others. This warning appears
- # in several other locations in this file.
- field_value = self._fields.setdefault(field, field_value)
- return field_value
-
+
Field ToRadio.peer_info
var want_config_id
-
Getter for want_config_id.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
-
-
-
Methods
-
-
-def ByteSize(self)
-
-
-
-
-
-Expand source code
-
-
def ByteSize(self):
- if not self._cached_byte_size_dirty:
- return self._cached_byte_size
-
- size = 0
- descriptor = self.DESCRIPTOR
- if descriptor.GetOptions().map_entry:
- # Fields of map entry should always be serialized.
- size = descriptor.fields_by_name['key']._sizer(self.key)
- size += descriptor.fields_by_name['value']._sizer(self.value)
- else:
- for field_descriptor, field_value in self.ListFields():
- size += field_descriptor._sizer(field_value)
- for tag_bytes, value_bytes in self._unknown_fields:
- size += len(tag_bytes) + len(value_bytes)
-
- self._cached_byte_size = size
- self._cached_byte_size_dirty = False
- self._listener_for_children.dirty = False
- return size
def ClearField(self, field_name):
- try:
- field = message_descriptor.fields_by_name[field_name]
- except KeyError:
- try:
- field = message_descriptor.oneofs_by_name[field_name]
- if field in self._oneofs:
- field = self._oneofs[field]
- else:
- return
- except KeyError:
- raise ValueError('Protocol message %s has no "%s" field.' %
- (message_descriptor.name, field_name))
-
- if field in self._fields:
- # To match the C++ implementation, we need to invalidate iterators
- # for map fields when ClearField() happens.
- if hasattr(self._fields[field], 'InvalidateIterators'):
- self._fields[field].InvalidateIterators()
-
- # Note: If the field is a sub-message, its listener will still point
- # at us. That's fine, because the worst than can happen is that it
- # will call _Modified() and invalidate our byte size. Big deal.
- del self._fields[field]
-
- if self._oneofs.get(field.containing_oneof, None) is field:
- del self._oneofs[field.containing_oneof]
-
- # Always call _Modified() -- even if nothing was changed, this is
- # a mutating method, and thus calling it should cause the field to become
- # present in the parent message.
- self._Modified()
-
-
-
-def DiscardUnknownFields(self)
-
-
-
-
-
-Expand source code
-
-
def _DiscardUnknownFields(self):
- self._unknown_fields = []
- self._unknown_field_set = None # pylint: disable=protected-access
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if _IsMapField(field):
- if _IsMessageMapField(field):
- for key in value:
- value[key].DiscardUnknownFields()
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
- for sub_message in value:
- sub_message.DiscardUnknownFields()
- else:
- value.DiscardUnknownFields()
-
-
-
-def FindInitializationErrors(self)
-
-
-
Finds required fields which are not initialized.
-
Returns
-
A list of strings.
-Each string is a path to an uninitialized field from
-the top-level message, e.g. "foo.bar[5].baz".
-
-
-Expand source code
-
-
def FindInitializationErrors(self):
- """Finds required fields which are not initialized.
-
- Returns:
- A list of strings. Each string is a path to an uninitialized field from
- the top-level message, e.g. "foo.bar[5].baz".
- """
-
- errors = [] # simplify things
-
- for field in required_fields:
- if not self.HasField(field.name):
- errors.append(field.name)
-
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.is_extension:
- name = '(%s)' % field.full_name
- else:
- name = field.name
-
- if _IsMapField(field):
- if _IsMessageMapField(field):
- for key in value:
- element = value[key]
- prefix = '%s[%s].' % (name, key)
- sub_errors = element.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
- else:
- # ScalarMaps can't have any initialization errors.
- pass
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
- for i in range(len(value)):
- element = value[i]
- prefix = '%s[%d].' % (name, i)
- sub_errors = element.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
- else:
- prefix = name + '.'
- sub_errors = value.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
-
- return errors
-
-
-
-def HasField(self, field_name)
-
-
-
-
-
-Expand source code
-
-
def HasField(self, field_name):
- try:
- field = hassable_fields[field_name]
- except KeyError:
- raise ValueError(error_msg % (message_descriptor.full_name, field_name))
-
- if isinstance(field, descriptor_mod.OneofDescriptor):
- try:
- return HasField(self, self._oneofs[field].name)
- except KeyError:
- return False
- else:
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- value = self._fields.get(field)
- return value is not None and value._is_present_in_parent
- else:
- return field in self._fields
-
-
-
-def IsInitialized(self, errors=None)
-
-
-
Checks if all required fields of a message are set.
-
Args
-
-
errors
-
A list which, if provided, will be populated with the field
-paths of all missing required fields.
-
-
Returns
-
True iff the specified message has all required fields set.
-
-
-Expand source code
-
-
def IsInitialized(self, errors=None):
- """Checks if all required fields of a message are set.
-
- Args:
- errors: A list which, if provided, will be populated with the field
- paths of all missing required fields.
-
- Returns:
- True iff the specified message has all required fields set.
- """
-
- # Performance is critical so we avoid HasField() and ListFields().
-
- for field in required_fields:
- if (field not in self._fields or
- (field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE and
- not self._fields[field]._is_present_in_parent)):
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- for field, value in list(self._fields.items()): # dict can change size!
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.label == _FieldDescriptor.LABEL_REPEATED:
- if (field.message_type.has_options and
- field.message_type.GetOptions().map_entry):
- continue
- for element in value:
- if not element.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
- elif value._is_present_in_parent and not value.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- return True
-
-
-
-def ListFields(self)
-
-
-
-
-
-Expand source code
-
-
def ListFields(self):
- all_fields = [item for item in self._fields.items() if _IsPresent(item)]
- all_fields.sort(key = lambda item: item[0].number)
- return all_fields
-
-
-
-def MergeFrom(self, msg)
-
-
-
-
-
-Expand source code
-
-
def MergeFrom(self, msg):
- if not isinstance(msg, cls):
- raise TypeError(
- 'Parameter to MergeFrom() must be instance of same class: '
- 'expected %s got %s.' % (_FullyQualifiedClassName(cls),
- _FullyQualifiedClassName(msg.__class__)))
-
- assert msg is not self
- self._Modified()
-
- fields = self._fields
-
- for field, value in msg._fields.items():
- if field.label == LABEL_REPEATED:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- elif field.cpp_type == CPPTYPE_MESSAGE:
- if value._is_present_in_parent:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- else:
- self._fields[field] = value
- if field.containing_oneof:
- self._UpdateOneofState(field)
-
- if msg._unknown_fields:
- if not self._unknown_fields:
- self._unknown_fields = []
- self._unknown_fields.extend(msg._unknown_fields)
- # pylint: disable=protected-access
- if self._unknown_field_set is None:
- self._unknown_field_set = containers.UnknownFieldSet()
- self._unknown_field_set._extend(msg._unknown_field_set)
-
-
-
-def MergeFromString(self, serialized)
-
-
-
-
-
-Expand source code
-
-
def MergeFromString(self, serialized):
- serialized = memoryview(serialized)
- length = len(serialized)
- try:
- if self._InternalParse(serialized, 0, length) != length:
- # The only reason _InternalParse would return early is if it
- # encountered an end-group tag.
- raise message_mod.DecodeError('Unexpected end-group tag.')
- except (IndexError, TypeError):
- # Now ord(buf[p:p+1]) == ord('') gets TypeError.
- raise message_mod.DecodeError('Truncated message.')
- except struct.error as e:
- raise message_mod.DecodeError(e)
- return length # Return this for legacy reasons.
def SerializeToString(self, **kwargs):
- # Check if the message has all of its required fields set.
- if not self.IsInitialized():
- raise message_mod.EncodeError(
- 'Message %s is missing required fields: %s' % (
- self.DESCRIPTOR.full_name, ','.join(self.FindInitializationErrors())))
- return self.SerializePartialToString(**kwargs)
-
-
-
-def SetInParent(self)
-
-
-
Sets the _cached_byte_size_dirty bit to true,
-and propagates this to our listener iff this was a state change.
-
-
-Expand source code
-
-
def Modified(self):
- """Sets the _cached_byte_size_dirty bit to true,
- and propagates this to our listener iff this was a state change.
- """
-
- # Note: Some callers check _cached_byte_size_dirty before calling
- # _Modified() as an extra optimization. So, if this method is ever
- # changed such that it does stuff even when _cached_byte_size_dirty is
- # already true, the callers need to be updated.
- if not self._cached_byte_size_dirty:
- self._cached_byte_size_dirty = True
- self._listener_for_children.dirty = True
- self._is_present_in_parent = True
- self._listener.Modified()
Returns the name of the currently set field inside a oneof, or None.
-
-
-Expand source code
-
-
def WhichOneof(self, oneof_name):
- """Returns the name of the currently set field inside a oneof, or None."""
- try:
- field = message_descriptor.oneofs_by_name[oneof_name]
- except KeyError:
- raise ValueError(
- 'Protocol message has no oneof "%s" field.' % oneof_name)
-
- nested_field = self._oneofs.get(field, None)
- if nested_field is not None and self.HasField(nested_field.name):
- return nested_field.name
- else:
- return None
-
+
Field ToRadio.want_config_id
class User
-(**kwargs)
+(*args, **kwargs)
-
Abstract base class for protocol messages.
-
Protocol message classes are almost always generated by the protocol
-compiler.
-These generated types subclass Message and implement the methods
-shown below.
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field User.ant_azimuth
var ant_gain_dbi
-
Getter for ant_gain_dbi.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field User.ant_gain_dbi
var hw_model
-
Getter for hw_model.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field User.hw_model
var id
-
Getter for id.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field User.id
var is_licensed
-
Getter for is_licensed.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field User.is_licensed
var long_name
-
Getter for long_name.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field User.long_name
var macaddr
-
Getter for macaddr.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field User.macaddr
var short_name
-
Getter for short_name.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field User.short_name
var team
-
Getter for team.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field User.team
var tx_power_dbm
-
Getter for tx_power_dbm.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
-
-
-
Methods
-
-
-def ByteSize(self)
-
-
-
-
-
-Expand source code
-
-
def ByteSize(self):
- if not self._cached_byte_size_dirty:
- return self._cached_byte_size
-
- size = 0
- descriptor = self.DESCRIPTOR
- if descriptor.GetOptions().map_entry:
- # Fields of map entry should always be serialized.
- size = descriptor.fields_by_name['key']._sizer(self.key)
- size += descriptor.fields_by_name['value']._sizer(self.value)
- else:
- for field_descriptor, field_value in self.ListFields():
- size += field_descriptor._sizer(field_value)
- for tag_bytes, value_bytes in self._unknown_fields:
- size += len(tag_bytes) + len(value_bytes)
-
- self._cached_byte_size = size
- self._cached_byte_size_dirty = False
- self._listener_for_children.dirty = False
- return size
def ClearField(self, field_name):
- try:
- field = message_descriptor.fields_by_name[field_name]
- except KeyError:
- try:
- field = message_descriptor.oneofs_by_name[field_name]
- if field in self._oneofs:
- field = self._oneofs[field]
- else:
- return
- except KeyError:
- raise ValueError('Protocol message %s has no "%s" field.' %
- (message_descriptor.name, field_name))
-
- if field in self._fields:
- # To match the C++ implementation, we need to invalidate iterators
- # for map fields when ClearField() happens.
- if hasattr(self._fields[field], 'InvalidateIterators'):
- self._fields[field].InvalidateIterators()
-
- # Note: If the field is a sub-message, its listener will still point
- # at us. That's fine, because the worst than can happen is that it
- # will call _Modified() and invalidate our byte size. Big deal.
- del self._fields[field]
-
- if self._oneofs.get(field.containing_oneof, None) is field:
- del self._oneofs[field.containing_oneof]
-
- # Always call _Modified() -- even if nothing was changed, this is
- # a mutating method, and thus calling it should cause the field to become
- # present in the parent message.
- self._Modified()
-
-
-
-def DiscardUnknownFields(self)
-
-
-
-
-
-Expand source code
-
-
def _DiscardUnknownFields(self):
- self._unknown_fields = []
- self._unknown_field_set = None # pylint: disable=protected-access
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if _IsMapField(field):
- if _IsMessageMapField(field):
- for key in value:
- value[key].DiscardUnknownFields()
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
- for sub_message in value:
- sub_message.DiscardUnknownFields()
- else:
- value.DiscardUnknownFields()
-
-
-
-def FindInitializationErrors(self)
-
-
-
Finds required fields which are not initialized.
-
Returns
-
A list of strings.
-Each string is a path to an uninitialized field from
-the top-level message, e.g. "foo.bar[5].baz".
-
-
-Expand source code
-
-
def FindInitializationErrors(self):
- """Finds required fields which are not initialized.
-
- Returns:
- A list of strings. Each string is a path to an uninitialized field from
- the top-level message, e.g. "foo.bar[5].baz".
- """
-
- errors = [] # simplify things
-
- for field in required_fields:
- if not self.HasField(field.name):
- errors.append(field.name)
-
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.is_extension:
- name = '(%s)' % field.full_name
- else:
- name = field.name
-
- if _IsMapField(field):
- if _IsMessageMapField(field):
- for key in value:
- element = value[key]
- prefix = '%s[%s].' % (name, key)
- sub_errors = element.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
- else:
- # ScalarMaps can't have any initialization errors.
- pass
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
- for i in range(len(value)):
- element = value[i]
- prefix = '%s[%d].' % (name, i)
- sub_errors = element.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
- else:
- prefix = name + '.'
- sub_errors = value.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
-
- return errors
-
-
-
-def HasField(self, field_name)
-
-
-
-
-
-Expand source code
-
-
def HasField(self, field_name):
- try:
- field = hassable_fields[field_name]
- except KeyError:
- raise ValueError(error_msg % (message_descriptor.full_name, field_name))
-
- if isinstance(field, descriptor_mod.OneofDescriptor):
- try:
- return HasField(self, self._oneofs[field].name)
- except KeyError:
- return False
- else:
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- value = self._fields.get(field)
- return value is not None and value._is_present_in_parent
- else:
- return field in self._fields
-
-
-
-def IsInitialized(self, errors=None)
-
-
-
Checks if all required fields of a message are set.
-
Args
-
-
errors
-
A list which, if provided, will be populated with the field
-paths of all missing required fields.
-
-
Returns
-
True iff the specified message has all required fields set.
-
-
-Expand source code
-
-
def IsInitialized(self, errors=None):
- """Checks if all required fields of a message are set.
-
- Args:
- errors: A list which, if provided, will be populated with the field
- paths of all missing required fields.
-
- Returns:
- True iff the specified message has all required fields set.
- """
-
- # Performance is critical so we avoid HasField() and ListFields().
-
- for field in required_fields:
- if (field not in self._fields or
- (field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE and
- not self._fields[field]._is_present_in_parent)):
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- for field, value in list(self._fields.items()): # dict can change size!
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.label == _FieldDescriptor.LABEL_REPEATED:
- if (field.message_type.has_options and
- field.message_type.GetOptions().map_entry):
- continue
- for element in value:
- if not element.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
- elif value._is_present_in_parent and not value.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- return True
-
-
-
-def ListFields(self)
-
-
-
-
-
-Expand source code
-
-
def ListFields(self):
- all_fields = [item for item in self._fields.items() if _IsPresent(item)]
- all_fields.sort(key = lambda item: item[0].number)
- return all_fields
-
-
-
-def MergeFrom(self, msg)
-
-
-
-
-
-Expand source code
-
-
def MergeFrom(self, msg):
- if not isinstance(msg, cls):
- raise TypeError(
- 'Parameter to MergeFrom() must be instance of same class: '
- 'expected %s got %s.' % (_FullyQualifiedClassName(cls),
- _FullyQualifiedClassName(msg.__class__)))
-
- assert msg is not self
- self._Modified()
-
- fields = self._fields
-
- for field, value in msg._fields.items():
- if field.label == LABEL_REPEATED:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- elif field.cpp_type == CPPTYPE_MESSAGE:
- if value._is_present_in_parent:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- else:
- self._fields[field] = value
- if field.containing_oneof:
- self._UpdateOneofState(field)
-
- if msg._unknown_fields:
- if not self._unknown_fields:
- self._unknown_fields = []
- self._unknown_fields.extend(msg._unknown_fields)
- # pylint: disable=protected-access
- if self._unknown_field_set is None:
- self._unknown_field_set = containers.UnknownFieldSet()
- self._unknown_field_set._extend(msg._unknown_field_set)
-
-
-
-def MergeFromString(self, serialized)
-
-
-
-
-
-Expand source code
-
-
def MergeFromString(self, serialized):
- serialized = memoryview(serialized)
- length = len(serialized)
- try:
- if self._InternalParse(serialized, 0, length) != length:
- # The only reason _InternalParse would return early is if it
- # encountered an end-group tag.
- raise message_mod.DecodeError('Unexpected end-group tag.')
- except (IndexError, TypeError):
- # Now ord(buf[p:p+1]) == ord('') gets TypeError.
- raise message_mod.DecodeError('Truncated message.')
- except struct.error as e:
- raise message_mod.DecodeError(e)
- return length # Return this for legacy reasons.
def SerializeToString(self, **kwargs):
- # Check if the message has all of its required fields set.
- if not self.IsInitialized():
- raise message_mod.EncodeError(
- 'Message %s is missing required fields: %s' % (
- self.DESCRIPTOR.full_name, ','.join(self.FindInitializationErrors())))
- return self.SerializePartialToString(**kwargs)
-
-
-
-def SetInParent(self)
-
-
-
Sets the _cached_byte_size_dirty bit to true,
-and propagates this to our listener iff this was a state change.
-
-
-Expand source code
-
-
def Modified(self):
- """Sets the _cached_byte_size_dirty bit to true,
- and propagates this to our listener iff this was a state change.
- """
-
- # Note: Some callers check _cached_byte_size_dirty before calling
- # _Modified() as an extra optimization. So, if this method is ever
- # changed such that it does stuff even when _cached_byte_size_dirty is
- # already true, the callers need to be updated.
- if not self._cached_byte_size_dirty:
- self._cached_byte_size_dirty = True
- self._listener_for_children.dirty = True
- self._is_present_in_parent = True
- self._listener.Modified()
Returns the name of the currently set field inside a oneof, or None.
-
-
-Expand source code
-
-
def WhichOneof(self, oneof_name):
- """Returns the name of the currently set field inside a oneof, or None."""
- try:
- field = message_descriptor.oneofs_by_name[oneof_name]
- except KeyError:
- raise ValueError(
- 'Protocol message has no oneof "%s" field.' % oneof_name)
-
- nested_field = self._oneofs.get(field, None)
- if nested_field is not None and self.HasField(nested_field.name):
- return nested_field.name
- else:
- return None
-
+
Field User.tx_power_dbm
@@ -9271,31 +2488,8 @@ and propagates this to our listener iff this was a state change.
class ServiceEnvelope
-(**kwargs)
+(*args, **kwargs)
-
Abstract base class for protocol messages.
-
Protocol message classes are almost always generated by the protocol
-compiler.
-These generated types subclass Message and implement the methods
-shown below.
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field ServiceEnvelope.channel_id
var gateway_id
-
Getter for gateway_id.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field ServiceEnvelope.gateway_id
var packet
-
Getter for packet.
-
-
-Expand source code
-
-
def getter(self):
- field_value = self._fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
-
- # Atomically check if another thread has preempted us and, if not, swap
- # in the new object we just created. If someone has preempted us, we
- # take that object and discard ours.
- # WARNING: We are relying on setdefault() being atomic. This is true
- # in CPython but we haven't investigated others. This warning appears
- # in several other locations in this file.
- field_value = self._fields.setdefault(field, field_value)
- return field_value
-
-
-
-
Methods
-
-
-def ByteSize(self)
-
-
-
-
-
-Expand source code
-
-
def ByteSize(self):
- if not self._cached_byte_size_dirty:
- return self._cached_byte_size
-
- size = 0
- descriptor = self.DESCRIPTOR
- if descriptor.GetOptions().map_entry:
- # Fields of map entry should always be serialized.
- size = descriptor.fields_by_name['key']._sizer(self.key)
- size += descriptor.fields_by_name['value']._sizer(self.value)
- else:
- for field_descriptor, field_value in self.ListFields():
- size += field_descriptor._sizer(field_value)
- for tag_bytes, value_bytes in self._unknown_fields:
- size += len(tag_bytes) + len(value_bytes)
-
- self._cached_byte_size = size
- self._cached_byte_size_dirty = False
- self._listener_for_children.dirty = False
- return size
def ClearField(self, field_name):
- try:
- field = message_descriptor.fields_by_name[field_name]
- except KeyError:
- try:
- field = message_descriptor.oneofs_by_name[field_name]
- if field in self._oneofs:
- field = self._oneofs[field]
- else:
- return
- except KeyError:
- raise ValueError('Protocol message %s has no "%s" field.' %
- (message_descriptor.name, field_name))
-
- if field in self._fields:
- # To match the C++ implementation, we need to invalidate iterators
- # for map fields when ClearField() happens.
- if hasattr(self._fields[field], 'InvalidateIterators'):
- self._fields[field].InvalidateIterators()
-
- # Note: If the field is a sub-message, its listener will still point
- # at us. That's fine, because the worst than can happen is that it
- # will call _Modified() and invalidate our byte size. Big deal.
- del self._fields[field]
-
- if self._oneofs.get(field.containing_oneof, None) is field:
- del self._oneofs[field.containing_oneof]
-
- # Always call _Modified() -- even if nothing was changed, this is
- # a mutating method, and thus calling it should cause the field to become
- # present in the parent message.
- self._Modified()
-
-
-
-def DiscardUnknownFields(self)
-
-
-
-
-
-Expand source code
-
-
def _DiscardUnknownFields(self):
- self._unknown_fields = []
- self._unknown_field_set = None # pylint: disable=protected-access
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if _IsMapField(field):
- if _IsMessageMapField(field):
- for key in value:
- value[key].DiscardUnknownFields()
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
- for sub_message in value:
- sub_message.DiscardUnknownFields()
- else:
- value.DiscardUnknownFields()
-
-
-
-def FindInitializationErrors(self)
-
-
-
Finds required fields which are not initialized.
-
Returns
-
A list of strings.
-Each string is a path to an uninitialized field from
-the top-level message, e.g. "foo.bar[5].baz".
-
-
-Expand source code
-
-
def FindInitializationErrors(self):
- """Finds required fields which are not initialized.
-
- Returns:
- A list of strings. Each string is a path to an uninitialized field from
- the top-level message, e.g. "foo.bar[5].baz".
- """
-
- errors = [] # simplify things
-
- for field in required_fields:
- if not self.HasField(field.name):
- errors.append(field.name)
-
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.is_extension:
- name = '(%s)' % field.full_name
- else:
- name = field.name
-
- if _IsMapField(field):
- if _IsMessageMapField(field):
- for key in value:
- element = value[key]
- prefix = '%s[%s].' % (name, key)
- sub_errors = element.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
- else:
- # ScalarMaps can't have any initialization errors.
- pass
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
- for i in range(len(value)):
- element = value[i]
- prefix = '%s[%d].' % (name, i)
- sub_errors = element.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
- else:
- prefix = name + '.'
- sub_errors = value.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
-
- return errors
-
-
-
-def HasField(self, field_name)
-
-
-
-
-
-Expand source code
-
-
def HasField(self, field_name):
- try:
- field = hassable_fields[field_name]
- except KeyError:
- raise ValueError(error_msg % (message_descriptor.full_name, field_name))
-
- if isinstance(field, descriptor_mod.OneofDescriptor):
- try:
- return HasField(self, self._oneofs[field].name)
- except KeyError:
- return False
- else:
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- value = self._fields.get(field)
- return value is not None and value._is_present_in_parent
- else:
- return field in self._fields
-
-
-
-def IsInitialized(self, errors=None)
-
-
-
Checks if all required fields of a message are set.
-
Args
-
-
errors
-
A list which, if provided, will be populated with the field
-paths of all missing required fields.
-
-
Returns
-
True iff the specified message has all required fields set.
-
-
-Expand source code
-
-
def IsInitialized(self, errors=None):
- """Checks if all required fields of a message are set.
-
- Args:
- errors: A list which, if provided, will be populated with the field
- paths of all missing required fields.
-
- Returns:
- True iff the specified message has all required fields set.
- """
-
- # Performance is critical so we avoid HasField() and ListFields().
-
- for field in required_fields:
- if (field not in self._fields or
- (field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE and
- not self._fields[field]._is_present_in_parent)):
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- for field, value in list(self._fields.items()): # dict can change size!
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.label == _FieldDescriptor.LABEL_REPEATED:
- if (field.message_type.has_options and
- field.message_type.GetOptions().map_entry):
- continue
- for element in value:
- if not element.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
- elif value._is_present_in_parent and not value.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- return True
-
-
-
-def ListFields(self)
-
-
-
-
-
-Expand source code
-
-
def ListFields(self):
- all_fields = [item for item in self._fields.items() if _IsPresent(item)]
- all_fields.sort(key = lambda item: item[0].number)
- return all_fields
-
-
-
-def MergeFrom(self, msg)
-
-
-
-
-
-Expand source code
-
-
def MergeFrom(self, msg):
- if not isinstance(msg, cls):
- raise TypeError(
- 'Parameter to MergeFrom() must be instance of same class: '
- 'expected %s got %s.' % (_FullyQualifiedClassName(cls),
- _FullyQualifiedClassName(msg.__class__)))
-
- assert msg is not self
- self._Modified()
-
- fields = self._fields
-
- for field, value in msg._fields.items():
- if field.label == LABEL_REPEATED:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- elif field.cpp_type == CPPTYPE_MESSAGE:
- if value._is_present_in_parent:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- else:
- self._fields[field] = value
- if field.containing_oneof:
- self._UpdateOneofState(field)
-
- if msg._unknown_fields:
- if not self._unknown_fields:
- self._unknown_fields = []
- self._unknown_fields.extend(msg._unknown_fields)
- # pylint: disable=protected-access
- if self._unknown_field_set is None:
- self._unknown_field_set = containers.UnknownFieldSet()
- self._unknown_field_set._extend(msg._unknown_field_set)
-
-
-
-def MergeFromString(self, serialized)
-
-
-
-
-
-Expand source code
-
-
def MergeFromString(self, serialized):
- serialized = memoryview(serialized)
- length = len(serialized)
- try:
- if self._InternalParse(serialized, 0, length) != length:
- # The only reason _InternalParse would return early is if it
- # encountered an end-group tag.
- raise message_mod.DecodeError('Unexpected end-group tag.')
- except (IndexError, TypeError):
- # Now ord(buf[p:p+1]) == ord('') gets TypeError.
- raise message_mod.DecodeError('Truncated message.')
- except struct.error as e:
- raise message_mod.DecodeError(e)
- return length # Return this for legacy reasons.
def SerializeToString(self, **kwargs):
- # Check if the message has all of its required fields set.
- if not self.IsInitialized():
- raise message_mod.EncodeError(
- 'Message %s is missing required fields: %s' % (
- self.DESCRIPTOR.full_name, ','.join(self.FindInitializationErrors())))
- return self.SerializePartialToString(**kwargs)
-
-
-
-def SetInParent(self)
-
-
-
Sets the _cached_byte_size_dirty bit to true,
-and propagates this to our listener iff this was a state change.
-
-
-Expand source code
-
-
def Modified(self):
- """Sets the _cached_byte_size_dirty bit to true,
- and propagates this to our listener iff this was a state change.
- """
-
- # Note: Some callers check _cached_byte_size_dirty before calling
- # _Modified() as an extra optimization. So, if this method is ever
- # changed such that it does stuff even when _cached_byte_size_dirty is
- # already true, the callers need to be updated.
- if not self._cached_byte_size_dirty:
- self._cached_byte_size_dirty = True
- self._listener_for_children.dirty = True
- self._is_present_in_parent = True
- self._listener.Modified()
Returns the name of the currently set field inside a oneof, or None.
-
-
-Expand source code
-
-
def WhichOneof(self, oneof_name):
- """Returns the name of the currently set field inside a oneof, or None."""
- try:
- field = message_descriptor.oneofs_by_name[oneof_name]
- except KeyError:
- raise ValueError(
- 'Protocol message has no oneof "%s" field.' % oneof_name)
-
- nested_field = self._oneofs.get(field, None)
- if nested_field is not None and self.HasField(nested_field.name):
- return nested_field.name
- else:
- return None
-
+
Field ServiceEnvelope.packet
@@ -721,27 +176,7 @@ and propagates this to our listener iff this was a state change.
diff --git a/docs/meshtastic/node.html b/docs/meshtastic/node.html
index 576b49b..b0a7365 100644
--- a/docs/meshtastic/node.html
+++ b/docs/meshtastic/node.html
@@ -37,26 +37,31 @@ from . import portnums_pb2, apponly_pb2, admin_pb2, channel_pb2
from .util import pskToString, stripnl, Timeout, our_exit, fromPSK
+
+
class Node:
"""A model of a (local or remote) node in the mesh
Includes methods for radioConfig and channels
"""
- def __init__(self, iface, nodeNum):
+ def __init__(self, iface, nodeNum, noProto=False):
"""Constructor"""
self.iface = iface
self.nodeNum = nodeNum
self.radioConfig = None
self.channels = None
- self._timeout = Timeout(maxSecs=60)
+ self._timeout = Timeout(maxSecs=300)
self.partialChannels = None
+ self.noProto = noProto
def showChannels(self):
"""Show human readable description of our channels."""
print("Channels:")
if self.channels:
+ logging.debug(f'self.channels:{self.channels}')
for c in self.channels:
+ #print('c.settings.psk:', c.settings.psk)
cStr = stripnl(MessageToJson(c.settings))
# only show if there is no psk (meaning disabled channel)
if c.settings.psk:
@@ -77,6 +82,7 @@ class Node:
def requestConfig(self):
"""Send regular MeshPackets to ask for settings and channels."""
+ logging.debug(f"requestConfig for nodeNum:{self.nodeNum}")
self.radioConfig = None
self.channels = None
self.partialChannels = [] # We keep our channels in a temp array until finished
@@ -113,6 +119,16 @@ class Node:
self._sendAdmin(p, adminIndex=adminIndex)
logging.debug(f"Wrote channel {channelIndex}")
+ def getChannelByChannelIndex(self, channelIndex):
+ """Get channel by channelIndex
+ channelIndex: number, typically 0-7; based on max number channels
+ returns: None if there is no channel found
+ """
+ ch = None
+ if self.channels and 0 <= channelIndex < len(self.channels):
+ ch = self.channels[channelIndex]
+ return ch
+
def deleteChannel(self, channelIndex):
"""Delete the specifed channelIndex and shift other channels up"""
ch = self.channels[channelIndex]
@@ -135,7 +151,7 @@ class Node:
# *moving* the admin channel index as we are writing
if (self.iface.localNode == self) and index >= adminIndex:
# We've now passed the old location for admin index
- # (and writen it), so we can start finding it by name again
+ # (and written it), so we can start finding it by name again
adminIndex = 0
def getChannelByName(self, name):
@@ -162,6 +178,7 @@ class Node:
def setOwner(self, long_name=None, short_name=None, is_licensed=False, team=None):
"""Set device owner name"""
+ logging.debug(f"in setOwner nodeNum:{self.nodeNum}")
nChars = 3
minChars = 2
if long_name is not None:
@@ -191,6 +208,11 @@ class Node:
if team is not None:
p.set_owner.team = team
+ # Note: These debug lines are used in unit tests
+ logging.debug(f'p.set_owner.long_name:{p.set_owner.long_name}:')
+ logging.debug(f'p.set_owner.short_name:{p.set_owner.short_name}:')
+ logging.debug(f'p.set_owner.is_licensed:{p.set_owner.is_licensed}')
+ logging.debug(f'p.set_owner.team:{p.set_owner.team}')
return self._sendAdmin(p)
def getURL(self, includeAll: bool = True):
@@ -226,6 +248,7 @@ class Node:
channelSet = apponly_pb2.ChannelSet()
channelSet.ParseFromString(decodedURL)
+
if len(channelSet.settings) == 0:
our_exit("Warning: There were no settings.")
@@ -236,39 +259,51 @@ class Node:
ch.index = i
ch.settings.CopyFrom(chs)
self.channels[ch.index] = ch
+ logging.debug(f'Channel i:{i} ch:{ch}')
self.writeChannel(ch.index)
i = i + 1
+
+ def onResponseRequestSettings(self, p):
+ """Handle the response packet for requesting settings _requestSettings()"""
+ logging.debug(f'onResponseRequestSetting() p:{p}')
+ errorFound = False
+ if 'routing' in p["decoded"]:
+ if p["decoded"]["routing"]["errorReason"] != "NONE":
+ errorFound = True
+ print(f'Error on response: {p["decoded"]["routing"]["errorReason"]}')
+ if errorFound is False:
+ self.radioConfig = p["decoded"]["admin"]["raw"].get_radio_response
+ logging.debug(f'self.radioConfig:{self.radioConfig}')
+ logging.debug("Received radio config, now fetching channels...")
+ self._timeout.reset() # We made foreward progress
+ self._requestChannel(0) # now start fetching channels
+
+
def _requestSettings(self):
"""Done with initial config messages, now send regular
MeshPackets to ask for settings."""
p = admin_pb2.AdminMessage()
p.get_radio_request = True
- def onResponse(p):
- """A closure to handle the response packet"""
- errorFound = False
- if 'routing' in p["decoded"]:
- if p["decoded"]["routing"]["errorReason"] != "NONE":
- errorFound = True
- print(f'Error on response: {p["decoded"]["routing"]["errorReason"]}')
- if errorFound is False:
- self.radioConfig = p["decoded"]["admin"]["raw"].get_radio_response
- logging.debug("Received radio config, now fetching channels...")
- self._timeout.reset() # We made foreward progress
- self._requestChannel(0) # now start fetching channels
-
# Show progress message for super slow operations
if self != self.iface.localNode:
- print("Requesting preferences from remote node (this could take a while)")
+ print("Requesting preferences from remote node.")
+ print("Be sure:")
+ print(" 1. There is a SECONDARY channel named 'admin'.")
+ print(" 2. The '--seturl' was used to configure.")
+ print(" 3. All devices have the same modem config. (i.e., '--ch-longfast')")
+ print(" 4. All devices have been rebooted after all of the above. (optional, but recommended)")
+ print("Note: This could take a while (it requests remote channel configs, then writes config)")
- return self._sendAdmin(p, wantResponse=True, onResponse=onResponse)
+ return self._sendAdmin(p, wantResponse=True, onResponse=self.onResponseRequestSettings)
def exitSimulator(self):
"""Tell a simulator node to exit (this message
is ignored for other nodes)"""
p = admin_pb2.AdminMessage()
p.exit_simulator = True
+ logging.debug('in exitSimulator()')
return self._sendAdmin(p)
@@ -302,6 +337,34 @@ class Node:
self.channels.append(ch)
index += 1
+
+ def onResponseRequestChannel(self, p):
+ """Handle the response packet for requesting a channel _requestChannel()"""
+ logging.debug(f'onResponseRequestChannel() p:{p}')
+ c = p["decoded"]["admin"]["raw"].get_channel_response
+ self.partialChannels.append(c)
+ self._timeout.reset() # We made foreward progress
+ logging.debug(f"Received channel {stripnl(c)}")
+ index = c.index
+
+ # for stress testing, we can always download all channels
+ fastChannelDownload = True
+
+ # Once we see a response that has NO settings, assume
+ # we are at the end of channels and stop fetching
+ quitEarly = (c.role == channel_pb2.Channel.Role.DISABLED) and fastChannelDownload
+
+ if quitEarly or index >= self.iface.myInfo.max_channels - 1:
+ logging.debug("Finished downloading channels")
+
+ self.channels = self.partialChannels
+ self._fixupChannels()
+
+ # FIXME, the following should only be called after we have settings and channels
+ self.iface._connected() # Tell everyone else we are ready to go
+ else:
+ self._requestChannel(index + 1)
+
def _requestChannel(self, channelNum: int):
"""Done with initial config messages, now send regular
MeshPackets to ask for settings"""
@@ -310,51 +373,32 @@ class Node:
# Show progress message for super slow operations
if self != self.iface.localNode:
- logging.info(f"Requesting channel {channelNum} info from remote node (this could take a while)")
+ print(f"Requesting channel {channelNum} info from remote node (this could take a while)")
+ logging.debug(f"Requesting channel {channelNum} info from remote node (this could take a while)")
else:
logging.debug(f"Requesting channel {channelNum}")
- def onResponse(p):
- """A closure to handle the response packet for requesting a channel"""
- c = p["decoded"]["admin"]["raw"].get_channel_response
- self.partialChannels.append(c)
- self._timeout.reset() # We made foreward progress
- logging.debug(f"Received channel {stripnl(c)}")
- index = c.index
+ return self._sendAdmin(p, wantResponse=True, onResponse=self.onResponseRequestChannel)
- # for stress testing, we can always download all channels
- fastChannelDownload = True
-
- # Once we see a response that has NO settings, assume
- # we are at the end of channels and stop fetching
- quitEarly = (c.role == channel_pb2.Channel.Role.DISABLED) and fastChannelDownload
-
- if quitEarly or index >= self.iface.myInfo.max_channels - 1:
- logging.debug("Finished downloading channels")
-
- self.channels = self.partialChannels
- self._fixupChannels()
-
- # FIXME, the following should only be called after we have settings and channels
- self.iface._connected() # Tell everone else we are ready to go
- else:
- self._requestChannel(index + 1)
-
- return self._sendAdmin(p, wantResponse=True, onResponse=onResponse)
+ # pylint: disable=R1710
def _sendAdmin(self, p: admin_pb2.AdminMessage, wantResponse=False,
onResponse=None, adminIndex=0):
"""Send an admin message to the specified node (or the local node if destNodeNum is zero)"""
- if adminIndex == 0: # unless a special channel index was used, we want to use the admin index
- adminIndex = self.iface.localNode._getAdminChannelIndex()
+ if self.noProto:
+ logging.warning(f"Not sending packet because protocol use is disabled by noProto")
+ else:
+ if adminIndex == 0: # unless a special channel index was used, we want to use the admin index
+ adminIndex = self.iface.localNode._getAdminChannelIndex()
+ logging.debug(f'adminIndex:{adminIndex}')
- return self.iface.sendData(p, self.nodeNum,
- portNum=portnums_pb2.PortNum.ADMIN_APP,
- wantAck=True,
- wantResponse=wantResponse,
- onResponse=onResponse,
- channelIndex=adminIndex)
class Node
-(iface, nodeNum)
+(iface, nodeNum, noProto=False)
A model of a (local or remote) node in the mesh
@@ -384,20 +428,23 @@ class Node:
Includes methods for radioConfig and channels
"""
- def __init__(self, iface, nodeNum):
+ def __init__(self, iface, nodeNum, noProto=False):
"""Constructor"""
self.iface = iface
self.nodeNum = nodeNum
self.radioConfig = None
self.channels = None
- self._timeout = Timeout(maxSecs=60)
+ self._timeout = Timeout(maxSecs=300)
self.partialChannels = None
+ self.noProto = noProto
def showChannels(self):
"""Show human readable description of our channels."""
print("Channels:")
if self.channels:
+ logging.debug(f'self.channels:{self.channels}')
for c in self.channels:
+ #print('c.settings.psk:', c.settings.psk)
cStr = stripnl(MessageToJson(c.settings))
# only show if there is no psk (meaning disabled channel)
if c.settings.psk:
@@ -418,6 +465,7 @@ class Node:
def requestConfig(self):
"""Send regular MeshPackets to ask for settings and channels."""
+ logging.debug(f"requestConfig for nodeNum:{self.nodeNum}")
self.radioConfig = None
self.channels = None
self.partialChannels = [] # We keep our channels in a temp array until finished
@@ -454,6 +502,16 @@ class Node:
self._sendAdmin(p, adminIndex=adminIndex)
logging.debug(f"Wrote channel {channelIndex}")
+ def getChannelByChannelIndex(self, channelIndex):
+ """Get channel by channelIndex
+ channelIndex: number, typically 0-7; based on max number channels
+ returns: None if there is no channel found
+ """
+ ch = None
+ if self.channels and 0 <= channelIndex < len(self.channels):
+ ch = self.channels[channelIndex]
+ return ch
+
def deleteChannel(self, channelIndex):
"""Delete the specifed channelIndex and shift other channels up"""
ch = self.channels[channelIndex]
@@ -476,7 +534,7 @@ class Node:
# *moving* the admin channel index as we are writing
if (self.iface.localNode == self) and index >= adminIndex:
# We've now passed the old location for admin index
- # (and writen it), so we can start finding it by name again
+ # (and written it), so we can start finding it by name again
adminIndex = 0
def getChannelByName(self, name):
@@ -503,6 +561,7 @@ class Node:
def setOwner(self, long_name=None, short_name=None, is_licensed=False, team=None):
"""Set device owner name"""
+ logging.debug(f"in setOwner nodeNum:{self.nodeNum}")
nChars = 3
minChars = 2
if long_name is not None:
@@ -532,6 +591,11 @@ class Node:
if team is not None:
p.set_owner.team = team
+ # Note: These debug lines are used in unit tests
+ logging.debug(f'p.set_owner.long_name:{p.set_owner.long_name}:')
+ logging.debug(f'p.set_owner.short_name:{p.set_owner.short_name}:')
+ logging.debug(f'p.set_owner.is_licensed:{p.set_owner.is_licensed}')
+ logging.debug(f'p.set_owner.team:{p.set_owner.team}')
return self._sendAdmin(p)
def getURL(self, includeAll: bool = True):
@@ -567,6 +631,7 @@ class Node:
channelSet = apponly_pb2.ChannelSet()
channelSet.ParseFromString(decodedURL)
+
if len(channelSet.settings) == 0:
our_exit("Warning: There were no settings.")
@@ -577,39 +642,51 @@ class Node:
ch.index = i
ch.settings.CopyFrom(chs)
self.channels[ch.index] = ch
+ logging.debug(f'Channel i:{i} ch:{ch}')
self.writeChannel(ch.index)
i = i + 1
+
+ def onResponseRequestSettings(self, p):
+ """Handle the response packet for requesting settings _requestSettings()"""
+ logging.debug(f'onResponseRequestSetting() p:{p}')
+ errorFound = False
+ if 'routing' in p["decoded"]:
+ if p["decoded"]["routing"]["errorReason"] != "NONE":
+ errorFound = True
+ print(f'Error on response: {p["decoded"]["routing"]["errorReason"]}')
+ if errorFound is False:
+ self.radioConfig = p["decoded"]["admin"]["raw"].get_radio_response
+ logging.debug(f'self.radioConfig:{self.radioConfig}')
+ logging.debug("Received radio config, now fetching channels...")
+ self._timeout.reset() # We made foreward progress
+ self._requestChannel(0) # now start fetching channels
+
+
def _requestSettings(self):
"""Done with initial config messages, now send regular
MeshPackets to ask for settings."""
p = admin_pb2.AdminMessage()
p.get_radio_request = True
- def onResponse(p):
- """A closure to handle the response packet"""
- errorFound = False
- if 'routing' in p["decoded"]:
- if p["decoded"]["routing"]["errorReason"] != "NONE":
- errorFound = True
- print(f'Error on response: {p["decoded"]["routing"]["errorReason"]}')
- if errorFound is False:
- self.radioConfig = p["decoded"]["admin"]["raw"].get_radio_response
- logging.debug("Received radio config, now fetching channels...")
- self._timeout.reset() # We made foreward progress
- self._requestChannel(0) # now start fetching channels
-
# Show progress message for super slow operations
if self != self.iface.localNode:
- print("Requesting preferences from remote node (this could take a while)")
+ print("Requesting preferences from remote node.")
+ print("Be sure:")
+ print(" 1. There is a SECONDARY channel named 'admin'.")
+ print(" 2. The '--seturl' was used to configure.")
+ print(" 3. All devices have the same modem config. (i.e., '--ch-longfast')")
+ print(" 4. All devices have been rebooted after all of the above. (optional, but recommended)")
+ print("Note: This could take a while (it requests remote channel configs, then writes config)")
- return self._sendAdmin(p, wantResponse=True, onResponse=onResponse)
+ return self._sendAdmin(p, wantResponse=True, onResponse=self.onResponseRequestSettings)
def exitSimulator(self):
"""Tell a simulator node to exit (this message
is ignored for other nodes)"""
p = admin_pb2.AdminMessage()
p.exit_simulator = True
+ logging.debug('in exitSimulator()')
return self._sendAdmin(p)
@@ -643,6 +720,34 @@ class Node:
self.channels.append(ch)
index += 1
+
+ def onResponseRequestChannel(self, p):
+ """Handle the response packet for requesting a channel _requestChannel()"""
+ logging.debug(f'onResponseRequestChannel() p:{p}')
+ c = p["decoded"]["admin"]["raw"].get_channel_response
+ self.partialChannels.append(c)
+ self._timeout.reset() # We made foreward progress
+ logging.debug(f"Received channel {stripnl(c)}")
+ index = c.index
+
+ # for stress testing, we can always download all channels
+ fastChannelDownload = True
+
+ # Once we see a response that has NO settings, assume
+ # we are at the end of channels and stop fetching
+ quitEarly = (c.role == channel_pb2.Channel.Role.DISABLED) and fastChannelDownload
+
+ if quitEarly or index >= self.iface.myInfo.max_channels - 1:
+ logging.debug("Finished downloading channels")
+
+ self.channels = self.partialChannels
+ self._fixupChannels()
+
+ # FIXME, the following should only be called after we have settings and channels
+ self.iface._connected() # Tell everyone else we are ready to go
+ else:
+ self._requestChannel(index + 1)
+
def _requestChannel(self, channelNum: int):
"""Done with initial config messages, now send regular
MeshPackets to ask for settings"""
@@ -651,51 +756,32 @@ class Node:
# Show progress message for super slow operations
if self != self.iface.localNode:
- logging.info(f"Requesting channel {channelNum} info from remote node (this could take a while)")
+ print(f"Requesting channel {channelNum} info from remote node (this could take a while)")
+ logging.debug(f"Requesting channel {channelNum} info from remote node (this could take a while)")
else:
logging.debug(f"Requesting channel {channelNum}")
- def onResponse(p):
- """A closure to handle the response packet for requesting a channel"""
- c = p["decoded"]["admin"]["raw"].get_channel_response
- self.partialChannels.append(c)
- self._timeout.reset() # We made foreward progress
- logging.debug(f"Received channel {stripnl(c)}")
- index = c.index
+ return self._sendAdmin(p, wantResponse=True, onResponse=self.onResponseRequestChannel)
- # for stress testing, we can always download all channels
- fastChannelDownload = True
-
- # Once we see a response that has NO settings, assume
- # we are at the end of channels and stop fetching
- quitEarly = (c.role == channel_pb2.Channel.Role.DISABLED) and fastChannelDownload
-
- if quitEarly or index >= self.iface.myInfo.max_channels - 1:
- logging.debug("Finished downloading channels")
-
- self.channels = self.partialChannels
- self._fixupChannels()
-
- # FIXME, the following should only be called after we have settings and channels
- self.iface._connected() # Tell everone else we are ready to go
- else:
- self._requestChannel(index + 1)
-
- return self._sendAdmin(p, wantResponse=True, onResponse=onResponse)
+ # pylint: disable=R1710
def _sendAdmin(self, p: admin_pb2.AdminMessage, wantResponse=False,
onResponse=None, adminIndex=0):
"""Send an admin message to the specified node (or the local node if destNodeNum is zero)"""
- if adminIndex == 0: # unless a special channel index was used, we want to use the admin index
- adminIndex = self.iface.localNode._getAdminChannelIndex()
+ if self.noProto:
+ logging.warning(f"Not sending packet because protocol use is disabled by noProto")
+ else:
+ if adminIndex == 0: # unless a special channel index was used, we want to use the admin index
+ adminIndex = self.iface.localNode._getAdminChannelIndex()
+ logging.debug(f'adminIndex:{adminIndex}')
- return self.iface.sendData(p, self.nodeNum,
- portNum=portnums_pb2.PortNum.ADMIN_APP,
- wantAck=True,
- wantResponse=wantResponse,
- onResponse=onResponse,
- channelIndex=adminIndex)
+ return self.iface.sendData(p, self.nodeNum,
+ portNum=portnums_pb2.PortNum.ADMIN_APP,
+ wantAck=True,
+ wantResponse=wantResponse,
+ onResponse=onResponse,
+ channelIndex=adminIndex)
Methods
@@ -730,7 +816,7 @@ class Node:
# *moving* the admin channel index as we are writing
if (self.iface.localNode == self) and index >= adminIndex:
# We've now passed the old location for admin index
- # (and writen it), so we can start finding it by name again
+ # (and written it), so we can start finding it by name again
adminIndex = 0
@@ -749,10 +835,33 @@ is ignored for other nodes)
is ignored for other nodes)"""
p = admin_pb2.AdminMessage()
p.exit_simulator = True
+ logging.debug('in exitSimulator()')
return self._sendAdmin(p)
Get channel by channelIndex
+channelIndex: number, typically 0-7; based on max number channels
+returns: None if there is no channel found
+
+
+Expand source code
+
+
def getChannelByChannelIndex(self, channelIndex):
+ """Get channel by channelIndex
+ channelIndex: number, typically 0-7; based on max number channels
+ returns: None if there is no channel found
+ """
+ ch = None
+ if self.channels and 0 <= channelIndex < len(self.channels):
+ ch = self.channels[channelIndex]
+ return ch
+
+
def getChannelByName(self, name)
@@ -809,6 +918,68 @@ is ignored for other nodes)
return f"https://www.meshtastic.org/d/#{s}".replace("=", "")
+
+def onResponseRequestChannel(self, p)
+
+
+
Handle the response packet for requesting a channel _requestChannel()
+
+
+Expand source code
+
+
def onResponseRequestChannel(self, p):
+ """Handle the response packet for requesting a channel _requestChannel()"""
+ logging.debug(f'onResponseRequestChannel() p:{p}')
+ c = p["decoded"]["admin"]["raw"].get_channel_response
+ self.partialChannels.append(c)
+ self._timeout.reset() # We made foreward progress
+ logging.debug(f"Received channel {stripnl(c)}")
+ index = c.index
+
+ # for stress testing, we can always download all channels
+ fastChannelDownload = True
+
+ # Once we see a response that has NO settings, assume
+ # we are at the end of channels and stop fetching
+ quitEarly = (c.role == channel_pb2.Channel.Role.DISABLED) and fastChannelDownload
+
+ if quitEarly or index >= self.iface.myInfo.max_channels - 1:
+ logging.debug("Finished downloading channels")
+
+ self.channels = self.partialChannels
+ self._fixupChannels()
+
+ # FIXME, the following should only be called after we have settings and channels
+ self.iface._connected() # Tell everyone else we are ready to go
+ else:
+ self._requestChannel(index + 1)
+
+
+
+def onResponseRequestSettings(self, p)
+
+
+
Handle the response packet for requesting settings _requestSettings()
+
+
+Expand source code
+
+
def onResponseRequestSettings(self, p):
+ """Handle the response packet for requesting settings _requestSettings()"""
+ logging.debug(f'onResponseRequestSetting() p:{p}')
+ errorFound = False
+ if 'routing' in p["decoded"]:
+ if p["decoded"]["routing"]["errorReason"] != "NONE":
+ errorFound = True
+ print(f'Error on response: {p["decoded"]["routing"]["errorReason"]}')
+ if errorFound is False:
+ self.radioConfig = p["decoded"]["admin"]["raw"].get_radio_response
+ logging.debug(f'self.radioConfig:{self.radioConfig}')
+ logging.debug("Received radio config, now fetching channels...")
+ self._timeout.reset() # We made foreward progress
+ self._requestChannel(0) # now start fetching channels
+
+
def reboot(self, secs: int = 10)
@@ -838,6 +1009,7 @@ is ignored for other nodes)
def requestConfig(self):
"""Send regular MeshPackets to ask for settings and channels."""
+ logging.debug(f"requestConfig for nodeNum:{self.nodeNum}")
self.radioConfig = None
self.channels = None
self.partialChannels = [] # We keep our channels in a temp array until finished
@@ -856,6 +1028,7 @@ is ignored for other nodes)
def setOwner(self, long_name=None, short_name=None, is_licensed=False, team=None):
"""Set device owner name"""
+ logging.debug(f"in setOwner nodeNum:{self.nodeNum}")
nChars = 3
minChars = 2
if long_name is not None:
@@ -885,6 +1058,11 @@ is ignored for other nodes)
if team is not None:
p.set_owner.team = team
+ # Note: These debug lines are used in unit tests
+ logging.debug(f'p.set_owner.long_name:{p.set_owner.long_name}:')
+ logging.debug(f'p.set_owner.short_name:{p.set_owner.short_name}:')
+ logging.debug(f'p.set_owner.is_licensed:{p.set_owner.is_licensed}')
+ logging.debug(f'p.set_owner.team:{p.set_owner.team}')
return self._sendAdmin(p)
@@ -918,6 +1096,7 @@ is ignored for other nodes)
channelSet = apponly_pb2.ChannelSet()
channelSet.ParseFromString(decodedURL)
+
if len(channelSet.settings) == 0:
our_exit("Warning: There were no settings.")
@@ -928,6 +1107,7 @@ is ignored for other nodes)
ch.index = i
ch.settings.CopyFrom(chs)
self.channels[ch.index] = ch
+ logging.debug(f'Channel i:{i} ch:{ch}')
self.writeChannel(ch.index)
i = i + 1
@@ -945,7 +1125,9 @@ is ignored for other nodes)
"""Show human readable description of our channels."""
print("Channels:")
if self.channels:
+ logging.debug(f'self.channels:{self.channels}')
for c in self.channels:
+ #print('c.settings.psk:', c.settings.psk)
cStr = stripnl(MessageToJson(c.settings))
# only show if there is no psk (meaning disabled channel)
if c.settings.psk:
@@ -1068,9 +1250,12 @@ is ignored for other nodes)
Protocol message classes are almost always generated by the protocol
-compiler.
-These generated types subclass Message and implement the methods
-shown below.
+
A ProtocolMessage
Ancestors
+
google.protobuf.pyext._message.CMessage
google.protobuf.message.Message
Class variables
@@ -996,536 +993,16 @@ shown below.
-
var PREFERENCES_FIELD_NUMBER
-
-
-
var UserPreferences
-
Abstract base class for protocol messages.
-
Protocol message classes are almost always generated by the protocol
-compiler.
-These generated types subclass Message and implement the methods
-shown below.
def getter(self):
- field_value = self._fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
-
- # Atomically check if another thread has preempted us and, if not, swap
- # in the new object we just created. If someone has preempted us, we
- # take that object and discard ours.
- # WARNING: We are relying on setdefault() being atomic. This is true
- # in CPython but we haven't investigated others. This warning appears
- # in several other locations in this file.
- field_value = self._fields.setdefault(field, field_value)
- return field_value
-
-
-
-
Methods
-
-
-def ByteSize(self)
-
-
-
-
-
-Expand source code
-
-
def ByteSize(self):
- if not self._cached_byte_size_dirty:
- return self._cached_byte_size
-
- size = 0
- descriptor = self.DESCRIPTOR
- if descriptor.GetOptions().map_entry:
- # Fields of map entry should always be serialized.
- size = descriptor.fields_by_name['key']._sizer(self.key)
- size += descriptor.fields_by_name['value']._sizer(self.value)
- else:
- for field_descriptor, field_value in self.ListFields():
- size += field_descriptor._sizer(field_value)
- for tag_bytes, value_bytes in self._unknown_fields:
- size += len(tag_bytes) + len(value_bytes)
-
- self._cached_byte_size = size
- self._cached_byte_size_dirty = False
- self._listener_for_children.dirty = False
- return size
def ClearField(self, field_name):
- try:
- field = message_descriptor.fields_by_name[field_name]
- except KeyError:
- try:
- field = message_descriptor.oneofs_by_name[field_name]
- if field in self._oneofs:
- field = self._oneofs[field]
- else:
- return
- except KeyError:
- raise ValueError('Protocol message %s has no "%s" field.' %
- (message_descriptor.name, field_name))
-
- if field in self._fields:
- # To match the C++ implementation, we need to invalidate iterators
- # for map fields when ClearField() happens.
- if hasattr(self._fields[field], 'InvalidateIterators'):
- self._fields[field].InvalidateIterators()
-
- # Note: If the field is a sub-message, its listener will still point
- # at us. That's fine, because the worst than can happen is that it
- # will call _Modified() and invalidate our byte size. Big deal.
- del self._fields[field]
-
- if self._oneofs.get(field.containing_oneof, None) is field:
- del self._oneofs[field.containing_oneof]
-
- # Always call _Modified() -- even if nothing was changed, this is
- # a mutating method, and thus calling it should cause the field to become
- # present in the parent message.
- self._Modified()
-
-
-
-def DiscardUnknownFields(self)
-
-
-
-
-
-Expand source code
-
-
def _DiscardUnknownFields(self):
- self._unknown_fields = []
- self._unknown_field_set = None # pylint: disable=protected-access
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if _IsMapField(field):
- if _IsMessageMapField(field):
- for key in value:
- value[key].DiscardUnknownFields()
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
- for sub_message in value:
- sub_message.DiscardUnknownFields()
- else:
- value.DiscardUnknownFields()
-
-
-
-def FindInitializationErrors(self)
-
-
-
Finds required fields which are not initialized.
-
Returns
-
A list of strings.
-Each string is a path to an uninitialized field from
-the top-level message, e.g. "foo.bar[5].baz".
-
-
-Expand source code
-
-
def FindInitializationErrors(self):
- """Finds required fields which are not initialized.
-
- Returns:
- A list of strings. Each string is a path to an uninitialized field from
- the top-level message, e.g. "foo.bar[5].baz".
- """
-
- errors = [] # simplify things
-
- for field in required_fields:
- if not self.HasField(field.name):
- errors.append(field.name)
-
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.is_extension:
- name = '(%s)' % field.full_name
- else:
- name = field.name
-
- if _IsMapField(field):
- if _IsMessageMapField(field):
- for key in value:
- element = value[key]
- prefix = '%s[%s].' % (name, key)
- sub_errors = element.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
- else:
- # ScalarMaps can't have any initialization errors.
- pass
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
- for i in range(len(value)):
- element = value[i]
- prefix = '%s[%d].' % (name, i)
- sub_errors = element.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
- else:
- prefix = name + '.'
- sub_errors = value.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
-
- return errors
-
-
-
-def HasField(self, field_name)
-
-
-
-
-
-Expand source code
-
-
def HasField(self, field_name):
- try:
- field = hassable_fields[field_name]
- except KeyError:
- raise ValueError(error_msg % (message_descriptor.full_name, field_name))
-
- if isinstance(field, descriptor_mod.OneofDescriptor):
- try:
- return HasField(self, self._oneofs[field].name)
- except KeyError:
- return False
- else:
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- value = self._fields.get(field)
- return value is not None and value._is_present_in_parent
- else:
- return field in self._fields
-
-
-
-def IsInitialized(self, errors=None)
-
-
-
Checks if all required fields of a message are set.
-
Args
-
-
errors
-
A list which, if provided, will be populated with the field
-paths of all missing required fields.
-
-
Returns
-
True iff the specified message has all required fields set.
-
-
-Expand source code
-
-
def IsInitialized(self, errors=None):
- """Checks if all required fields of a message are set.
-
- Args:
- errors: A list which, if provided, will be populated with the field
- paths of all missing required fields.
-
- Returns:
- True iff the specified message has all required fields set.
- """
-
- # Performance is critical so we avoid HasField() and ListFields().
-
- for field in required_fields:
- if (field not in self._fields or
- (field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE and
- not self._fields[field]._is_present_in_parent)):
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- for field, value in list(self._fields.items()): # dict can change size!
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.label == _FieldDescriptor.LABEL_REPEATED:
- if (field.message_type.has_options and
- field.message_type.GetOptions().map_entry):
- continue
- for element in value:
- if not element.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
- elif value._is_present_in_parent and not value.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- return True
-
-
-
-def ListFields(self)
-
-
-
-
-
-Expand source code
-
-
def ListFields(self):
- all_fields = [item for item in self._fields.items() if _IsPresent(item)]
- all_fields.sort(key = lambda item: item[0].number)
- return all_fields
-
-
-
-def MergeFrom(self, msg)
-
-
-
-
-
-Expand source code
-
-
def MergeFrom(self, msg):
- if not isinstance(msg, cls):
- raise TypeError(
- 'Parameter to MergeFrom() must be instance of same class: '
- 'expected %s got %s.' % (_FullyQualifiedClassName(cls),
- _FullyQualifiedClassName(msg.__class__)))
-
- assert msg is not self
- self._Modified()
-
- fields = self._fields
-
- for field, value in msg._fields.items():
- if field.label == LABEL_REPEATED:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- elif field.cpp_type == CPPTYPE_MESSAGE:
- if value._is_present_in_parent:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- else:
- self._fields[field] = value
- if field.containing_oneof:
- self._UpdateOneofState(field)
-
- if msg._unknown_fields:
- if not self._unknown_fields:
- self._unknown_fields = []
- self._unknown_fields.extend(msg._unknown_fields)
- # pylint: disable=protected-access
- if self._unknown_field_set is None:
- self._unknown_field_set = containers.UnknownFieldSet()
- self._unknown_field_set._extend(msg._unknown_field_set)
-
-
-
-def MergeFromString(self, serialized)
-
-
-
-
-
-Expand source code
-
-
def MergeFromString(self, serialized):
- serialized = memoryview(serialized)
- length = len(serialized)
- try:
- if self._InternalParse(serialized, 0, length) != length:
- # The only reason _InternalParse would return early is if it
- # encountered an end-group tag.
- raise message_mod.DecodeError('Unexpected end-group tag.')
- except (IndexError, TypeError):
- # Now ord(buf[p:p+1]) == ord('') gets TypeError.
- raise message_mod.DecodeError('Truncated message.')
- except struct.error as e:
- raise message_mod.DecodeError(e)
- return length # Return this for legacy reasons.
def SerializeToString(self, **kwargs):
- # Check if the message has all of its required fields set.
- if not self.IsInitialized():
- raise message_mod.EncodeError(
- 'Message %s is missing required fields: %s' % (
- self.DESCRIPTOR.full_name, ','.join(self.FindInitializationErrors())))
- return self.SerializePartialToString(**kwargs)
-
-
-
-def SetInParent(self)
-
-
-
Sets the _cached_byte_size_dirty bit to true,
-and propagates this to our listener iff this was a state change.
-
-
-Expand source code
-
-
def Modified(self):
- """Sets the _cached_byte_size_dirty bit to true,
- and propagates this to our listener iff this was a state change.
- """
-
- # Note: Some callers check _cached_byte_size_dirty before calling
- # _Modified() as an extra optimization. So, if this method is ever
- # changed such that it does stuff even when _cached_byte_size_dirty is
- # already true, the callers need to be updated.
- if not self._cached_byte_size_dirty:
- self._cached_byte_size_dirty = True
- self._listener_for_children.dirty = True
- self._is_present_in_parent = True
- self._listener.Modified()
Returns the name of the currently set field inside a oneof, or None.
-
-
-Expand source code
-
-
def WhichOneof(self, oneof_name):
- """Returns the name of the currently set field inside a oneof, or None."""
- try:
- field = message_descriptor.oneofs_by_name[oneof_name]
- except KeyError:
- raise ValueError(
- 'Protocol message has no oneof "%s" field.' % oneof_name)
-
- nested_field = self._oneofs.get(field, None)
- if nested_field is not None and self.HasField(nested_field.name):
- return nested_field.name
- else:
- return None
-
+
Field RadioConfig.preferences
@@ -1548,26 +1025,8 @@ and propagates this to our listener iff this was a state change.
"""Remote hardware
"""
+import logging
from pubsub import pub
from . import portnums_pb2, remote_hardware_pb2
+from .util import our_exit
def onGPIOreceive(packet, interface):
"""Callback for received GPIO responses
-
- FIXME figure out how to do closures with methods in python"""
+ """
+ logging.debug(f"packet:{packet} interface:{interface}")
hw = packet["decoded"]["remotehw"]
- print(f'Received RemoteHardware typ={hw["typ"]}, gpio_value={hw["gpioValue"]}')
+ gpioValue = hw["gpioValue"]
+ #print(f'mask:{interface.mask}')
+ value = int(gpioValue) & int(interface.mask)
+ print(f'Received RemoteHardware typ={hw["typ"]}, gpio_value={gpioValue} value={value}')
+ interface.gotResponse = True
class RemoteHardwareClient:
@@ -57,26 +63,28 @@ class RemoteHardwareClient:
self.iface = iface
ch = iface.localNode.getChannelByName("gpio")
if not ch:
- raise Exception(
- "No gpio channel found, please create on the sending and receive nodes "\
- "to use this (secured) service (--ch-add gpio --info then --seturl)")
+ our_exit(
+ "Warning: No channel named 'gpio' was found.\n"\
+ "On the sending and receive nodes create a channel named 'gpio'.\n"\
+ "For example, run '--ch-add gpio' on one device, then '--seturl' on\n"\
+ "the other devices using the url from the device where the channel was added.")
self.channelIndex = ch.index
- pub.subscribe(
- onGPIOreceive, "meshtastic.receive.remotehw")
+ pub.subscribe(onGPIOreceive, "meshtastic.receive.remotehw")
def _sendHardware(self, nodeid, r, wantResponse=False, onResponse=None):
if not nodeid:
- raise Exception(
- r"You must set a destination node ID for this operation (use --dest \!xxxxxxxxx)")
+ our_exit(r"Warning: Must use a destination node ID for this operation (use --dest \!xxxxxxxxx)")
return self.iface.sendData(r, nodeid, portnums_pb2.REMOTE_HARDWARE_APP,
- wantAck=True, channelIndex=self.channelIndex, wantResponse=wantResponse, onResponse=onResponse)
+ wantAck=True, channelIndex=self.channelIndex,
+ wantResponse=wantResponse, onResponse=onResponse)
def writeGPIOs(self, nodeid, mask, vals):
"""
Write the specified vals bits to the device GPIOs. Only bits in mask that
are 1 will be changed
"""
+ logging.debug(f'writeGPIOs nodeid:{nodeid} mask:{mask} vals:{vals}')
r = remote_hardware_pb2.HardwareMessage()
r.typ = remote_hardware_pb2.HardwareMessage.Type.WRITE_GPIOS
r.gpio_mask = mask
@@ -85,6 +93,7 @@ class RemoteHardwareClient:
def readGPIOs(self, nodeid, mask, onResponse = None):
"""Read the specified bits from GPIO inputs on the device"""
+ logging.debug(f'readGPIOs nodeid:{nodeid} mask:{mask}')
r = remote_hardware_pb2.HardwareMessage()
r.typ = remote_hardware_pb2.HardwareMessage.Type.READ_GPIOS
r.gpio_mask = mask
@@ -92,9 +101,11 @@ class RemoteHardwareClient:
def watchGPIOs(self, nodeid, mask):
"""Watch the specified bits from GPIO inputs on the device for changes"""
+ logging.debug(f'watchGPIOs nodeid:{nodeid} mask:{mask}')
r = remote_hardware_pb2.HardwareMessage()
r.typ = remote_hardware_pb2.HardwareMessage.Type.WATCH_GPIOS
r.gpio_mask = mask
+ self.iface.mask = mask
return self._sendHardware(nodeid, r)
@@ -109,18 +120,21 @@ class RemoteHardwareClient:
def onGPIOreceive(packet, interface)
-
Callback for received GPIO responses
-
FIXME figure out how to do closures with methods in python
+
Callback for received GPIO responses
Expand source code
def onGPIOreceive(packet, interface):
"""Callback for received GPIO responses
-
- FIXME figure out how to do closures with methods in python"""
+ """
+ logging.debug(f"packet:{packet} interface:{interface}")
hw = packet["decoded"]["remotehw"]
- print(f'Received RemoteHardware typ={hw["typ"]}, gpio_value={hw["gpioValue"]}')
@@ -159,26 +173,28 @@ code for how you can connect to your own custom meshtastic services
self.iface = iface
ch = iface.localNode.getChannelByName("gpio")
if not ch:
- raise Exception(
- "No gpio channel found, please create on the sending and receive nodes "\
- "to use this (secured) service (--ch-add gpio --info then --seturl)")
+ our_exit(
+ "Warning: No channel named 'gpio' was found.\n"\
+ "On the sending and receive nodes create a channel named 'gpio'.\n"\
+ "For example, run '--ch-add gpio' on one device, then '--seturl' on\n"\
+ "the other devices using the url from the device where the channel was added.")
self.channelIndex = ch.index
- pub.subscribe(
- onGPIOreceive, "meshtastic.receive.remotehw")
+ pub.subscribe(onGPIOreceive, "meshtastic.receive.remotehw")
def _sendHardware(self, nodeid, r, wantResponse=False, onResponse=None):
if not nodeid:
- raise Exception(
- r"You must set a destination node ID for this operation (use --dest \!xxxxxxxxx)")
+ our_exit(r"Warning: Must use a destination node ID for this operation (use --dest \!xxxxxxxxx)")
return self.iface.sendData(r, nodeid, portnums_pb2.REMOTE_HARDWARE_APP,
- wantAck=True, channelIndex=self.channelIndex, wantResponse=wantResponse, onResponse=onResponse)
+ wantAck=True, channelIndex=self.channelIndex,
+ wantResponse=wantResponse, onResponse=onResponse)
def writeGPIOs(self, nodeid, mask, vals):
"""
Write the specified vals bits to the device GPIOs. Only bits in mask that
are 1 will be changed
"""
+ logging.debug(f'writeGPIOs nodeid:{nodeid} mask:{mask} vals:{vals}')
r = remote_hardware_pb2.HardwareMessage()
r.typ = remote_hardware_pb2.HardwareMessage.Type.WRITE_GPIOS
r.gpio_mask = mask
@@ -187,6 +203,7 @@ code for how you can connect to your own custom meshtastic services
def readGPIOs(self, nodeid, mask, onResponse = None):
"""Read the specified bits from GPIO inputs on the device"""
+ logging.debug(f'readGPIOs nodeid:{nodeid} mask:{mask}')
r = remote_hardware_pb2.HardwareMessage()
r.typ = remote_hardware_pb2.HardwareMessage.Type.READ_GPIOS
r.gpio_mask = mask
@@ -194,9 +211,11 @@ code for how you can connect to your own custom meshtastic services
def watchGPIOs(self, nodeid, mask):
"""Watch the specified bits from GPIO inputs on the device for changes"""
+ logging.debug(f'watchGPIOs nodeid:{nodeid} mask:{mask}')
r = remote_hardware_pb2.HardwareMessage()
r.typ = remote_hardware_pb2.HardwareMessage.Type.WATCH_GPIOS
r.gpio_mask = mask
+ self.iface.mask = mask
return self._sendHardware(nodeid, r)
Methods
@@ -212,6 +231,7 @@ code for how you can connect to your own custom meshtastic services
def readGPIOs(self, nodeid, mask, onResponse = None):
"""Read the specified bits from GPIO inputs on the device"""
+ logging.debug(f'readGPIOs nodeid:{nodeid} mask:{mask}')
r = remote_hardware_pb2.HardwareMessage()
r.typ = remote_hardware_pb2.HardwareMessage.Type.READ_GPIOS
r.gpio_mask = mask
@@ -229,9 +249,11 @@ code for how you can connect to your own custom meshtastic services
def watchGPIOs(self, nodeid, mask):
"""Watch the specified bits from GPIO inputs on the device for changes"""
+ logging.debug(f'watchGPIOs nodeid:{nodeid} mask:{mask}')
r = remote_hardware_pb2.HardwareMessage()
r.typ = remote_hardware_pb2.HardwareMessage.Type.WATCH_GPIOS
r.gpio_mask = mask
+ self.iface.mask = mask
return self._sendHardware(nodeid, r)
@@ -251,6 +273,7 @@ are 1 will be changed
Write the specified vals bits to the device GPIOs. Only bits in mask that
are 1 will be changed
"""
+ logging.debug(f'writeGPIOs nodeid:{nodeid} mask:{mask} vals:{vals}')
r = remote_hardware_pb2.HardwareMessage()
r.typ = remote_hardware_pb2.HardwareMessage.Type.WRITE_GPIOS
r.gpio_mask = mask
diff --git a/docs/meshtastic/remote_hardware_pb2.html b/docs/meshtastic/remote_hardware_pb2.html
index ff58876..37cfa5a 100644
--- a/docs/meshtastic/remote_hardware_pb2.html
+++ b/docs/meshtastic/remote_hardware_pb2.html
@@ -163,16 +163,13 @@ DESCRIPTOR._options = None
class HardwareMessage
-(**kwargs)
+(*args, **kwargs)
-
Abstract base class for protocol messages.
-
Protocol message classes are almost always generated by the protocol
-compiler.
-These generated types subclass Message and implement the methods
-shown below.
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field HardwareMessage.gpio_mask
var gpio_value
-
Getter for gpio_value.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field HardwareMessage.gpio_value
var typ
-
Getter for typ.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
-
-
-
Methods
-
-
-def ByteSize(self)
-
-
-
-
-
-Expand source code
-
-
def ByteSize(self):
- if not self._cached_byte_size_dirty:
- return self._cached_byte_size
-
- size = 0
- descriptor = self.DESCRIPTOR
- if descriptor.GetOptions().map_entry:
- # Fields of map entry should always be serialized.
- size = descriptor.fields_by_name['key']._sizer(self.key)
- size += descriptor.fields_by_name['value']._sizer(self.value)
- else:
- for field_descriptor, field_value in self.ListFields():
- size += field_descriptor._sizer(field_value)
- for tag_bytes, value_bytes in self._unknown_fields:
- size += len(tag_bytes) + len(value_bytes)
-
- self._cached_byte_size = size
- self._cached_byte_size_dirty = False
- self._listener_for_children.dirty = False
- return size
def ClearField(self, field_name):
- try:
- field = message_descriptor.fields_by_name[field_name]
- except KeyError:
- try:
- field = message_descriptor.oneofs_by_name[field_name]
- if field in self._oneofs:
- field = self._oneofs[field]
- else:
- return
- except KeyError:
- raise ValueError('Protocol message %s has no "%s" field.' %
- (message_descriptor.name, field_name))
-
- if field in self._fields:
- # To match the C++ implementation, we need to invalidate iterators
- # for map fields when ClearField() happens.
- if hasattr(self._fields[field], 'InvalidateIterators'):
- self._fields[field].InvalidateIterators()
-
- # Note: If the field is a sub-message, its listener will still point
- # at us. That's fine, because the worst than can happen is that it
- # will call _Modified() and invalidate our byte size. Big deal.
- del self._fields[field]
-
- if self._oneofs.get(field.containing_oneof, None) is field:
- del self._oneofs[field.containing_oneof]
-
- # Always call _Modified() -- even if nothing was changed, this is
- # a mutating method, and thus calling it should cause the field to become
- # present in the parent message.
- self._Modified()
-
-
-
-def DiscardUnknownFields(self)
-
-
-
-
-
-Expand source code
-
-
def _DiscardUnknownFields(self):
- self._unknown_fields = []
- self._unknown_field_set = None # pylint: disable=protected-access
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if _IsMapField(field):
- if _IsMessageMapField(field):
- for key in value:
- value[key].DiscardUnknownFields()
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
- for sub_message in value:
- sub_message.DiscardUnknownFields()
- else:
- value.DiscardUnknownFields()
-
-
-
-def FindInitializationErrors(self)
-
-
-
Finds required fields which are not initialized.
-
Returns
-
A list of strings.
-Each string is a path to an uninitialized field from
-the top-level message, e.g. "foo.bar[5].baz".
-
-
-Expand source code
-
-
def FindInitializationErrors(self):
- """Finds required fields which are not initialized.
-
- Returns:
- A list of strings. Each string is a path to an uninitialized field from
- the top-level message, e.g. "foo.bar[5].baz".
- """
-
- errors = [] # simplify things
-
- for field in required_fields:
- if not self.HasField(field.name):
- errors.append(field.name)
-
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.is_extension:
- name = '(%s)' % field.full_name
- else:
- name = field.name
-
- if _IsMapField(field):
- if _IsMessageMapField(field):
- for key in value:
- element = value[key]
- prefix = '%s[%s].' % (name, key)
- sub_errors = element.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
- else:
- # ScalarMaps can't have any initialization errors.
- pass
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
- for i in range(len(value)):
- element = value[i]
- prefix = '%s[%d].' % (name, i)
- sub_errors = element.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
- else:
- prefix = name + '.'
- sub_errors = value.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
-
- return errors
-
-
-
-def HasField(self, field_name)
-
-
-
-
-
-Expand source code
-
-
def HasField(self, field_name):
- try:
- field = hassable_fields[field_name]
- except KeyError:
- raise ValueError(error_msg % (message_descriptor.full_name, field_name))
-
- if isinstance(field, descriptor_mod.OneofDescriptor):
- try:
- return HasField(self, self._oneofs[field].name)
- except KeyError:
- return False
- else:
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- value = self._fields.get(field)
- return value is not None and value._is_present_in_parent
- else:
- return field in self._fields
-
-
-
-def IsInitialized(self, errors=None)
-
-
-
Checks if all required fields of a message are set.
-
Args
-
-
errors
-
A list which, if provided, will be populated with the field
-paths of all missing required fields.
-
-
Returns
-
True iff the specified message has all required fields set.
-
-
-Expand source code
-
-
def IsInitialized(self, errors=None):
- """Checks if all required fields of a message are set.
-
- Args:
- errors: A list which, if provided, will be populated with the field
- paths of all missing required fields.
-
- Returns:
- True iff the specified message has all required fields set.
- """
-
- # Performance is critical so we avoid HasField() and ListFields().
-
- for field in required_fields:
- if (field not in self._fields or
- (field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE and
- not self._fields[field]._is_present_in_parent)):
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- for field, value in list(self._fields.items()): # dict can change size!
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.label == _FieldDescriptor.LABEL_REPEATED:
- if (field.message_type.has_options and
- field.message_type.GetOptions().map_entry):
- continue
- for element in value:
- if not element.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
- elif value._is_present_in_parent and not value.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- return True
-
-
-
-def ListFields(self)
-
-
-
-
-
-Expand source code
-
-
def ListFields(self):
- all_fields = [item for item in self._fields.items() if _IsPresent(item)]
- all_fields.sort(key = lambda item: item[0].number)
- return all_fields
-
-
-
-def MergeFrom(self, msg)
-
-
-
-
-
-Expand source code
-
-
def MergeFrom(self, msg):
- if not isinstance(msg, cls):
- raise TypeError(
- 'Parameter to MergeFrom() must be instance of same class: '
- 'expected %s got %s.' % (_FullyQualifiedClassName(cls),
- _FullyQualifiedClassName(msg.__class__)))
-
- assert msg is not self
- self._Modified()
-
- fields = self._fields
-
- for field, value in msg._fields.items():
- if field.label == LABEL_REPEATED:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- elif field.cpp_type == CPPTYPE_MESSAGE:
- if value._is_present_in_parent:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- else:
- self._fields[field] = value
- if field.containing_oneof:
- self._UpdateOneofState(field)
-
- if msg._unknown_fields:
- if not self._unknown_fields:
- self._unknown_fields = []
- self._unknown_fields.extend(msg._unknown_fields)
- # pylint: disable=protected-access
- if self._unknown_field_set is None:
- self._unknown_field_set = containers.UnknownFieldSet()
- self._unknown_field_set._extend(msg._unknown_field_set)
-
-
-
-def MergeFromString(self, serialized)
-
-
-
-
-
-Expand source code
-
-
def MergeFromString(self, serialized):
- serialized = memoryview(serialized)
- length = len(serialized)
- try:
- if self._InternalParse(serialized, 0, length) != length:
- # The only reason _InternalParse would return early is if it
- # encountered an end-group tag.
- raise message_mod.DecodeError('Unexpected end-group tag.')
- except (IndexError, TypeError):
- # Now ord(buf[p:p+1]) == ord('') gets TypeError.
- raise message_mod.DecodeError('Truncated message.')
- except struct.error as e:
- raise message_mod.DecodeError(e)
- return length # Return this for legacy reasons.
def SerializeToString(self, **kwargs):
- # Check if the message has all of its required fields set.
- if not self.IsInitialized():
- raise message_mod.EncodeError(
- 'Message %s is missing required fields: %s' % (
- self.DESCRIPTOR.full_name, ','.join(self.FindInitializationErrors())))
- return self.SerializePartialToString(**kwargs)
-
-
-
-def SetInParent(self)
-
-
-
Sets the _cached_byte_size_dirty bit to true,
-and propagates this to our listener iff this was a state change.
-
-
-Expand source code
-
-
def Modified(self):
- """Sets the _cached_byte_size_dirty bit to true,
- and propagates this to our listener iff this was a state change.
- """
-
- # Note: Some callers check _cached_byte_size_dirty before calling
- # _Modified() as an extra optimization. So, if this method is ever
- # changed such that it does stuff even when _cached_byte_size_dirty is
- # already true, the callers need to be updated.
- if not self._cached_byte_size_dirty:
- self._cached_byte_size_dirty = True
- self._listener_for_children.dirty = True
- self._is_present_in_parent = True
- self._listener.Modified()
Returns the name of the currently set field inside a oneof, or None.
-
-
-Expand source code
-
-
def WhichOneof(self, oneof_name):
- """Returns the name of the currently set field inside a oneof, or None."""
- try:
- field = message_descriptor.oneofs_by_name[oneof_name]
- except KeyError:
- raise ValueError(
- 'Protocol message has no oneof "%s" field.' % oneof_name)
-
- nested_field = self._oneofs.get(field, None)
- if nested_field is not None and self.HasField(nested_field.name):
- return nested_field.name
- else:
- return None
-
+
Field HardwareMessage.typ
@@ -776,35 +241,15 @@ and propagates this to our listener iff this was a state change.
class StoreAndForward
-(**kwargs)
+(*args, **kwargs)
-
Abstract base class for protocol messages.
-
Protocol message classes are almost always generated by the protocol
-compiler.
-These generated types subclass Message and implement the methods
-shown below.
+
A ProtocolMessage
Ancestors
+
google.protobuf.pyext._message.CMessage
google.protobuf.message.Message
Class variables
@@ -364,17 +361,9 @@ shown below.
-
var HISTORY_FIELD_NUMBER
-
-
-
var History
-
Abstract base class for protocol messages.
-
Protocol message classes are almost always generated by the protocol
-compiler.
-These generated types subclass Message and implement the methods
-shown below.
+
A ProtocolMessage
var ROUTER_BUSY
@@ -396,584 +385,32 @@ shown below.
-
var RR_FIELD_NUMBER
-
-
-
var RequestResponse
-
var STATS_FIELD_NUMBER
-
-
-
var Statistics
-
Abstract base class for protocol messages.
-
Protocol message classes are almost always generated by the protocol
-compiler.
-These generated types subclass Message and implement the methods
-shown below.
def getter(self):
- field_value = self._fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
-
- # Atomically check if another thread has preempted us and, if not, swap
- # in the new object we just created. If someone has preempted us, we
- # take that object and discard ours.
- # WARNING: We are relying on setdefault() being atomic. This is true
- # in CPython but we haven't investigated others. This warning appears
- # in several other locations in this file.
- field_value = self._fields.setdefault(field, field_value)
- return field_value
-
+
Field StoreAndForward.history
var rr
-
Getter for rr.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field StoreAndForward.rr
var stats
-
Getter for stats.
-
-
-Expand source code
-
-
def getter(self):
- field_value = self._fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
-
- # Atomically check if another thread has preempted us and, if not, swap
- # in the new object we just created. If someone has preempted us, we
- # take that object and discard ours.
- # WARNING: We are relying on setdefault() being atomic. This is true
- # in CPython but we haven't investigated others. This warning appears
- # in several other locations in this file.
- field_value = self._fields.setdefault(field, field_value)
- return field_value
-
-
-
-
Methods
-
-
-def ByteSize(self)
-
-
-
-
-
-Expand source code
-
-
def ByteSize(self):
- if not self._cached_byte_size_dirty:
- return self._cached_byte_size
-
- size = 0
- descriptor = self.DESCRIPTOR
- if descriptor.GetOptions().map_entry:
- # Fields of map entry should always be serialized.
- size = descriptor.fields_by_name['key']._sizer(self.key)
- size += descriptor.fields_by_name['value']._sizer(self.value)
- else:
- for field_descriptor, field_value in self.ListFields():
- size += field_descriptor._sizer(field_value)
- for tag_bytes, value_bytes in self._unknown_fields:
- size += len(tag_bytes) + len(value_bytes)
-
- self._cached_byte_size = size
- self._cached_byte_size_dirty = False
- self._listener_for_children.dirty = False
- return size
def ClearField(self, field_name):
- try:
- field = message_descriptor.fields_by_name[field_name]
- except KeyError:
- try:
- field = message_descriptor.oneofs_by_name[field_name]
- if field in self._oneofs:
- field = self._oneofs[field]
- else:
- return
- except KeyError:
- raise ValueError('Protocol message %s has no "%s" field.' %
- (message_descriptor.name, field_name))
-
- if field in self._fields:
- # To match the C++ implementation, we need to invalidate iterators
- # for map fields when ClearField() happens.
- if hasattr(self._fields[field], 'InvalidateIterators'):
- self._fields[field].InvalidateIterators()
-
- # Note: If the field is a sub-message, its listener will still point
- # at us. That's fine, because the worst than can happen is that it
- # will call _Modified() and invalidate our byte size. Big deal.
- del self._fields[field]
-
- if self._oneofs.get(field.containing_oneof, None) is field:
- del self._oneofs[field.containing_oneof]
-
- # Always call _Modified() -- even if nothing was changed, this is
- # a mutating method, and thus calling it should cause the field to become
- # present in the parent message.
- self._Modified()
-
-
-
-def DiscardUnknownFields(self)
-
-
-
-
-
-Expand source code
-
-
def _DiscardUnknownFields(self):
- self._unknown_fields = []
- self._unknown_field_set = None # pylint: disable=protected-access
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if _IsMapField(field):
- if _IsMessageMapField(field):
- for key in value:
- value[key].DiscardUnknownFields()
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
- for sub_message in value:
- sub_message.DiscardUnknownFields()
- else:
- value.DiscardUnknownFields()
-
-
-
-def FindInitializationErrors(self)
-
-
-
Finds required fields which are not initialized.
-
Returns
-
A list of strings.
-Each string is a path to an uninitialized field from
-the top-level message, e.g. "foo.bar[5].baz".
-
-
-Expand source code
-
-
def FindInitializationErrors(self):
- """Finds required fields which are not initialized.
-
- Returns:
- A list of strings. Each string is a path to an uninitialized field from
- the top-level message, e.g. "foo.bar[5].baz".
- """
-
- errors = [] # simplify things
-
- for field in required_fields:
- if not self.HasField(field.name):
- errors.append(field.name)
-
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.is_extension:
- name = '(%s)' % field.full_name
- else:
- name = field.name
-
- if _IsMapField(field):
- if _IsMessageMapField(field):
- for key in value:
- element = value[key]
- prefix = '%s[%s].' % (name, key)
- sub_errors = element.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
- else:
- # ScalarMaps can't have any initialization errors.
- pass
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
- for i in range(len(value)):
- element = value[i]
- prefix = '%s[%d].' % (name, i)
- sub_errors = element.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
- else:
- prefix = name + '.'
- sub_errors = value.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
-
- return errors
-
-
-
-def HasField(self, field_name)
-
-
-
-
-
-Expand source code
-
-
def HasField(self, field_name):
- try:
- field = hassable_fields[field_name]
- except KeyError:
- raise ValueError(error_msg % (message_descriptor.full_name, field_name))
-
- if isinstance(field, descriptor_mod.OneofDescriptor):
- try:
- return HasField(self, self._oneofs[field].name)
- except KeyError:
- return False
- else:
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- value = self._fields.get(field)
- return value is not None and value._is_present_in_parent
- else:
- return field in self._fields
-
-
-
-def IsInitialized(self, errors=None)
-
-
-
Checks if all required fields of a message are set.
-
Args
-
-
errors
-
A list which, if provided, will be populated with the field
-paths of all missing required fields.
-
-
Returns
-
True iff the specified message has all required fields set.
-
-
-Expand source code
-
-
def IsInitialized(self, errors=None):
- """Checks if all required fields of a message are set.
-
- Args:
- errors: A list which, if provided, will be populated with the field
- paths of all missing required fields.
-
- Returns:
- True iff the specified message has all required fields set.
- """
-
- # Performance is critical so we avoid HasField() and ListFields().
-
- for field in required_fields:
- if (field not in self._fields or
- (field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE and
- not self._fields[field]._is_present_in_parent)):
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- for field, value in list(self._fields.items()): # dict can change size!
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.label == _FieldDescriptor.LABEL_REPEATED:
- if (field.message_type.has_options and
- field.message_type.GetOptions().map_entry):
- continue
- for element in value:
- if not element.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
- elif value._is_present_in_parent and not value.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- return True
-
-
-
-def ListFields(self)
-
-
-
-
-
-Expand source code
-
-
def ListFields(self):
- all_fields = [item for item in self._fields.items() if _IsPresent(item)]
- all_fields.sort(key = lambda item: item[0].number)
- return all_fields
-
-
-
-def MergeFrom(self, msg)
-
-
-
-
-
-Expand source code
-
-
def MergeFrom(self, msg):
- if not isinstance(msg, cls):
- raise TypeError(
- 'Parameter to MergeFrom() must be instance of same class: '
- 'expected %s got %s.' % (_FullyQualifiedClassName(cls),
- _FullyQualifiedClassName(msg.__class__)))
-
- assert msg is not self
- self._Modified()
-
- fields = self._fields
-
- for field, value in msg._fields.items():
- if field.label == LABEL_REPEATED:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- elif field.cpp_type == CPPTYPE_MESSAGE:
- if value._is_present_in_parent:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- else:
- self._fields[field] = value
- if field.containing_oneof:
- self._UpdateOneofState(field)
-
- if msg._unknown_fields:
- if not self._unknown_fields:
- self._unknown_fields = []
- self._unknown_fields.extend(msg._unknown_fields)
- # pylint: disable=protected-access
- if self._unknown_field_set is None:
- self._unknown_field_set = containers.UnknownFieldSet()
- self._unknown_field_set._extend(msg._unknown_field_set)
-
-
-
-def MergeFromString(self, serialized)
-
-
-
-
-
-Expand source code
-
-
def MergeFromString(self, serialized):
- serialized = memoryview(serialized)
- length = len(serialized)
- try:
- if self._InternalParse(serialized, 0, length) != length:
- # The only reason _InternalParse would return early is if it
- # encountered an end-group tag.
- raise message_mod.DecodeError('Unexpected end-group tag.')
- except (IndexError, TypeError):
- # Now ord(buf[p:p+1]) == ord('') gets TypeError.
- raise message_mod.DecodeError('Truncated message.')
- except struct.error as e:
- raise message_mod.DecodeError(e)
- return length # Return this for legacy reasons.
def SerializeToString(self, **kwargs):
- # Check if the message has all of its required fields set.
- if not self.IsInitialized():
- raise message_mod.EncodeError(
- 'Message %s is missing required fields: %s' % (
- self.DESCRIPTOR.full_name, ','.join(self.FindInitializationErrors())))
- return self.SerializePartialToString(**kwargs)
-
-
-
-def SetInParent(self)
-
-
-
Sets the _cached_byte_size_dirty bit to true,
-and propagates this to our listener iff this was a state change.
-
-
-Expand source code
-
-
def Modified(self):
- """Sets the _cached_byte_size_dirty bit to true,
- and propagates this to our listener iff this was a state change.
- """
-
- # Note: Some callers check _cached_byte_size_dirty before calling
- # _Modified() as an extra optimization. So, if this method is ever
- # changed such that it does stuff even when _cached_byte_size_dirty is
- # already true, the callers need to be updated.
- if not self._cached_byte_size_dirty:
- self._cached_byte_size_dirty = True
- self._listener_for_children.dirty = True
- self._is_present_in_parent = True
- self._listener.Modified()
Returns the name of the currently set field inside a oneof, or None.
-
-
-Expand source code
-
-
def WhichOneof(self, oneof_name):
- """Returns the name of the currently set field inside a oneof, or None."""
- try:
- field = message_descriptor.oneofs_by_name[oneof_name]
- except KeyError:
- raise ValueError(
- 'Protocol message has no oneof "%s" field.' % oneof_name)
-
- nested_field = self._oneofs.get(field, None)
- if nested_field is not None and self.HasField(nested_field.name):
- return nested_field.name
- else:
- return None
-
+
Field StoreAndForward.stats
@@ -995,42 +432,22 @@ and propagates this to our listener iff this was a state change.
diff --git a/docs/meshtastic/stream_interface.html b/docs/meshtastic/stream_interface.html
index ff41f1c..bdec6d7 100644
--- a/docs/meshtastic/stream_interface.html
+++ b/docs/meshtastic/stream_interface.html
@@ -53,7 +53,6 @@ class StreamInterface(MeshInterface):
"""Constructor, opens a connection to self.stream
Keyword Arguments:
- devPath {string} -- A filepath to a device, i.e. /dev/ttyUSB0 (default: {None})
debugOut {stream} -- If a stream is provided, any debug serial output from the
device will be emitted to that stream. (default: {None})
@@ -62,15 +61,14 @@ class StreamInterface(MeshInterface):
Exception: [description]
"""
- if not hasattr(self, 'stream'):
+ if not hasattr(self, 'stream') and not noProto:
raise Exception(
"StreamInterface is now abstract (to update existing code create SerialInterface instead)")
self._rxBuf = bytes() # empty
self._wantExit = False
# FIXME, figure out why daemon=True causes reader thread to exit too early
- self._rxThread = threading.Thread(
- target=self.__reader, args=(), daemon=True)
+ self._rxThread = threading.Thread(target=self.__reader, args=(), daemon=True)
MeshInterface.__init__(self, debugOut=debugOut, noProto=noProto)
@@ -122,7 +120,10 @@ class StreamInterface(MeshInterface):
def _readBytes(self, length):
"""Read an array of bytes from our stream"""
- return self.stream.read(length)
+ if self.stream:
+ return self.stream.read(length)
+ else:
+ return None
def _sendToRadioImpl(self, toRadio):
"""Send a ToRadio protobuf to the device"""
@@ -131,6 +132,7 @@ class StreamInterface(MeshInterface):
bufLen = len(b)
# We convert into a string, because the TCP code doesn't work with byte arrays
header = bytes([START1, START2, (bufLen >> 8) & 0xff, bufLen & 0xff])
+ logging.debug(f'sending header:{header} b:{b}')
self._writeBytes(header + b)
def close(self):
@@ -145,16 +147,18 @@ class StreamInterface(MeshInterface):
def __reader(self):
"""The reader thread that reads bytes from our stream"""
+ logging.debug('in __reader()')
empty = bytes()
try:
while not self._wantExit:
- # logging.debug("reading character")
+ logging.debug("reading character")
b = self._readBytes(1)
- # logging.debug("In reader loop")
- # logging.debug(f"read returned {b}")
+ logging.debug("In reader loop")
+ #logging.debug(f"read returned {b}")
if len(b) > 0:
c = b[0]
+ #logging.debug(f'c:{c}')
ptr = len(self._rxBuf)
# Assume we want to append this byte, fixme use bytearray instead
@@ -173,12 +177,13 @@ class StreamInterface(MeshInterface):
if c != START2:
self._rxBuf = empty # failed to find start2
elif ptr >= HEADER_LEN - 1: # we've at least got a header
- # big endian length follos header
+ #logging.debug('at least we received a header')
+ # big endian length follows header
packetlen = (self._rxBuf[2] << 8) + self._rxBuf[3]
if ptr == HEADER_LEN - 1: # we _just_ finished reading the header, validate length
if packetlen > MAX_TO_FROM_RADIO_SIZE:
- self._rxBuf = empty # length ws out out bounds, restart
+ self._rxBuf = empty # length was out out bounds, restart
if len(self._rxBuf) != 0 and ptr + 1 >= packetlen + HEADER_LEN:
try:
@@ -220,7 +225,6 @@ class StreamInterface(MeshInterface):
Interface class for meshtastic devices over a stream link (serial, TCP, etc)
Constructor, opens a connection to self.stream
Keyword Arguments:
-devPath {string} – A filepath to a device, i.e. /dev/ttyUSB0 (default: {None})
debugOut {stream} – If a stream is provided, any debug serial output from the
device will be emitted to that stream. (default: {None})
Raises
@@ -241,7 +245,6 @@ device will be emitted to that stream. (default: {None})
"""Constructor, opens a connection to self.stream
Keyword Arguments:
- devPath {string} -- A filepath to a device, i.e. /dev/ttyUSB0 (default: {None})
debugOut {stream} -- If a stream is provided, any debug serial output from the
device will be emitted to that stream. (default: {None})
@@ -250,15 +253,14 @@ device will be emitted to that stream. (default: {None})
Exception: [description]
"""
- if not hasattr(self, 'stream'):
+ if not hasattr(self, 'stream') and not noProto:
raise Exception(
"StreamInterface is now abstract (to update existing code create SerialInterface instead)")
self._rxBuf = bytes() # empty
self._wantExit = False
# FIXME, figure out why daemon=True causes reader thread to exit too early
- self._rxThread = threading.Thread(
- target=self.__reader, args=(), daemon=True)
+ self._rxThread = threading.Thread(target=self.__reader, args=(), daemon=True)
MeshInterface.__init__(self, debugOut=debugOut, noProto=noProto)
@@ -310,7 +312,10 @@ device will be emitted to that stream. (default: {None})
def _readBytes(self, length):
"""Read an array of bytes from our stream"""
- return self.stream.read(length)
+ if self.stream:
+ return self.stream.read(length)
+ else:
+ return None
def _sendToRadioImpl(self, toRadio):
"""Send a ToRadio protobuf to the device"""
@@ -319,6 +324,7 @@ device will be emitted to that stream. (default: {None})
bufLen = len(b)
# We convert into a string, because the TCP code doesn't work with byte arrays
header = bytes([START1, START2, (bufLen >> 8) & 0xff, bufLen & 0xff])
+ logging.debug(f'sending header:{header} b:{b}')
self._writeBytes(header + b)
def close(self):
@@ -333,16 +339,18 @@ device will be emitted to that stream. (default: {None})
def __reader(self):
"""The reader thread that reads bytes from our stream"""
+ logging.debug('in __reader()')
empty = bytes()
try:
while not self._wantExit:
- # logging.debug("reading character")
+ logging.debug("reading character")
b = self._readBytes(1)
- # logging.debug("In reader loop")
- # logging.debug(f"read returned {b}")
+ logging.debug("In reader loop")
+ #logging.debug(f"read returned {b}")
if len(b) > 0:
c = b[0]
+ #logging.debug(f'c:{c}')
ptr = len(self._rxBuf)
# Assume we want to append this byte, fixme use bytearray instead
@@ -361,12 +369,13 @@ device will be emitted to that stream. (default: {None})
if c != START2:
self._rxBuf = empty # failed to find start2
elif ptr >= HEADER_LEN - 1: # we've at least got a header
- # big endian length follos header
+ #logging.debug('at least we received a header')
+ # big endian length follows header
packetlen = (self._rxBuf[2] << 8) + self._rxBuf[3]
if ptr == HEADER_LEN - 1: # we _just_ finished reading the header, validate length
if packetlen > MAX_TO_FROM_RADIO_SIZE:
- self._rxBuf = empty # length ws out out bounds, restart
+ self._rxBuf = empty # length was out out bounds, restart
if len(self._rxBuf) != 0 and ptr + 1 >= packetlen + HEADER_LEN:
try:
diff --git a/docs/meshtastic/tcp_interface.html b/docs/meshtastic/tcp_interface.html
index 60fffbf..1ea7d18 100644
--- a/docs/meshtastic/tcp_interface.html
+++ b/docs/meshtastic/tcp_interface.html
@@ -46,18 +46,29 @@ class TCPInterface(StreamInterface):
hostname {string} -- Hostname/IP address of the device to connect to
"""
- logging.debug(f"Connecting to {hostname}")
-
- server_address = (hostname, portNumber)
- sock = socket.create_connection(server_address)
-
# Instead of wrapping as a stream, we use the native socket API
# self.stream = sock.makefile('rw')
self.stream = None
- self.socket = sock
- StreamInterface.__init__(
- self, debugOut=debugOut, noProto=noProto, connectNow=connectNow)
+ self.hostname = hostname
+ self.portNumber = portNumber
+
+ if connectNow:
+ logging.debug(f"Connecting to {hostname}")
+ server_address = (hostname, portNumber)
+ sock = socket.create_connection(server_address)
+ self.socket = sock
+ else:
+ self.socket = None
+
+ StreamInterface.__init__(self, debugOut=debugOut, noProto=noProto,
+ connectNow=connectNow)
+
+ def myConnect(self):
+ """Connect to socket"""
+ server_address = (self.hostname, self.portNumber)
+ sock = socket.create_connection(server_address)
+ self.socket = sock
def close(self):
"""Close a connection to the device"""
@@ -115,18 +126,29 @@ hostname {string} – Hostname/IP address of the device to connect toStreamInterface
Meshtastic test that the examples run as expected.
+We assume you have a python virtual environment in current directory.
+If not, you need to run: …
Meshtastic test that the examples run as expected.
+We assume you have a python virtual environment in current directory.
+If not, you need to run: "python3 -m venv venv", "source venv/bin/activate", "pip install ."
+
+
+Expand source code
+
+
"""Meshtastic test that the examples run as expected.
+ We assume you have a python virtual environment in current directory.
+ If not, you need to run: "python3 -m venv venv", "source venv/bin/activate", "pip install ."
+"""
+import subprocess
+
+import pytest
+
+@pytest.mark.examples
+def test_examples_hello_world_serial_no_arg():
+ """Test hello_world_serial without any args"""
+ return_value, _ = subprocess.getstatusoutput('source venv/bin/activate; python3 examples/hello_world_serial.py')
+ assert return_value == 3
+
+
+@pytest.mark.examples
+def test_examples_hello_world_serial_with_arg(capsys):
+ """Test hello_world_serial with arg"""
+ return_value, _ = subprocess.getstatusoutput('source venv/bin/activate; python3 examples/hello_world_serial.py hello')
+ assert return_value == 1
+ _, err = capsys.readouterr()
+ assert err == ''
+ # TODO: Why does this not work?
+ # assert out == 'Warning: No Meshtastic devices detected.'
Test onReceive with a reply
+To capture: on one device run '–sendtext aaa –reply' and on another
+device run '–sendtext bbb –reply', then back to the first device and
+run '–sendtext aaa2 –reply'. You should now see a "Sending reply" message.
+
+
+Expand source code
+
+
@pytest.mark.unit
+def test_main_onReceive_with_reply(caplog, capsys, reset_globals):
+ """Test onReceive with a reply
+ To capture: on one device run '--sendtext aaa --reply' and on another
+ device run '--sendtext bbb --reply', then back to the first device and
+ run '--sendtext aaa2 --reply'. You should now see a "Sending reply" message.
+ """
+ sys.argv = ['', '--sendtext', 'hello', '--reply']
+ Globals.getInstance().set_args(sys.argv)
+
+ # Note: 'TEXT_MESSAGE_APP' value is 1
+
+ send_packet = {
+ 'to': 4294967295,
+ 'decoded': {
+ 'portnum': 1,
+ 'payload': "hello"
+ },
+ 'id': 334776977,
+ 'hop_limit': 3,
+ 'want_ack': True
+ }
+
+ reply_packet = {
+ 'from': 682968668,
+ 'to': 4294967295,
+ 'decoded': {
+ 'portnum': 'TEXT_MESSAGE_APP',
+ 'payload': b'bbb',
+ 'text': 'bbb'
+ },
+ 'id': 1709936182,
+ 'rxTime': 1640381999,
+ 'rxSnr': 6.0,
+ 'hopLimit': 3,
+ 'raw': 'faked',
+ 'fromId': '!28b5465c',
+ 'toId': '^all'
+ }
+
+ iface = MagicMock(autospec=SerialInterface)
+ iface.myInfo.my_node_num = 4294967295
+
+ with patch('meshtastic.serial_interface.SerialInterface', return_value=iface) as mo:
+ with caplog.at_level(logging.DEBUG):
+ main()
+ onReceive(send_packet, iface)
+ onReceive(reply_packet, iface)
+ assert re.search(r'in onReceive', caplog.text, re.MULTILINE)
+ out, err = capsys.readouterr()
+ assert re.search(r'got msg ', out, re.MULTILINE)
+ assert err == ''
+ mo.assert_called()
Protocol message classes are almost always generated by the protocol
-compiler.
-These generated types subclass Message and implement the methods
-shown below.
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field Channel.index
var role
-
Getter for role.
-
-
-Expand source code
-
-
def getter(self):
- # TODO(protobuf-team): This may be broken since there may not be
- # default_value. Combine with has_default_value somehow.
- return self._fields.get(field, default_value)
-
+
Field Channel.role
var settings
-
Getter for settings.
-
-
-Expand source code
-
-
def getter(self):
- field_value = self._fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
-
- # Atomically check if another thread has preempted us and, if not, swap
- # in the new object we just created. If someone has preempted us, we
- # take that object and discard ours.
- # WARNING: We are relying on setdefault() being atomic. This is true
- # in CPython but we haven't investigated others. This warning appears
- # in several other locations in this file.
- field_value = self._fields.setdefault(field, field_value)
- return field_value
-
-
-
-
Methods
-
-
-def ByteSize(self)
-
-
-
-
-
-Expand source code
-
-
def ByteSize(self):
- if not self._cached_byte_size_dirty:
- return self._cached_byte_size
-
- size = 0
- descriptor = self.DESCRIPTOR
- if descriptor.GetOptions().map_entry:
- # Fields of map entry should always be serialized.
- size = descriptor.fields_by_name['key']._sizer(self.key)
- size += descriptor.fields_by_name['value']._sizer(self.value)
- else:
- for field_descriptor, field_value in self.ListFields():
- size += field_descriptor._sizer(field_value)
- for tag_bytes, value_bytes in self._unknown_fields:
- size += len(tag_bytes) + len(value_bytes)
-
- self._cached_byte_size = size
- self._cached_byte_size_dirty = False
- self._listener_for_children.dirty = False
- return size
def ClearField(self, field_name):
- try:
- field = message_descriptor.fields_by_name[field_name]
- except KeyError:
- try:
- field = message_descriptor.oneofs_by_name[field_name]
- if field in self._oneofs:
- field = self._oneofs[field]
- else:
- return
- except KeyError:
- raise ValueError('Protocol message %s has no "%s" field.' %
- (message_descriptor.name, field_name))
-
- if field in self._fields:
- # To match the C++ implementation, we need to invalidate iterators
- # for map fields when ClearField() happens.
- if hasattr(self._fields[field], 'InvalidateIterators'):
- self._fields[field].InvalidateIterators()
-
- # Note: If the field is a sub-message, its listener will still point
- # at us. That's fine, because the worst than can happen is that it
- # will call _Modified() and invalidate our byte size. Big deal.
- del self._fields[field]
-
- if self._oneofs.get(field.containing_oneof, None) is field:
- del self._oneofs[field.containing_oneof]
-
- # Always call _Modified() -- even if nothing was changed, this is
- # a mutating method, and thus calling it should cause the field to become
- # present in the parent message.
- self._Modified()
-
-
-
-def DiscardUnknownFields(self)
-
-
-
-
-
-Expand source code
-
-
def _DiscardUnknownFields(self):
- self._unknown_fields = []
- self._unknown_field_set = None # pylint: disable=protected-access
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if _IsMapField(field):
- if _IsMessageMapField(field):
- for key in value:
- value[key].DiscardUnknownFields()
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
- for sub_message in value:
- sub_message.DiscardUnknownFields()
- else:
- value.DiscardUnknownFields()
-
-
-
-def FindInitializationErrors(self)
-
-
-
Finds required fields which are not initialized.
-
Returns
-
A list of strings.
-Each string is a path to an uninitialized field from
-the top-level message, e.g. "foo.bar[5].baz".
-
-
-Expand source code
-
-
def FindInitializationErrors(self):
- """Finds required fields which are not initialized.
-
- Returns:
- A list of strings. Each string is a path to an uninitialized field from
- the top-level message, e.g. "foo.bar[5].baz".
- """
-
- errors = [] # simplify things
-
- for field in required_fields:
- if not self.HasField(field.name):
- errors.append(field.name)
-
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.is_extension:
- name = '(%s)' % field.full_name
- else:
- name = field.name
-
- if _IsMapField(field):
- if _IsMessageMapField(field):
- for key in value:
- element = value[key]
- prefix = '%s[%s].' % (name, key)
- sub_errors = element.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
- else:
- # ScalarMaps can't have any initialization errors.
- pass
- elif field.label == _FieldDescriptor.LABEL_REPEATED:
- for i in range(len(value)):
- element = value[i]
- prefix = '%s[%d].' % (name, i)
- sub_errors = element.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
- else:
- prefix = name + '.'
- sub_errors = value.FindInitializationErrors()
- errors += [prefix + error for error in sub_errors]
-
- return errors
-
-
-
-def HasField(self, field_name)
-
-
-
-
-
-Expand source code
-
-
def HasField(self, field_name):
- try:
- field = hassable_fields[field_name]
- except KeyError:
- raise ValueError(error_msg % (message_descriptor.full_name, field_name))
-
- if isinstance(field, descriptor_mod.OneofDescriptor):
- try:
- return HasField(self, self._oneofs[field].name)
- except KeyError:
- return False
- else:
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- value = self._fields.get(field)
- return value is not None and value._is_present_in_parent
- else:
- return field in self._fields
-
-
-
-def IsInitialized(self, errors=None)
-
-
-
Checks if all required fields of a message are set.
-
Args
-
-
errors
-
A list which, if provided, will be populated with the field
-paths of all missing required fields.
-
-
Returns
-
True iff the specified message has all required fields set.
-
-
-Expand source code
-
-
def IsInitialized(self, errors=None):
- """Checks if all required fields of a message are set.
-
- Args:
- errors: A list which, if provided, will be populated with the field
- paths of all missing required fields.
-
- Returns:
- True iff the specified message has all required fields set.
- """
-
- # Performance is critical so we avoid HasField() and ListFields().
-
- for field in required_fields:
- if (field not in self._fields or
- (field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE and
- not self._fields[field]._is_present_in_parent)):
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- for field, value in list(self._fields.items()): # dict can change size!
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.label == _FieldDescriptor.LABEL_REPEATED:
- if (field.message_type.has_options and
- field.message_type.GetOptions().map_entry):
- continue
- for element in value:
- if not element.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
- elif value._is_present_in_parent and not value.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- return True
-
-
-
-def ListFields(self)
-
-
-
-
-
-Expand source code
-
-
def ListFields(self):
- all_fields = [item for item in self._fields.items() if _IsPresent(item)]
- all_fields.sort(key = lambda item: item[0].number)
- return all_fields
-
-
-
-def MergeFrom(self, msg)
-
-
-
-
-
-Expand source code
-
-
def MergeFrom(self, msg):
- if not isinstance(msg, cls):
- raise TypeError(
- 'Parameter to MergeFrom() must be instance of same class: '
- 'expected %s got %s.' % (_FullyQualifiedClassName(cls),
- _FullyQualifiedClassName(msg.__class__)))
-
- assert msg is not self
- self._Modified()
-
- fields = self._fields
-
- for field, value in msg._fields.items():
- if field.label == LABEL_REPEATED:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- elif field.cpp_type == CPPTYPE_MESSAGE:
- if value._is_present_in_parent:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- else:
- self._fields[field] = value
- if field.containing_oneof:
- self._UpdateOneofState(field)
-
- if msg._unknown_fields:
- if not self._unknown_fields:
- self._unknown_fields = []
- self._unknown_fields.extend(msg._unknown_fields)
- # pylint: disable=protected-access
- if self._unknown_field_set is None:
- self._unknown_field_set = containers.UnknownFieldSet()
- self._unknown_field_set._extend(msg._unknown_field_set)
-
-
-
-def MergeFromString(self, serialized)
-
-
-
-
-
-Expand source code
-
-
def MergeFromString(self, serialized):
- serialized = memoryview(serialized)
- length = len(serialized)
- try:
- if self._InternalParse(serialized, 0, length) != length:
- # The only reason _InternalParse would return early is if it
- # encountered an end-group tag.
- raise message_mod.DecodeError('Unexpected end-group tag.')
- except (IndexError, TypeError):
- # Now ord(buf[p:p+1]) == ord('') gets TypeError.
- raise message_mod.DecodeError('Truncated message.')
- except struct.error as e:
- raise message_mod.DecodeError(e)
- return length # Return this for legacy reasons.
def SerializeToString(self, **kwargs):
- # Check if the message has all of its required fields set.
- if not self.IsInitialized():
- raise message_mod.EncodeError(
- 'Message %s is missing required fields: %s' % (
- self.DESCRIPTOR.full_name, ','.join(self.FindInitializationErrors())))
- return self.SerializePartialToString(**kwargs)
-
-
-
-def SetInParent(self)
-
-
-
Sets the _cached_byte_size_dirty bit to true,
-and propagates this to our listener iff this was a state change.
-
-
-Expand source code
-
-
def Modified(self):
- """Sets the _cached_byte_size_dirty bit to true,
- and propagates this to our listener iff this was a state change.
- """
-
- # Note: Some callers check _cached_byte_size_dirty before calling
- # _Modified() as an extra optimization. So, if this method is ever
- # changed such that it does stuff even when _cached_byte_size_dirty is
- # already true, the callers need to be updated.
- if not self._cached_byte_size_dirty:
- self._cached_byte_size_dirty = True
- self._listener_for_children.dirty = True
- self._is_present_in_parent = True
- self._listener.Modified()
Returns the name of the currently set field inside a oneof, or None.
-
-
-Expand source code
-
-
def WhichOneof(self, oneof_name):
- """Returns the name of the currently set field inside a oneof, or None."""
- try:
- field = message_descriptor.oneofs_by_name[oneof_name]
- except KeyError:
- raise ValueError(
- 'Protocol message has no oneof "%s" field.' % oneof_name)
-
- nested_field = self._oneofs.get(field, None)
- if nested_field is not None and self.HasField(nested_field.name):
- return nested_field.name
- else:
- return None
-
+
Field Channel.settings
@@ -3518,8 +3905,15 @@ and propagates this to our listener iff this was a state change.