mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-11-12 08:31:03 +01:00
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
44 lines
3.5 KiB
JSON
44 lines
3.5 KiB
JSON
{
|
|
"intent": "Bring python_pkg/wsg_grabber/downloader.py under the 250-line file cap by splitting the Worker class's board-walking and file-fetching halves into mixins, keeping every method reachable as a bound attribute of Worker.",
|
|
"scope": [
|
|
"python_pkg/wsg_grabber/downloader.py",
|
|
"python_pkg/wsg_grabber/_scan.py (new)",
|
|
"python_pkg/wsg_grabber/_fetch.py (new)",
|
|
"python_pkg/wsg_grabber/_worker_base.py (new)",
|
|
"Non-goal: no behaviour change, no test changes, no pylint config change"
|
|
],
|
|
"changes": [
|
|
"Moved the board-walking methods -- _scan_step, _refresh_thread_list, _archive_refs, _conditional_get, _fetch_thread, _write_off_deleted -- into ScanMixin in _scan.py.",
|
|
"Moved _download_one and _apply_result into DownloadMixin in _fetch.py.",
|
|
"Added _worker_base.py holding WorkerBase(ABC): the state both halves touch, plus abstract _get_json / _publish / _wait_for_slot which Worker supplies. Both mixins inherit from it, so neither redeclares the other's bookkeeping.",
|
|
"Worker is now `class Worker(ScanMixin, DownloadMixin)`; __init__ is unchanged and remains the only place instance state is created.",
|
|
"downloader.py 420 -> 238 lines; _scan.py 134; _fetch.py 98; _worker_base.py 52."
|
|
],
|
|
"verification": [
|
|
{
|
|
"command": "python3 -m pytest python_pkg/wsg_grabber/tests/ -q",
|
|
"result": "pass",
|
|
"evidence": "277 passed in 15.20s, unchanged from before the split. This is the load-bearing check: test_downloader_part2.py calls worker._download_one() and worker._fetch_thread(ThreadRef(7, 100)) as bound methods and sets worker._catalog_fresh directly, so the mixin composition is exercised rather than assumed."
|
|
},
|
|
{
|
|
"command": "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",
|
|
"result": "pass",
|
|
"evidence": "ruff, ruff format, mypy, pylint, bandit and the coverage-gated pytest all pass. The only remaining hook failures were 'no staged evidence artifact' and 'no workflow contract', which this file and the paired contract satisfy. No suppression was added."
|
|
},
|
|
{
|
|
"command": "bash ~/utils/scripts/check_file_length.sh --all | grep -c 'over by'",
|
|
"result": "pass",
|
|
"evidence": "All four files are under the cap: 238 / 134 / 98 / 52."
|
|
}
|
|
],
|
|
"risks": [
|
|
"Two intermediate designs failed the gate and were abandoned rather than suppressed. Bare `raise NotImplementedError` stubs on the mixins would have been uncovered lines under the 100% gate; `if TYPE_CHECKING` method stubs satisfied mypy but left pylint reporting no-member. The ABC with real abstract methods satisfies both.",
|
|
"_downloaded carries a class-level default of 0 rather than a bare annotation, because _fetch does `self._downloaded += 1` and pylint only accepts an attribute as assignable when there is something to assign to. Worker.__init__ still sets the instance value, so no state is shared between instances -- ints are immutable, so the class attribute is never mutated in place.",
|
|
"Mixin method resolution order now matters: Worker(ScanMixin, DownloadMixin) means ScanMixin wins on any name collision. There are none today; adding a same-named method to both would silently pick ScanMixin's."
|
|
],
|
|
"rollback": [
|
|
"git revert the commit; downloader.py returns to its 420-line form and the three new modules are deleted.",
|
|
"After rollback, run python3 -m pytest python_pkg/wsg_grabber/tests/ -q to confirm 277 tests still pass."
|
|
]
|
|
}
|