From 8204bf69155b8909618b4a2567b0f485688c3bba Mon Sep 17 00:00:00 2001 From: mio Date: Tue, 13 May 2025 00:12:18 +0800 Subject: [PATCH] Allow afl-cmin.py for pre-3.12 by backport from more-itertools --- afl-cmin.py | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/afl-cmin.py b/afl-cmin.py index aad7bc16..5ceace8f 100755 --- a/afl-cmin.py +++ b/afl-cmin.py @@ -28,6 +28,38 @@ import shutil import subprocess import sys +# https://more-itertools.readthedocs.io/en/stable/_modules/more_itertools/recipes.html#batched +from sys import hexversion + +def _batched(iterable, n, *, strict=False): + """Batch data into tuples of length *n*. If the number of items in + *iterable* is not divisible by *n*: + * The last batch will be shorter if *strict* is ``False``. + * :exc:`ValueError` will be raised if *strict* is ``True``. + + >>> list(batched('ABCDEFG', 3)) + [('A', 'B', 'C'), ('D', 'E', 'F'), ('G',)] + + On Python 3.13 and above, this is an alias for :func:`itertools.batched`. + """ + if n < 1: + raise ValueError('n must be at least one') + iterator = iter(iterable) + while batch := tuple(itertools.islice(iterator, n)): + if strict and len(batch) != n: + raise ValueError('batched(): incomplete batch') + yield batch + + +if hexversion >= 0x30D00A2: # pragma: no cover + from itertools import batched as itertools_batched + def batched(iterable, n, *, strict=False): + return itertools_batched(iterable, n, strict=strict) +else: + batched = _batched + + batched.__doc__ = _batched.__doc__ + try: from tqdm import tqdm except ImportError: @@ -574,7 +606,7 @@ def main(): workers.append(p) chunk = max(1, min(128, len(files) // args.workers)) - jobs = list(itertools.batched(enumerate(files), chunk)) + jobs = list(batched(enumerate(files), chunk)) jobs += [None] * args.workers # sentinel dispatcher = JobDispatcher(job_queue, jobs)