One function

exactly_n in more-itertools/more-itertools

The author described this change as Fix bug for negative inputs to exactly_n(). Optimize code.. It counts as a record because the check below fails on the code as it stood at f75535b5e and passes on adeda34bd, with nothing else changed between the two runs.

Fix saved2025-10-28
Sharing licenceMIT · LICENSE
Change size+14 1

What the code was meant to do, written into the code itself as a docstring

Return `True` if exactly `n` items in the iterable are `True` according to the *predicate* function. The iterable will be advanced until `n + 1` truthy items are encountered, so avoid calling it on infinite iterables.

The change

1313 so avoid calling it on infinite iterables.
1414
1515 """
16- return ilen(islice(filter(predicate, iterable), n + 1)) == n
16+ iterator = filter(predicate, iterable)
17+ if n <= 0:
18+ if n < 0:
19+ return False
20+ for _ in iterator:
21+ return False
22+ return True
23+
24+ iterator = islice(iterator, n - 1, None)
25+ for _ in iterator:
26+ for _ in iterator:
27+ return False
28+ return True
29+ return False

The check that tells the two apart

failpass·tests/test_more.py::ExactlyNTests::test_false

Check file tests/test_more.py, taken without changes from the fix and copied onto the older code, so the exact same check runs against both versions.

Origin and history

The code before itf75535b5ed95394a3a24c1495e1f8508a06d56ab
Broken version dated2025-10-25
Modulemore_itertools.more
Units changedexactly_n
Fingerprint785b3f7ba4e1f07c
Checked2026-08-17 by goldset/0.1

Every field above is generated by our program. None of it is written by hand.

Other bugs found in more-itertools/more-itertools