in tensorflow_federated/python/core/impl/types/computation_types.py [0:0]
def _string_representation(type_spec, formatted: bool) -> str:
"""Returns the string representation of a TFF `Type`.
This function creates a `list` of strings representing the given `type_spec`;
combines the strings in either a formatted or un-formatted representation; and
returns the resulting string representation.
Args:
type_spec: An instance of a TFF `Type`.
formatted: A boolean indicating if the returned string should be formatted.
Raises:
TypeError: If `type_spec` has an unexpected type.
"""
py_typecheck.check_type(type_spec, Type)
def _combine(components):
"""Returns a `list` of strings by combining `components`.
This function creates and returns a `list` of strings by combining a `list`
of `components`. Each `component` is a `list` of strings representing a part
of the string of a TFF `Type`. The `components` are combined by iteratively
**appending** the last element of the result with the first element of the
`component` and then **extending** the result with remaining elements of the
`component`.
For example:
>>> _combine([['a'], ['b'], ['c']])
['abc']
>>> _combine([['a', 'b', 'c'], ['d', 'e', 'f']])
['abcd', 'ef']
This function is used to help track where new-lines should be inserted into
the string representation if the lines are formatted.
Args:
components: A `list` where each element is a `list` of strings
representing a part of the string of a TFF `Type`.
"""
lines = ['']
for component in components:
lines[-1] = '{}{}'.format(lines[-1], component[0])
lines.extend(component[1:])
return lines
def _indent(lines, indent_chars=' '):
"""Returns an indented `list` of strings."""
return ['{}{}'.format(indent_chars, e) for e in lines]
def _lines_for_named_types(named_type_specs, formatted):
"""Returns a `list` of strings representing the given `named_type_specs`.
Args:
named_type_specs: A `list` of named comutations, each being a pair
consisting of a name (either a string, or `None`) and a
`ComputationBuildingBlock`.
formatted: A boolean indicating if the returned string should be
formatted.
"""
lines = []
for index, (name, type_spec) in enumerate(named_type_specs):
if index != 0:
if formatted:
lines.append([',', ''])
else:
lines.append([','])
element_lines = _lines_for_type(type_spec, formatted)
if name is not None:
element_lines = _combine([
['{}='.format(name)],
element_lines,
])
lines.append(element_lines)
return _combine(lines)
def _lines_for_type(type_spec, formatted):
"""Returns a `list` of strings representing the given `type_spec`.
Args:
type_spec: An instance of a TFF `Type`.
formatted: A boolean indicating if the returned string should be
formatted.
"""
if type_spec.is_abstract():
return [type_spec.label]
elif type_spec.is_federated():
member_lines = _lines_for_type(type_spec.member, formatted)
placement_line = '@{}'.format(type_spec.placement)
if type_spec.all_equal:
return _combine([member_lines, [placement_line]])
else:
return _combine([['{'], member_lines, ['}'], [placement_line]])
elif type_spec.is_function():
if type_spec.parameter is not None:
parameter_lines = _lines_for_type(type_spec.parameter, formatted)
else:
parameter_lines = ['']
result_lines = _lines_for_type(type_spec.result, formatted)
return _combine([['('], parameter_lines, [' -> '], result_lines, [')']])
elif type_spec.is_struct():
if len(type_spec) == 0: # pylint: disable=g-explicit-length-test
return ['<>']
elements = structure.to_elements(type_spec)
elements_lines = _lines_for_named_types(elements, formatted)
if formatted:
elements_lines = _indent(elements_lines)
lines = [['<', ''], elements_lines, ['', '>']]
else:
lines = [['<'], elements_lines, ['>']]
return _combine(lines)
elif type_spec.is_placement():
return ['placement']
elif type_spec.is_sequence():
element_lines = _lines_for_type(type_spec.element, formatted)
return _combine([element_lines, ['*']])
elif type_spec.is_tensor():
if type_spec.shape.ndims is None:
return ['{!r}(shape=None)'.format(type_spec.dtype.name)]
elif type_spec.shape.ndims > 0:
def _value_string(value):
return str(value) if value is not None else '?'
value_strings = [_value_string(e.value) for e in type_spec.shape.dims]
values_strings = ','.join(value_strings)
return ['{}[{}]'.format(type_spec.dtype.name, values_strings)]
else:
return [type_spec.dtype.name]
else:
raise NotImplementedError('Unexpected type found: {}.'.format(
type(type_spec)))
lines = _lines_for_type(type_spec, formatted)
lines = [line.rstrip() for line in lines]
if formatted:
return '\n'.join(lines)
else:
return ''.join(lines)