chore: type the codebase (mypy strict, ANN) and modernize paths and boolean signatures (PTH, FBT001/FBT002)

#8 · closed · 0 comments

View on GitHub ↗

Toilal

Everything deliberately left out of #4, gathered here because it is one piece of work: annotating the codebase and modernizing the signatures it exposes. Counts measured on `develop` after #4 landed. | item | violations | why it was deferred | | --- | --- | --- | | `mypy --strict` | 1356 errors in 89 / 110 files | requires annotations everywhere | | `ANN` (flake8-annotations) | 1546 | the same work, seen from the linter | | `PTH` (flake8-use-pathlib) | 1073 | `os.path` → `pathlib` on cross-platform code | | `FBT001` / `FBT002` | 90 | changes public signatures | ## 1. Typing: `mypy --strict` and `ANN` together These two are the same task. `ANN` breaks down as 373 unannotated arguments, 291 missing return types on public functions, 105 on static methods, 78 on private functions, 62 on special methods, 24 on `*args`. `mypy --strict` reports the same gaps plus the inference failures they cause. Doing it in one commit is not reviewable. Suggested order: - [ ] Annotate the core first: `ddb/registry.py`, `ddb/action`, `ddb/phase`, `ddb/command`, `ddb/event`, `ddb/config`. These define the interfaces every feature implements, so annotating them propagates. - [ ] Then the features, one per PR, enabling `strict = true` per module through `[[tool.mypy.overrides]] module = "ddb.feature.<name>.*"` as each is finished. - [ ] Add `ANN` to the ruff selection only once a module is strict-clean, otherwise the two tools report the same thing twice. - [ ] Decide about `ANN401` (`Any` in signatures): the configuration layer genuinely passes `Any` around (dotty dicts), so it will likely stay off. Expect real findings on the way: the non-strict pass already surfaced a broken `includes` option, a `ClassVar` used as a return annotation on 20 features, and a dead parameter. ## 2. `PTH`: os.path → pathlib 1073 occurrences. This one is riskier than its mechanical look: - Windows and macOS test jobs are currently disabled (see #1), so the platforms where path semantics differ most are not covered. - `ddb/utils/file.py` mixes `os.path`, `Path` and string manipulation on purpose — generated targets are compared as strings against cache keys and gitignore entries. Converting blindly changes separators and trailing-slash behaviour. - Ruff's fixes for `PTH` are unsafe fixes; applying them wholesale is not an option here. - [ ] Re-enable the Windows test job first, or accept that this cannot be validated. - [ ] Convert module by module, starting with the ones that only build paths (`ddb/feature/*/actions.py`) and leaving `ddb/utils/file.py` last. ## 3. `FBT001` / `FBT002`: boolean parameters 90 signatures take a boolean positionally. Making them keyword-only is the fix, and it breaks: - features and actions written by third parties (`.ddb` plugins, `ddb_features` entry points), - any caller of the public helpers in `ddb/utils`. `FBT003` (boolean *arguments* at call sites) is already enabled and fixed — that one changes nothing for callers. - [ ] Schedule with the next major release, alongside the `N818` exception renames also deferred in #4. - [ ] Consider `*, ` on new code from now on, so the count stops growing. ## Related - Toilal/docker-devbox-ddb#4 code quality tooling (closed scope, these were the exclusions) - Toilal/docker-devbox-ddb#1 toolchain modernization (Windows/macOS jobs) - Toilal/docker-devbox-ddb#5 test coverage

Comments