from typing import Iterable
from typing import Any


def only_one(iterable: Iterable[Any]) -> Any:
    """Consume and return first and only item of an iterable.

    If the iterable has exactly one item, return that item, otherwise raise
    an exception.

    Arguments:
        iterable: iterator or collection expected to contain only one item

    Returns:
        single item of iterable

    Raises:
        ValueError: the iterable is empty or has more than one item

    Examples:

    >>> only_one([])
    Traceback (most recent call last):
     ...
    ValueError: expected 1 item, got empty iterable
    >>> only_one(['test'])
    'test'
    >>> only_one(['this', 'should', 'fail'])
    Traceback (most recent call last):
     ...
    ValueError: expected only 1 item in iterable
    """
    iterator = iter(iterable)
    try:
        value = next(iterator)
    except StopIteration:
        msg = f'expected 1 item, got empty iterable'
        raise ValueError(msg)
    try:
        next(iterator)
    except StopIteration:
        return value
    else:
        msg = f'expected only 1 item in iterable'
        raise ValueError(msg)