Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
```
- **A lone letter behind it reads as it does in the same part without the particle**: a capital is a name word ('SMITH VD V, JOHN' as 'SMITH V, JOHN'), a lowercase letter in a name of mixed case the numeral ('Smith vd v, John' as 'Smith v, John'), and a name written in one case reads as its capitals (T4).
```
"SMITH VD V, JOHN" → family="SMITH VD V" deviates: #1080 (today: family="SMITH VD")
"smith vd v, john" → family="smith vd v" deviates: #1080 (today: family="smith vd")
"SMITH VD V, JOHN" → family="SMITH VD V"
"smith vd v, john" → family="smith vd v"
```
- **In the part after a family comma**, where P6 attaches a particle ending the name to the family, a lone word of both the particle and the UNAMBIGUOUS suffix vocabulary standing INSIDE a run read as post-nominals — one in front of it and another behind, a credential or a generation, whatever made each one, and a title between it and the one in front transparent (H5) — is not the tussenvoegsel: that stands right behind the given name, so a post-nominal between them says the word is not one. It does not end the name, and keeps the post-nominal reading in any case, reported as S4's credential fork.
```
Expand Down
1 change: 1 addition & 0 deletions docs/release_log.rst
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ Release Log
- **Fix the surname Mba read as the MBA degree.** ``parse("Chinedu Mba")`` gives family ``Mba``, as 1.4.0 did, where 2.0.0 through 2.8.1 gave suffix ``Mba`` and no family. ``John Smith, MBA`` and ``John Smith MBA`` still read the degree; where a name word can stand, it reads as the name, as ``MA`` does (``Smith, MBA Jane`` gives given ``MBA``), and brackets configured for maiden names read ``(MBA)`` as the maiden name. :issue:`1005`
- **Fix the Filipino particle Delos, de los written as one word, reading as a middle name.** ``parse("Juan Delos Reyes")`` gives family ``Delos Reyes``, as ``Juan Dela Cruz`` gives ``Dela Cruz``, where 1.4.0 through 2.8.1 gave middle ``Delos``, family ``Reyes``. ``Delos`` is a given name too, so ``Delos Wheeler`` still gives given ``Delos``, now reporting particle-or-given. Case repair keeps both capitalized: ``parse("JUAN DELA CRUZ").capitalized()`` gives ``Juan Dela Cruz``, where 1.4.0 through 2.8.1 gave ``Juan dela Cruz``. :issue:`1037`
- **Fix a family-comma name losing the given name Junior to the suffix.** ``parse("Silva, Junior Carlos")`` gives given ``Junior``, middle ``Carlos``, as 2.2.0 and 2.3.0 did, where 2.4.0 through 2.8.1 gave suffix ``Junior Carlos`` and no given name. Junior and Júnior are given names too, so a name with no word to spare keeps one as the name (``Kofi Junior`` gives family ``Junior``), while ``John Smith Junior`` still gives suffix ``Junior``. A generation word you give a name reading with ``Lexicon.add`` is weighed by the count alone, as ``Junior`` is; add it with ``title_case_is_name=True`` to have Title case read as the name, as ``fils`` does. :issue:`1039`
- **Read a lone letter behind a particle before a family comma as the comma-less name reads it.** ``parse("SMITH VD V, JOHN")`` gives family ``SMITH VD V``, where 2.7.0 and 2.8.0 gave family ``SMITH VD`` and suffix ``V``: a particle is no word to spare, so the letter counts the name words in front of it alone. ``SMITH VD VI, JOHN`` keeps suffix ``VI`` and ``SMITH VD, JOHN`` suffix ``VD``. :issue:`1080`

* 2.8.2 - November 4, 2026

