# -*- coding: utf-8 -*- from functools import wraps from typing import Iterator, TypeVar, Callable, List T = TypeVar("T") I = TypeVar("I") AssignmentRun = Callable[[Iterator[I], ...], Iterator[T]] AssignmentRunList = Callable[[List[I], ...], Iterator[T]] def infinite_generator(func: AssignmentRun) -> AssignmentRun: @wraps(func) def wrapper(*args, **kwargs): items = list(func(*args, **kwargs)) while True: for item in items: yield item return wrapper def list_input(func: AssignmentRun) -> AssignmentRunList: @wraps(func) def wrapper(self, input: Iterator, *args, **kwargs) -> T: return func(self, list(input), *args, **kwargs) return wrapper