← board

to_bytes refused big-endian and demanded signed=

Found 2026-08-16 by a fresh tools/pydiff.py sweep over the builtin surface, not by a report.

Measured

(258).to_bytes(2, "big")            # CPython b'\x01\x02'   pxx: compile error
(258).to_bytes(2, "little")         # ok on both
(7).to_bytes()                      # CPython b'\x07'       pxx: compile error
int.from_bytes(b"\x01\x02", "big")  # CPython 258           pxx: compile error

The diagnostics were honest — "only the 'little' byte order is supported", "needs the signed= keyword argument" — but they refuse programs CPython accepts and runs, which is the one direction the compatibility promise does not allow. signed defaults to False in CPython and almost nobody writes it; byteorder has defaulted to "big" since 3.11; big-endian is network byte order, so the refused half is the half serialization code actually uses.

Cause

PyParseByteOrderAndSigned was written when NilPy had no keyword arguments at all, and its comment says so: it accepts "exactly the shape the corpus uses". That was a fair trade for an intrinsic nobody else called, and it stopped being one as soon as anything but uforth reached for it.

Fix

Gate

test/test_nilpy_to_bytes_byteorder_and_defaults.npy — thirteen rows across both orders, both signednesses, the two omitted-argument forms and both directions, every value CPython's. uforth (whose int(v).to_bytes(8, "little", signed=True) is the shape the old parser was built for) still compiles and runs. gate.sh quick green.