Chunk an iterable into fixed-size batches

Python
from collections.abc import Iterable, Iterator
from itertools import islice


def chunked(items: Iterable, size: int) -> Iterator[list]:
    """Yield consecutive lists holding at most `size` items."""
    if size < 1:
        raise ValueError("size must be positive")
    iterator = iter(items)
    while batch := list(islice(iterator, size)):
        yield batch


if __name__ == "__main__":
    for batch in chunked(range(1, 11), 4):
        print(batch)
    # [1, 2, 3, 4]
    # [5, 6, 7, 8]
    # [9, 10]