import itertools


def iter_pairs(iterable, final_partner=None):
    """
    Produces a generator that iterates over the iterable provided, yielding a tuple of consecutive
    items. When the final item in the iterable is reached, it is yielded with the final partner
    parameter. For example, printing the result of:

        iter_pairs([1,2,3,4])

    would produce

        (1, 2)
        (2, 3)
        (3, 4)
        (4, None)

    :param iterable: the iterable or iterator to pair up
    :param final_partner: the value that will partner the final item in the iterable (defaults to
                          None)
    :return: a generator object
    """
    i1, i2 = itertools.tee(iterable)
    return zip(i1, itertools.chain(itertools.islice(i2, 1, None), [final_partner]))