testsAndMisc/python_pkg/wsg_grabber/_player_api.py
Krzysztof kuhy Rudnicki 16c626661d Split wsg_grabber/player.py under the 250-line cap
The stateless half of talking to mpv moves out:

  _mpv_ipc.py    read_reply, build_argv, encode, note_errors, and
                 probe_properties/query lifted out of MpvPlayer.probe/_query,
                 which only ever needed the socket path
  _player_api.py the Player Protocol that ui.py actually depends on

player.py keeps the class that owns the process and the socket, and re-exports
Player/build_argv/encode through __all__.

_note_errors stays as a bound delegate on MpvPlayer: test_player.py calls it on
the instance, and the tests are out of scope here. Caught by the suite failing,
not by guessing.

The probe constants moved across verbatim -- _PROBE_ID is 9001, and read_reply
matches replies on it, so a placeholder would have made every probe hang until
timeout while still returning a plausible error string.

player.py 373 -> 235, _mpv_ipc.py 158, _player_api.py 49. 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:05:41 +02:00

50 lines
1.3 KiB
Python

"""What the reviewer window requires of a video player.
Split out of :mod:`python_pkg.wsg_grabber.player` to keep it under the 250-line
cap. ``ui`` depends on this protocol rather than on :class:`~.player.MpvPlayer`,
so the window can be driven by a stub in the tests without mpv present.
"""
from __future__ import annotations
from typing import TYPE_CHECKING, Protocol
if TYPE_CHECKING:
from pathlib import Path
class Player(Protocol):
"""What the reviewer needs from a video player."""
def play(self, path: Path) -> None:
"""Show *path*, replacing whatever is on screen.
Args:
path: Video file to play.
"""
... # pragma: no cover
def stop(self) -> None:
"""Blank the video area."""
... # pragma: no cover
def is_alive(self) -> bool:
"""Report whether the player is still running.
Returns:
bool: True while the process lives.
"""
... # pragma: no cover
def probe(self) -> dict[str, object]:
"""Report what the player is currently doing, for diagnostics.
Returns:
dict[str, object]: Property name to value.
"""
... # pragma: no cover
def close(self) -> None:
"""Shut the player down and release its resources."""
... # pragma: no cover