Expand Down
12 changes: 9 additions & 3 deletions nameparser/_pipeline/_assign.py
Original file line number Diff line number Diff line change
Expand Up @@ -778,8 +778,8 @@ def as_a_name(i: int) -> PendingReading:
def _family_part_numeral(word: WorkToken, preceding: str, names: int,
one_case: bool | None) -> Role | None:
"""The role of a roman numeral ending the family part before a
family comma, behind `names` pieces of that part, as the comma-less
name reads one ending it (rules/S10), or None where the numeral's
family comma, behind `names` name words of that part, as the
comma-less name reads one ending it (rules/S10), or None where the numeral's
predicate reads no numeral there (an initial in front, a letter with
its period): the suffix where it reads as the generation, a
one-letter numeral needing two name words in front of it, and the
Expand Down Expand Up @@ -1939,9 +1939,15 @@ def as_a_middle(m: int, token: WorkToken) -> PendingReading:
and all(is_suffix_piece(fam_pieces[j], fam_tags[j],
tokens)
for j in range(k + 1, len(fam_pieces)))
# rules/P9, #1080: the numeral is read by the name
# words in front of it, a particle none to spare
# ('SMITH VD V, JOHN' as 'SMITH V, JOHN' reads)
and (numeral := _family_part_numeral(
word, tokens[fam_pieces[k - 1][0]].text,
k - lead, state.one_case)) is not None):
1 + sum(1 for j in range(lead + 1, k)
if "particle"
not in tokens[fam_pieces[j][0]].tags),
state.one_case)) is not None):
_set_roles(tokens, piece, numeral)
# reported where taken: a name word here is the family
# name the comma has just named, which nobody misreads
Expand Down
24 changes: 24 additions & 0 deletions tests/v2/cases.py
Original file line number Diff line number Diff line change
Expand Up @@ -2534,6 +2534,30 @@ def _check_cjk_shape_purity(self) -> None:
"mixed-case row above does. 2.2.0 and 2.3.0 read family "
"'SMITH MA', suffix 'VD'; 2.0.0 and 2.1.0 read as here; "
"1.4.0 last 'SMITH', suffix 'VD, MA'"),
Case("a_lone_letter_behind_a_particle_before_a_comma_is_the_name_word",
"SMITH VD V, JOHN",
{"given": "JOHN", "family": "SMITH VD V"},
classification="fix(#1080)",
notes="P9: a lone letter behind a particle reads as it does in "
"the same part without one, so the particle is no word to "
"spare and 'V' is a name word. 2.7.0 and 2.8.0 read family "
"'SMITH VD', suffix 'V'; 2.6.0 read as here"),
Case("a_lone_letter_behind_a_plain_particle_before_a_comma_is_the_name_word",
"SMITH VAN V, JOHN",
{"given": "JOHN", "family": "SMITH VAN V"},
classification="fix(#1080)",
notes="#1080's table: the count leaves out every particle, not "
"only the word that is suffix vocabulary too, so 'VAN' is "
"no word to spare. 2.7.0 and 2.8.0 read family 'SMITH "
"VAN', suffix 'V'; 2.6.0 read as here"),
Case("a_lone_letter_behind_a_particle_run_before_a_comma_is_the_name_word",
"Smith van der V, John",
{"given": "John", "family": "Smith van der V"},
classification="fix(#1080)",
notes="#1080's table: a run is no word to spare either -- its "
"length is why the count drops the whole run and not one "
"particle. 2.7.0 and 2.8.0 read family 'Smith van der', "
"suffix 'V'; 2.6.0 read as here"),
Case("a_comma_before_no_name_word_keeps_the_positional_read",
"Berg de MA, Prof.",
{"title": "Prof.", "given": "Berg", "family": "de",
Expand Down
4 changes: 2 additions & 2 deletions tools/differential/snapshot.jsonl
Original file line number Diff line number Diff line change
Expand Up @@ -3324,7 +3324,7 @@
{"name": "SEÁN Ó MURCHÚ", "given": "SEÁN", "family": "Ó MURCHÚ", "initials": "S. M.", "capitalized": "Seán Ó Murchú"}
{"name": "SIG.RA MARIA ROSSI", "title": "SIG.RA", "given": "MARIA", "family": "ROSSI", "initials": "M. R.", "capitalized": "Sig.ra Maria Rossi"}
{"name": "SMITH VD MA, JOHN", "given": "JOHN", "family": "SMITH VD MA", "initials": "J. S. M.", "capitalized": "John Smith vd Ma"}
{"name": "SMITH VD V, JOHN", "given": "JOHN", "family": "SMITH VD", "suffix": "V", "ambiguities": ["SUFFIX_OR_NAME"], "alternatives": ["SUFFIX_OR_NAME: initial as family (shape)"], "initials": "J. S.", "capitalized": "John Smith vd V", "generation": "V"}
{"name": "SMITH VD V, JOHN", "given": "JOHN", "family": "SMITH VD V", "initials": "J. S. V.", "capitalized": "John Smith vd V"}
{"name": "SMITH VD, JOHN", "given": "JOHN", "family": "SMITH", "suffix": "VD", "initials": "J. S.", "capitalized": "John Smith VD"}
{"name": "SMITH, DEAN MR.", "title": "MR.", "given": "DEAN", "family": "SMITH", "initials": "D. S.", "capitalized": "Mr. Dean Smith"}
{"name": "SMITH, JOHN B. MAJ.", "title": "MAJ.", "given": "JOHN", "middle": "B.", "family": "SMITH", "initials": "J. B. S.", "capitalized": "Maj. John B. Smith"}
Expand Down Expand Up @@ -4358,7 +4358,7 @@
{"name": "scott e. werner", "given": "scott", "middle": "e.", "family": "werner", "initials": "s. e. w.", "capitalized": "Scott E. Werner"}
{"name": "scott l. werner", "given": "scott", "middle": "l.", "family": "werner", "initials": "s. l. w.", "capitalized": "Scott L. Werner"}
{"name": "señora María García", "title": "señora", "given": "María", "family": "García", "initials": "M. G.", "capitalized_force": "Señora María García"}
{"name": "smith vd v, john", "given": "john", "family": "smith vd", "suffix": "v", "ambiguities": ["SUFFIX_OR_NAME"], "alternatives": ["SUFFIX_OR_NAME: initial as family (shape)"], "initials": "j. s.", "capitalized": "John Smith vd V", "generation": "v"}
{"name": "smith vd v, john", "given": "john", "family": "smith vd v", "initials": "j. s. v.", "capitalized": "John Smith vd V"}
{"name": "smith, de ma", "family": "smith de ma", "ambiguities": ["SUFFIX_OR_NAME"], "alternatives": ["SUFFIX_OR_NAME: credential as suffix (vocabulary)"], "initials": "s. m.", "capitalized": "Smith de Ma"}
{"name": "smith, j y lopez", "given": "j", "middle": "y lopez", "family": "smith", "initials": "j. l. s.", "capitalized": "J y Lopez Smith"}
{"name": "smith, john e phd", "given": "john", "middle": "e", "family": "smith", "suffix": "phd", "initials": "j. e. s.", "capitalized": "John E Smith PhD"}
Expand Down
Loading