Repository navigation
Fix Ruff's complexity findings (C90, PLR), leaving only the permanent ignores - #71
Merged
Merged
Conversation
- 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
#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>
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>
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>
Brings in #69's merge and the release commit after it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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 #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
C90andPLR(89 on #55). Ruff then ignores onlyCOM812,ISC001,D203,D213andCPY, 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.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:run(_initialize_modules,_start_workers,_serve,_shut_down,_send_reply);apply_release_change(_attempt_release_change,_read_head_state,_release_order,_checked_record,_changed_record,_commit_violations,_commit_release_record, and three private dataclasses);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);wire_value, the sanitizer, bundles, hub, submissions client, collector delivery, telemetry lifecycle and Orrery upload;PLR0913,PLR0917):LeaseRenewaldataclass, whichHeldLeasesand the submissions delivery take, plus a few test helpers.# noqa, each with its reason above thedef:EmitterClient.start,add_buildandLocalTelemetryEmitter.start;redirect_request;ServiceRuntime,HuggingFaceModule,CollectorSubmissionClient,stage_run_files,enqueue_job,claim_jobandfinish_job. These could be grouped if those tests change too;PLR2004(18): named constants. HTTP statuses usehttp.HTTPStatusmembers throughout, ascore/auth.pyalready does.core/http_status.pydefines the retryable client errors andis_permanent_client_erroronce, for the submissions client and the telemetry collector delivery; the submissions client'sRETRYABLE_STATUSESkeeps its name (round 1).PLR0124:value == value and abs(value) != infbecomesmath.isfinite(value), which is the same for floats.C90andPLRleave the ignore list, which now holds only the permanent ignores. The README andemitter.quality.ruff-lintno 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.
bbfc9cfThe fixes (committed as work in progress), and the temporary list emptiedruff check .andruff format --check .pass with only the permanent ignores.06b1d2cMerge of #69's round 1_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,45208baThe fragment, and the wording without the temporary listtools/bump-version.py --checkpasses; the five guards pass withGITHUB_BASE_REF=main.Review round 1:
291c23fTests of two refactored branchesValueError; a 403 to the events request makes only that run local withcollector_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.30d26bdThe review's other pointsstageandhand_overtest helpers raiseTypeErrorfor an option they don't read. The four test suppressions say they are pytest test functions._ReleaseOrderstays frozen with a read-only mapping, and the commit message uses a copy. One shared client-error check, andHTTPStatusmembers.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'saddedfragment 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