Repository navigation
Conversation
anth-volk
added this pull request to stack #3917
October 14, 2026 15:08
2 tasks done
anth-volk
force-pushed
the
ruff-idioms-arguments
branch
2 times, most recently
from
October 14, 2026 16:59
7b5a851 to
d89b4b5
Compare
anth-volk
force-pushed
the
ruff-idioms-arguments
branch
from
October 14, 2026 18:08
d89b4b5 to
24a3be7
Compare
anth-volk
force-pushed
the
ruff-idioms-arguments
branch
2 times, most recently
from
October 14, 2026 20:04
1d0d644 to
6ad4b2c
Compare
anth-volk
force-pushed
the
ruff-idioms-arguments
branch
7 times, most recently
from
October 15, 2026 15:21
29808ba to
aae6fe4
Compare
anth-volk
force-pushed
the
ruff-idioms-arguments
branch
from
October 15, 2026 15:45
aae6fe4 to
bc3381a
Compare
anth-volk
force-pushed
the
ruff-idioms-arguments
branch
from
October 15, 2026 17:21
bc3381a to
0ae1220
Compare
anth-volk
force-pushed
the
ruff-idioms-arguments
branch
from
October 16, 2026 05:40
0ae1220 to
cbac3c2
Compare
anth-volk
force-pushed
the
ruff-idioms-arguments
branch
2 times, most recently
from
October 16, 2026 06:40
1827772 to
a4541ae
Compare
anth-volk
force-pushed
the
ruff-idioms-arguments
branch
from
October 16, 2026 06:45
a4541ae to
eba9e3b
Compare
The shared rules tool needs only the standard library, so its tests use unittest on purpose. Registered as api.quality.unittest-ruff-exemptions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Rewrite keyword dict() calls as dict literals, generators passed to set() as set comprehensions and a constant-valued dict comprehension as dict.fromkeys. Replace append loops with list.extend or a comprehension, and the two conditional bundle-merging loops with dict.update. Key order, values and messages are unchanged. Two lists that mypy inferred from their first append are now annotated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Combine nested with statements into one statement with the same contexts in the same order, collapse nested ifs whose inner condition has no side effects, drop .keys() from dict membership and iteration, put constants on the right of comparisons, and open the smoke test's temporary log files in context managers. The two try/except/pass blocks that catch specific exceptions become contextlib.suppress. The best-effort blocks that groups 5 and 6 kept with a BLE001/S110 suppression stay as try/except: ruff reports SIM105 on the try line, so each try line now carries the handler's reason. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Annotate mutable class attributes with ClassVar, make the implicit Optional defaults explicit, sort __all__, use unpacking instead of list concatenation and conversion flags instead of str() in f-strings, parenthesize a mixed and/or, write regex match patterns as raw strings (escaping the two dots that are literal), prefix unused unpacked names with an underscore, and drop the E402 suppressions that ruff no longer needs after an os.environ assignment. compare_economic_outputs already defaulted country_id to None, so the three helpers it passes country_id to, which only compare it with "uk", are annotated to accept None too. The fullwidth and Arabic-Indic digits in the identity tests are the inputs under test, so their lines keep them with a RUF001 suppression. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Pass parametrize names as tuples and values as lists, split composite assertions, return from the fixture that has no teardown, and give every broad pytest.raises a match on the message the code really raises. Where a test only asserted that a literal appeared in the message, the match replaces that assertion; stricter assertions stay. The two tests that raise inside a transaction to prove it rolls back now do the work in a local helper, so pytest.raises wraps a single call. The forecast test asserts on the exception from pytest.raises instead of in an except block, and the Alembic test enters pytest.warns around the lookup that emits the warning rather than around the script load as well. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Prefix the ignored *args and **kwargs of the cache-key callbacks and the disabled cache backend with an underscore, and the parameters of the rules tool's no-op resolver lambda, which is only called positionally. Drop the unused job_indent parameter of the rules tool's private _parse_job and its two call sites. Keep the named parameters that callers may pass by keyword, with a reason: Flask passes the <country_id> URL variable to the views, the disabled cache backend overrides InMemoryCacheBackend (typing.override needs Python 3.12 and typing_extensions is not a declared dependency), and RegistryCapability implements the SPMCapabilitySource protocol. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Request fixtures that a test needs only for their side effects through pytest.mark.usefixtures instead of unused parameters. The collected test IDs are unchanged, and the moved fixtures patch independent targets, so setting them up before the remaining arguments changes nothing. Prefix unused parameters of stand-in lambdas and callbacks with an underscore where every caller passes them positionally (checked against the code under test), including every ignored *args and **kwargs. Keep, with a reason, the parameters that callers may pass by keyword or that a framework passes: fixtures that depend on another fixture for its side effect (marks don't apply to fixtures), methods of stand-in classes that implement or override the interface the code under test calls, a SQLAlchemy event listener, and stand-ins for callables that EconomyService, the migration target or importlib callers call with keyword arguments. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every caller already passes these flags by keyword, so they become keyword-only: spm_requested (and prepared) on PolicyEngineCountry's calculate and prepare_calculation, include_cliffs and the options after it on EconomyService._setup_sim_options, and transaction on the cache backend protocol's pipeline and the in-memory fake. The test helpers and stand-ins get the same treatment, and the test inspector is built with table_exists by keyword. sa.literal receives its value by keyword. The FastAPI current query parameter and the _reflected argument of Alembic's positional include_object hook keep their shape, with a reason. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- B904: re-raise the BadRequest of the simulation and report-output routes from the caught validation error, keeping it as the cause. - B905: zip strictly where the lengths are fixed by literals (the country tuples and the income-change bounds and labels), and say strict=False in the contract helper, which compares a prefix. - B023: bind the loop values that the rules tool's adapter check and a dual-write test's mock side effects close over, as default arguments. Each closure runs only within its own iteration. - B009: read the region attributes directly instead of through getattr with a constant name. - PLW1510: pass check=False to the rules tool's subprocess calls, which inspect the return code themselves. - PLW2901: give the float-converted reform value and the bracketed parameter name their own variables instead of reusing the loop names. - PLW0603: keep the global statements for the process-owned database state and readiness flag, with a reason. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Open the bundle manifest and GITHUB_ENV through Path.open, which opens them the same way as open(). Keep the remaining calls, with a reason: MicroSeries overrides .values and its .to_numpy() emits a different warning, the dashboard experiment reads a string column that pandas 3 stores in an extension array, and the runtime measurement script reads its payload file once before any request starts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Select ARG, ASYNC, B, C4, FBT, PD, PERF, PGH, PLW, PT, PTH, RUF and SIM. The earlier commits in this branch fix or explain every finding, so ruff reports none. Complexity (C901 and PLR) is left for group 8b. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
api.quality.ruff-lint now lists ARG, ASYNC, B, C4, FBT, PD, PERF, PGH, PLW, PT, PTH, RUF and SIM. The rendered rules page also picks up the rules tool's new hash. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- FBT001: require_not_mirror_owned and require_owned_user_policy take their boolean flag by keyword, and their three callers pass it so. - B008: the default account authenticator declares its bearer and unauthenticated-user security dependencies with Annotated instead of as parameter defaults. - ARG001: DELETE /v2/me needs its country query only for validation, so the parameter is named _query, like the _size request-size check. The OpenAPI documents, with the injected test authenticator and with the default one, are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…fects The five run-progress polling tests and the two run-progress economy service tests took mock_modal_logger or mock_logger without using it (ARG002). They now request it through pytest.mark.usefixtures, as the neighbouring tests do; the collected test IDs are unchanged. These were the ruff group 8a findings in the code #3916 added. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- PT018: split the 12 composite assertions, so a failure names the part that failed. - SIM117: the three pytest.raises blocks that open a transaction enter both contexts in one with statement, in the same order. - PT011, PT007: the update-input validation tests match the message each ValueError really carries, and the user-service guard's parametrize values are a list. - ARG: the qualification test and the signed-out header test request the sessions and configured_auth fixtures through pytest.mark.usefixtures; stand-in lambdas and result callbacks that are only called positionally prefix their unused parameters with an underscore, as does the Alembic test's unused loop name; and the deferred reference service test's stand-in keeps its keyword parameters with a reason. - FBT001: the signed-out header test takes auth_configured by keyword, which pytest already does. - SIM118, RUF005: drop a .keys() membership check and unpack a list instead of concatenating it. The collected test IDs are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Test fakes and stand-ins mirror the signatures of what they replace, because callers pass those arguments by keyword. Each one carried an inline ARG001, ARG002 or ARG005 suppression with that reason. Tests may take file-level exceptions, so the **/tests/** entry and api.quality.tests-ruff-exemptions now include the three codes, and the 32 inline codes in 16 test files are removed. Application code keeps its unused-argument suppressions and reasons. Comments and configuration only: no code changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Nineteen try/except Exception/pass blocks kept SIM105 suppressions so the reason for swallowing the failure could sit on the except line. Each now uses contextlib.suppress(Exception), with that reason as a plain comment above it. The behaviour is identical: any exception from the wrapped call is still ignored. The sites are telemetry and logging calls in the ASGI factory, request context, migration logging, observability runtime, the household and policy routes, the economy service's SPM error handling, the three mirroring services and the household-event command script. This removes 19 SIM105, 19 BLE001 and 17 S110 inline codes, plus a BLE001 on migration_logging's outer handler. Ruff now sees that handler log the traceback, because the logging call is no longer nested in a try. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
anth-volk
force-pushed
the
ruff-idioms-arguments
branch
from
October 16, 2026 07:05
7702a61 to
9b3d71f
Compare
This branch has not been deployed
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.
Fixes #3923
Summary
Phase 1 step 1.8, group 8a: arguments, idioms and pytest style. Stacked on #3920. Group 8b follows with the complexity refactors and the switch to
select = ["ALL"].ARG001,ARG002andARG005join the**/tests/**file-level exceptions (api.quality.tests-ruff-exemptions). That removes 32 inline codes from 16 test files here and 37 by Register weighted-microdata rules, with AST guards and #767 proofs #3938.scripts/rules/tests/**is exempt from ruff's pytest-style rules (PT), registered asapi.quality.unittest-ruff-exemptions.selectgainsARG,ASYNC,B,C4,FBT,PD,PERF,PGH,PLW,PT,PTH,RUFandSIM. All 912 findings are fixed or kept with an inline reason, one commit per family.@pytest.mark.usefixtures; the collected test IDs are identical.*args/**kwargsbecame*_args/**_kwargs. A named lambda or callback parameter is underscored only where every caller passes it positionally.typing.overrideneeds Python 3.12), Flask views that receive URL variables by keyword, and SQLAlchemy and Alembic hooks keep an inline reason. Test fakes called by keyword are covered by the test exceptions above.PolicyEngineCountry.calculateandprepare_calculation(spm_requested,prepared),EconomyService._setup_sim_options, and the cache backend protocol'spipeline(*, transaction=True). Every caller already passed these by keyword. The FastAPIcurrentquery parameter and Alembic's positionalinclude_objecthook are kept, with reasons.BadRequest(...) from e. The 400 responses are unchanged; only the traceback's chaining text changes.zip(..., strict=True)where the lengths are fixed by literals.try: … except Exception: passaround a telemetry or logging call is nowwith contextlib.suppress(Exception):, with the reason as a plain comment above it. Behaviour is identical.try/exceptwith suppressions, plus two converted earlier.SIM105, 20BLE001and 17S110. OneBLE001was on migration logging's outer handler, which ruff now sees log the traceback.BLE001doesn't flagcontextlib.suppress(Exception). These catch-alls are documented by their comments rather than by a reasoned suppression.dict()calls become literals, plus comprehensions (C4, PERF), simplified conditions and combinedwithstatements in the same order (SIM),ClassVarannotations, explicitOptionaltypes, raw regex patterns and sorted__all__(RUF),Path.open(PTH) andcheck=Falseonsubprocess.run(PLW1510).pytest.raisesgainmatch=with the real message; where a test only asserted that text separately, the match replaces that assertion. Parametrize names and values use tuples and lists, and composite assertions are split.PLW0603).RUF001..values:MicroSeriesand a pandas extension array, where.to_numpy()would differ (PD011).ASYNC240.api.quality.ruff-lintnow lists the 13 families. The rules tool changed (comprehensions,check=False, a bound loop variable and an unused parser parameter removed); sim takes the same changes in Enable ruff argument, idiom and pytest-style rules (ARG, B, C4, FBT, PERF, PLW, PT, PTH, RUF, SIM and others) policyengine-sim-api#802.Testing
make testset (tests/unit,tests/contract, to_refactor and the dedupe integration test): 2,416 passed, 4 failed, the same as the base today.master.tests/unit/v2/test_stage12_comparison_models.pyfixesretention_expires_atat 2026-10-14 but leavescreated_aton the real clock, so its inserts fail the retention check since that date. It's unrelated to this PR and needs its own fix againstmaster.make typecheck-v2is clean. mypy on the 128 changed files outside that gate shows no new errors.ruff checkandruff format --check(0.15.12) are clean repo-wide./v2/openapi.jsonpreview and the legacy spec are byte-identical to the base.ruff check(includingRUF100) andruff format --checkare clean, and so are the guards and the rules tool unittests.noqacomments, apart from:contextlib.suppressrewrites;ruff formatre-wrapped once its comment was gone..github/find-api-model-versions.pychanged only in idioms; it reads onlyGITHUB_ENV, which the Actions runner provides, and only when run without--shell, which its CI caller always passes.CI complete, which fails and says why. Its full run starts once the PRs below it merge.🤖 Generated with Claude Code