Measured 2026-09-10, compiler 4d3d006cf973
import sys
h = sys.stderr
h.write("TO-STDERR\n")
compiles clean -> rc=217
Unhandled exception: TypeError: object is not callable
nothing on stdout, nothing on stderr
Why this is worse than the sibling that was fixed
The dotted spelling failed at COMPILE time with expected ':' before '.' — loud,
located, cannot ship. This one is past every gate a compile can be. A probe
that only asks "does it compile" reports the silent shape as the working one and
the loud shape as the broken one, which reverses the severity ordering, and
that is how it was reported to a peer for an hour on 2026-09-10 before being
re-measured.
The boundary
| shape | today |
|---|---|
print(..., file=sys.stderr) |
works, byte-identical to CPython, both streams |
sys.stdout.write(x) / .flush() / .isatty() |
works since 2026-09-10 |
sys.stdin.read() / .readline() / .isatty() |
works, and always did |
h = sys.stdout; h.write(x) |
compiles, dies at run time |
f = sys.stdout if c else sys.stderr then f.write(x) |
same |
Every working row goes through a name the dotted-call table can see. Nothing
reaches a stream through a VARIABLE, and real code does that constantly — a
routine taking a stream parameter is the ordinary way to write this.
The fix, and why it is one change and not two
pylib's TPyFile (FFd, write(AnsiString), write(TPyBytes), readline) is
already the object a stream should be — open() returns one. Making
sys.stdout a TPyFile on fd 1 fixes BOTH spellings at once and deletes the
special case rather than growing a second path.
But PyParsePrintFile reads the fd back out of the AST:
if (CurASTNode < 0) or (ASTKind[CurASTNode] <> AN_INT_LIT) or
((ASTIVal[CurASTNode] <> 1) and (ASTIVal[CurASTNode] <> 2)) then
Error('Nil Python: print file= expects sys.stdout or sys.stderr');
so the moment sys.stderr stops being an integer literal, the five working
print(..., file=sys.stderr) sites in lekkerzeilen/main.py go red. The two
have to move together, which is why this was NOT smuggled into the table patch
that fixed the dotted spelling.
Positive control for whoever takes it
The three-line program above must exit 0 and put TO-STDERR on fd 2. And
print(..., file=sys.stderr) must still work — assert both, because a fix that
only satisfies the first is the regression this ticket exists to prevent.