parameters: (shallow_tree, input_tree, check_types=True,
                    expand_composites=False)
return_statement: return [
        v for _, v in _yield_flat_up_to(shallow_tree, input_tree, is_nested_fn)
    ]
docstring: Flattens `input_tree` up to `shallow_tree`.
  
    Refer to [tf.nest](https://www.tensorflow.org/api_docs/python/tf/nest)
    for the definition of a structure.
  
    Any further depth in structure in `input_tree` is retained as structures in
    the partially flatten output.
  
    If `shallow_tree` and `input_tree` are atoms, this returns a
    single-item list: `[input_tree]`.
  
    Use Case:
  
    Sometimes we may wish to partially flatten a structure, retaining some
    of the nested structure. We achieve this by specifying a shallow structure,
    `shallow_tree`, we wish to flatten up to.
  
    The input, `input_tree`, can be thought of as having the same structure layout
    as `shallow_tree`, but with leaf nodes that are themselves tree structures.
  
    Examples:
  
    ```python
    input_tree = [[[2, 2], [3, 3]], [[4, 9], [5, 5]]]
    shallow_tree = [[True, True], [False, True]]
  
    flattened_input_tree = flatten_up_to(shallow_tree, input_tree)
    flattened_shallow_tree = flatten_up_to(shallow_tree, shallow_tree)
  
    # Output is:
    # [[2, 2], [3, 3], [4, 9], [5, 5]]
    # [True, True, False, True]
    ```
  
    ```python
    input_tree = [[('a', 1), [('b', 2), [('c', 3), [('d', 4)]]]]]
    shallow_tree = [['level_1', ['level_2', ['level_3', ['level_4']]]]]
  
    input_tree_flattened_as_shallow_tree = flatten_up_to(shallow_tree, input_tree)
    input_tree_flattened = flatten(input_tree)
  
    # Output is:
    # [('a', 1), ('b', 2), ('c', 3), ('d', 4)]
    # ['a', 1, 'b', 2, 'c', 3, 'd', 4]
    ```
  
    Edge Cases for atoms:
  
    ```python
    flatten_up_to(0, 0)  # Output: [0]
    flatten_up_to(0, [0, 1, 2])  # Output: [[0, 1, 2]]
    flatten_up_to([0, 1, 2], 0)  # Output: TypeError
    flatten_up_to([0, 1, 2], [0, 1, 2])  # Output: [0, 1, 2]
    ```
  
    Args:
      shallow_tree: a possibly pruned structure of input_tree.
      input_tree: an atom or a nested structure.
        Note, numpy arrays are considered atoms.
      check_types: bool. If True, check that each node in shallow_tree has the
        same type as the corresponding node in input_tree.
      expand_composites: If true, then composite tensors such as
        `tf.sparse.SparseTensor` and `tf.RaggedTensor` are expanded into their
        component tensors.
  
    Returns:
      A Python list, the partially flattened version of `input_tree` according to
      the structure of `shallow_tree`.
  
    Raises:
      TypeError: If `shallow_tree` is a nested structure but `input_tree` is not.
      TypeError: If the structure types of `shallow_tree` are different from
        `input_tree`.
      ValueError: If the structure lengths of `shallow_tree` are different from
        `input_tree`.
docstring_summary: Flattens `input_tree` up to `shallow_tree`.
docstring_tokens: Flattens input_tree up to shallow_tree .
function: def flatten_up_to(shallow_tree, input_tree, check_types=True,
                    expand_composites=False):
    """Flattens `input_tree` up to `shallow_tree`.
  
    Refer to [tf.nest](https://www.tensorflow.org/api_docs/python/tf/nest)
    for the definition of a structure.
  
    Any further depth in structure in `input_tree` is retained as structures in
    the partially flatten output.
  
    If `shallow_tree` and `input_tree` are atoms, this returns a
    single-item list: `[input_tree]`.
  
    Use Case:
  
    Sometimes we may wish to partially flatten a structure, retaining some
    of the nested structure. We achieve this by specifying a shallow structure,
    `shallow_tree`, we wish to flatten up to.
  
    The input, `input_tree`, can be thought of as having the same structure layout
    as `shallow_tree`, but with leaf nodes that are themselves tree structures.
  
    Examples:
  
    ```python
    input_tree = [[[2, 2], [3, 3]], [[4, 9], [5, 5]]]
    shallow_tree = [[True, True], [False, True]]
  
    flattened_input_tree = flatten_up_to(shallow_tree, input_tree)
    flattened_shallow_tree = flatten_up_to(shallow_tree, shallow_tree)
  
    # Output is:
    # [[2, 2], [3, 3], [4, 9], [5, 5]]
    # [True, True, False, True]
    ```
  
    ```python
    input_tree = [[('a', 1), [('b', 2), [('c', 3), [('d', 4)]]]]]
    shallow_tree = [['level_1', ['level_2', ['level_3', ['level_4']]]]]
  
    input_tree_flattened_as_shallow_tree = flatten_up_to(shallow_tree, input_tree)
    input_tree_flattened = flatten(input_tree)
  
    # Output is:
    # [('a', 1), ('b', 2), ('c', 3), ('d', 4)]
    # ['a', 1, 'b', 2, 'c', 3, 'd', 4]
    ```
  
    Edge Cases for atoms:
  
    ```python
    flatten_up_to(0, 0)  # Output: [0]
    flatten_up_to(0, [0, 1, 2])  # Output: [[0, 1, 2]]
    flatten_up_to([0, 1, 2], 0)  # Output: TypeError
    flatten_up_to([0, 1, 2], [0, 1, 2])  # Output: [0, 1, 2]
    ```
  
    Args:
      shallow_tree: a possibly pruned structure of input_tree.
      input_tree: an atom or a nested structure.
        Note, numpy arrays are considered atoms.
      check_types: bool. If True, check that each node in shallow_tree has the
        same type as the corresponding node in input_tree.
      expand_composites: If true, then composite tensors such as
        `tf.sparse.SparseTensor` and `tf.RaggedTensor` are expanded into their
        component tensors.
  
    Returns:
      A Python list, the partially flattened version of `input_tree` according to
      the structure of `shallow_tree`.
  
    Raises:
      TypeError: If `shallow_tree` is a nested structure but `input_tree` is not.
      TypeError: If the structure types of `shallow_tree` are different from
        `input_tree`.
      ValueError: If the structure lengths of `shallow_tree` are different from
        `input_tree`.
    """
    is_nested_fn = _is_nested_or_composite if expand_composites else _is_nested
    assert_shallow_structure(shallow_tree,
                             input_tree,
                             check_types=check_types,
                             expand_composites=expand_composites)
    # Discard paths returned by _yield_flat_up_to.
    return [
        v for _, v in _yield_flat_up_to(shallow_tree, input_tree, is_nested_fn)
    ]
function_tokens: def flatten_up_to ( shallow_tree , input_tree , check_types = True , expand_composites = False ) : is_nested_fn = _is_nested_or_composite if expand_composites else _is_nested assert_shallow_structure ( shallow_tree , input_tree , check_types = check_types , expand_composites = expand_composites ) # Discard paths returned by _yield_flat_up_to. return [ v for _ , v in _yield_flat_up_to ( shallow_tree , input_tree , is_nested_fn ) ]