Every zip() now says what it expects, and two of them did not - #96
Merged
Conversation
`zip()` without `strict=` truncates to the shorter argument and says nothing.
The ratchet recorded 41 of them and the obvious move is
`ruff --fix --unsafe-fixes`. It writes `strict=False` -- the current behaviour,
spelled out loud. That takes the count to zero, looks exactly like the job
being done, and preserves every defect the rule exists to expose. So this was
done by hand, one site at a time, and the count was the least interesting part.
**58 sites, not 41.** The other 17 are in `notebooks/`, which is not in
SOURCE_DIRS in tests/test_lint_debt_only_shrinks.py, so no ruff guard here had
ever read them -- in the three notebooks a student is most likely to open.
Same shape as KNOWN_NON_EXAMPLE_CHAPTER_FILES: a file outside the sweep's scope
is a file nothing sweeps, and that scope is a tuple somebody wrote once.
**One real defect.** ch5_fingerprinting/example_comparison.py built
`colors_box` with five shades against six methods, so Linear Regression's box
kept matplotlib's default blue among five pastels and read as deliberately
highlighted. Nothing raised, nothing left a range, no printed number moved --
the sixth box simply never got its colour, which only opening the PNG shows.
comparison_all_methods.{svg,pdf,png} regenerated; all three reproduce
byte-identically from the fixed code.
**One site where strict=True is wrong.** `zip(scales, scales[1:])` is the
consecutive-pairs idiom and depends on the truncation, so strict raises on
every call; it is `itertools.pairwise` now. `zip(xs, count())` and
`zip(xs, cycle(ys))` are the same family -- the tell is a second argument
derived from the first, and a grep for `[1:]` finds only the spelling you
thought of.
B905 is deleted from BASELINE rather than set to 0, and the deletion is the
guard: test_no_rule_has_more_findings_than_it_did fails on any rule not listed.
Verified by adding one unguarded zip() and watching `B905: 1 findings, new`.
Coverage says the sweep is not decorative: 34 of the 42 .py sites execute,
including two only reachable through ch4's `--data` branch and ch7's
`--animate` callback. Six sit inside test bodies, one is reached by
tests/core/fingerprinting/test_classification.py, and the last is ch8's
unobservable-mode print, which the fixes-aided configuration never enters and
which is equal-length by construction.
ruff B905 41 in SOURCE_DIRS, 58 repo-wide -> 0
full suite 3404 passed / 21 skipped -> 3404 passed / 21 skipped
notebooks 7 execute in a real kernel -> still do, with strict=True
black 299 files clean -> 299 files clean
The first pass measured coverage over the examples and the generators, which reaches 34 of the 42 `.py` zip sites, and left the remaining eight argued for rather than measured -- six inside test bodies, one in `core/fingerprinting`, one unreachable in the shipped configuration. Measuring the seven was worth doing and needed the harness fixed first. `[tool.coverage.run] omit` in pyproject.toml excludes `*/tests/*` and `*/test_*.py`, so a run measuring test files reports every line in them as never executed -- which is exactly what "this code never runs" looks like, for the third time in this audit. With a scratch rcfile that drops the omit, all seven execute. That leaves one site out of 42, ch8's unobservable-mode print, and it is the one worth naming: `if n_unobservable > 0` is false for the fixes-aided configuration by design, which is the point the example is making. Its twin in the odometry-only branch does execute, and the pairing is equal-length by construction either way.
Self-review of the previous commit. The comment explaining why deleting the B905 entry tightens the ratchet pointed at "`appeared` above"; BASELINE is at line 79 and `appeared` is at 133, inside the test. A comment that sends the reader the wrong way through its own file is a small thing, and this one sits on the sentence explaining the guard.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
zip()withoutstrict=truncates to the shorter argument and says nothing.BASELINEintests/test_lint_debt_only_shrinks.pyrecorded 41 of them, andthe obvious move is
ruff --fix --unsafe-fixes. It writesstrict=False—the current behaviour, spelled out loud. That takes the count to zero, looks
exactly like the job being done, and preserves every defect the rule exists to
expose. Done by hand instead, one site at a time.
58 sites, not 41
The other 17 are in
notebooks/, which is not inSOURCE_DIRS, so no ruffguard here had ever read them — in the three notebooks a student is most likely
to open. Same shape as
KNOWN_NON_EXAMPLE_CHAPTER_FILES: a file outside thesweep's scope is a file nothing sweeps, and that scope is a tuple somebody wrote
once.
One real defect
ch5_fingerprinting/example_comparison.pybuiltcolors_boxwith five shadesagainst six methods, so Linear Regression's box kept matplotlib's default blue
among five pastels and read as deliberately highlighted. Nothing raised, nothing
left a range, no printed number moved — the sixth box simply never got its
colour, which only opening the PNG shows.
comparison_all_methods.{svg,pdf,png}regenerated, and all three reproduce byte-identically from the fixed code.
One site where
strict=Trueis wrongzip(scales, scales[1:])is the consecutive-pairs idiom and depends on thetruncation, so strict raises on every call — confirmed by running it. It is
itertools.pairwisenow.zip(xs, count())andzip(xs, cycle(ys))are thesame family; the tell is a second argument derived from the first, and a grep
for
[1:]finds only the spelling you thought of.The ratchet is tighter, not looser
B905is deleted fromBASELINErather than set to0, and the deletionis the guard:
test_no_rule_has_more_findings_than_it_didfails on any rule notlisted. Verified by adding one unguarded
zip()and watchingB905: 1 findings, new, not by reading the assertion.A green sweep only means something where the line runs
Measured with
coverage: 41 of the 42.pysites execute. 34 run underthe examples, the generators, and two paths a plain run never reaches — ch4's
--databranch and ch7's--animatecallback, which between them hold twosites nothing else touches. The other seven — six inside test bodies, one in
core/fingerprinting— needed the harness fixed before they could be seen:[tool.coverage.run] omitinpyproject.tomlexcludes*/tests/*, so a runmeasuring test files reports every line in them as never executed, which looks
exactly like "this code never runs". With a scratch rcfile that drops the omit,
all seven execute.
The one remaining site is ch8's unobservable-mode print, behind
if n_unobservable > 0— false for the fixes-aided configuration by design,which is the point the example makes. Its twin in the odometry-only branch does
execute, and the pairing is equal-length by construction either way. The 17
notebook sites are covered by
tests/docs/test_notebooks_run.py.Test plan
ruff check --statisticsoverSOURCE_DIRS: B905 gone, every other ruleunchanged against
BASELINEruff check --select B905 .: zero repo-wide, notebooks includedmaintests/docs/test_notebooks_run.py: 14 passed, all seven notebooks executein a real kernel
strict=Trueblack --check: 299 files clean (six files reflowed by the insertedkeyword, and every changed line in them mentions
zip/strict)zip()added → ratchet red; removed → green🤖 Generated with Claude Code