test: enforce PT011 and PT014 so a broad pytest.raises cannot pass on the wrong error - #37769
Merged
ryan-crabbe-berri merged 1 commit intoAug 21, 2026
Conversation
…arametrize cases `pytest.raises(Exception)` with no `match=` passes on any error that broad. A TypeError from a refactor, a botched fixture, an import that moved: all of them read as the rejection the test claims to police, so the test goes green for the wrong reason and stays green after the behaviour it guards is gone. PT011 closes that gap for the 317 sites B017 could not reach, because B017 only fires on a single-statement body with no `as e` binding. Each pattern here is the message the code actually raised, recorded by running the sites under a plugin that logged the concrete type and text per call site, so the assertions describe observed behaviour rather than a guess. Where a site raises more than one message across its parametrize cases, the pattern is an alternation of what was seen; where the exception carries an empty `str()` and puts the text on `.message`, the site keeps a narrow `noqa` with the reason. PT014 removes four parametrize cases that were listed twice. The duplicate re-runs an assertion that already passed, and it usually marks a case someone meant to vary and forgot to edit.
Contributor
|
Too many files changed for review (145 files, 100 file limit). Bypass the limit by tagging |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
yuneng-berri
approved these changes
Aug 21, 2026
yucheng-berri
approved these changes
Aug 21, 2026
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.
TLDR
Problem this solves:
pytest.raises(Exception)with nomatch=passes on any errorHow it solves it:
PT011andPT014inruff-tests.toml, already wired to CIUser Flow
Before: a proxy admin gives a key two models, and the 403 that names those models can quietly stop naming them
"models": ["gpt-5.5"]and get back a keyclaude-sonnet-4-5Access denied for model claude-sonnet-4-5After: that change turns CI red before it ships
Exceptionwithout pinning the message is rejected at lint time, so the next one cannot go quiet eitherRelevant issues
Linear ticket
Pre-Submission checklist
Screenshots / Proof of Fix
This PR changes lint config and tests, so there is no proxy route to curl. The proof is three mutations: break a behavior a test exists to police, and show the old test does not notice while the new one does. Every command is identical on both sides; only the
tests/tree differs.The three mutations, applied one at a time and reverted after each run:
Before (354f497)
The rejected filename stops saying why
filename_message_reworded, then runA helper crashes before reaching its own check
prefix_helper_crashes_first, then runThe 403 stops listing the models the key can use
model_denial_stops_naming_the_key, then runAfter (b76def0)
The rejected filename stops saying why
filename_message_reworded, then runA helper crashes before reaching its own check
prefix_helper_crashes_first, then runThe 403 stops listing the models the key can use
model_denial_stops_naming_the_key, then runRule and regression numbers
ruff check --config ruff-tests.toml testswent from 317PT011and 4PT014findings to zero. Ruff has no autofix for either, so 291 sites took a pattern recorded by running them under a plugin that logged the concrete exception and message per call site, and the remaining 26 were resolved by hand: 18 took the message the test itself plants, 6 narrowed to a real type, and 2 kept anoqabecause their exception carries an emptystr().The 144 touched test files were run in full at both hashes. 196 tests fail identically on each side, all of them live-provider tests with no Fireworks, Azure, Gemini or Bedrock credentials on this machine. Nothing is new and nothing disappeared.
Type
🧹 Refactoring
🚄 Infrastructure
✅ Test
Caveats (if any)
match=noqa: their exception carries an emptystr()Final Attestation