Keep the row for an unverifiable paragraph, so the gap says why
A paragraph whose translation could not be verified produced no rows at all, which is indistinguishable from one that was never translated: the review lane showed a missing utterance with no explanation. The project's own rule for a gap is "the row is kept, the gap is visible, no clip is generated", and it already applies to the collapse orphans. An unverifiable paragraph is the same kind of gap, so it now gets the same treatment: a voiced=false row carrying the reason. Measured on the real ch-15 window: the ten drifted paragraphs now produce thirteen explicit not-voiced rows instead of vanishing, and the reviewer can see that the translation was dropped because it renders another paragraph rather than because nobody translated it. 60 tests, ruff clean.
This commit is contained in:
@@ -880,6 +880,25 @@ def build_delivery(
|
||||
for alignment in alignments:
|
||||
paragraph = bundle_ids.get(alignment.paragraph_id) or {}
|
||||
sources = {source.source_id: source for source in source_utterances(paragraph, bundle)}
|
||||
if alignment.method == "mismatch":
|
||||
# The paragraph's translation could not be trusted - it
|
||||
# renders another paragraph. The utterances still get a row,
|
||||
# marked as not voiced and carrying the reason, so the gap is
|
||||
# visible in the review lane and says why. Silence would be
|
||||
# indistinguishable from "never translated".
|
||||
reason = "; ".join(alignment.problems) or "the translation could not be verified"
|
||||
for source in sources.values():
|
||||
if source.row_id is None:
|
||||
continue
|
||||
utterances.append(
|
||||
{
|
||||
"utterance_id": source.row_id,
|
||||
"voiced": False,
|
||||
"reason": reason,
|
||||
"source_ref": source_ref or alignment.paragraph_id,
|
||||
}
|
||||
)
|
||||
continue
|
||||
for segment in alignment.segments:
|
||||
source = sources.get(segment.source_id)
|
||||
if source is None or source.row_id is None:
|
||||
|
||||
@@ -333,6 +333,28 @@ class DeliveryTests(unittest.TestCase):
|
||||
self.assertIn("absorbed", collapsed[0]["reason"])
|
||||
self.assertNotIn("text", collapsed[0])
|
||||
|
||||
def test_an_unverifiable_paragraph_is_delivered_as_a_visible_gap(self) -> None:
|
||||
"""The row is kept and says why, rather than vanishing.
|
||||
|
||||
A delivery that simply omits the utterances is indistinguishable
|
||||
from one that was never translated. The review lane needs to see the
|
||||
gap and its reason.
|
||||
"""
|
||||
alignment = align_paragraph(paragraph_fixture(), "这艘船很大。设计师很用心。", bundle_fixture())
|
||||
alignment.method = "mismatch"
|
||||
alignment.segments = []
|
||||
alignment.problems = ["translation belongs to another paragraph: it renders the next one"]
|
||||
delivery = build_delivery(
|
||||
{"target_language": "zh"},
|
||||
[({"id": "ch-1", "paragraphs": [paragraph_fixture()]}, [alignment])],
|
||||
bundle_fixture(),
|
||||
)
|
||||
self.assertEqual(len(delivery["utterances"]), 2)
|
||||
self.assertTrue(all(not u["voiced"] for u in delivery["utterances"]))
|
||||
self.assertEqual([u["utterance_id"] for u in delivery["utterances"]], [100, 101])
|
||||
self.assertIn("another paragraph", delivery["utterances"][0]["reason"])
|
||||
self.assertNotIn("text", delivery["utterances"][0])
|
||||
|
||||
|
||||
class CommandTests(unittest.TestCase):
|
||||
def test_the_cache_directory_is_created_before_the_first_call(self) -> None:
|
||||
|
||||
Reference in New Issue
Block a user