from typing import Iterable
from typing import Optional
from typing import Tuple
from typing import List


def tokens_to_sentences(tsv_lines: Iterable[Optional[Tuple[str, ...]]]) -> Iterable[Tuple[Tuple[str, ...], ...]]:
    """Accept a sequence of tuples (token, tag, ...) and returns a sequence of sentences (tokens, tags).

    An end of sentence is marked with a None element.
    """

    def pack_sentence(example_list: List[Tuple[str, ...]]) -> Tuple[Tuple[str, ...], ...]:
        return tuple(tuple(column_values) for column_values in zip(*example_list))

    example: List[Tuple[str, ...]] = []
    for line in tsv_lines:
        if line is None:
            if len(example) != 0:
                packed = pack_sentence(example)
                yield packed
                example.clear()
            # Otherwise pass silently
        else:
            example.append(line)