Skip to content

Measure the word size in T08 and T09 rather than writing eight down - #81

Merged
tamnd merged 1 commit into
mainfrom
word-size
Aug 29, 2026
Merged

Measure the word size in T08 and T09 rather than writing eight down#81
tamnd merged 1 commit into
mainfrom
word-size

Conversation

@tamnd

@tamnd tamnd commented Aug 29, 2026

Copy link
Copy Markdown
Owner

Closes #79.

A pointer is eight bytes on the machines these lessons were written on and four in a browser, because Pyodide is a wasm32 build. That is measured, in probes/pyodide/report.md: word_bytes is 8 natively and 4 there, and sysconfig.get_platform() says emscripten-5.0.3-wasm32.

T08 said "eight bytes per slot, which is one pointer on a 64 bit machine" and T09 opened a cell with ALIGNMENT = 16. Both lessons are meant to run in a browser tab, and a reader who follows along there gets different numbers from the ones in the text and reasonably concludes they did something wrong.

What changed

T08 measures instead. A new cell prints ctypes.sizeof(ctypes.c_void_p), the size of an empty list, the size of a list of ten, and the per slot cost worked out from those two. The paragraph after it says that eight is what a laptop reports and four is what a browser reports, and that neither is a fact about Python: the fact about Python is one pointer per slot. The exercise that said sys.getsizeof([]) is 56 now asks the reader to find out what it is.

T09 picks its alignment off the pointer size the same way pycore_obmalloc.h does, which is the #if SIZEOF_VOID_P > 4 already covered by the citation on that section. It prints the alignment and the number of size classes it implies, so 16 and 32 on a desktop and 8 and 64 in a browser, and the last line works out the wasted bytes for an empty list rather than the text asserting 56 and 64.

Both new cells carry a varies= note, which is the right kind: this is about the machine rather than the version, so two recordings cannot decide it.

The diagram caption in T09 already said "on a 64 bit build the classes are 16 bytes apart", so it names its assumption and did not need changing.

The flake this turned up

just versions was reporting anywhere from one to five undeclared differences on identical code, in different cells each run, and every one of them was a single blank line.

The cause is in nbversion.normalise.outputs. A cell's standard output does not arrive as one message. The kernel sends it in chunks and where it breaks them depends on how fast the process was going, so the same cell run twice produces one stream output or three. The normaliser strips the trailing newlines off each part before joining them with a single newline, which is right between a print and a returned value and wrong in the middle of one print's output: a break landing on a blank line the cell printed on purpose ate that line.

Adjacent stream outputs are glued together before the join now. Three tests cover it, including one that asserts the split and the whole read the same, and just versions comes back clean twice running where it failed twice running before.

Checks

just check green: lint clean, 1431 passed and 3 skipped, 535 citations, 12 lessons and 12 notebooks up to date and running, the probe unchanged, 5 animations. just versions: 53 declared, 13 noted, nothing undeclared.

Closes #79.

A pointer is eight bytes on the machines these lessons were written on and
four in a browser, because Pyodide is a wasm32 build. Measured in
probes/pyodide/report.md. T08 said "eight bytes per slot" and T09 hard coded
ALIGNMENT = 16, so a reader following along in a browser gets different
numbers and concludes they did it wrong.

T08 now prints the pointer size and works the per slot cost out of two real
lists, and says which of those numbers is about Python and which is about the
machine. T09 picks its alignment off the pointer size the same way
pycore_obmalloc.h does, prints how many size classes that gives, and works out
the wasted bytes for an empty list instead of asserting 56 and 64. Both cells
carry a varies note.

Also fixes a real flake in nbversion that this work turned up. A cell's stdout
does not arrive as one message: the kernel chunks it and where it breaks
depends on timing, so the same cell can produce one stream output or three.
The normaliser strips trailing newlines off each part before joining, so a
break landing on a blank line the cell printed on purpose ate that line, and
`just versions` reported anything from one to five undeclared differences on
identical code. Adjacent stream outputs are glued together first now, and
`just versions` comes back clean twice running.
@tamnd
tamnd merged commit 8ff43da into main Aug 29, 2026
10 checks passed
@tamnd
tamnd deleted the word-size branch August 29, 2026 04:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Say the word size out loud in T08 and T09

1 participant