style: clean up prose

This commit is contained in:
imSp4rky
2026-08-19 13:45:58 -06:00
parent 54adb82746
commit 29d0828c33
40 changed files with 109 additions and 110 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
"""Tests for SubtitleCodecChoice — notably the ``original`` keep-source sentinel that
"""Tests for SubtitleCodecChoice, notably the ``original`` keep-source sentinel that
services set via the ``sub_format`` override (must not be rejected as an invalid codec)."""
from __future__ import annotations
+1 -1
View File
@@ -1,4 +1,4 @@
"""Tests for ``dl.write_export`` — the ``--export`` JSON sidecar.
"""Tests for ``dl.write_export``, the ``--export`` JSON sidecar.
Regression: DRM-free tracks never pass through ``prepare_drm``, so ``write_export``
must accept ``drm=None`` (and DRM systems without ``to_dict``/``content_keys`` such
+2 -2
View File
@@ -61,7 +61,7 @@ VIDEO_HEVC_SDR_CPD = (
)
# Real Dolby Vision (dvhe, DoViProfile "stn") CodecPrivateData from a Smooth
# manifest: NALs arrive SPS,PPS,VPS (VPS last) and the VUI colour triple is
# Unspecified (2,2,2) — DV is signalled by FourCC only, never by CICP.
# Unspecified (2,2,2): DV is signalled by FourCC only, never by CICP.
VIDEO_HEVC_DV_CPD = (
"00000001420101022000000300B00000030000030096A001E020021C4D9457B91CAF016E0404042800001F480002EE0401F4E1"
"15EE7E0001312D00002FAF0C80000000014401C1ACBE0EC90000000140010C01FFFF022000000300B00000030000030096"
@@ -295,7 +295,7 @@ def test_ec3_without_dolby_guid_builds_bare_entry():
def test_aac_codec_private_data_synthesis_matches_real_manifest():
# 48 kHz stereo AAC-LC must produce 0x1190 — the exact ASC real manifests carry.
# 48 kHz stereo AAC-LC must produce 0x1190, the exact ASC real manifests carry.
assert synthesize_aac_codec_private_data("AACL", 48000, 2).hex() == "1190"
+1 -1
View File
@@ -1,4 +1,4 @@
"""Tests for ``apply_service_dl_overrides`` — precedence: CLI/env > service dl > global dl > defaults."""
"""Tests for ``apply_service_dl_overrides``. Precedence: CLI/env > service dl > global dl > defaults."""
from __future__ import annotations
+1 -1
View File
@@ -246,7 +246,7 @@ def test_changed_services_up_to_date(monkeypatch):
@pytest.mark.parametrize("order", [["a", "b"], ["b", "a"]])
def test_collision_first_source_wins(tmp_path, order):
"""Discovery dedupes by tag honoring list order — the FIRST source to define a tag wins,
"""Discovery dedupes by tag honoring list order: the FIRST source to define a tag wins,
whether it's a local dir or a repo clone; later duplicates are shadowed."""
dirs = {}
for name in ("a", "b"):
+9 -9
View File
@@ -2,10 +2,10 @@
Test suite for the unshackle remote-services subsystem:
- `unshackle/core/remote_service.py` — `RemoteClient`, `RemoteService`, helpers
- `unshackle/core/api/` — routes, handlers, session_store, input_bridge,
- `unshackle/core/remote_service.py`: `RemoteClient`, `RemoteService`, helpers
- `unshackle/core/api/`: routes, handlers, session_store, input_bridge,
download_manager, errors, compression
- `unshackle/commands/serve.py` — CLI surface
- `unshackle/commands/serve.py`: CLI surface
Two tiers:
@@ -38,7 +38,7 @@ The suite can either:
`--server-url http://host:port`.
Spawn mode is controlled by `--spawn-serve {auto, always, never}` (default
`auto` — spawn only when `--server-url` is empty).
`auto` spawns only when `--server-url` is empty).
### Auto-spawn (recommended)
@@ -78,7 +78,7 @@ services you have access to. Schema (see the example file for full docs):
services:
EXAMPLE:
title_url: "..." # required
series_url: "..." # optional — overrides movie target when set
series_url: "..." # optional, overrides movie target when set
target_season: 1
target_episode: 1
search_query: "..."
@@ -114,9 +114,9 @@ uv run pytest tests/remote -v --live
## Markers
- `unit` — fast, mocked (default)
- `live` — needs `--live`
- `slow` — hits real services; combine with `--live`
- `unit`: fast, mocked (default)
- `live`: needs `--live`
- `slow`: hits real services; combine with `--live`
Run only fast unit tests:
@@ -127,4 +127,4 @@ uv run pytest tests/remote -m "unit and not slow"
## Adding a new service to e2e
1. Add a block under `services:` in your local `fixtures.yaml`.
2. No new Python needed — every e2e test is parametrized over the YAML.
2. No new Python needed; every e2e test is parametrized over the YAML.
+15 -15
View File
@@ -8,39 +8,39 @@
# unshackle (matches the service directory name, e.g. EXAMPLE). The keys
# below are read by the e2e tests:
#
# title_url (required) — movie URL/slug/ID accepted by the service
# series_url (optional) — series URL/slug/ID; when set, the
# title_url (required): movie URL/slug/ID accepted by the service
# series_url (optional): series URL/slug/ID; when set, the
# quality + license + download tests
# target target_season/target_episode
# instead of the movie
# target_season (optional, default 1)
# target_episode (optional, default 1)
# search_query (optional) — string to send to /api/search
# requires_auth (optional, default true) — informational
# server_cdm (optional, default false) — informational
# drm (optional) — informational ("widevine" / "playready")
# search_query (optional): string to send to /api/search
# requires_auth (optional, default true): informational
# server_cdm (optional, default false): informational
# drm (optional): informational ("widevine" / "playready")
#
# expected_quality (optional) — when present, the quality test
# expected_quality (optional): when present, the quality test
# asserts these limits against the
# discovered video tracks
# min_height (optional) — max video.height >= this
# min_codecs (optional) — codec names that must be present
# min_height (optional): max video.height >= this
# min_codecs (optional): codec names that must be present
# (AVC, HEVC, VC1, VP8, VP9, AV1)
# min_ranges (optional) — range names that must be present
# min_ranges (optional): range names that must be present
# (SDR, HDR10, HDR10P, DV, HLG, HYBRID)
# min_track_count (optional) — at least this many video tracks
# min_track_count (optional): at least this many video tracks
#
# runs_download_test (optional, default false) — when true, the
# runs_download_test (optional, default false): when true, the
# download smoke test
# runs for this service
# runs_license_test (optional, default false) — when true, the
# runs_license_test (optional, default false): when true, the
# license test runs for
# this service
# license_drm (optional, default "widevine") — DRM type the
# license_drm (optional, default "widevine"): DRM type the
# license test
# requests ("widevine"
# or "playready")
# license_quality (optional, default 1080) — pixel height of the
# license_quality (optional, default 1080): pixel height of the
# track the license test
# targets
+1 -1
View File
@@ -7,7 +7,7 @@ For any fixture service with ``runs_download_test: true``, this test:
4. Fetches the manifest URL with the resolved headers.
5. Asserts the body is non-empty and looks like DASH/HLS.
It does NOT decrypt or mux — that requires a full local CDM. It proves
It does NOT decrypt or mux; that requires a full local CDM. It proves
the end-to-end pipeline up to CDN reachability for the selected quality.
"""
+3 -3
View File
@@ -22,7 +22,7 @@ def create_session(http_session, server_url: str, service: str, title_id: str) -
payload = {
"service": service,
"title_id": title_id,
# Quality knobs — send enum names the server's session_create parser accepts.
# Quality knobs: send enum names the server's session_create parser accepts.
"range_": ["SDR", "HDR10", "DV"],
"vcodec": ["AVC", "HEVC"],
"best_available": True,
@@ -115,13 +115,13 @@ def test_track_quality_meets_expected(http_session, server_url: str, service_cas
tracks = r.json()
video = tracks.get("video") or []
summary = summarize(video)
# Print summary even when test passes — discovery aid.
# Print summary even when the test passes, as a discovery aid.
with capsys.disabled():
print(f"\n[{service}] target={kind} '{target.get('name')}' -> {summary}")
expected = conf.get("expected_quality") or {}
if not expected:
pytest.skip(f"{service}: no expected_quality in fixtures.yaml — discovered={summary}")
pytest.skip(f"{service}: no expected_quality in fixtures.yaml; discovered={summary}")
if "min_height" in expected:
assert summary["max_height"] >= expected["min_height"], (
+1 -1
View File
@@ -1,7 +1,7 @@
"""Unit tests for DownloadJob + DownloadQueueManager state machine.
These tests focus on the queue manager's data layer (create/get/list/cancel/
cleanup/serialize) — they do not exercise the actual subprocess download path.
cleanup/serialize); they do not exercise the actual subprocess download path.
"""
from __future__ import annotations
+2 -2
View File
@@ -47,7 +47,7 @@ def test_api_error_default_http_status_per_code() -> None:
APIErrorCode.NETWORK_ERROR: 503,
APIErrorCode.SERVICE_UNAVAILABLE: 503,
}
# Lock that the cases above are the *complete* live set — a new/removed code trips this.
# Lock that the cases above are the *complete* live set; a new/removed code trips this.
assert {c.name for c in cases} == {c.name for c in APIErrorCode}
for code, expected in cases.items():
assert APIError(code, "x").http_status == expected, code
@@ -142,7 +142,7 @@ def test_handle_api_exception_categorizes_generic() -> None:
assert body["error_code"] == "NETWORK_ERROR"
# Locks the FULL observable response — (http status, error_code, retryable) — that
# Locks the FULL observable response (http status, error_code, retryable) that
# a client sees for a generic (non-APIError) exception flowing through the
# handle_api_exception funnel that every route's `except Exception` path calls.
# This is the equivalence reference: after the categorize_exception collapse,
+1 -1
View File
@@ -190,5 +190,5 @@ async def test_auth_middleware_accepts_known_key(make_app, aiohttp_client) -> No
app["config"]["users"]["good-key"] = {"devices": []}
client = await aiohttp_client(app)
resp = await client.get("/api/session/nonexistent", headers={"X-Secret-Key": "good-key"})
# Auth passed; handler then 404s the session — anything other than 401 is fine here.
# Auth passed; handler then 404s the session; anything other than 401 is fine here.
assert resp.status != 401
+7 -7
View File
@@ -2,14 +2,14 @@
Covers the selection primitives that back `-r ...,DV,HYBRID` downloads:
- ``Tracks.select_hybrid`` — picks the HDR base layer per resolution and the
- ``Tracks.select_hybrid``: picks the HDR base layer per resolution and the
single lowest DV track used as a hybrid ingredient.
- ``Tracks.merge_video_selections`` — de-duplicates the ingredient/deliverable
- ``Tracks.merge_video_selections``: de-duplicates the ingredient/deliverable
overlap so a DV track that is chosen as both is not muxed/downloaded twice.
- ``Tracks.partition_hybrid_videos`` — splits the ladder into hybrid-ingredient
- ``Tracks.partition_hybrid_videos``: splits the ladder into hybrid-ingredient
candidates and the standalone-deliverable pool; HDR10/HDR10+/DV only enter
the pool when their range was explicitly requested alongside HYBRID.
- ``Tracks.flag_hybrid_ingredients`` — marks ingredient-only tracks with
- ``Tracks.flag_hybrid_ingredients``: marks ingredient-only tracks with
``hybrid_base_only`` so the standalone mux loop skips them.
The remaining ``dl`` glue (the Cartesian deliverable product and the mux loop)
@@ -169,7 +169,7 @@ def flagged(tracks: list[Video]) -> set[str]:
def test_flag_hybrid_only_flags_base_and_ingredient_dv(ladder: list[Video]) -> None:
"""`-r HYBRID`: no deliverables, so the base and the ingredient DV are both
skipped by the standalone mux loop — only the hybrid output remains."""
skipped by the standalone mux loop; only the hybrid output remains."""
hybrid_selected = list(filter(Tracks().select_hybrid(ladder, [1080]), ladder))
Tracks.flag_hybrid_ingredients(hybrid_selected, [])
assert flagged(ladder) == {"hdr10p-1080", "dv-360"}
@@ -177,7 +177,7 @@ def test_flag_hybrid_only_flags_base_and_ingredient_dv(ladder: list[Video]) -> N
def test_flag_hybrid_plus_hdr10p_keeps_base_deliverable(ladder: list[Video]) -> None:
"""`-r HYBRID,HDR10P`: the base is also an explicit deliverable, only the
ingredient DV is skipped — hybrid + standalone HDR10+ are muxed."""
ingredient DV is skipped; hybrid + standalone HDR10+ are muxed."""
hybrid_selected = list(filter(Tracks().select_hybrid(ladder, [1080]), ladder))
base = next(t for t in ladder if t.id == "hdr10p-1080")
Tracks.flag_hybrid_ingredients(hybrid_selected, [base])
@@ -186,7 +186,7 @@ def test_flag_hybrid_plus_hdr10p_keeps_base_deliverable(ladder: list[Video]) ->
def test_flag_hybrid_plus_hdr10p_and_dv_keeps_both_deliverables(ladder: list[Video]) -> None:
"""`-r HYBRID,HDR10P,DV`: best DV is a deliverable, lowest DV stays
ingredient-only — hybrid + HDR10+ + DV are muxed."""
ingredient-only; hybrid + HDR10+ + DV are muxed."""
hybrid_selected = list(filter(Tracks().select_hybrid(ladder, [1080]), ladder))
base = next(t for t in ladder if t.id == "hdr10p-1080")
best_dv = next(t for t in ladder if t.id == "dv-1080")