Skip to content

Commit 67621fe

Browse files
derek73claude
andcommitted
Add suffix-comma title/last-prefix tests; split dense AGENTS.md sentence
Reviewer follow-ups on PR #205: add regression tests for title and last-name-prefix interaction in the suffix-comma branch, mirroring existing coverage for the no-comma branch, and split a run-on sentence in AGENTS.md's parse-flow notes for readability. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
1 parent 8b2179f commit 67621fe

2 files changed

Lines changed: 15 additions & 1 deletion

File tree

AGENTS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ Parse flow:
9797
3. `parse_pieces()` — splits on spaces, detects dotted abbreviations like "Lt.Gov." and adds them to constants dynamically
9898
4. `join_on_conjunctions()` — merges pieces adjacent to conjunctions into single tokens (e.g. `['Secretary', 'of', 'State']``['Secretary of State']`); also joins prefix particles to the following lastname token
9999
— a piece merged with a title *or prefix* neighbor is re-registered into that constant set so later steps still recognize it, e.g. `von`+`und`+`zu` → registered as a prefix so the whole phrase joins to the last name (German "von und zu"; PR #191)
100-
4a. `_join_bound_first_name()` — called immediately after step 4 in all three paths that build a first-name-bearing token sequence: no-comma, lastname-comma (post-comma pieces), and suffix-comma (`parts[0]`); merges bound given-name prefixes (e.g. "abdul") with the next piece before the assignment loop runs; suffixes are still in `pieces` at this point, so the `reserve_last` guard must count non-suffix pieces only. Not called for the lastname portion itself (`lastname_pieces` in the lastname-comma path) — that token sequence is a surname, not first-name text, so the join must not apply there. This is why the join lives at each of these three call sites individually rather than inside `parse_pieces()` itself: `parse_pieces()` is also called for the lastname portion with the same `additional_parts_count` value used for the (joinable) post-comma given-names portion, so `additional_parts_count` alone can't disambiguate which callers want the join.
100+
4a. `_join_bound_first_name()` — called immediately after step 4 in all three paths that build a first-name-bearing token sequence: no-comma, lastname-comma (post-comma pieces), and suffix-comma (`parts[0]`); merges bound given-name prefixes (e.g. "abdul") with the next piece before the assignment loop runs; suffixes are still in `pieces` at this point, so the `reserve_last` guard must count non-suffix pieces only. Not called for the lastname portion itself (`lastname_pieces` in the lastname-comma path) — that token sequence is a surname, not first-name text, so the join must not apply there. The join lives at each of these three call sites individually rather than inside `parse_pieces()` itself. That's because `parse_pieces()` is also called for the lastname portion with the same `additional_parts_count` value used for the (joinable) post-comma given-names portion, so `additional_parts_count` alone can't disambiguate which callers want the join.
101101
5. Iterates pieces, assigning to `title_list`, `first_list`, `middle_list`, `last_list`, `suffix_list`
102102
6. `post_process()``handle_firstnames()` swaps first/last when only a title + one name; then, gated on `patronymic_name_order`, `handle_east_slavic_patronymic_name_order()` and `handle_turkic_patronymic_name_order()` reorder Russian-formal-order and reversed Turkic patronymics; then, gated on `middle_name_as_last`, `handle_middle_name_as_last()` folds `middle_list` into `last_list`; finally `handle_capitalization()` applies optional auto-cap. Any new `self._attr` used by `post_process()` helpers must be initialized in `__init__` (with its default value) — the direct-kwargs path bypasses `parse_full_name()`, so the attribute won't exist otherwise.
103103

tests/test_bound_first_names.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,20 @@ def test_suffix_comma_guard_two_tokens_no_join(self) -> None:
128128
self.m(hn.last, "Salam", hn)
129129
self.m(hn.suffix, "MD", hn)
130130

131+
def test_suffix_comma_title_kept_prefix_joins(self) -> None:
132+
hn = HumanName("Dr. Abdul Salam Hassan, MD")
133+
self.m(hn.title, "Dr.", hn)
134+
self.m(hn.first, "Abdul Salam", hn)
135+
self.m(hn.last, "Hassan", hn)
136+
self.m(hn.suffix, "MD", hn)
137+
138+
def test_suffix_comma_abu_bakr_al_baghdadi(self) -> None:
139+
"""abu joins forward as first-prefix; al joins forward as last-prefix, even with suffix comma."""
140+
hn = HumanName("Abu Bakr Al Baghdadi, MD")
141+
self.m(hn.first, "Abu Bakr", hn)
142+
self.m(hn.last, "Al Baghdadi", hn)
143+
self.m(hn.suffix, "MD", hn)
144+
131145
# --- opt-out ---
132146
def test_opt_out_via_clear(self) -> None:
133147
"""Clearing bound_first_names restores prior behavior."""

0 commit comments

Comments
 (0)