Skip to content

Fix Ruff's complexity findings (C90, PLR), leaving only the permanent ignores - #71

Merged
anth-volk merged 107 commits into
mainfrom
claude/ruff-complexity
Nov 3, 2026
Merged

anth-volk merged 107 commits into
mainfrom
claude/ruff-complexity

Conversation

@anth-volk

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

Copy link
Copy Markdown
Contributor

Fixes #53

Fixes #70

What this does

The last of the pull requests stacked on #55. It fixes the 82 findings left on this branch in C90 and PLR (89 on #55). Ruff then ignores only COM812, ISC001, D203, D213 and CPY, plus the registered per-file ignores, as #53's end state requires, so it closes #53. Stacked on #69. Ruff keeps its default limits, as the simulation API and the Public API do. Behaviour is unchanged.

  • Complexity (C901, PLR0911, PLR0912, PLR0915): long functions are split into private helpers in the same module, keeping the order of side effects, the exception handlers around the same calls, and the early returns' results:
    • the host runtime's run (_initialize_modules, _start_workers, _serve, _shut_down, _send_reply);
    • the Hugging Face release writer's apply_release_change (_attempt_release_change, _read_head_state, _release_order, _checked_record, _changed_record, _commit_violations, _commit_release_record, and three private dataclasses);
    • the Hugging Face module's query (an exactly equivalent table of command handlers) and its delivery (_deliver_leased, with private dataclasses for a delivery's work and a job's result);
    • the interface's release-record parser, wire_value, the sanitizer, bundles, hub, submissions client, collector delivery, telemetry lifecycle and Orrery upload;
    • in tests, the fake collector's request handler, now a module-level class, and the longest tests.
  • Argument counts (PLR0913, PLR0917):
    • Grouped where every caller is in this repository: lease renewal settings become a LeaseRenewal dataclass, which HeldLeases and the submissions delivery take, plus a few test helpers.
    • 15 # noqa, each with its reason above the def:
      • published signatures other code relies on: EmitterClient.start, add_build and LocalTelemetryEmitter.start;
      • the standard library's redirect_request;
      • constructors and queue methods that tests call with their arguments by name: ServiceRuntime, HuggingFaceModule, CollectorSubmissionClient, stage_run_files, enqueue_job, claim_job and finish_job. These could be grouped if those tests change too;
      • four pytest test functions, whose fixtures and parametrized values pytest passes by name.
  • PLR2004 (18): named constants. HTTP statuses use http.HTTPStatus members throughout, as core/auth.py already does. core/http_status.py defines the retryable client errors and is_permanent_client_error once, for the submissions client and the telemetry collector delivery; the submissions client's RETRYABLE_STATUSES keeps its name (round 1).
  • PLR0124: value == value and abs(value) != inf becomes math.isfinite(value), which is the same for floats.
  • C90 and PLR leave the ignore list, which now holds only the permanent ignores. The README and emitter.quality.ruff-lint no longer mention a temporary list.

Two helper agents made these changes from a brief I gave them, one for package code and one for tests, with the rules above. Their refactors were checked with Ruff, and with the tests they changed. CI's test jobs check the package refactors.

Test-first record

There is no red step, since nothing changes behaviour.

Commit Result
bbfc9cf The fixes (committed as work in progress), and the temporary list emptied ruff check . and ruff format --check . pass with only the permanent ignores.
06b1d2c Merge of #69's round 1 Two conflicts, where #69 changed code this branch had moved into helpers: _run_files_to_commit's callers now pass its flags by keyword inside _deliver_leased, and the fake collector's socket path uses pathlib in _add_tls_upload_server. Every test function that changed passes by node ID (24 cases), and so does every test that builds the refactored fake collector (25 cases).
ce1fce5, 45208ba The fragment, and the wording without the temporary list tools/bump-version.py --check passes; the five guards pass with GITHUB_BASE_REF=main.

Review round 1:

Commit Result
291c23f Tests of two refactored branches An unknown Hugging Face hand-over command raises ValueError; a 403 to the events request makes only that run local with collector_authorization_rejected, keeps its events and asks the collector nothing more. Red: each failed when its branch was changed in a scratch copy (the command answered; the 403 handled as another client error). Green: both pass.
30d26bd The review's other points The stage and hand_over test helpers raise TypeError for an option they don't read. The four test suppressions say they are pytest test functions. _ReleaseOrder stays frozen with a read-only mapping, and the commit message uses a copy. One shared client-error check, and HTTPStatus members. ruff check ., ruff format --check . and the guards pass; the 23 tests that call the two helpers and the two new tests pass (27 cases).

