← board

NilPy: dict v1 — TPyDict

Hangs off [[feature-nilpy-corpus-uforth]] milestone 1. Filed 2026-07-19 after the ctor-field fix moved uforth's wall from "cannot infer class field type" to Nil Python: dict/tuple/set types are not supported yet (PyAnnTypeAt).

Why now

Dict is the single largest remaining blocker in the uforth census, and it is load-bearing rather than incidental — VM.dict IS the Forth dictionary:

use count in uforth.py
Dict[...] annotations 18
{} / {k: v} literals 18
.get(k[, default]) 21
.items() / .keys() / .values() 5
del d[k] 4
k in d 2 (plus .dict[...] subscripts, 3)

Nested forms are real, not hypothetical: Dict[int, Dict[str, Any]] (block_buffers, file_handles) and Dict[int, List[Word]] (wordlist_entries).

Shape — mirror TPyList exactly

compiler/builtin/pylib.pas already has the pattern: a class over a heap block of 16-byte variant slots, with the frontend desugaring Python syntax onto its methods. TPyDict = two parallel slot arrays (keys, values) + count.

Frontend work (pyparser.inc):

Sequencing note

.items() returning an iterable is only useful once for k, v in ... (tuple unpack + for-in over a list) lands, which is its own rung. Land the mapping core first (literal, subscript, get, in, len, del); the iteration methods can return a TPyList of keys and grow later.

Gate

test-nilpy green (with new .npy cases diffed against CPython as the oracle) + --tier quick + self-host byte-identical + make fpc-check (see [[feedback_fpc_bootstrap_advisory_invisible_to_local_gate]]).

Log