def from_container()

in tensorflow_federated/python/common_libs/structure.py [0:0]


def from_container(value: Any, recursive=False) -> Struct:
  """Creates an instance of `Struct` from a Python container.

  By default, this conversion is only performed at the top level for Python
  dictionaries, `collections.OrderedDict`s, `namedtuple`s, `list`s,
  `tuple`s, and `attr.s` classes. Elements of these structures are not
  recursively converted.

  Args:
    value: The Python container to convert.
    recursive: Whether to convert elements recursively (`False` by default).

  Returns:
    The corresponding instance of `Struct`.

  Raises:
    TypeError: If the `value` is not of one of the supported container types.
  """

  def _convert(value, recursive, must_be_container=False):
    """The actual conversion function.

    Args:
      value: Same as in `from_container`.
      recursive: Same as in `from_container`.
      must_be_container: When set to `True`, causes an exception to be raised if
        `value` is not a container.

    Returns:
      The result of conversion.

    Raises:
      TypeError: If `value` is not a container and `must_be_container` has
        been set to `True`.
    """
    if isinstance(value, Struct):
      if recursive:
        return Struct((k, _convert(v, True)) for k, v in iter_elements(value))
      else:
        return value
    elif py_typecheck.is_attrs(value):
      return _convert(
          attr.asdict(
              value, dict_factory=collections.OrderedDict, recurse=False),
          recursive, must_be_container)
    elif py_typecheck.is_named_tuple(value):
      return _convert(
          # In Python 3.8 and later `_asdict` no longer return OrdereDict,
          # rather a regular `dict`.
          collections.OrderedDict(value._asdict()),
          recursive,
          must_be_container)
    elif isinstance(value, collections.OrderedDict):
      items = value.items()
      if recursive:
        return Struct((k, _convert(v, True)) for k, v in items)
      else:
        return Struct(items)
    elif isinstance(value, dict):
      items = sorted(list(value.items()))
      if recursive:
        return Struct((k, _convert(v, True)) for k, v in items)
      else:
        return Struct(items)
    elif isinstance(value, (tuple, list)):
      if recursive:
        return Struct((None, _convert(v, True)) for v in value)
      else:
        return Struct((None, v) for v in value)
    elif isinstance(value, tf.RaggedTensor):
      if recursive:
        nested_row_splits = _convert(value.nested_row_splits, True)
      else:
        nested_row_splits = value.nested_row_splits
      return Struct([('flat_values', value.flat_values),
                     ('nested_row_splits', nested_row_splits)])
    elif isinstance(value, tf.SparseTensor):
      # Each element is a tensor
      return Struct([('indices', value.indices), ('values', value.values),
                     ('dense_shape', value.dense_shape)])
    elif must_be_container:
      raise TypeError('Unable to convert a Python object of type {} into '
                      'an `Struct`. Object: {}'.format(
                          py_typecheck.type_string(type(value)), value))
    else:
      return value

  return _convert(value, recursive, must_be_container=True)