def takewhile_peek(predicate, iterable):
    """
    Like takewhile, but takes a peekable iterable and doesn't
    consume the non-matching item.

    >>> items = Peekable(range(10))
    >>> is_small = lambda n: n < 4

    >>> small_items = takewhile_peek(is_small, items)

    >>> list(small_items)
    [0, 1, 2, 3]

    >>> list(items)
    [4, 5, 6, 7, 8, 9]

    >>> empty = takewhile_peek(is_small, Peekable([]))
    >>> list(empty)
    []

    >>> items = Peekable([3])
    >>> small_items = takewhile_peek(is_small, items)
    >>> list(small_items)
    [3]
    >>> list(items)
    []

    >>> items = Peekable([4])
    >>> small_items = takewhile_peek(is_small, items)
    >>> list(small_items)
    []
    >>> list(items)
    [4]
    """
    while True:
        try:
            if not predicate(iterable.peek()):
                break
            yield next(iterable)
        except StopIteration:
            break