No other test was run locally: the package refactors are left to CI's test jobs.

CI

No workflow, trigger or script changes, and no environment variable or secret is read differently.

Release

The fragment is changelog.d/ruff-complexity.changed.md. With #65's added fragment below it in the stack, merging releases a minor version (0.12.0); on its own this fragment would give a patch bump.

🤖 Generated with Claude Code

anth-volk and others added 30 commits October 30, 2026 21:30
- EM101 and EM102: Ruff's fix assigns each message before the raise;
  the variable is named error_message rather than Ruff's msg.
- RSE102: no parentheses on a bare raise (Ruff's fix).
- TRY301: checks that raised inside a try block move into helper
  functions the block calls, in the host's client, runtime, launcher and
  entry point, the interface's launcher and transport, the Orrery
  delivery, the Hugging Face request parser, and one startup test.
- TRY300: the host entry point and the Orrery delivery return success
  from an else block.
- TRY004: TypeError where only a catch-all handler sees the exception
  (the runtime's request reader, the entry point's module list, the
  Orrery upload list, the telemetry block request). Elsewhere the type
  stays, with a reason: the interface README promises ValueError for an
  invalid request field, the client reports the exception's type name,
  the JSON column's readers handle ValueError, and the Alembic
  environments report a missing connection.
- Ruff no longer ignores EM, RSE and TRY.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- D209 and D202: Ruff's fixes put closing quotes on their own line and
  remove blank lines after function docstrings.
- D101, D102, D103, D105 and D107: docstrings for the public classes,
  methods, functions, magic methods and __init__ methods that had none,
  describing what the code does.
- D205, D401 and D404: one-sentence summaries in the imperative mood on
  the first line, with the rest of each docstring kept as its
  description.
- Two docstrings replace a placeholder body (`pass` in BuildCompleted,
  `...` in GraphTransport's methods), which PIE790 would otherwise flag.
  With docstrings removed, every changed module's syntax tree matches
  the base branch's.
- Ruff no longer ignores D.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The host entry point: module settings that are not an object end
  startup with exit code 1 and the fixed "startup_failure" text on
  stderr, and no module is loaded.
- The Orrery delivery: an upload answer whose uploads value is not a
  list keeps the job pending with the
  publication_invalid_evidence_or_response code, after one request.
- The telemetry block request: a blocking_gate_ids value that is not a
  list queues no event and leaves the lifecycle unchanged.

The tests pass on #55's code, where these checks raised ValueError, and
on this branch. The startup test's variable is named startup_reason.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The 57 variables that hold a startup reason (for EmitterStartupError
  and ServiceStartupError) are named startup_reason, and the ones that
  hold a refusal code (for RequestRefusedError and _refuse) are named
  refusal_code.
- The Orrery helpers take only the values they check, typed as the
  unchecked JSON they are: _upload_list(object), _check_listed_name
  (object), _check_upload_url(SplitResult) and _check_publication_answer
  with the two answered values. The .get and urlsplit calls stay at the
  call sites, so every exception is raised where it was.
- The suppression reasons say what the code does: the interface
  constructors raise ValueError for every invalid value, and the JSON
  column raises the same type as json.loads for invalid JSON.

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

- TC001, TC002, TC003: Ruff's fixes move the 65 imports used only in
  annotations into each module's TYPE_CHECKING block, and TC006 quotes
  the 15 types passed to cast(). No module imports a moved name from
  the module that moved it, no test patches one, and every name
  Microcosm imports from the emitter still resolves.
- PLC0414: the seven modules that re-export interface names with
  "import X as X" list every public name in __all__ instead, so type
  checkers of this py.typed package still treat them as exported.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The root conftest.py moves to tests/conftest.py, where the test
  exemptions apply, as in both services, which have no root conftest.
  testpaths is tests, so its autouse fixture still applies to every test
  (pytest --fixtures lists it from tests/conftest.py). The isolation rule
  names the new path.
- banned-module-level-imports lists microcosm_emitter.host.__main__,
  which only `microcosm-emitter host` imports, inside main.
- auth.py imports threading at module level.
- cli.py keeps three in-function imports with `# noqa: PLC0415` and the
  reason: the collector-origin and authentication modules load only when
  their command runs, so `microcosm-emitter host` never loads them, and
  the telemetry-token tests patch core.auth's functions, which the
  command must look up when it runs. TELEMETRY_SCOPE, a constant, is
  imported at module level.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- ANN401: parameters that accept any value and only inspect it are
  typed object. JSON values use the interface package's new JsonValue
  alias, which wire_value now returns; three callers narrow it with
  cast. Hugging Face Hub objects are typed with the Hub's own classes,
  imported only under TYPE_CHECKING, since the functions still import
  them at runtime only when called.
- ANN001, ANN002, ANN003, ANN201, ANN202, ANN204: the missing parameter
  and return types, including the standard library's signature for
  redirect_request, sqlalchemy's Dialect, and -> None on __init__.
- With annotations, TYPE_CHECKING blocks, typing imports and casts
  removed, the syntax tree of every changed module matches the base.
- Ruff no longer ignores ANN, PLC or TC.

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

- TelemetryRecorder.transition_stage and StageTransition (interface):
  how each status is mapped, that an update for another stage finishes
  the current one first, that only a start makes a stage current (and is
  recorded as progress for the current stage), and that completed or
  failed ends the current stage.
- calibration_progress and transition_calibration_progress (interface
  and emitter client): the service records only calibration_epoch
  events, moves to the calibrating stage only when the run is not there
  already, and the call returns True for an ignored event too.
- GraphPublicationDelivery.__init__ names the three accepted local
  hosts; CollectorSession.invalidate gives the answers that come before
  token_rejected; StageDatasetBundle refuses a whitespace-only commit
  message; HuggingFaceSettings calls the file the event queue file.
- The changelog fragment says only function and method summaries are
  imperative, as D401 checks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- BLE001: the broad excepts stay, since narrowing them would change
  what reaches the build, the host or the queue; each has
  `# noqa: BLE001` and its reason above it. One try/except/pass becomes
  contextlib.suppress(Exception) (also S110).
- S101: 19 asserts in package code become explicit checks raising the
  same AssertionError with the same message, so they also hold under
  python -O. Two stay, with reasons: an explicit raise there would
  trigger TRY301 or TRY004.
- T201: microcosm_emitter.cli and microcosm_emitter.host.__main__, which
  run as programs, may print (emitter.quality.program-ruff-exemptions,
  as in the Public API). Elsewhere the prints are warnings and answers
  on purpose and keep print, which does not raise when sys.stderr is
  None, with `# noqa: T201`.
- S105 (environment variable names, paths, codes and messages), S603
  (the emitter's own command), S310 (an origin checked first) and S506
  (yaml.BaseLoader in tests) keep their code with reasons; S324 passes
  usedforsecurity=False.
- SLF001: the installed-artifact checks may read the clients' private
  members (emitter.quality.installed-checks-ruff-exemptions); host
  client's ModuleClient keeps its call to SocketClient._request.
- Ruff no longer ignores BLE, S, SLF and T20.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each module's __all__ must equal the listed names, and every listed name
must exist, so a public name can't be dropped or added unnoticed. With
PublicationReceipt dropped from orrery.contracts' __all__, the test
failed for that module (1 failed, 6 passed); restored, all 7 pass.

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

- The cli.py comments say exactly when the collector-origin and
  authentication code loads: `microcosm-emitter host` loads it only when
  it loads a module, after reading its configuration.
- changelog.d/json-value.added.md records the interface's new public
  JsonValue alias, so the release is a minor one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- ISC004 (108): implicit concatenations in collection literals are
  wrapped in parentheses; none looked like a missing comma.
- PT018, PT011, PT006, PT017 (tests): one assert per condition, match=
  on the broad pytest.raises, tuple parametrize names, pytest.raises
  instead of asserting in an except block.
- RET, SIM, C4, PERF, RUF005, RUF022, RUF036, RUF059, FBT003, E501 and 9
  of 10 PTH findings: the equivalent rewrites (explicit return None,
  contextlib.suppress, combined if and with statements, comprehensions,
  unpacking, sorted __all__, wrapped lines, pathlib).
- 20 `# noqa`, each with its reason: ARG for signatures fixed by their
  callers (redirect_request, TypeDecorator, the ServiceModule protocol),
  FBT001 where callers pass flags positionally, PLW0108 where a lambda
  must look up a function tests replace, A002 on log_message(format),
  PTH118 where httpx's uds option takes a str.
- Ruff no longer ignores the smaller-rule families.

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

- The runtime's worker shutdown gets its dispatcher from a new
  _started_requests helper, which raises the same AssertionError, so the
  try block no longer holds a raise (TRY301). The sanitizer's invariant
  is an explicit check raising AssertionError, with `# noqa: TRY004`
  and its reason, as #58 handles type checks that keep their exception.
- SLF001 applies only to tools/installed-smoke.py and
  tools/installed-interface-smoke.py, under the new rule
  emitter.quality.installed-smoke-ruff-exemptions; check-installed.py
  needs it for nothing.
- The 14 copies of an inaccurate comment about print and a missing
  sys.stderr are replaced by one note per module: each print marked
  `# noqa: T201` writes one of its messages to standard error on
  purpose.
- The Ruff configuration comment includes modules that run as programs,
  and the changelog fragment says all 21 asserts are converted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The notes quoted the suppression comment itself, which Ruff parsed as a
`# noqa` directive and warned was invalid on every run, once per module.
They now say "suppresses Ruff's T201" in words; ruff check prints no
warning.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- _run_files_to_commit takes run_files and at_shutdown as keyword-only
  arguments, as its sibling methods do, and both calls pass them by
  name, so FBT001 needs no suppression.
- The fake collector builds the upload socket path with
  str(Path(directory) / "tls.sock"), the same string as os.path.join.
- CollectorDelivery passes _http_post and huggingface_token directly:
  every test replaces them before it builds a delivery, so the lambdas
  that looked them up at each call were not needed.
- The changelog fragment says 15 findings keep a `# noqa` with a reason.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts:
#	src/microcosm_emitter/huggingface/service/delivery.py
#	tests/support/fake_collector.py
anth-volk and others added 9 commits November 2, 2026 20:53
#63 to #69 were rebased onto main after #58 merged, so this merge
conflicted in the 14 files this branch had changed on top of #69. Each
keeps this branch's side, plus the release's version bump in
pyproject.toml; python -m scripts.rules render left the rules views as
they were. The tree differs from 8776389 exactly by main's release
(ff7d34b..a837a06).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- BLE001: the broad excepts stay, since narrowing them would change
  what reaches the build, the host or the queue; each has
  `# noqa: BLE001` and its reason above it. One try/except/pass becomes
  contextlib.suppress(Exception) (also S110).
- S101: 19 asserts in package code become explicit checks raising the
  same AssertionError with the same message, so they also hold under
  python -O. Two stay, with reasons: an explicit raise there would
  trigger TRY301 or TRY004.
- T201: microcosm_emitter.cli and microcosm_emitter.host.__main__, which
  run as programs, may print (emitter.quality.program-ruff-exemptions,
  as in the Public API). Elsewhere the prints are warnings and answers
  on purpose and keep print, which does not raise when sys.stderr is
  None, with `# noqa: T201`.
- S105 (environment variable names, paths, codes and messages), S603
  (the emitter's own command), S310 (an origin checked first) and S506
  (yaml.BaseLoader in tests) keep their code with reasons; S324 passes
  usedforsecurity=False.
- SLF001: the installed-artifact checks may read the clients' private
  members (emitter.quality.installed-checks-ruff-exemptions); host
  client's ModuleClient keeps its call to SocketClient._request.
- Ruff no longer ignores BLE, S, SLF and T20.

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

- The runtime's worker shutdown gets its dispatcher from a new
  _started_requests helper, which raises the same AssertionError, so the
  try block no longer holds a raise (TRY301). The sanitizer's invariant
  is an explicit check raising AssertionError, with `# noqa: TRY004`
  and its reason, as #58 handles type checks that keep their exception.
- SLF001 applies only to tools/installed-smoke.py and
  tools/installed-interface-smoke.py, under the new rule
  emitter.quality.installed-smoke-ruff-exemptions; check-installed.py
  needs it for nothing.
- The 14 copies of an inaccurate comment about print and a missing
  sys.stderr are replaced by one note per module: each print marked
  `# noqa: T201` writes one of its messages to standard error on
  purpose.
- The Ruff configuration comment includes modules that run as programs,
  and the changelog fragment says all 21 asserts are converted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- ISC004 (108): implicit concatenations in collection literals are
  wrapped in parentheses; none looked like a missing comma.
- PT018, PT011, PT006, PT017 (tests): one assert per condition, match=
  on the broad pytest.raises, tuple parametrize names, pytest.raises
  instead of asserting in an except block.
- RET, SIM, C4, PERF, RUF005, RUF022, RUF036, RUF059, FBT003, E501 and 9
  of 10 PTH findings: the equivalent rewrites (explicit return None,
  contextlib.suppress, combined if and with statements, comprehensions,
  unpacking, sorted __all__, wrapped lines, pathlib).
- 20 `# noqa`, each with its reason: ARG for signatures fixed by their
  callers (redirect_request, TypeDecorator, the ServiceModule protocol),
  FBT001 where callers pass flags positionally, PLW0108 where a lambda
  must look up a function tests replace, A002 on log_message(format),
  PTH118 where httpx's uds option takes a str.
- Ruff no longer ignores the smaller-rule families.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The notes quoted the suppression comment itself, which Ruff parsed as a
`# noqa` directive and warned was invalid on every run, once per module.
They now say "suppresses Ruff's T201" in words; ruff check prints no
warning.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The rebase left docs/generated/rules.md's summary counting 56 rules,
48 of them enforced and 49 blocking; the registry holds 57, 49
enforced and 50 blocking. python -m scripts.rules render brings it back
to the registry.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- _run_files_to_commit takes run_files and at_shutdown as keyword-only
  arguments, as its sibling methods do, and both calls pass them by
  name, so FBT001 needs no suppression.
- The fake collector builds the upload socket path with
  str(Path(directory) / "tls.sock"), the same string as os.path.join.
- CollectorDelivery passes _http_post and huggingface_token directly:
  every test replaces them before it builds a delivery, so the lambdas
  that looked them up at each call were not needed.
- The changelog fragment says 15 findings keep a `# noqa` with a reason.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
anth-volk and others added 6 commits November 3, 2026 17:13
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#65 to #69 were rebased onto main after #63 merged, so this merge
conflicted in the 13 files this branch had changed on top of #69. Each
keeps this branch's side, plus the release's version bump in
pyproject.toml; python -m scripts.rules render left the rules views as
they were. The tree differs from 746e71e exactly by main's release
(213b093..ed06bc2).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- ISC004 (108): implicit concatenations in collection literals are
  wrapped in parentheses; none looked like a missing comma.
- PT018, PT011, PT006, PT017 (tests): one assert per condition, match=
  on the broad pytest.raises, tuple parametrize names, pytest.raises
  instead of asserting in an except block.
- RET, SIM, C4, PERF, RUF005, RUF022, RUF036, RUF059, FBT003, E501 and 9
  of 10 PTH findings: the equivalent rewrites (explicit return None,
  contextlib.suppress, combined if and with statements, comprehensions,
  unpacking, sorted __all__, wrapped lines, pathlib).
- 20 `# noqa`, each with its reason: ARG for signatures fixed by their
  callers (redirect_request, TypeDecorator, the ServiceModule protocol),
  FBT001 where callers pass flags positionally, PLW0108 where a lambda
  must look up a function tests replace, A002 on log_message(format),
  PTH118 where httpx's uds option takes a str.
- Ruff no longer ignores the smaller-rule families.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- _run_files_to_commit takes run_files and at_shutdown as keyword-only
  arguments, as its sibling methods do, and both calls pass them by
  name, so FBT001 needs no suppression.
- The fake collector builds the upload socket path with
  str(Path(directory) / "tls.sock"), the same string as os.path.join.
- CollectorDelivery passes _http_post and huggingface_token directly:
  every test replaces them before it builds a delivery, so the lambdas
  that looked them up at each call were not needed.
- The changelog fragment says 15 findings keep a `# noqa` with a reason.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
anth-volk and others added 2 commits November 3, 2026 18:28
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#67 and #69 were rebased onto main after #65 merged, so this merge
conflicted in the 9 files this branch had changed on top of #69. Each
keeps this branch's side, plus the release's version bump in
pyproject.toml; python -m scripts.rules render left the rules views as
they were. The tree differs from 54f2464 exactly by main's release
(e233d97..d79aa4d).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#69 was rebased onto main after #67 merged, so this merge conflicted in
the 5 files this branch had changed on top of #69. Each keeps this
branch's side, plus the release's version bump in pyproject.toml;
python -m scripts.rules render left the rules views as they were. The
tree differs from ca655a7 exactly by main's release (6625a18..72205e8).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Base automatically changed from claude/ruff-smaller-rules to main November 3, 2026 20:34
@anth-volk
anth-volk removed this pull request from stack #72 November 3, 2026 20:47
@anth-volk
anth-volk added this pull request to stack #76 November 3, 2026 20:47
Brings in #69's merge and the release commit after it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@anth-volk
anth-volk marked this pull request as ready for review November 3, 2026 21:14
@anth-volk
anth-volk merged commit 977f6a7 into main Nov 3, 2026
12 checks passed
@anth-volk
anth-volk deleted the claude/ruff-complexity branch November 3, 2026 21:15
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.

Fix Ruff's complexity findings (C90, PLR) Select every Ruff rule, as the simulation API and the Public API do

1 participant