Skip to content

Enable ruff argument, idiom and pytest-style rules (ARG, B, C4, FBT, PERF, PLW, PT, PTH, RUF, SIM and others) - #3924

Draft
anth-volk wants to merge 21 commits into
masterfrom
ruff-idioms-arguments
Draft

anth-volk wants to merge 21 commits into
masterfrom
ruff-idioms-arguments

Conversation

@anth-volk

@anth-volk anth-volk commented Oct 14, 2026 •

Copy link
Copy Markdown
Collaborator

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"].

  • Test stand-ins exempt from unused-argument rules (added 2026-10-16): test fakes and stand-ins mirror the signatures of what they replace, because callers pass those arguments by keyword.
    • ARG001, ARG002 and ARG005 join 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.
    • Application code doesn't get this exception. Its findings are fixed in code, or kept inline where listed under "Inline suppressions".
  • Unittest exemption (decided for this group): the shared rules tool's tests use unittest on purpose, because the tool needs only the standard library. scripts/rules/tests/** is exempt from ruff's pytest-style rules (PT), registered as api.quality.unittest-ruff-exemptions.
  • Rules: select gains ARG, ASYNC, B, C4, FBT, PD, PERF, PGH, PLW, PT, PTH, RUF and SIM. All 912 findings are fixed, covered by the tests' file-level exceptions, or kept with one of the 8 inline suppressions listed below. There's one commit per family.
  • Unused arguments (ARG, 468):
    • 118 tests now request side-effect fixtures with @pytest.mark.usefixtures; the collected test IDs are identical.
    • Unused *args/**kwargs became *_args/**_kwargs. A named lambda or callback parameter is underscored only where every caller passes it positionally, as in the v2 Alembic environment's include_object hook.
    • Methods that override a base method or implement a protocol are decorated with @override from typing_extensions, which works on Python 3.11 (typing.override needs 3.12). Ruff doesn't report unused arguments of an @override method. This covers every DisabledCacheBackend method in runtime_cache/fake.py, and RegistryCapability.get_spm_capability in worker_spm_release.py, which now subclasses the SPMCapabilitySource protocol explicitly.
    • typing-extensions is now a direct dependency (>=4.4,<5; override was added in 4.4). It was already installed indirectly at 4.15.0. The uv.lock diff only records the new direct dependency: no package version changes, and the lock was written with uv 0.12.1, the version CI pins, so its format revision is unchanged.
    • Flask views that receive the <country_id> URL variable by keyword keep an inline reason (see "Inline suppressions").
  • Keyword-only booleans (FBT): PolicyEngineCountry.calculate and prepare_calculation (spm_requested, prepared), EconomyService._setup_sim_options, and the cache backend protocol's pipeline(*, transaction=True). Every caller already passed these by keyword. The FastAPI current query parameter and Alembic's positional include_object hook are kept, with reasons.
  • Bugbear (B):
    • B904: the simulation and report-output routes' create and update handlers now raise BadRequest(...) from e. The 400 responses are unchanged; only the traceback's chaining text changes.
    • B905: zip(..., strict=True) where the lengths are fixed by literals.
    • B023: loop variables bound in closures that only run within their own iteration.
  • Module-level state (PLW0603): no function rebinds a module global any more.
    • readiness.py: the lock and boolean pair is one threading.Event, set at import because the default is ready. mark_not_ready clears it and mark_ready sets it. is_ready still returns False without running the configuration check when the event is clear, and runs the check otherwise.
    • data/orm.py: the Cloud SQL connector, engine and session factory are fields of one private _CloudSqlState instance.
    • data/v2/database.py: the engine, the ID of the process that created it, its URL fingerprint and the session factory are fields of one private _V2EngineState instance. _state_lock and the fork handling are unchanged.
    • Two tests reach these names. tests/unit/data/test_sqlalchemy_v2.py patches the orm state, and tests/unit/v2/test_database.py reads the v2 engine's process ID. Both now use the state objects. No test patches the readiness state.
  • Best-effort swallows (SIM105): Enable ruff exception rules (TRY, EM, BLE) #3913 and Enable ruff security, logging and debugging rules (S, T20, LOG, G, DTZ, ERA, TD, FIX, EXE) #3915 already turned every try: … except Exception: pass around a telemetry or logging call into with contextlib.suppress(Exception):, with the reason in a comment above it. Here SIM105 converts the two remaining try/except/pass blocks, which catch specific exceptions: country.py (TypeError, ValueError, OverflowError) and reform_impacts_service.py (CacheCoordinationError). No suppression changes.
  • Idioms: 154 dict() calls become literals, plus comprehensions (C4, PERF), simplified conditions and combined with statements in the same order (SIM), ClassVar annotations, explicit Optional types, raw regex patterns and sorted __all__ (RUF), Path.open (PTH) and check=False on subprocess.run (PLW1510).
  • Non-ASCII digits in tests (RUF001): the tests that check numeric identity use Arabic-Indic and full-width digits as inputs. They're now written as escape sequences: named escapes such as "\N{FULLWIDTH DIGIT ONE}" for single digits, and \u escapes, with a comment, for the two ten-digit translation tables.
  • Blocking read in async code (ASYNC240): scripts/measure_cloud_run_runtime.py reads and parses the payload file in main() before asyncio.run(...), and passes the parsed payload to _run().
  • Pytest style (PT): 37 pytest.raises gain match= 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.
  • Registry: api.quality.ruff-lint now 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.

Inline suppressions

This PR adds 8 inline suppressions; it adds no file-level exception for application code.

Location Code Reason Why no code change or setting
policyengine_api/routes/household_routes.py, get_calculate and get_calculate_full ARG001 Flask passes the <country_id> URL variable by keyword; validate_country checks it. Renaming or removing the parameter breaks Flask's call. A file-level exception isn't allowed for application code.
policyengine_api/routes/user_profile_routes.py, get_user_profile and update_user_profile ARG001 The same <country_id> URL variable, also checked by validate_country. As above.
migrations/v2/env.py, _include_application_object(..., _reflected, ...) FBT001 Alembic calls this include_object hook with positional arguments. A keyword-only parameter breaks Alembic's call, and the file isn't one that file-level exceptions may cover.
policyengine_api/fastapi_routes/v2/metadata/parameter_routes.py, current: bool = False FBT001, FBT002 A FastAPI query parameter. #3933 replaces the parameter list with one ParameterValueListingQuery dependency, which removes this suppression.
policyengine_api/services/economy_comparison.py, two MicroSeries(...).values reads PD011 MicroSeries overrides .values, and .to_numpy() emits a different warning. #3936 deletes the module, which has no callers.

Suppression counts

Counted as lines containing # noqa in Python files (git grep -c '# noqa' -- '*.py', summed). The counts are one lower than before, because #3959 merged two BLE001 suppressions on master:

Base (#3920) This PR before 2026-10-20 This PR now
Lines with # noqa 96 125 98
Added by this PR 35 (and 6 E402 removed) 8 (and 6 E402 removed)

2026-10-20: rebased onto #3985

#3985 (v2 table privileges) added new application code. This PR's rules found three findings in it, and commit d8a153bef fixes them with code changes, adding no suppressions:

  • PTH123: the privilege reconciliation appends its GitHub step summary through Path.open.
  • PERF401: the annotation scan in privilege_requirements.py extends its list from one generator.
  • C420: the manifest proof test builds its no-access map with dict.fromkeys.

Behaviour is unchanged, and #3985's 70 privilege tests pass. The only environment variable the changed code reads is GITHUB_STEP_SUMMARY, which the GitHub Actions runner sets for every step; how it is read is unchanged. The suppression counts are unchanged too.

2026-10-20 update: 27 fewer suppressions

Four commits on top of the branch remove 27 of the 35 inline suppressions this PR added. The earlier commits are unchanged.

  1. 023b02420 Keep process state in objects instead of rebinding module globals (PLW0603): removes 11. See "Module-level state" above.
  2. 14f29aeab Mark method overrides with typing_extensions.override (ARG002): removes 9, and adds the typing-extensions direct dependency.
  3. e319ee6d6 Write the non-ASCII test digits as escape sequences (RUF001): removes 6. The parsed ASTs of all four test files are identical to the previous version, so every string constant and test parameter is unchanged.
  4. f6d25ebb6 Read the load generator's payload before starting the event loop (ASYNC240): removes 1.

Testing

2026-10-20 update. At this tip (f6d25ebb6), on Python 3.12 with the uv.lock dependencies (uv sync --frozen --extra dev --python 3.12):

  • ruff format --check . and ruff check . (ruff 0.15.12, with RUF100) are clean.
  • python scripts/run_quality_guards.py and python -m scripts.rules guard --base-ref origin/ruff-structure-imports pass, and python -m scripts.rules render leaves no diff.
  • mypy (the configured files): no issues in 167 source files. mypy on data/orm.py, data/v2/database.py, readiness.py, runtime_cache/fake.py and worker_spm_release.py reports nothing new.
  • pytest tests/unit: 2,686 passed.
  • Environment variables: the changes to data/orm.py, data/v2/database.py and readiness.py add, remove and rename none, and each is read in the same place and way as before.
    • orm.py reads POLICYENGINE_DB_INSTANCE_CONNECTION_NAME and POLICYENGINE_DB_PASSWORD (both required), and POLICYENGINE_DB_USER and POLICYENGINE_DB_NAME (both default to policyengine), when the engine is first built. It still calls load_dotenv() at import.
    • database.py and readiness.py read none directly. They call the same settings loaders under the same conditions.

2026-10-19 update. The stack was restacked onto #3915, which now converts the last best-effort blocks and removes the dashboard experiment, so this PR's contextlib.suppress commit was dropped and its SIM105 change shrank to the two blocks above. At that tip (7e92040), ruff check (with RUF100) and ruff format --check were clean and the quality guards passed. At the top of the stack (#3938, 7b23281), the make test set passed: 3,197 tests on Python 3.12 with the uv.lock dependencies. The earlier notes below describe the previous tips.

🤖 Generated with Claude Code

@anth-volk
anth-volk added this pull request to stack #3917 October 14, 2026 15:08
@anth-volk anth-volk changed the title ruff idioms arguments Enable ruff argument, idiom and pytest-style rules (ARG, B, C4, FBT, PERF, PLW, PT, PTH, RUF, SIM and others) Oct 14, 2026
@anth-volk
anth-volk force-pushed the ruff-idioms-arguments branch 2 times, most recently from 7b5a851 to d89b4b5 Compare October 14, 2026 16:59
@anth-volk
anth-volk force-pushed the ruff-idioms-arguments branch from d89b4b5 to 24a3be7 Compare October 14, 2026 18:08
@anth-volk
anth-volk force-pushed the ruff-idioms-arguments branch 2 times, most recently from 1d0d644 to 6ad4b2c Compare October 14, 2026 20:04
@anth-volk
anth-volk force-pushed the ruff-idioms-arguments branch 7 times, most recently from 29808ba to aae6fe4 Compare October 15, 2026 15:21
@anth-volk
anth-volk force-pushed the ruff-idioms-arguments branch from aae6fe4 to bc3381a Compare October 15, 2026 15:45
@anth-volk
anth-volk force-pushed the ruff-idioms-arguments branch from bc3381a to 0ae1220 Compare October 15, 2026 17:21
@anth-volk
anth-volk force-pushed the ruff-idioms-arguments branch from 0ae1220 to cbac3c2 Compare October 16, 2026 05:40
@anth-volk
anth-volk force-pushed the ruff-idioms-arguments branch 2 times, most recently from 1827772 to a4541ae Compare October 16, 2026 06:40
@anth-volk
anth-volk force-pushed the ruff-idioms-arguments branch from 869fee2 to 5791dc2 Compare October 20, 2026 18:00
anth-volk added a commit that referenced this pull request Oct 20, 2026
#3924 moved the payload file read out of the async _run() into main(), so
_run() now takes the parsed payload as its second argument. The test reads
the same payload file and passes it in.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@anth-volk
anth-volk force-pushed the ruff-idioms-arguments branch from 5791dc2 to d8a153b Compare October 20, 2026 18:29
anth-volk added a commit that referenced this pull request Oct 20, 2026
#3924 moved the payload file read out of the async _run() into main(), so
_run() now takes the parsed payload as its second argument. The test reads
the same payload file and passes it in.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Base automatically changed from ruff-structure-imports to master October 20, 2026 22:05
anth-volk and others added 21 commits October 21, 2026 02:05
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. Groups 5 and 6 already gave the best-effort
telemetry and logging blocks that form.

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>
…W0603)

Remove the 11 PLW0603 suppressions without changing behaviour:

- readiness: the lock and boolean pair becomes one threading.Event, set at
  import because the default is ready. mark_not_ready clears it, mark_ready
  sets it, and is_ready still runs the configuration check only when it is
  set.
- data/orm: the Cloud SQL connector, engine and session factory are fields
  of one private _CloudSqlState instance.
- data/v2/database: the engine, its process ID, its URL fingerprint and the
  session factory are fields of one private _V2EngineState instance.
  _state_lock and the fork handling are unchanged.

The two tests that read or patch these names now use the state objects.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Ruff does not report unused arguments of a method decorated with
@OverRide, so this removes the 9 ARG002 suppressions:

- runtime_cache/fake.py: every DisabledCacheBackend method overrides
  InMemoryCacheBackend and is decorated with @OverRide.
- worker_spm_release.py: RegistryCapability now subclasses the
  SPMCapabilitySource protocol explicitly, and get_spm_capability is
  decorated with @OverRide.

typing.override needs Python 3.12; typing_extensions.override also works on
3.11, the oldest version the project supports. typing-extensions was already
installed as an indirect dependency (4.15.0) and is now declared directly as
typing-extensions>=4.4,<5, the release series that has override. uv.lock
records the new direct dependency only; no package version changes. The lock
was written with uv 0.12.1, the version CI pins, so its format revision is
unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The tests that check numeric identity use Arabic-Indic and full-width
digits as inputs. Writing them as escape sequences instead of literal
characters removes the 6 RUF001 suppressions: single digits use named
escapes such as "\N{FULLWIDTH DIGIT ONE}", and the two ten-digit
translation tables use \u escapes, with a comment naming them.

The parsed ASTs of all four files, and so every string constant and test
parameter, are identical to the previous version.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…NC240)

main() now reads and parses the calculate payload file before
asyncio.run(), and passes the parsed payload to _run(). The file is still
read once, before any request, so the requests and output are unchanged.
This removes the ASYNC240 suppression for a blocking read inside an async
function.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The privilege reconciliation appends its GitHub step summary through
Path.open, the annotation scan in privilege_requirements extends its list
from one generator, and the manifest proof test builds its no-access map
with dict.fromkeys. Behaviour is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@codecov

codecov Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 73.05389% with 45 lines in your changes missing coverage. Please review.
✅ Project coverage is 84.74%. Comparing base (f117791) to head (5ae76f9).
⚠️ Report is 28 commits behind head on master.

Files with missing lines Patch % Lines
policyengine_api/services/economy_comparison.py 31.03% 20 Missing ⚠️
policyengine_api/country.py 41.66% 6 Missing and 1 partial ⚠️
policyengine_api/data/orm.py 76.19% 3 Missing and 2 partials ⚠️
policyengine_api/data/v2/database.py 93.54% 0 Missing and 2 partials ⚠️
policyengine_api/routes/policy_routes.py 33.33% 0 Missing and 2 partials ⚠️
policyengine_api/services/economy_service.py 0.00% 0 Missing and 2 partials ⚠️
.../payload_validators/validate_set_policy_payload.py 0.00% 1 Missing and 1 partial ⚠️
policyengine_api/constants.py 50.00% 1 Missing ⚠️
policyengine_api/data/congressional_districts.py 0.00% 0 Missing and 1 partial ⚠️
...licyengine_api/data/v2/privilege_reconciliation.py 50.00% 1 Missing ⚠️
... and 2 more
Additional details and impacted files
@@             Coverage Diff             @@
##           master    #3924       +/-   ##
===========================================
+ Coverage   49.20%   84.74%   +35.53%     
===========================================
  Files         242      258       +16     
  Lines       14307    15676     +1369     
  Branches     2357     2640      +283     
===========================================
+ Hits         7040    13284     +6244     
+ Misses       6637     1623     -5014     
- Partials      630      769      +139     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

This branch was successfully deployed

1 active deployment
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Enable ruff argument, idiom and pytest-style rules (ARG, B, C4, FBT, PERF, PLW, PT, PTH, RUF, SIM and others)

1 participant