testsAndMisc/docs/superpowers/contracts/wsg-grabber-downloader-split-2026-08-16.json
Krzysztof kuhy Rudnicki 324ec0c9b5 Split wsg_grabber/downloader.py under the 250-line cap
Worker did two separable jobs. Both become mixins, because the tests drive
their methods as bound attributes (worker._download_one(), worker._fetch_thread)
and free functions would have broken that:

  _scan.py    ScanMixin      -- threads.json, the archive, one changed thread
  _fetch.py   DownloadMixin  -- claim a file, fetch it, record the outcome

_worker_base.py holds WorkerBase(ABC) with the state both halves touch and the
three methods Worker supplies. Two earlier shapes were abandoned rather than
suppressed: NotImplementedError stubs are uncovered lines under the 100% gate,
and `if TYPE_CHECKING` stubs satisfy mypy but leave pylint reporting no-member.
The ABC satisfies both with no disable comment anywhere.

_downloaded needs a real class-level default: _fetch does `self._downloaded += 1`
and pylint only accepts an attribute as assignable when there is something to
assign to. Worker.__init__ still owns the instance value.

downloader.py 420 -> 238, _scan.py 134, _fetch.py 98, _worker_base.py 52.
277 tests pass.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011w2Pj4Ek3ZNMQVYcFHgXDY
2026-08-16 16:01:11 +02:00

18 lines
1.5 KiB
JSON

{
"title": "Split wsg_grabber/downloader.py under the 250-line cap",
"objective": "Bring python_pkg/wsg_grabber/downloader.py (420 lines) under the repo-wide 250-line file cap by separating the Worker class's two independent halves -- walking the board and fetching a claimed file -- into mixins, with no change to behaviour, to the public Worker API, or to how the tests drive it.",
"acceptance_criteria": [
"downloader.py, _scan.py, _fetch.py and _worker_base.py are each at most 250 lines.",
"All 277 python_pkg/wsg_grabber tests pass unchanged, including the ones that call worker._download_one() and worker._fetch_thread() as bound methods.",
"The package holds 100% branch coverage: no new uncovered lines are introduced by the split (in particular, no NotImplementedError stub bodies).",
"pre-commit passes on all four files with no suppression added -- no # noqa, no # type: ignore, no pylint disable, no new per-file-ignores in meta/pyproject.toml."
],
"out_of_scope": [
"Any behaviour, retry, backoff or state-transition change.",
"Any change to the test files.",
"Splitting the wsg_grabber test files -- that is separate work.",
"Adding pylint mixin configuration to meta/pyproject.toml."
],
"verifier": "pre-commit run --files python_pkg/wsg_grabber/downloader.py python_pkg/wsg_grabber/_scan.py python_pkg/wsg_grabber/_fetch.py python_pkg/wsg_grabber/_worker_base.py (runs ruff, ruff format, mypy, pylint, bandit and the coverage-gated pytest), plus bash ~/utils/scripts/check_file_length.sh --all for the cap itself."
}