Say which error each test is waiting for (#610)
* Say which error each test is waiting for
`PT` is selected. The 241 `pytest.raises(ValueError)` calls that named no
message now name one, and the fragment they name is the part that does not
move: the parameter the guard is about, not a bound, not the list of allowed
values, not wording that belongs to numpy.
Reading the guards turned up two `match=` that already existed and pinned
nothing, neither of them reported by the linter because both do pass a
`match=`: one waited on `frequencies`, a word three messages in its module
share, and one waited on `must be positive`, which every positivity guard in
its module shares.
One test could only pin numpy's shape-mismatch text because
`reception_plate_power` broadcast two of its arguments without checking them
first. It has its own guard now, through a new shared helper, so the caller is
told which argument was the wrong length.
Alongside it, 44 `parametrize` decorators take the shape the other 467 use,
and ten `assert a is not None and b is not None` became two assertions.
* Regenerate the reference page for the guard that now names its argument
* Refuse the one-element array the band axis would have stretched
A scalar means the same value in every band and a band-long array means one
value per band. Broadcasting alone also accepted a one-element array and
repeated it across every band, which is the shape a caller lands on after
computing one value where the bands needed several, and four copies of one
measurement read exactly like a measurement of four bands.
The changelog's counts were measured before earlier work moved them: the
suite holds 2075 `pytest.raises`, of which 1795 already named a message. The
39 that still name none are the classes that are their own assertion.
A flag is written by name everywhere, and the clip gate learns which changes cannot move a frame (#760)
#759 closed the flags a caller could reach. This closes the rest, so ruff's
FBT family is selected outright instead of documented as absent: 202
signatures take the star, and the 296 calls that passed a bare True name the
parameter.
Every one of the 156 call sites the change forced was named rather than left
positional. Two of them no static gate sees: _cached_weighting_sos and
_cached_weighting_filter are lru_cache'd, so mypy reads the call through
_lru_cache_wrapper and checks nothing, and only the suite found them.
The one place a keyword-only parameter is not a rewrite: Callable[[...], R]
cannot say that a parameter is keyword-only. ColumnsBuilder in
_report/_insulation_fiche.py and a new LeftCellBuilder in
_report/ansi_s12_2.py become protocols, which say what the alias could not.
FBT003 came down to ax.grid(True, alpha=0.3) in 295 of its 296 sites.
matplotlib declares that parameter visible, so the sites say visible=True and
a test pins the name, because a matplotlib release that moved it would
otherwise surface as a wall of unrelated red. The one that was left is
np.bool_(True) in a test, a cast rather than a flag; it is np.True_ now.
The clips are not re-rendered, and none of them needed to be.
animation_fingerprint already normalises away what cannot move a frame, the
docstrings, the import order, the TYPE_CHECKING blocks, with the reason on
each. Where the keyword-only star sits is the same kind of thing: it decides
how a caller may write the call, not what the function computes. With that
normalisation the 43 fingerprints are identical either side of the signature
sweep, measured, not assumed. The manifest is re-stamped because the
fingerprint itself changed, and the stamp records the same clips it always
described.
scripts/check_public_flags.py goes: ruff now says the same thing on every
definition, and a guard that cannot fire is noise.