Skip to content
Merged
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
4 changes: 4 additions & 0 deletions docs/design/decisions.md
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,10 @@ Declined (ambiguity kinds for script-resolved names, 2026-07-27):
FOUND BY THE PR REVIEW'S P5 FINDING, and that is the part worth keeping. The reserve fix under #P5 was correct on its own terms and left `Sir abdul rahman Prof.` reading family `abdul rahman`: the join fired for the right reason and the field was still wrong. What the review then asked was which run each site reads, and the answer was that they read DIFFERENT runs — group's licence has always read only the pieces ahead of the bound word (`range(fk)`), while H1 read every title token — so the 2026-08-22 #369 invariant under #P5, that H1 and P5 cannot read one run two ways, had been broken by the composite keying without any site's own tests noticing. Both now read the leading run, through the same predicate, and `nameparser/_pipeline/_group.py` records that beside the licence.
MEASURED 2026-09-09, over every distinct name in `tools/differential/corpus*.jsonl`, parsed on the fix's parent (`e489dc1`) and on the fix and diffed across the seven fields and the ambiguity kinds: over the corpus AS THE PARENT HAD IT, not one name moves; over the corpus as this commit leaves it, exactly TWO do and they are the two rules.md examples this entry adds (`Sir John Prof.`, `Dr. Smith Sir.`). The composite shape needs a title run at BOTH ends and no corpus name had one before those two, which is why a defect this plain sat behind four green gates. `Dr. King Sir.` is untouched and stays #H4's: its leading run is `dr king`, whose last word `king` IS a given-name title, so the word the peel left standing reads given `Sir.` with `title-or-name` reported. The end-to-end invariant is `tests/v2/test_parser.py::test_the_p5_licence_and_h1_read_a_title_run_the_same_way`, whose trailing-title half now requires `f"{title} abdul rahman Prof."` and `f"{title} John Prof."` to give the same given and family as the spellings without the trailing title; restoring the whole-`titles` key fails six of its eleven rows, which is the mutation that proves it discriminates. It carries the nickname spellings as well, and those are the only rows that separate the two splits above. Frame delta zero on both entry points: the run is built inside H1's guard, after the role counts have short-circuited, and the reference name `Dr. Juan0000 de la Vega III` has a family and never enters it.

- 2026-09-10 [#519](https://github.com/derek73/python-nameparser/issues/519) — `prince` and `princess` join the given-name titles; `lord` and `lady` do not. This RESOLVES the VOCABULARY SCOPE paragraph of the 2026-09-08 #489 bullet above, which is left as written: it named the four as not given-name titles and filed the question, and two of the four have now moved. The criterion is rules.md H Background's — membership follows how the title addresses — and `prince` and `princess` address by the given name (`Prince Harry`, `Princess Anne`), with no surname reading of the word behind it. The clause is for the two words and not for a royal class: TITLES holds `emperor`, `tsar`, `sultan`, `pharaoh`, `archduke`, `maharani` and their pairs, none of them weighed here, and `Emperor Akihito` still reads family `Akihito`. `lord` and `lady` split the same way as each other, by the bearer's rank, which the text does not carry: the given-name form is a courtesy style for children of the senior ranks alone — younger sons of dukes and marquesses (`Lord Peter`), daughters of dukes, marquesses and earls (`Lady Diana`) — and every peer and every wife takes the title or surname (`Lord Byron`, `Lady Thatcher`). [Debrett's "The trouble with titles"](https://debretts.com/the-trouble-with-titles/) and [Bratman's peerage primer](https://www.dbratman.net/nobility.html), both read 2026-09-10, agree on that boundary, Debrett's naming `Lady Jane Debrett` for a baronet's wife as the typical error. The issue gave `lord` the surname reading outright, hedged with a "mostly"; the hedge is this class. The set has no way to say "sometimes" — the `venerable` reasoning under #indic-honorifics — so Derek's call was to leave both out, decided rather than deferred, and the issue's proposed frequency test on `lady` was not run. Both are pinned as negative controls (`Lord Byron`, `Lady Gaga`) beside `His Excellency Lord Duncan`.
Both read sites move, through the one predicate: H1's fold reads `Prince Harry` given `Harry` and `Her Royal Highness Princess Anne` given `Anne` (the #489 bundle's negative control, flipped), and P5's licence reads `Prince abdul Rahman` given `abdul Rahman` with an empty family, as `Sir abdul Rahman` does. What membership does NOT decide is whether the word is a title at all: `Prince Fielder` reads given `Fielder` now and read family `Fielder` before, wrong both ways, and that is [#348](https://github.com/derek73/python-nameparser/issues/348)'s collision.
Measured 2026-09-10 over every name in `tools/differential/corpus*.jsonl` (1308 rows), parsed on this tree and on the same tree with a Lexicon whose `given_name_titles` lacks the two words, diffed across the seven fields and the ambiguity kinds: exactly TWO names move, `Prince Charles` and `Prince Fielder`, both radar-tier in corpus_issues.jsonl, both `{family, given}`. THREE after the docs commit, which puts `Her Royal Highness Princess Anne` in corpus_rules.jsonl as an H1 example. `Prince of Wales Jr` does not move — the joined run addresses by `wales`. Recompute by parsing the corpus glob twice with the two Lexicons and diffing. TITLES membership is unchanged, TITLES being the union.

