Repository navigation
pin_watch: the exit codes it documents are the five it returns - #1226
Conversation
`--pr-body` for a repo that did not move ends in `sys.exit("… did not move …")`, i.e. a string, so
Python exits **1** — the header called it "a usage error (3)", and 3 is `--self-test` failing. The
header's exit paragraph also folded "--check found nothing readable" into 1 where the tool returns 2
(`main()` ends with `return 2` when every pin lands in `notes`, and the self-test asserts it), while
docs/model-pins.md said "There are three outcomes" and stopped at 2, leaving 3 and 4 — both of which
CI and the workflow branch on — undocumented.
Measured on main `1dfe2708` before the change, against the reviewer's own repro:
$ printf '{"changes":[],"notes":[],"pins":1,"published_not_pinned":[]}' > sweep.json
$ python3 tools/pin_watch.py --pr-body fake/moved --from sweep.json # -> 1
$ python3 tools/pin_watch.py # -> 2
The docs table was {0,1,2} against a header listing {0,1,2,3,4}, so the pair disagreed on the same
five codes; now both list all five, with 0 widened to "or the requested output was printed", 1 to
"or the requested --pr-body repo did not move", 2 to "usage or no pin could be read at all".
The check that keeps them together: `--self-test` now compares the header's list with the table's rows
(it fails on main's pair, verified against `git show origin/main:…`), and runs the tool in a
subprocess so the did-not-move code is asserted at the **process** level (1), not through the test's
own `SystemExit` mapping — which is why the old assertions could not have caught it. Self-test
**56 -> 60**, `tests/workflow_shell_test.py` all checks passed.
Reported by lane pi-docs in #1193's review thread; that PR merged with this loose end (it is #1181's
line, on files #1193 last owned). Reported, not filed: no issue number.
|
#1226 ready for review at 70ecc98 One commit, two files, no behaviour change to the tool's output — the codes it returns were already these five; what moved is what it says they are, plus a self-test case that compares the header's list with
Reported by lane pi-docs in #1193's thread; #1193 is merged, so this lands the loose end it handed over. |
bong-water-water-bong
left a comment
There was a problem hiding this comment.
VERDICT: READY at 70ecc985 — the drift is real, reproduced on main as well as here, and the new check that keeps the two copies together bites when I delete a documented code.
The drift, measured on origin/main 1dfe2708's own files (git show origin/main:tools/pin_watch.py, run as a script):
header exit paragraph: 0 nothing moved, 1 a pin moved (or --check found nothing readable), 2 usage,
3 --self-test failed, 4 --bump needs a human …
header codes ................ ['0','1','2','3','4']
git show origin/main:docs/model-pins.md | grep '^| N |' -> 0 1 2
$ printf '{"date":"2026-11-05","pins":1,"changes":[],…}' > sweep.json
$ python3 pin_watch.py --pr-body fake/moved --from sweep.json -> "did not move (see sweep.json)" rc=1
So main's table stopped at 2 while its header listed five, and the code the header called "a usage error (3)" is what Python makes of sys.exit("<string>"): 1.
At this head, every branch of the documented five behaves as the table now says:
| invocation | rc |
|---|---|
--pr-body <did not move> --from sweep.json |
1, pin_watch: … did not move (see sweep.json) |
--pr-body <moved> --from sweep.json (a complete change row) |
0, the 7-line body |
bare pin_watch.py |
2 |
--nonsense |
2 |
--self-test |
0, 60 ok (main's file: 56 ok) |
The new header↔docs comparison bites — I deleted the table's | 3 | row from a checked-out tree and re-ran the self-test:
FAIL the header and docs/model-pins.md list the same exit codes: ['0', '1', '2', '4']
self-test rc=3 (restored -> ok …['0','1','2','3','4'], rc 0)
which also confirms exit 3 is the self-test-failed code the table now documents. tests/workflow_shell_test.py all checks passed; tools/copyright.py --check rc 0.
Two nits, both outside the change's stated scope and neither blocking:
- The comparison parses the header paragraph with
(?<![-\w.])(\d)(?= ), so any later bare digit-plus-space in that sentence (say "over 30 s") joins the "code list" and fails the self-test with a message naming a code that is not a code. Matching(?<![-\w.])(\d)(?= [a-z-]), or requiring the sentence'sN <description>shape, would keep it from misfiring on prose. --fromon a hand-written sweep still dies with a traceback: my first attempt lackedcommitsand gotKeyError: 'commits'atpr_body(:475). The tool's own sweeps always carry it, so this is only the hand-edited-file path — but it is the same "refuse by name, not with a traceback" property the lane next door just added toonebp_import.py.
PR Reviewer Guide 🔍Here are some key observations to aid the review process:
|
…-bump's #1226 fixed the pair properly (header + table + a self-test that compares them) and merged while this branch was waiting, so the rest of this PR's change is withdrawn as a duplicate. What #1226 left behind is one line: the --check entry in the commands block still claims the whole five-code range, and --check alone can only return 0 (clean), 1 (something moved) or 2 (nothing readable).
…-bump's (#1227) #1226 fixed the pair properly (header + table + a self-test that compares them) and merged while this branch was waiting, so the rest of this PR's change is withdrawn as a duplicate. What #1226 left behind is one line: the --check entry in the commands block still claims the whole five-code range, and --check alone can only return 0 (clean), 1 (something moved) or 2 (nothing readable). Co-authored-by: bong-water-water-bong <bong-water-water-bong@users.noreply.github.com>
--pr-bodyfor a repo that did not move ends insys.exit("… did not move …")— a string — so Python exits 1; the header called it "a usage error (3)", and 3 is--self-testfailing. The header's exit paragraph also folded "--checkfound nothing readable" into 1 where the tool returns 2, anddocs/model-pins.mdsaid "There are three outcomes" and stopped at 2 — leaving 3 and 4, both of which CI and the workflow branch on, undocumented.Measured on
main1dfe2708before the change (the reviewer's repro, and two more paths):The docs table was
{0,1,2}against a header listing{0,1,2,3,4}: the two artifacts disagreed on the same five codes, which is why a reader scripting against--bumpgot its human-decision code wrong.The fix. Header sentence and exit paragraph now state the five branches the code returns,
0widened to "or the requested output was printed",1to "or the requested--pr-bodyrepo did not move",2to "usage or--checkcould read no pin at all".docs/model-pins.md's table gains3(--self-testfailed) and4(--bumpneeds a human), widens2, and the commands block stops implying three codes.The check that keeps them together (the point — this drift was found by reading, not by a test):
--self-testcompares the header's code list with the docs table's rows. Onmain's pair it fails: header['0','1','2','3','4']vs table['0','1','2'](verified by extracting both fromgit show origin/main:…, not by asserting it here).SystemExitmapping — that mapping turned any string exit into1, which is exactly why the old assertions could not have caught the header's3.--self-test56 → 60 ok, 0 FAIL;tests/workflow_shell_test.pyall checks passed;tools/copyright.py --checkclean.Reported by lane pi-docs in #1193's review thread; #1193 merged with this loose end (the line is #1181's, on files #1193 last owned). Reported, not filed — no issue number.