def cycle_iterator_function(iterator_function: Callable[[], Iterable[T]]) -> Iterator[T]:
    """
    Functionally equivalent to `itertools.cycle(iterator_function())`, but this function does not
    cache the result of calling the iterator like `cycle` does.  Instead, we just call
    `iterator_function()` again whenever we get a `StopIteration`.  This should only be preferred
    over `itertools.cycle` in cases where you're sure you don't want the caching behavior that's
    done in `itertools.cycle`.
    """
    iterator = iter(iterator_function())
    while True:
        try:
            yield next(iterator)
        except StopIteration:
            iterator = iter(iterator_function())
Functionally equivalent to `itertools.cycle(iterator_function())`, but this function does not
cache the result of calling the iterator like `cycle` does.  Instead, we just call
`iterator_function()` again whenever we get a `StopIteration`.  This should only be preferred
over `itertools.cycle` in cases where you're sure you don't want the caching behavior that's
done in `itertools.cycle`.
allennlp/common/util.py