code: def batch(
      iterable: Iterable[_T], n: int
  ) -> Generator[tuple[_T, ...], None, None]:
      """Splits an iterable into chunks of size n.
  
      TODO(ddunleavy): once python 3.12 is available, use itertools.batch.
  
      Arguments:
        iterable: the iterable to batch.
        n: the number of elements in each batch.
  
      Yields:
        A tuple of length n of the type that the iterable produces.
      """
      iterator = iter(iterable)
      while True:
          try:
              # Unnecessary list here, but a generator won't raise StopIteration,
              # instead it will raise RuntimeError: "generator raises StopIteration".
              # I'd rather have a list comprehension in place of a generator expression
              # than catch RuntimeError and have to inspect the payload to verify it's
              # the one I want to be catching.
              yield tuple([next(iterator) for _ in range(n)])
          except StopIteration:
              return
  
file_path: tensorflow-upstream/third_party/xla/build_tools/lint/diff_parser.py
imports: import dataclasses
  import re
  import subprocess
  from typing import Generator, Iterable, TypeVar
label_desc: Use image node_id 1 for calling a global function with example usage: batch(iterable, n) without return types