r"""
    Enumerate chunks of data from an iterable or a chain

    :param iterable: object supporting iteration, or an index
    :type iterable: iterable, None or int
    :param start: an index to start counting from
    :type start: int
    :raises TypeError: if both parameters are set and ``iterable`` does not support iteration

    In pull mode, :py:func:`~.enumeratelet` works similar to the
    builtin :py:func:`~.enumerate` but is chainable:

    .. code::

        chain = enumeratelet(['Paul', 'Thomas', 'Brian']) >> printlet(sep=':\t')
        for value in chain:
            pass  # prints `0:	Paul`, `1:	Thomas`, `2:	Brian`

    By default, :py:func:`~.enumeratelet` enumerates chunks passed in from a pipeline.
    To use a different starting index, *either* set the ``start`` keyword parameter *or*
    set the first positional parameter.

    .. code::

        chain = iteratelet(['Paul', 'Thomas', 'Brian']) >> enumeratelet() >> printlet(sep=':\t')
        for value in chain:
            pass  # prints `0:	Paul`, `1:	Thomas`, `2:	Brian`

def enumeratelet(iterable=None, start=0):
    r"""
    Enumerate chunks of data from an iterable or a chain

    :param iterable: object supporting iteration, or an index
    :type iterable: iterable, None or int
    :param start: an index to start counting from
    :type start: int
    :raises TypeError: if both parameters are set and ``iterable`` does not support iteration

    In pull mode, :py:func:`~.enumeratelet` works similar to the
    builtin :py:func:`~.enumerate` but is chainable:

    .. code::

        chain = enumeratelet(['Paul', 'Thomas', 'Brian']) >> printlet(sep=':\t')
        for value in chain:
            pass  # prints `0:	Paul`, `1:	Thomas`, `2:	Brian`

    By default, :py:func:`~.enumeratelet` enumerates chunks passed in from a pipeline.
    To use a different starting index, *either* set the ``start`` keyword parameter *or*
    set the first positional parameter.

    .. code::

        chain = iteratelet(['Paul', 'Thomas', 'Brian']) >> enumeratelet() >> printlet(sep=':\t')
        for value in chain:
            pass  # prints `0:	Paul`, `1:	Thomas`, `2:	Brian`
    """
    # shortcut directly to chain enumeration
    if iterable is None:
        return _enumeratelet(start=start)
    try:
        iterator = iter(iterable)
    except TypeError:
        if start != 0:
            raise  # first arg is not iterable but start is explicitly set
        return _enumeratelet(start=iterable)  # first arg is not iterable, try short notation
    else:
        return iterlet(enumerate(iterator, start=start))