← board

test-core RED: test_nilpy_dataclass_dict_factory.npy

What tstate says

open regression: test-core#src:test/test_nilpy_dataclass_dict_factory.npy
                 bad=2fbb5a270acc (4 in range)

The flagged commit cannot be the cause

2fbb5a270 is tickets-only — a single markdown file (bug-nilpy-class-attribute-unreachable-through-the-class-name.md). It changes no code at all, so the bisect has landed on an innocent commit inside its range. Worth knowing before anyone reads it as the culprit.

The range contains exactly one code change

commit what it touches
ef73cf545 fix(N): annotated class attributes parse and register — compiler
42ac7bedc tickets only
2fbb5a270 tickets only
d31a18713 lib/crtl only (isatty, Track B)

ef73cf545 is the only candidate, and it is a plausible one on its face: it changes class-attribute parsing and registration, which is precisely what a @dataclass with a field(default_factory=dict) exercises.

Measured, so the next person starts from facts

Ruled out: the Track B commit in the range

d31a18713 touches only lib/crtl (an isatty implementation). The same session did widen TPalFileStat earlier, which would be the plausible way for Track B work to reach NilPy — but compiler/builtin does not mirror that record: TPyStat is its own class and PyPalStat issues its own syscall with its own buffer. Checked, not assumed.

Next step

Build a fixedpoint at ef73cf545 and at its parent and run test_nilpy_dataclass_dict_factory.npy against each. If it reproduces, the class-attribute registration change is it; the ticket that commit belongs to ([[bug-nilpy-class-attribute-unreachable-through-the-class-name]]) is the place to record the finding.

Resolved 2026-08-02 — commit e1e9ea07a

The triage was right on every point: 2fbb5a270 is innocent, and ef73cf545 was the only code change in the range and was the cause. Mine.

That commit generalised the class-attribute branches in PyRegisterClassMembers to match name : ann = value — which is precisely how a @dataclass field is written. Those branches run BEFORE the isDC ones, so a dataclass's fields were registered as ordinary class attributes and never reached the branches that record their defaults into the PyDc* tables and build the generated ctor. Hence the segfault, and hence a field(default_factory=dict) test being the one to catch it.

Fix: the annotated shape is a PLAIN class's attribute only. A dataclass keeps the pre-existing unannotated-only rule, so its behaviour is exactly what it was.

test/test_nilpy_annotated_class_attribute.npy now carries a @dataclass with str / float / default_factory=list fields as a permanent control — the interaction is pinned rather than remembered.

Gate: gate.sh quick GREEN, self-host fixedpoint byte-identical, both dataclass tests green.

Filed by the Track B agent rather than by me; the range table saved the next reader a bisect against a tickets-only commit.

Log