Repository navigation
Conversation
anth-volk
added this pull request to stack #3917
October 14, 2026 18:47
anth-volk
force-pushed
the
ruff-complexity-application
branch
2 times, most recently
from
October 14, 2026 20:04
984feb4 to
e599f21
Compare
anth-volk
force-pushed
the
ruff-complexity-application
branch
6 times, most recently
from
October 15, 2026 00:06
44ad18f to
30cb394
Compare
anth-volk
force-pushed
the
ruff-complexity-application
branch
from
October 15, 2026 15:21
30cb394 to
1cf7ff3
Compare
anth-volk
force-pushed
the
ruff-complexity-application
branch
2 times, most recently
from
October 15, 2026 17:20
1a1e093 to
a92ce80
Compare
anth-volk
force-pushed
the
ruff-complexity-application
branch
from
October 16, 2026 05:40
a92ce80 to
86ca615
Compare
anth-volk
force-pushed
the
ruff-complexity-application
branch
from
October 16, 2026 06:00
86ca615 to
f9166fb
Compare
anth-volk
force-pushed
the
ruff-complexity-application
branch
3 times, most recently
from
October 16, 2026 06:59
fab7882 to
4a2abbc
Compare
anth-volk
force-pushed
the
ruff-complexity-application
branch
from
October 16, 2026 07:05
4a2abbc to
103c752
Compare
…mbership steps normalize_household_document now checks the supported collections, the saved SPM selection, each collection's records (identity, then contents) and the people's memberships in separate helpers, in the same order and with the same messages and key order. The two require_json_value validators check a container's members in their own helper. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… people steps translate_legacy_household now checks the source collections, translates each collection's groups (their values and member memberships) and the people in separate helpers that share a _LegacyTranslation holding the person ids, memberships and values read so far. Groups and people are read in the same order and raise the same errors. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
create_legacy_household_mapping takes the LegacyHouseholdSnapshot, which supplies the v1 country, household id and API version, instead of those three values as separate arguments. The insert statement is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
read_user_household_page and read_user_household_rows take a UserHouseholdListing (country, user, optional household, offset and limit) instead of five keyword arguments; V2UserHouseholdService.list_user_households keeps its signature and builds the listing. The query is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ne value each LegacyUserPolicyRevision carries a v1 revision's country, saved-policy id, reform label, fingerprint, source revision and changed fields through persist_legacy_user_policy_mapping, apply_existing_legacy_user_policy_mapping, validate_existing_legacy_user_policy_mapping and the mapping insert and update connectors, which also take the projected association instead of its user and policy ids. UserPolicyListing describes a requested page of associations for read_user_policy_page and read_user_policy_rows; list_user_policies keeps its signature. The statements, writes and their order are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
create_report_run takes a ReportRunPackageVersions (country package and PolicyEngine.py versions) instead of two separate arguments; it validates them in the same order and stores the same run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…on steps normalize_json_value now dispatches through an ordered table of type normalizers (float, enum, date, mapping, sequence) and unwraps scalars in its own helper. _normalize_country checks the model identity, release manifest, default dataset and region registry, normalizes parameter nodes, selects each region's dataset and normalizes each region in separate helpers, called in the same order so the same error is raised first. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
_catalog_rows now maps each staging table to a module-level generator (model, variables, parameter nodes, parameters, parameter values, datasets and regions) instead of seven nested closures. Each generator stays lazy and yields the same rows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ne value _log_copy_operation and _log_mirror_event take the outcome, write sources, destination result and failure category as one frozen outcome value instead of five or six keyword arguments. The logged records are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
mirror_pending_user_policy_events_after_commit takes its event service, reform snapshot loader and mirror factory as one optional UserPolicyMirrorCollaborators value; any collaborator left None still takes its default. _log_mirror_operation takes the mirrored revision and the mirror outcome as two values instead of nine keyword arguments. The policy routes and the tests pass the new values; the logged records are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
create_simulation_run and create_report_output_run take an optional NewSimulationRun or NewReportOutputRun holding the run's status, trigger, output, error, source run, spec snapshot, version manifest and fixed ID, with the same defaults, instead of up to ten keyword arguments. The report output service and the tests build the new values; the stored rows are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
build_report_spec takes an optional EconomyReportSettings instead of three keyword arguments, with the same defaults; the spec check builds it from the stored economy spec. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The simulation lookup was only ever called with for_update=True, so it is renamed _lock_existing_simulation and always locks. PolicyService's _create_new_policy had no callers and is removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…own steps _decode_mirror_event now validates the changed fields and the event type against them in two module helpers, in the same order and with the same messages. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
GatewayAuthTokenProvider takes an optional GatewayAuthCredentials (issuer, audience, client ID, client secret and secret resource) instead of five positional arguments; any setting left None is still read from its environment variable. The tests build the credentials. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
find_unrecognized_household_inputs hands each known entity group to _find_unrecognized_entity_inputs, which reports each variable through _unrecognized_variable; findings keep their order. get_safe_json writes infinities through _safe_json_number. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Calling app.exception_handler(...) on the module-level handlers, as the nested decorators did, keeps their types acceptable to mypy; the handlers are registered the same way. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Cover the paths the refactor touched that no test reached: the 128 character catalog version limit, the one-date-range legacy period rule, the metadata page bounds, the five-digit place FIPS code, enum values that are also tuples or dates, and invalid migration flags in the log context. The new limit and enum tests pass on the pre-refactor code too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#3918 added _serialize_region_filter_value, which compares against the literal 255 (PLR2004). Name it MAX_REGION_FILTER_VALUE_LENGTH, the size of the catalog's filter_value column; the error message text is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Management API client compares the token response with HTTPStatus.OK and retries a deletion after HTTPStatus.UNAUTHORIZED, as the gateway token provider does. HTTPStatus is an IntEnum, so the comparisons are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
user_resource_operation maps each typed service failure #3891 added to a status, message and headers, and logs persistence and unexpected failures by event name only. The new characterization test pins all eighteen cases, including subclasses that must match their base's clause and an IntegrityError that must win over the SQLAlchemyError clause, and passes on the current code. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
user_resource_operation now runs the service call and hands any failure to _user_failure_response, which answers with the first UserResourceFailure in USER_RESOURCE_FAILURES that the error matches: its status, the error's own or a fixed message, the 401's WWW-Authenticate challenge, and a logged event for persistence failures. The entries follow the order of the old except clauses, and an unmatched failure is still logged and answered with the generic 500, so each failure gets the same response and log record; the pinned failure-mapping test passes unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The user-report and user-simulation create routes call a module helper that checks the body and query countries agree and runs the creation, as the user-household and user-policy routes do. The /v2/me router builds its signed-in-only dependency through _signed_in_user_dependency and runs the upgrade through _upgrade_account. The three builders #3891 added stay within the complexity limit (C901); route registration, order, signatures and the OpenAPI documents are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#3891 added include_compute to get_migration_context, giving it six arguments (PLR0913). Its db_entity and sim_flow overrides were never passed: every caller, including the request logging and the tests, lets the route group's configuration name them. The overrides go, so the context takes the entity and flow from the route group and, with include_compute=False, records no flow; every logged context is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…value each The PLR0913 findings in the code #3891 added: - The user-household and user-policy services, their route Protocols and routes take an optional UserHouseholdFilter or UserPolicyFilter (the v2 and v1 ids to narrow a listing to) instead of two keyword arguments, as the metadata layers take a ParameterValueFilter. The routes build the filter from the same query fields. - read_user_report_rows and read_user_simulation_rows take a UserReportListing or UserSimulationListing, as the household and policy row readers take their listings. - create_user_identity takes the UserPrincipal whose issuer, subject and email it stores, instead of the three fields. The statements, their parameters and the OpenAPI documents are unchanged. The route and service tests, and the concurrent sign-in test's stand-in, use the new arguments. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
get_household_under_policy and _calculate each caught every exception and passed it to one mapping helper. Each now has two except clauses: - one for the error types the route expects (household or policy not found and unrecognized inputs for a stored household; unrecognized inputs and situation parsing errors for a request), which the helper maps to the same 404 and 400 responses as before; - then except Exception, which returns the SPM error response when the error or its cause is an SPM error, and otherwise calls module_logger.exception() itself and returns the 500 response, as the code did before the complexity refactor. Ruff accepts a broad except whose handler logs the traceback, so this removes both BLE001 suppressions. Responses, status codes, log messages and their order are unchanged, and the complexity rules still pass. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
_normalize_region took its PolicyEngine.py region as Any. It now takes a private _SourceRegion protocol that declares the two attributes it reads directly, code and region_type, as read-only properties; it reads every other attribute through getattr with a default, as before. This removes the ANN401 suppression without changing behaviour. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…istence test mirror_legacy_user_policy_in_session imports mirror_legacy_policy_in_session from the policies services module when it runs, because #3920 made that module a banned module-level import. The test's autouse fixture replaced the function as an attribute of the user-policies services module, which no longer has one, so all 13 tests errored at setup. The fixture now replaces it in the policies services module, which the deferred import reads at call time. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
anth-volk
force-pushed
the
ruff-complexity-application
branch
from
October 20, 2026 22:05
5f74b2a to
7030d9c
Compare
This branch was successfully 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 #3930
Summary
Phase 1 step 1.8, group 8b, part 2 of 3: the rest of
policyengine_api/, refactored within ruff's complexity limits. Stacked on #3932.tests/fixtures/recording_session.pyrecords every statement, compiled for PostgreSQL, and every ORM write, in order.asgi_factory, complexity 34 and 113 statements):exceptprecedence.get_household_under_policyand_calculateeach catch the error types they expect in one clause, which a helper maps to the same 404 and 400 responses. A followingexcept Exceptionreturns the SPM error response when the error or its cause is an SPM error, and otherwise callsmodule_logger.exception()itself and returns the 500 response._copy_saved_policy_events_to_v2, which Make dual-write log failed v2 copies instead of returning HTTP 503 #3959 added.run_v2_operation).ComparisonReportRecord.validate_statekeeps its Pydantic signature, with its checks split into helpers.ParameterValueListingQuerydependency; its OpenAPI is byte-identical._normalize_regiontakes a private_SourceRegionprotocol that declares the two region attributes it reads directly,codeandregion_type; it reads the rest throughgetattrwith a default, as before.NewReportOutputRun,NewSimulationRunandReportRunPackageVersions.ServedRequestvalue.GatewayAuthTokenProvidertakesGatewayAuthCredentials.policy_service._create_new_policy, which had no callers, and an always-true lock flag.HTTPStatusmember, with messages unchanged._serialize_region_filter_value, so flat membership lists such as the England filter are stored as JSON arrays.255limit is nowMAX_REGION_FILTER_VALUE_LENGTH, with the message text unchanged.Inline suppressions
This PR adds no inline suppression of its own. It removes 2 and moves 3 existing ones:
FBT001, FBT002on the FastAPIcurrentquery parameter infastapi_routes/v2/metadata/parameter_routes.py, which theParameterValueListingQuerydependency replaces.BLE001infastapi_routes/v2/households/routes.pyand the one infastapi_routes/v2/policies/routes.pybecome one in the sharedfastapi_routes/v2/errors.py, with the same reason (return a secret-safe typed error).ANN401onasgi_factory'swsgi_appparameter and theBLE001around telemetry inmigration_logging.py.2026-10-20 update
Three commits on top of the branch:
4315457e7Catch expected household calculation errors by type (BLE001): the split had folded the household routes' specificexceptclauses into oneexcept Exception, with aBLE001suppression in each of the two handlers. The handlers now catch the expected types first and log the unexpected failures directly, as described under "Flask routes". Responses, status codes and log messages are unchanged, and the complexity rules still pass.18c8b0c4cType the catalog region parameter with a private protocol (ANN401):_normalize_region(source_region: Any)and itsANN401suppression are replaced by the_SourceRegionprotocol.ccf4298feReplace the policy mirror where it is defined in the user-policy persistence test: Enable ruff structure and import rules (INP, PLC, SLF, N, A, FAST, E) #3920 mademirror_legacy_user_policy_in_sessionimportmirror_legacy_policy_in_sessionwhen it runs, because the policies services module is a banned module-level import. The new characterization test still replaced the function as an attribute of the user-policies services module, so all 13 of its tests errored at setup. Its fixture now replaces the function in the policies services module.Lines containing
# noqain Python files (git grep -c '# noqa' -- '*.py', summed):BLE001, 1ANN401)2026-10-20: rebased onto #3959
#3959 makes dual-write log a failed v2 copy instead of returning 503. It moved the saved-policy copy into its own helper,
_copy_saved_policy_events_to_v2, which logs instead of returning a response. Two of this PR's commits conflicted with it:320ca6558Share the saved-policy write configuration and failure steps:_mirror_user_policy_eventsis dropped, and the shared steps call Make dual-write log failed v2 copies instead of returning HTTP 503 #3959's helper._UserPolicyWriteAttemptand the named 503 comparison are kept.MAXIMUM_LEGACY_INTEGER_ID, because Make dual-write log failed v2 copies instead of returning HTTP 503 #3959's_safe_legacy_integer_idalso checks policy IDs.74d912c20Group saved-policy mirror collaborators: the groupedUserPolicyMirrorCollaboratorsis now passed in Make dual-write log failed v2 copies instead of returning HTTP 503 #3959's helper.f2ea2c97a):test_committed_write_without_a_mirror_is_mirror_unavailableasserted the 503 that Make dual-write log failed v2 copies instead of returning HTTP 503 #3959 removed. Its six cases are nowtest_committed_write_without_a_v2_copy_is_logged_and_still_succeeds, which captures Make dual-write log failed v2 copies instead of returning HTTP 503 #3959's behaviour:missing_mirror_revisionorunexpected, and logs nothing extra when the mirroring service has already logged the failure.Checks at this tip (
ccf4298fe):pytest tests/unitgave 3,130 passed, 0 failed. Ruff, the quality guards and the rules guard are clean, and rendered rules are fresh.Testing
2026-10-20 update. At this tip (
4fab246dc), on Python 3.12 with theuv.lockdependencies (uv sync --frozen --extra dev --python 3.12):pytest tests/unit: 3,120 passed. Before the test fix in4fab246dc, the same run gave 3,107 passed and the 13 setup errors described above; they also occur at the previous tip,1ff10c1ba.tests/unit/routes/test_household_route_error_responses.py, 15) and the catalog extraction tests pass.ruff format --check .andruff check .(ruff 0.15.12) are clean, including C901, PLR0911, PLR0912 and PLR0915 onroutes/household_routes.py.python scripts/run_quality_guards.pyandpython -m scripts.rules guard --base-ref origin/ruff-complexity-economypass, andpython -m scripts.rules renderleaves no diff.mypy(the configured files): no issues. mypy onroutes/household_routes.pyanddata/v2/catalog/extraction.pyreports the same messages as before these commits.Earlier notes:
make testset at this branch's tip: 2,848 passed, which is the base plus part 1's 166 and this PR's 249.make typecheck-v2is clean. mypy on the 28 changed application files outside its file list gives identical output to the base.ruff check,ruff format --checkand the quality guards (migration-contracts,rules-registry,ci-scripts) pass./v2/openapi.jsonpreview, the legacy spec and every existing model and adapter schema are byte-identical, with and withoutOLD_SIMULATION_GATEWAY_URLset.tests/integration/test_v1_user_policy_dual_write.pyneeds MySQL and PostgreSQL; its 6 call sites were updated.CI completeruns until the PRs below merge.🤖 Generated with Claude Code