← board

iter(xs) is undefined — the explicit iterator protocol

it = iter(xs)          # error: undefined variable (iter)
print(next(it), next(it))
print(list(it))        # the rest, from where next() left off

next() already exists for a bare generator expression (next(x for x in xs)), so the gap is iter itself and, with it, the idea of a RESUMABLE position over a container. That second half is the real work: list(it) after two next() calls must yield only the remainder, so the iterator has to hold state that survives being passed around.

Walls visibly as an undefined name.

Related and deliberately not merged: feature-nilpy-yield-outside-a-for-loop records that generators are unimplemented full stop. A user-defined __iter__ / __next__ pair is a third piece again. This ticket is only the builtin over an existing container, which is the cheapest of the three and the one real code reaches for first.

Gate

make test-nilpy + self-host byte-identical, CPython-diffed over iter on a list, tuple, set, dict (keys) and string; next() to exhaustion raising StopIteration; next(it, default); and consuming the remainder with list() and with a for after partial consumption.


ALREADY DELIVERED — closed 2026-08-30 (frankwasm)

The feature landed under a different ticket and this one was never closed. 0e171a8d1, "feat(N): TPyIter cursors — iter()/next(), and a for-loop that consumes one", filed under [[feature-nilpy-lazy-iterator-objects]]. This ticket's opening claim — "iter(xs) is undefined ... walls visibly as an undefined name" — is no longer true at HEAD.

Its exact repro, run before claiming:

xs = [1, 2, 3, 4]
it = iter(xs)
print(next(it), next(it))     # 1 2
print(list(it))               # [3, 4]

matches CPython, including the half this ticket called "the real work" — a resumable position, so list(it) after two next() calls yields only the remainder.

Every item of the Gate above was then run against CPython and every one passes: iter over a list, tuple, set, dict (keys) and string; next() to exhaustion raising StopIteration; next(it, default); consuming the remainder with list() and with a for after partial consumption.

What was actually missing was the ASSERTIONS, not the code

test/test_nilpy_iter_next_cursor.npy landed with the feature and already pinned most of that gate — plus resume-after-break, continue, and tuple-unpack in a for. Two of this ticket's gate rows had no coverage: tuple and set as iter() sources. Added there rather than in a new file, since a second file asserting the same cursor would be the duplicate this repo warns about.

The set row goes through sorted(): CPython does not specify set iteration ORDER, so asserting the raw sequence would pin an implementation detail and fail for something that is not a defect. The property under test is that the cursor yields every element once.

Both Makefile rules for that test were updated — it is registered twice (lines 592 and 10485), and changing one would have left the other failing.

Note on this ticket's Gate line

It says make test-nilpy, which is superseded by CLAUDE.md's per-fix loop (decide-gate-line-convention, 2026-08-01). Gate run here: make compiler/pascal26 — the byte-identical self-host fixedpoint — plus the test above and a CPython diff of every gate row. Left in place rather than edited: the line is a record of what the ticket asked for when it was written.

Log