Skip to content

Commit c19ce96

Browse files
derek73claude
andcommitted
fix: correct suffix boundary lookup for prefixed last names (#100)
The prefix-joining loop located the suffix stop boundary with a value-based pieces.index() that searched from position 0. When a token value repeated (a trailing title that is also a suffix acronym, e.g. the second 'dr' in 'dr Vincent van Gogh dr'), it matched the leading occurrence, producing an empty slice that duplicated pieces and corrupted the middle name. Constrain the lookup to start at i + 1, consistent with the sibling next_prefix lookup. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent f14fb58 commit c19ce96

2 files changed

Lines changed: 16 additions & 1 deletion

File tree

nameparser/parser.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -980,7 +980,10 @@ def join_on_conjunctions(self, pieces: list[str], additional_parts_count: int =
980980
try:
981981
# if there are no more prefixes, look for a suffix to stop at
982982
stop_at = next(iter(filter(self.is_suffix, pieces[i + 1:])))
983-
j = pieces.index(stop_at)
983+
# search from i + 1 so a repeated token earlier in the
984+
# list (e.g. a leading title that is also a suffix
985+
# acronym) is not matched instead of the trailing one
986+
j = pieces.index(stop_at, i + 1)
984987
new_piece = ' '.join(pieces[i:j])
985988
pieces = pieces[:i] + [new_piece] + pieces[j:]
986989
except StopIteration:

tests/test_prefixes.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,18 @@ def test_prefix_before_two_part_last_name_with_acronym_suffix(self) -> None:
4343
self.m(hn.last, "von bergen wessels", hn)
4444
self.m(hn.suffix, "M.D.", hn)
4545

46+
def test_title_before_and_after_prefixed_last_name(self) -> None:
47+
# Issue #100: a repeated title/suffix token ("dr") before AND after a
48+
# prefixed last name used to corrupt the middle name into
49+
# " dr Vincent van" because the suffix-boundary lookup matched the
50+
# LEADING "dr" instead of the trailing one.
51+
hn = HumanName("dr Vincent van Gogh dr")
52+
self.m(hn.title, "dr", hn)
53+
self.m(hn.first, "Vincent", hn)
54+
self.m(hn.middle, "", hn)
55+
self.m(hn.last, "van Gogh", hn)
56+
self.m(hn.suffix, "dr", hn)
57+
4658
def test_two_part_last_name_with_suffix_comma(self) -> None:
4759
hn = HumanName("pennie von bergen wessels, III")
4860
self.m(hn.first, "pennie", hn)

0 commit comments

Comments
 (0)