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)