refactor(release): freeze ParsedRelease + enrich_from_probe returns new instance
ParsedRelease is now @dataclass(frozen=True). The enrichment passes that used to patch fields in place now produce new instances: - enrich_from_probe(parsed, info, kb) returns a new ParsedRelease via dataclasses.replace (no allocation when no field changed). - inspect_release rebinds 'parsed' after detect_media_type (wrapped in MediaTypeToken — the strict isinstance check now also runs on replace) and after enrich_from_probe. languages becomes a tuple[str, ...] so the VO is properly immutable. Parser pipeline packs languages as a tuple in the assemble dict. Callers updated: inspect_release, testing/recognize_folders_in_downloads.py. Tests updated: 22 enrich_from_probe call sites rebound, language assertions switched to tuple literals, test_release_fixtures normalizes result['languages'] back to list for YAML-fixture comparison. Suite: 1077 passed.
This commit is contained in:
@@ -198,7 +198,7 @@ class TestEnrichers:
|
||||
assert annotated is not None
|
||||
fields = assemble(annotated, tag, name, _KB)
|
||||
|
||||
assert fields["languages"] == ["FRENCH", "MULTI"]
|
||||
assert fields["languages"] == ("FRENCH", "MULTI")
|
||||
assert fields["audio_codec"] == "DTS-HD.MA"
|
||||
assert fields["audio_channels"] == "5.1"
|
||||
|
||||
@@ -212,5 +212,5 @@ class TestEnrichers:
|
||||
assert fields["title"] == "Show"
|
||||
assert fields["season"] == 1
|
||||
assert fields["episode"] == 5
|
||||
assert fields["languages"] == ["FRENCH"]
|
||||
assert fields["languages"] == ("FRENCH",)
|
||||
assert fields["media_type"] == "tv_show"
|
||||
|
||||
@@ -264,10 +264,10 @@ class TestParsedReleaseInvariants:
|
||||
r = _parse(raw)
|
||||
assert r.raw == raw
|
||||
|
||||
def test_languages_defaults_to_empty_list_not_none(self):
|
||||
def test_languages_defaults_to_empty_tuple_not_none(self):
|
||||
r = _parse("Movie.2020.1080p.BluRay.x264-GRP")
|
||||
# __post_init__ ensures languages is a list, never None
|
||||
assert r.languages == []
|
||||
# ``languages`` defaults to an empty tuple (frozen VO).
|
||||
assert r.languages == ()
|
||||
|
||||
def test_tech_string_joined(self):
|
||||
r = _parse("Movie.2020.1080p.BluRay.x264-GRP")
|
||||
|
||||
@@ -48,6 +48,9 @@ def test_parse_matches_fixture(fixture: ReleaseFixture, tmp_path) -> None:
|
||||
# ``asdict()`` does not include them.
|
||||
result["is_season_pack"] = parsed.is_season_pack
|
||||
result["tech_string"] = parsed.tech_string
|
||||
# ``languages`` is a tuple on the VO; fixtures encode it as a YAML list.
|
||||
# Compare list-to-list so the equality is unambiguous.
|
||||
result["languages"] = list(result.get("languages", ()))
|
||||
|
||||
for field, expected in fixture.expected_parsed.items():
|
||||
assert field in result, (
|
||||
|
||||
Reference in New Issue
Block a user