Repository navigation
Fix verse range marker placement bug - #371
benjaminking wants to merge 5 commits into
Conversation
A verse range in the USFM being updated can be matched by more than one row. The updater concatenated all of their texts but kept only the last row's metadata, so the place markers handler received alignment info that did not describe the text it was given. Extracting a verse range puts all of its text on the first verse and leaves the rest empty, so the common shape is one row with text followed by empty rows. The empty row's metadata won, its alignment matrix was empty, and the handler silently placed no markers at all for that range. The block now carries every matched row's metadata alongside the existing single dict, which is left as it was so that existing handlers reading block.metadata are unaffected. The place markers handler ignores rows that have no alignment info or an empty alignment matrix, since they contributed no text to align. If more than one row is left it warns, as only one row's alignment can be used and it describes only part of the block's text. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Code reviewNo issues found. Checked for bugs and CLAUDE.md compliance. |
Enkidu93
left a comment
There was a problem hiding this comment.
@Enkidu93 reviewed 4 files and all commit messages, and made 1 comment.
Reviewable status:complete! all files reviewed, all discussions resolved (waiting on ddaspit).
ddaspit
left a comment
There was a problem hiding this comment.
@ddaspit reviewed 4 files and all commit messages, and made 2 comments.
Reviewable status: all files reviewed, 2 unresolved discussions (waiting on benjaminking).
machine/corpora/place_markers_usfm_update_block_handler.py line 45 at r1 (raw file):
len(infos), ) return infos[-1] if len(infos) > 0 else None
Unless I'm missing something, this seems to contradict the comments above.
machine/corpora/usfm_update_block.py line 32 at r1 (raw file):
@property def metadata(self) -> dict[str, object]:
Nit: maybe we should remove this property altogether and just use row_metadata. It is unclear what the difference is between the two properties.
|
@benjaminking No rush, but if you could wrap this up when you get a chance, that would be great! |
…ces within a single update block.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #371 +/- ##
==========================================
+ Coverage 92.13% 92.22% +0.08%
==========================================
Files 390 390
Lines 24644 24838 +194
==========================================
+ Hits 22705 22906 +201
+ Misses 1939 1932 -7 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
|
||
| def pop(self) -> UsfmUpdateBlockElement: | ||
| return self._elements.pop() | ||
| def rows(self) -> Sequence[UsfmUpdateBlockRow]: |
There was a problem hiding this comment.
Minor: F2. UsfmUpdateBlock is exported in __all__, and this removes its metadata property, its metadata= keyword, and add_text/add_token/add_embed/extend_last_element/update_refs/get_last_paragraph/pop, with no deprecation. A downstream handler that reads block.metadata gets AttributeError after a wheel upgrade, and C# UsfmUpdateBlock still has all of these. Is the break intended? If so, release it as one, or keep a metadata shim.
There was a problem hiding this comment.
F2 still applies at c8973a5: making rows keyword-only fixes F1, but metadata and the builder methods are still removed from the exported UsfmUpdateBlock, with no shim and no deprecation note. A positional third argument is now a TypeError too. Is this going out as a breaking release?
There was a problem hiding this comment.
The change in interface was intentional. There are no clients who use this particular property, so it's ok to make a breaking change.
| or not any( | ||
| e.is_placeable(alignment_info["paragraph_behavior"], alignment_info["style_behavior"]) for e in elements | ||
| ) | ||
| if len(elements) == 0 or not any( |
There was a problem hiding this comment.
FYI: F4. Removing the row_count == 0 or column_count == 0 early return changes single-row output and diverges from C# PlaceMarkersUsfmUpdateBlockHandler, which still has that check. On the test_single_row_with_empty_alignment_matrix_places_markers_at_end input, base gives ... parte. \f + \ft note\f* then \p \w \w*, and this PR moves the embed after \p \w \w*. Issue #370 is about verse ranges, so if the single-row change is deliberate, note it for the C# port.
There was a problem hiding this comment.
This was an intentional change. Previously, this could result in no markers being placed for some rows. The C# version should be updated to match.
This comment has been minimized.
This comment has been minimized.
Each row's alignment info describes only that row's text, so it is now always merged, even when another row has the same info. Deduplicating by identity broke rows that held equal copies, and deduplicating by equality would drop a repeated verse whose text and alignment are identical. Aligned word pairs outside a row's tokens are now rejected for every row, not only when rows are merged. A single row with such a pair used to place markers silently or fail with an IndexError that bypassed the error handler. Blocks with no markers to place return before their alignment is read, so they no longer log warnings about missing alignment info. The rows argument of UsfmUpdateBlock is keyword-only, so a metadata dict passed where it used to go raises a TypeError instead of being taken as rows. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This comment has been minimized.
This comment has been minimized.
A block whose alignment info strips every marker it has is left alone, so its alignment is never used. Checking the aligned word pairs while reading the alignment info, before the info's behaviors were known, let such a block fail the whole update. The pairs are now checked only once there are markers to place, and still before rows are merged. Also trim the comments added on this branch to the non-obvious reasons behind the code. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
benjaminking
left a comment
There was a problem hiding this comment.
@benjaminking partially reviewed 5 files, made 5 comments, and resolved 4 discussions.
Reviewable status: 0 of 5 files reviewed, 1 unresolved discussion (waiting on ddaspit and Enkidu93).
machine/corpora/place_markers_usfm_update_block_handler.py line 45 at r1 (raw file):
Previously, ddaspit (Damien Daspit) wrote…
Unless I'm missing something, this seems to contradict the comments above.
Yes, it was a confusing way of writing it. Logically that line could only be reached if there was exactly one item in infos, so this was a way of selecting the only item. It should be more clear now.
machine/corpora/usfm_update_block.py line 32 at r1 (raw file):
Previously, ddaspit (Damien Daspit) wrote…
Nit: maybe we should remove this property altogether and just use
row_metadata. It is unclear what the difference is between the two properties.
Done.
| or not any( | ||
| e.is_placeable(alignment_info["paragraph_behavior"], alignment_info["style_behavior"]) for e in elements | ||
| ) | ||
| if len(elements) == 0 or not any( |
There was a problem hiding this comment.
This was an intentional change. Previously, this could result in no markers being placed for some rows. The C# version should be updated to match.
|
|
||
| def pop(self) -> UsfmUpdateBlockElement: | ||
| return self._elements.pop() | ||
| def rows(self) -> Sequence[UsfmUpdateBlockRow]: |
There was a problem hiding this comment.
The change in interface was intentional. There are no clients who use this particular property, so it's ok to make a breaking change.
Review
Public API and parity: unchanged since the last round and still open as F2. Findings: F1 addressed, F2 open, F3 addressed, F4 open, F5 addressed, F6 addressed, F7 addressed. Reviewed at 414db9d |
Enkidu93
left a comment
There was a problem hiding this comment.
@Enkidu93 reviewed 5 files and all commit messages, and dismissed @claude[bot] from 2 discussions.
Reviewable status: all files reviewed, 1 unresolved discussion (waiting on ddaspit).
This PR fixes #370, which is caused by verse ranges containing empty rows with empty alignment matrices, resulting in no markers being placed for the verse range. This changes the marker placement algorithm to ignore any empty rows with an empty alignment matrix.
This change is