### H2 — the leading-abbreviation title

- 2026-06-30 (leading-period-title design; v2 core, PR #288) — the shape test is v1 parity (period_abbreviation): two-plus letters then a period, bare initials exempt. Its site is the head of the part CARRYING THE GIVEN NAME — the whole name, or the post-comma part under a family comma — not "the head of the name"; that scope correction is PR #315 (2026-08-01, docs-only), verified against 1.4.0 from PyPI, so the parity claim is real and the narrower description never was. The extraction litmus (2026-08-15): the spec drafted this rule as
Expand Down
9 changes: 7 additions & 2 deletions docs/design/rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ H1. Rationale: a title normally addresses by surname, so a title
"Sir John Prof." → given="John"
"Dr. Smith Sir." → family="Smith"
"His Excellency Lord Duncan" → family="Duncan"
"Her Royal Highness Princess Anne" → given="Anne"
"Sir John" → given="John" · boundary
Accepted: a given-name title plus one name word leaves the
family empty — the input names no family, and inventing one
Expand All @@ -78,8 +79,12 @@ H1. Rationale: a title normally addresses by surname, so a title
not change what the run addresses by, the last word being the
one asked — `His Excellency Lord Duncan` reads family `Duncan`
because `lord` is not a given-name title, not because the run is
long, and `Her Royal Highness Princess Anne` reads family `Anne`
for the same reason.
long. `lord` and `lady` stay out of that list by decision
(#519): each addresses by given name only as a courtesy style for
children of the senior ranks (`Lord Peter`, `Lady Diana`) and by
title or surname for every peer and every wife (`Lord Byron`,
`Lady Thatcher`), and the text does not say which the bearer is,
which the list cannot express; `prince` and `princess` are in it.
history: decisions.md#H1 · interacts: H3, H5, P2, P3, P5, M2, S1, S2, N1, N3 · implemented: nameparser/_pipeline/_post_rules.py

H2. Rationale: before a name, an abbreviation is almost always a
Expand Down
4 changes: 3 additions & 1 deletion docs/release_log.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Release Log

- **Mark ba as an acronym that is also an ordinary name, so a bare trailing Ba keeps the family name.** ``HumanName("Anna Ba")`` gives last ``Ba`` and reports a suffix-or-name ambiguity, where 2.0.0 through 2.2.0 gave suffix ``Ba`` and no last name. The SPACED full-name form keeps the credential reading: ``John Smith BA`` still gives suffix ``BA``, now flagged, and the dotted ``John Smith B.A.`` is an unflagged suffix, the periods settling it. The COMMA forms move, and this is the marking's real cost: ``Smith, BA`` gives first ``BA``, and ``John Smith, BA`` gives first ``BA``, last ``John Smith``, where 2.0.0 through 2.2.0 gave suffix ``BA`` for both -- what ``Smith, Ed`` costs, which S2 already accepted for the other ambiguous acronyms. A bracketed or quoted ``John Smith (BA)`` falls through to nickname parsing, as the 2.0 note for ``ma``/``do`` below recorded for that pair. Write ``B.A.`` to keep the credential reading. BA is a common credential and Ba a real surname in Vietnamese and Senegalese Fula, which is the ``ma``/``Ma`` shape exactly. No corpus name moves (#342)

- **Fix a title run addressing by its first title rather than its last.** ``HumanName("Her Majesty Queen Elizabeth")`` gives first ``Elizabeth`` with an empty last name, where every release since 1.4.0 gave last ``Elizabeth``. Several titles written together are one form of address and the one that does the addressing is the last, so the run is now matched whole or by its last word: ``Reverend Mother Teresa``, ``Dr. Sir John`` and ``Mr Sir John`` move the same way, and ``Sir Sheikh abdul rahman`` gives first ``abdul rahman``. What does NOT move is a run whose last word addresses by surname: ``His Excellency Lord Duncan`` still gives last ``Duncan`` and ``Her Royal Highness Princess Anne`` last ``Anne``, ``lord`` and ``princess`` not being given-name titles -- a vocabulary question with its own argument, filed separately (#519). A caller's multi-word entry still matches as a phrase. Two names in the differential corpora read differently for this rule. See the ``H1`` entry of ``docs/design/decisions.md`` (closes #489)
- **Fix a title run addressing by its first title rather than its last.** ``HumanName("Her Majesty Queen Elizabeth")`` gives first ``Elizabeth`` with an empty last name, where every release since 1.4.0 gave last ``Elizabeth``. Several titles written together are one form of address and the one that does the addressing is the last, so the run is now matched whole or by its last word: ``Reverend Mother Teresa``, ``Dr. Sir John`` and ``Mr Sir John`` move the same way, and ``Sir Sheikh abdul rahman`` gives first ``abdul rahman``. What does NOT move is a run whose last word addresses by surname: ``His Excellency Lord Duncan`` still gives last ``Duncan``, ``lord`` not being a given-name title. A caller's multi-word entry still matches as a phrase. Two names in the differential corpora read differently for this rule. See the ``H1`` entry of ``docs/design/decisions.md`` (closes #489)

- **Fix the leading title peel taking a name word and leaving a post-nominal to be the name.** ``HumanName("Dr King Jr")`` gives title ``Dr``, last ``King``, suffix ``Jr``, where every release since 1.4.0 gave title ``Dr King``, last ``Jr`` and no suffix at all; ``Dr. King MD`` moves the same way, and both now read as the comma spelling ``King, Dr Jr`` always has. A title addresses somebody, so the run leaves a name word standing and a post-nominal is not one. A name that is nothing but titles or nothing but post-nominals is untouched, the word given back having to be a name candidate: ``Marquess of Bath``, ``MD DDS`` and ``Jr. Ph. D.`` are unchanged, and so is a title written as one joined unit -- ``Prince of Wales Jr`` keeps title ``Prince of Wales`` rather than losing the title to make a name. Where the run's whole content is the word given back there is no title left, so ``Dr Jr`` gives first ``Dr``, suffix ``Jr`` and reports a title-or-name ambiguity. Three names in the differential corpora read differently for this rule. See the ``H3`` entry of ``docs/design/decisions.md``

Expand All @@ -34,6 +34,8 @@ Release Log

- **Add the renunciate titles to the given-name title list, so a renunciate's one name is a given name.** ``HumanName("Swami Vivekananda")`` gives first ``Vivekananda`` with an empty last name, where every release since 1.4.0 gave last ``Vivekananda``; ``Guru Nanak``, ``Baba Ramdev`` and ``Lama Zopa`` move the same way, and so do the Devanagari and Bengali spellings added below. Two name words behind the title are unchanged -- ``Swami Vivekananda Saraswati`` keeps last ``Saraswati`` -- and a surname-retaining title is untouched: ``Rabbi Cohen`` still gives last ``Cohen``. ``venerable`` is deliberately not in the list, the traditions using it splitting on whether the family name survives. See the ``indic-honorifics`` entry of ``docs/design/decisions.md`` (closes #346)

- **Add prince and princess to the given-name title list, so a royal's one name is a given name.** ``HumanName("Prince Harry")`` gives first ``Harry`` with an empty last name, where every release since 1.4.0 gave last ``Harry``; ``Princess Anne``, ``Her Royal Highness Princess Anne`` and ``Prince Charles`` move the same way, and ``Prince abdul Rahman`` gives first ``abdul Rahman`` as ``Sir abdul Rahman`` does. Two name words behind the title are unchanged -- ``Prince Harry Windsor`` keeps last ``Windsor`` -- and ``Prince of Wales Jr`` is unchanged, the joined title addressing by its last word. ``lord`` and ``lady`` are deliberately NOT in the list: ``Lord Byron`` still gives last ``Byron``, and ``Lady Gaga`` last ``Gaga``, because each addresses by given name only as a courtesy style for children of the senior ranks (``Lord Peter``, ``Lady Diana``) and by title or surname for every peer and every wife (``Lord Byron``, ``Lady Thatcher``), which the list cannot express. The given-name collision is untouched: ``Prince Fielder`` now gives first ``Fielder`` (#348). See the ``H1`` entry of ``docs/design/decisions.md`` (closes #519)

- **Add trailing honorifics as post-nominal vocabulary:** Latin ``rinpoche``, Devanagari ``जी``, ``साहब``, ``साहिब``, ``साहेब``, ``महाराज``, and Bengali ``সাহেব``, ``বাবু``, ``মহারাজ``. ``HumanName("Lama Zopa Rinpoche")`` reads title ``Lama``, first ``Zopa``, suffix ``Rinpoche``; ``नरेन्द्र मोदी जी`` reads last ``मोदी``, suffix ``जी``. They are recognized SPACED only and are deliberately absent from ``Lexicon.honorific_tails``: Banerjee, Mukherjee and Chatterjee end in the ``जी`` substring (``बनर्जी``, ``मुखर्जी``, ``चटर्जी``), so a glued peel would cut a real family name in two, and ``गांधीजी`` staying unpeeled is the accepted cost. Bengali ``বাবু`` is trailing where Devanagari ``बाबू`` is a leading title (#344, #343)

- **Add Devanagari honorifics (#344):** ``डॉक्टर``, ``डा``, ``प्रो``, ``प्रोफेसर``, ``प्राध्यापक``, ``प्रा``, ``पंडित``, ``पं``, ``सरदार``, ``सुश्री``, ``श्रीयुत``, ``श्रीमान``, ``सौ``, ``बाबू``, ``महात्मा``, ``न्यायमूर्ति``, ``मौलाना``, ``जनाब`` and ``महाराजा`` as titles, beside the ``श्री``/``श्रीमती``/``डॉ`` that shipped in 2.1.0, and ``स्वामी``, ``गुरु``, ``बाबा``, ``संत`` as given-name titles. ``डॉक्टर शर्मा`` reads title ``डॉक्टर``, last ``शर्मा``; ``स्वामी विवेकानंद`` reads first ``विवेकानंद`` with no last name. Dotted spellings (``प्रो.``, ``पं.``) match the same entries. Excluded under the collision rule: ``कुमारी`` (Kumari is a given and a family name), ``बेगम``, ``शेख``, ``आचार्य``, ``राजा``/``रानी`` and ``ठाकुर``, all borne as ordinary names (closes #344)
Expand Down
16 changes: 14 additions & 2 deletions nameparser/config/titles.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,20 @@
'master',
'mother',
'pope',
# #519: prince and princess address by the GIVEN name ("Prince
# Harry", "Princess Anne"), which is what membership here means
# (rules.md#H Background); both were in the TITLES-only block
# until 2026-09-10. 'lord' and 'lady' stay there, decided rather
# than deferred: both split by the bearer's rank, which the text
# does not carry -- the given-name form is a courtesy style for
# children of the senior ranks alone ("Lord Peter", "Lady Diana"),
# and every peer and every wife takes the title or surname ("Lord
# Byron", "Lady Thatcher") -- and this set has no way to say
# "sometimes" (the 'venerable' reasoning above). Membership decides only which field the one word
# behind the title takes: "Prince Fielder" is #348's collision
# either way.
'prince',
'princess',
'queen',
'sir',
'sister',
Expand Down Expand Up @@ -584,8 +598,6 @@
'primate',
'prime',
'prin',
'prince',
'princess',
'principal',
'printer',
'printmaker',
Expand Down
Loading