mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-11-10 22:07: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
53 lines
1.9 KiB
Python
53 lines
1.9 KiB
Python
"""The state and collaborators the worker's two halves both rely on.
|
|
|
|
:class:`~python_pkg.wsg_grabber.downloader.Worker` is assembled from two mixins
|
|
-- :mod:`._scan` and :mod:`._fetch` -- so that no single module exceeds the
|
|
250-line cap. Each half touches bookkeeping the other half owns, so both
|
|
inherit from here rather than declaring the same attributes twice.
|
|
|
|
The annotations carry no values: ``Worker.__init__`` remains the only place
|
|
this state is created. The two methods are abstract because ``Worker`` supplies
|
|
them; declaring them gives mypy and pylint something real to resolve against,
|
|
which a bare mixin does not.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from abc import ABC, abstractmethod
|
|
from typing import TYPE_CHECKING
|
|
|
|
if TYPE_CHECKING:
|
|
from python_pkg.wsg_grabber.downloader import WorkerDeps
|
|
from python_pkg.wsg_grabber.models import (
|
|
DownloadEvent,
|
|
JsonResponse,
|
|
ThreadRef,
|
|
)
|
|
|
|
|
|
class WorkerBase(ABC):
|
|
"""State and collaborators shared by the worker's two halves."""
|
|
|
|
_deps: WorkerDeps
|
|
_pending_threads: list[ThreadRef]
|
|
_catalog_fresh: bool
|
|
_finished_announced: bool
|
|
|
|
# Given a real class-level default rather than a bare annotation: _fetch
|
|
# increments it (`self._downloaded += 1`), and pylint only treats an
|
|
# attribute as existing for assignment when there is something to assign
|
|
# to. Worker.__init__ still sets the instance value on construction.
|
|
_downloaded: int = 0
|
|
|
|
@abstractmethod
|
|
def _get_json(self, url: str, stamp: str | None = None) -> JsonResponse:
|
|
"""Fetch a JSON endpoint, pacing requests and counting the last one."""
|
|
|
|
@abstractmethod
|
|
def _publish(self, event: DownloadEvent) -> None:
|
|
"""Hand an event to the UI thread."""
|
|
|
|
@abstractmethod
|
|
def _wait_for_slot(self) -> None:
|
|
"""Block until the polite inter-request delay has elapsed."""
|