import torch


def unwrap_packed_sequences_recursive(packed):
    """Unwrap `PackedSequence` class of packed sequences recursively.

    This function extract `torch.Tensor` that
    `torch.nn.utils.rnn.PackedSequence` holds internally. Sequences in the
    internal tensor is ordered with time axis first.

    Unlike `torch.nn.pad_packed_sequence`, this function just returns the
    underlying tensor as it is without padding.

    To wrap the data by `PackedSequence` again, use
    `wrap_packed_sequences_recursive`.

    Args:
        packed (object): Packed sequences.

    Returns:
        object: Unwrapped packed sequences. If `packed` is a `PackedSequence`,
            then the returned value is `PackedSequence.data`, the underlying
            tensor. If `Packed` is a tuple of `PackedSequence`, then the
            returned value is a tuple of the underlying tensors.
    """
    if isinstance(packed, torch.nn.utils.rnn.PackedSequence):
        return packed.data
    if isinstance(packed, tuple):
        return tuple(unwrap_packed_sequences_recursive(x) for x in packed)
    return packed