diff --git a/AGENTS.md b/AGENTS.md index 15c476e63..0b8aa6898 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -312,7 +312,7 @@ Don't use the bare `python3 -m doctest .rst` CLI (no `optionflags`) to che **`pr/NNN` local branches** track upstream PRs — don't commit to them by accident. Check `git branch --show-current` before starting work. -**Title vs suffix is positional for BARE words, and the leading period-abbreviation rule overrides even that** — a word matching `TITLES` at the front of a name becomes `title`; the same word matching `SUFFIX_ACRONYMS`/`SUFFIX_WORDS` at the end becomes `suffix` (never both, regardless of the word's real-world meaning). The `TITLES`/suffix overlap was audited in #296 (2026-08-23): the pure postnominals (`jr`, `junior`, `phd`, `do`, `se`) left `TITLES`, the v1-residue `dr`/`sra` left the suffix sets, and the ten words still in both (`ms`, `sr`, `lt`, `ra`, `vc`, and the ranks `cpl`, `cpo`, `cpt`, `csm`, `sgm`; `md` and `sa` were duals too until #853 took `md`'s title reading out, a leading `Md` being the given name Muhammad, and #857 took `sa` out of the vocabulary) are deliberate duals that position decides. External test sources (old issue gists, etc.) sometimes assert `suffix` for a leading professional abbreviation like `RA`/`PD`/`Dipl.-Ing.` — that's the source data being wrong, not a parser bug. Verify position before "fixing" it. Two qualifications the older "purely positional" wording papered over, the first measured 2026-08-01 and the second answered 2026-09-08 (#316): a PERIOD-marked leading word is claimed by the shape rule before any vocabulary is read (`"Esq. Smith"` → `title`, though `esq` is suffix-only), save a listed title and, since #789, a given name written short (`"Chas. Smith"` → `given`), and a PERIOD-marked trailing word is claimed by VOCABULARY — first the suffix sets, which the peel reads before anything else (`"John Smith Esq."` → `suffix`), then the titles (`"John Smith Prof."` → `title='Prof.'`, `rules/H5`) — while an unlisted abbreviation there stays a name part (`"John Smith Xyz."` → `family='Xyz.'`) unless it is written as two or more period-separated chunks, which since 2.4 IS a trailing shape rule (`Policy.unlisted_dotted_suffixes`, default on: `"John Smith X.Y.Z."` → `suffix='X.Y.Z.'`, read by the same words-to-spare count a bare ambiguous acronym takes, `rules/S3`), except paired initials in a script with capitals, which stay a name word (`"Ram Bahadur B.K."` → `family='B.K.'`, #864). The SINGLE trailing period is still not one, deliberately — it is the abbreviation shape any word can wear. The bare word is where "positional" still holds whole -- outside a part past the second comma, which holds no name word, so C2 reads a bare title word there as a title since #603 (`Eric H. Holder, Jr., Attorney General`), and outside a listed salutation ending the given part after a family comma, which rules/H8 reads as the title since #835 (`Doe, Jane Mrs`), the comma having marked the surname's place -- and the reason it must: `TITLES` holds words that are in no suffix set — 787 of them on 2026-10-11 (746 before #606's salutations), measured with `L = Parser().lexicon; len(L.titles - L.suffix_acronyms - L.suffix_words)`, a figure that grows with the vocabulary and never shrinks the argument — and many are ordinary surnames (`pope`, `bishop`, `prince`, `judge`, `sheriff`, `baron`, `master`, ...), so a vocabulary-first rule over BARE trailing words would read `"Mary Jane Pope"` as `title='Pope'`, `family='Jane'`. The period is what separates the safe case from that one, and it separates it by being a WRITING convention rather than by making the collision go away: `"Mary Jane Pope"` keeps `family='Pope'` while `"Mary Jane Pope."` reads `title='Pope.'`, `family='Jane'`, a cost accepted under the input-is-a-name premise rather than one the rule prevents (the trailing-position bullet in decisions/vocabulary-exclusions, measured 2026-09-09). Since #316 that sentence describes the shipped rule rather than an aspiration. +**Title vs suffix is positional for BARE words, and the leading period-abbreviation rule overrides even that** — a word matching `TITLES` at the front of a name becomes `title`; the same word matching `SUFFIX_ACRONYMS`/`SUFFIX_WORDS` at the end becomes `suffix` (never both, regardless of the word's real-world meaning). The `TITLES`/suffix overlap was audited in #296 (2026-08-23): the pure postnominals (`jr`, `junior`, `phd`, `do`, `se`) left `TITLES`, the v1-residue `dr`/`sra` left the suffix sets, and the ten words still in both (`ms`, `sr`, `lt`, `ra`, `vc`, and the ranks `cpl`, `cpo`, `cpt`, `csm`, `sgm`; `md` and `sa` were duals too until #853 took `md`'s title reading out, a leading `Md` being the given name Muhammad, and #857 took `sa` out of the vocabulary) are deliberate duals that position decides. External test sources (old issue gists, etc.) sometimes assert `suffix` for a leading professional abbreviation like `RA`/`PD`/`Dipl.-Ing.` — that's the source data being wrong, not a parser bug. Verify position before "fixing" it. Two qualifications the older "purely positional" wording papered over, the first measured 2026-08-01 and the second answered 2026-09-08 (#316): a PERIOD-marked leading word is claimed by the shape rule before any vocabulary is read (`"Esq. Smith"` → `title`, though `esq` is suffix-only), save a listed title and, since #789, a given name written short (`"Chas. Smith"` → `given`), and a PERIOD-marked trailing word is claimed by VOCABULARY — first the suffix sets, which the peel reads before anything else (`"John Smith Esq."` → `suffix`), then the titles (`"John Smith Prof."` → `title='Prof.'`, `rules/H5`) — while an unlisted abbreviation there stays a name part (`"John Smith Xyz."` → `family='Xyz.'`) unless it is written as two or more period-separated chunks, which since 2.4 IS a trailing shape rule (`Policy.unlisted_dotted_suffixes`, default on: `"John Smith X.Y.Z."` → `suffix='X.Y.Z.'`, read by the same words-to-spare count a bare ambiguous acronym takes, `rules/S3`), except paired initials in a script with capitals, which stay a name word (`"Ram Bahadur B.K."` → `family='B.K.'`, #864). The SINGLE trailing period is still not one, deliberately — it is the abbreviation shape any word can wear. The bare word is where "positional" still holds whole -- outside a part past the second comma, which holds no name word, so C2 reads a bare title word there as a title since #603 (`Eric H. Holder, Jr., Attorney General`), and outside a listed salutation ending the given part after a family comma, which rules/H8 reads as the title since #835 (`Doe, Jane Mrs`), the comma having marked the surname's place -- and the reason it must: `TITLES` holds words that are in no suffix set — 787 of them on 2026-10-11 (746 before #606's salutations), measured with `L = Parser().lexicon; len(L.titles - L.suffix_acronyms - L.suffix_words)`, a figure that grows with the vocabulary and never shrinks the argument — and many are ordinary surnames (`pope`, `bishop`, `judge`, `sheriff`, `baron`, `master`, ...), so a vocabulary-first rule over BARE trailing words would read `"Mary Jane Pope"` as `title='Pope'`, `family='Jane'`. The period is what separates the safe case from that one, and it separates it by being a WRITING convention rather than by making the collision go away: `"Mary Jane Pope"` keeps `family='Pope'` while `"Mary Jane Pope."` reads `title='Pope.'`, `family='Jane'`, a cost accepted under the input-is-a-name premise rather than one the rule prevents (the trailing-position bullet in decisions/vocabulary-exclusions, measured 2026-09-09). Since #316 that sentence describes the shipped rule rather than an aspiration. ### Tests (`tests/`) diff --git a/docs/design/decisions/H1-title-and-one-name-word.md b/docs/design/decisions/H1-title-and-one-name-word.md index f49fca37f..9a3411693 100644 --- a/docs/design/decisions/H1-title-and-one-name-word.md +++ b/docs/design/decisions/H1-title-and-one-name-word.md @@ -6,13 +6,13 @@ - The guard tests which roles are unoccupied and counts no units, a gap recorded and not fixed: a given run of two name units moves whole (`Freiherr de V Jr` → family 'de V') — 2026-08-25 #410. - A title run addresses as its last title does, its key matched whole or by its last word through the one predicate H1 and P5's licence share: `Her Majesty Queen Elizabeth` and `Mr Sir John` read given 'Elizabeth' and 'John' — 2026-09-08 #489. - Where a run stands before the one name word, that run addresses; a run behind the word decides its field only when none stands before, and a run written around a nickname is one run: `Sir John Prof.` → given 'John', `Dr. Smith Sir.` → family 'Smith', `Smith Sir.` → given 'Smith', `Dr. 'Smitty' Sir John` → given 'John' — 2026-09-08 #489; 2026-09-09 #316. -- `prince` and `princess` are given-name titles and `lord` and `lady` are not, decided rather than deferred, since the text does not say which rank a bearer holds: `Prince Harry` → given 'Harry', `Lord Byron` → family 'Byron', `His Excellency Lord Duncan` → family 'Duncan' — 2026-09-10 #519. +- `prince` and `princess` are given-name titles and `lord` and `lady` are not, decided rather than deferred, since the text does not say which rank a bearer holds: `His Royal Highness Prince Harry` → given 'Harry' (the bare `Prince Harry` reads given 'Prince' in the default order since 2026-10-27, `prince` being a title only inside a title phrase, decisions/H9), `Lord Byron` → family 'Byron', `His Excellency Lord Duncan` → family 'Duncan' — 2026-09-10 #519. - H1 decides the field of the one name word before a comma with no given name after it, and of the one name word of a name read family-first: `Elizabeth II, Queen` → given 'Elizabeth', `Smith, Sir` → given 'Smith' with the family empty, `Sir John` and `Pope Francis` given under every order — 2026-10-18 #720. - A particle surname keeps the family where something settled it, a comma (`van der Berg, Sir`, `Van, Sir`) or P1's fold asked of the leading name piece (`Sir de Mesnil`); an ambiguous particle no comma settled reads given (`Sheik Abu Bakar`, `Sir Van` family-first), and so does a never-given one the fold does not take (`St Sir de Mesnil` under every order) — 2026-10-18 #720. Elsewhere: the graf class, a title word borne as a name but rarely as its first word shipping as a title (`Greve Anna` → title 'Greve', family 'Anna'), is decisions/salutation-titles' 2026-10-04 #606 bundle; the renunciate class, the given-name titles of traditions that drop the surname (`Swami Vivekananda` → given 'Vivekananda'), is decisions/indic-honorifics' 2026-09-06 #346/#344/#343 bundle. -Open: [#348](https://github.com/derek73/python-nameparser/issues/348) (whether a word that is both a title and a given name reports an ambiguity; `Prince Fielder` reads given 'Fielder'); [#815](https://github.com/derek73/python-nameparser/issues/815) (whether N3 sets a suffix aside as this rule does, the nickname-led question the 2026-08-25 #410 entry left open: `'Smitty' Jones Jr.` reads given 'Jones', family ''). +Open: [#348](https://github.com/derek73/python-nameparser/issues/348) (whether a word that is both a title and a given name reports an ambiguity; `Baron Davis` reads title 'Baron'; `Prince Fielder` reads given 'Prince' in the default order since 2026-10-27, decisions/H9); [#815](https://github.com/derek73/python-nameparser/issues/815) (whether N3 sets a suffix aside as this rule does, the nickname-led question the 2026-08-25 #410 entry left open: `'Smitty' Jones Jr.` reads given 'Jones', family ''). ## Log diff --git a/docs/design/decisions/H4-input-that-is-nothing-but-vocabulary-still-has-to-name-somebody.md b/docs/design/decisions/H4-input-that-is-nothing-but-vocabulary-still-has-to-name-somebody.md index 2525be50f..3857083ad 100644 --- a/docs/design/decisions/H4-input-that-is-nothing-but-vocabulary-still-has-to-name-somebody.md +++ b/docs/design/decisions/H4-input-that-is-nothing-but-vocabulary-still-has-to-name-somebody.md @@ -7,8 +7,8 @@ - Nothing is reported where no word was chosen or where the word left standing is no title word: a title alone or a title run with nothing behind it (`Dr.`, `Prince of Wales`), and a title before an ordinary word (`Dr. Smith`) — 2026-09-07 #491. - An input whose every word is post-nominal vocabulary reads its first word as the name and reports `suffix-or-name` (`Rinpoche`, `QC MP` → given 'QC', `PhD`), reached only where no title was peeled (`RA DDS` reports nothing) and not with a maiden name beside it (`abd née Jones`) or for a lone CJK honorific a script order placed (`さん`); `Jr.` alone is H2's title — 2026-09-07 #491. - `MA` alone reports `given-or-family` where `PhD` alone reports `suffix-or-name`, an asymmetry between this rule and O5 recorded and not fixed — 2026-09-07 #491. -- A lone name unit that is a join carrying title vocabulary reports `title-or-name` too (`John of Prince`, `Smith and Prince`), stated since 2026-10-20 as rules/H7 — 2026-09-07 #491. -- The join clause (rules/H7's, recorded here) stands beside the peel clause, so a peeled title, a maiden name or a claimed word does not silence it (`Dr. Smith and Prince`, `van and Prince`, `Attorney General of Minnesota` report) — 2026-09-08 #518. +- A lone name unit that is a join carrying title vocabulary reports `title-or-name` too (`John of Bishop`, `Smith and Bishop`; `prince` was the example until it left TITLES on 2026-10-27, decisions/H9), stated since 2026-10-20 as rules/H7 — 2026-09-07 #491. +- The join clause (rules/H7's, recorded here) stands beside the peel clause, so a peeled title, a maiden name or a claimed word does not silence it (`Dr. Smith and Bishop`, `van and Bishop`, `Attorney General of Minnesota` report) — 2026-09-08 #518. Elsewhere: the title run's floor that leaves `Pope` standing in `Dr Pope Jr` and `Dr. Pope MD`, both reporting here, is decisions/H3's 2026-09-08 entry; the suffix and join halves' `detail` naming the field the word lands in, which moves with the order (`Rinpoche` 'a given name' by default, 'a family name' family-first), is decisions/A1's 2026-10-08 #626 entry; the join clause's move into a rule of its own is decisions/H7's 2026-10-20 #761 entry. diff --git a/docs/design/decisions/H9-title-phrase.md b/docs/design/decisions/H9-title-phrase.md index 064f9bd90..6dba575f0 100644 --- a/docs/design/decisions/H9-title-phrase.md +++ b/docs/design/decisions/H9-title-phrase.md @@ -71,3 +71,8 @@ - THE COST, accepted by Derek on 2026-10-27 ("accepted"), shown the share of rulers below beside `king`'s and `sultan`'s and that `His Highness` in front keeps the title: a ruler or a member of a ruling house written with the bare title in front reads it as the given name (`Shaikh Hamad bin Isa Al Khalifa` → given 'Shaikh', middle 'Hamad bin Isa', where 1.4.0 through 2.6.0 read title 'Shaikh', given 'Hamad'), the class accepted for `king` and `sultan`, here larger in news text and smaller in record data. In jrc-names 59 persons have a spelling opening with `Shaikh`: by a reading of each, about 38 are Gulf rulers and members of their houses (`Shaikh` is the Bahraini English press's spelling), about 13 clerics and tribal or political leaders, and about 8 people whose name opens with it. In PSC the forename box holds it first in 38 of the 41 moved records and the title box in 2, beside 3 title-box filings newly set aside (below). - MEASURED (2026-10-26, against master `fb4cafac`, py3.11, every local check with `--base`). PSC (1,039,171 scored, 3 more title boxes set aside, each `Shaikh` filed as a title) 33 records fixed, 1 broken (`Shaikh` filed in the title box), 7 changed, each still wrong for another reason (among them a two-word surname box and a title-box filing); ctgov-officials 8 moved, 7 fixes (4 `Shaikh A Aa, CRED` read with the initial as the given name, 2 `Aa Shaikh, CRED, CRED` whose credential master read as the given name), 1 still reading its credential as the given name; fec-individuals 2, both fixes after a family comma (`AA, SHAIKH` and `AA, SHAIKH AA`: given 'SHAIKH' where master read the title); tse-donors and nepal-candidates none; spelling pairs (mechanisms.md#PAIRED-SPELLINGS-PER-CHANGE) jrc-names 0 persons now alike and 12 now apart, every one a person spelled both `Shaikh` and `Sheikh`, which `sheikh`'s batch is to rejoin. No committed corpus name held `shaikh` before the batch's three rule examples, so they and CLDR and GND agreement do not move, and could not have. A v1 `Constants().titles` keeps `shaikh` with no edit (the v1 title list entry above), its sweep in `tests/v2/test_config_shim.py` gaining six rows. Recompute: `uv run python tools/differential/local_agreement.py psc-individuals --base `, and `uv run python tools/differential/snapshot.py --local ctgov-officials --base ` (and `fec-individuals`, `tse-donors`, `nepal-candidates`). +- **2026-10-27 #752, phase 2j, `prince` and `princess` (Derek) — THE EIGHTH TITLE BATCH: TWO GIVEN-NAME TITLES.** The batch decisions/vocabulary-model's 2026-10-24 #752 (Derek) entry put next, the two words taken together as one rank in two genders. Both gain a dated `given` reading and are titles only inside a title phrase; no listed phrase holds either, so nothing is reported. `Prince Fielder`, `Mr Prince Smith`, `Ms Princess Smith` and `Smith, Princess` read given 'Prince' or 'Princess', where 1.4.0 through 2.6.0 read the title (`Prince Fielder` given 'Fielder' from 2.3.0, last 'Fielder' in 1.4.0). A style keeps the title (`His Royal Highness Prince Harry`, `Her Royal Highness Princess Anne`), and so does `of` (`Prince of Wales`) or a modifier (`Grand Prince Vladimir`); inside the phrase each still addresses by the given name (decisions/H1's 2026-09-10 #519 entry), so the word behind it is the given name. The other sites read as for `king`: before a family comma H6 no longer peels it (`Prince Smith, John` → family 'Prince Smith', 1.4.0's reading), ending the name, alone after a full name and a comma, and past a second comma. `prince` was a worked example in three places, each now written with a word that reads as it did on master: H7's join (`John of Bishop`, `Dr. Smith and Bishop`, `John of Bishop Prof.`, where `John of Prince` now reports `given-or-family`, `prince` being no longer TITLES vocabulary), H1's comma example (`Anne, Swami`), and H9's modifier written after its head (`Her Royal Highness Princess Royal Anne`, the style keeping `princess` a title for `royal` to follow). The #519 case rows that pin the membership write the style in front. + - THE COUNTS, recorded on the words (`uv run python tools/name_usage.py Prince` and `Princess`, 2026-10-27): `prince` given US SSA 24,151 births (23,601 male), Wikidata 204 (United States 53, Ghana 19, Nigeria 10), nam_dict band 1 in the U.S.A. and India/Sri Lanka; family Census 47,168 (rank 743), Wikidata 525. `princess` given US SSA 15,982 births, Wikidata 29 (Nigeria 6, Ghana 3), nam_dict band 1 in the U.S.A.; family Census under 100, Wikidata 1. + - THE COST, accepted by Derek on 2026-10-27, shown the share of royals below beside `king`'s, `sultan`'s and `shaikh`'s and that a style or `of` keeps the title: a royal written with the bare title in front reads it as the given name (`Prince Harry` → given 'Prince', family 'Harry', where 2.3.0 through 2.6.0 read title 'Prince', given 'Harry'), the class accepted for `king`, `sultan` and `shaikh`. In jrc-names 43 persons have a spelling opening with a bare `Prince` or `Princess` (one not followed by `of`): by a reading of each, about 33 are royals, 8 people whose given name is Prince, and 2 no person at all (a fictional character, a place). In PSC 12 of the 233 moved records file the word in the title box (10 broken, 2 changed). + - MEASURED (2026-10-27, against master `ac81de9c`, py3.11, every local check with `--base`). PSC 205 records fixed, 10 broken, every one `Prince` (6) or `Princess` (4) filed in the title box, which the scorer now sets aside, 18 changed, most now reading the given name right and splitting a two-word surname box, 2 of them title-box filings; ctgov-officials 6 moved, all fixes: 4 open with the word, 3 of them before a credential comma, 1 glues an initial to it (`J.Prince Aa, CRED`), and 1 is `Aa Prince, CRED`, whose credential master read as the given name; fec-individuals 43, all fixes, every one `AA, PRINCE` or `AA, PRINCESS` in the listing form, 28 of which had read no family name; nepal-candidates 3, fixes; jrc-names 101 spellings moved, the royals above and `Archduchess of X Princess Y`, a title before the word that is no partner of it; tse-donors and ukec-individuals none; spelling pairs (mechanisms.md#PAIRED-SPELLINGS-PER-CHANGE) jrc-names 4 persons now alike and 0 apart, nepal-candidates 3 and 0. The committed corpora move by `Prince Charles` and `Prince Fielder` (corpus_issues, #348's examples) beside the batch's own rule examples; CLDR and GND agreement do not move. A v1 `Constants().titles` keeps both words with no edit (the v1 title list entry above). + Recompute: `uv run python tools/differential/local_agreement.py psc-individuals --base `, and `uv run python tools/differential/snapshot.py --local ctgov-officials --base ` (and `fec-individuals`, `tse-donors`, `ukec-individuals`, `nepal-candidates`, `jrc-names`). diff --git a/docs/design/decisions/vocabulary-model.md b/docs/design/decisions/vocabulary-model.md index bed94e1d7..d96df7f60 100644 --- a/docs/design/decisions/vocabulary-model.md +++ b/docs/design/decisions/vocabulary-model.md @@ -218,6 +218,7 @@ Open: #752 (phase 2, derived ambiguity; its sub-phases 2a to 2m, each its own PR - `dean`, `justice` and `major` gain an office or military reading beside a dated `given` one; `justice`'s exclusion (#606) is replaced by the reading. The batches of 2j declare the rest. Adding the four fields changes `Lexicon`'s pickle layout, as phase 2h did. - **2026-10-26 #752, phase 2i (Derek) — `attaches` MAY NAME A TITLE WORD AS WELL AS A KIND, AND `grace` AND `marshal` JOIN THE CONTESTED TITLES.** Amends the `attaches` bullet of the 2026-10-25 #752, phase 2i entry: a kind reaches every word that later joins it, and once `marshal` became a contested military word the military kind made `Sgt Marshal Smith` a title phrase. A list entry that is no kind must be a word with a title reading (a build check, its mutation in tests/v2/test_vocab.py). `major` attaches to `general` and `sergeant` and `sgt` to `major`. `grace` (style) and `marshal` (military, its #606 exclusion replaced) carry dated `given` readings. The measurement and Derek's answers are decisions/H9's entry of this date. +- **2026-10-27 #752, phase 2j, `prince` and `princess` (Derek) — THE EIGHTH TITLE BATCH: both have a dated `given` reading**, so each is a title only inside a title phrase. `Prince Fielder`, `Mr Prince Smith` and `Smith, Princess` read the given name; a royal written with the bare title does too (`Prince Harry`), the class accepted for `king`, `sultan` and `shaikh`, accepted by Derek on 2026-10-27. `His Royal Highness Prince Harry` and `Prince of Wales` keep the title. The measurement is decisions/H9's entry of this date. - **2026-10-26 #752, phase 2j, `shaikh` (Derek) — THE SEVENTH TITLE BATCH: `shaikh` has a dated `given` reading**, so the style is a title only inside a title phrase. `Shaikh Ahmed Khan` and `Mr Shaikh Ahmed` read given 'Shaikh'; a ruler written with the bare title does too (`Shaikh Hamad bin Isa`), the class accepted for `king` and `sultan`, the larger share of rulers Derek accepted on 2026-10-27. `sheikh` keeps its own batch. The measurement is decisions/H9's entry of this date. - **2026-10-26 #752, phase 2j, `sultana` and `sultan` (Derek) — THE FIFTH AND SIXTH TITLE BATCHES, IN ONE PR: both have dated `given` readings**, `sultan`'s on its tr.toml entry, so each is a title only inside a title phrase. `Sultana Begum` and `Sultan Khan` read the given name; a sultan written with the bare title does too (`Sultan Hassanal Bolkiah`), the cost accepted for `king`. Derek combined the two batches on 2026-10-26. The measurement is decisions/H9's entry of this date. - **2026-10-26 #752, phase 2j, `king` (Derek) — THE FOURTH TITLE BATCH: `king` has a dated `given` reading**, US SSA 37,890 births and Census rank 34 as a surname, so it is a title only inside a title phrase. `King Curtis` and `Mr King Smith` read given 'King'; a monarch written with the bare title does too (`King Henry`), the cost Derek accepted on 2026-10-26. `pope` replaces `king` as the worked example of a title that is also a surname wherever the rules and tests used it. The measurement is decisions/H9's entry of this date. diff --git a/docs/design/rules/H1-title-and-one-name-word.md b/docs/design/rules/H1-title-and-one-name-word.md index 315b48b61..e14cab6b7 100644 --- a/docs/design/rules/H1-title-and-one-name-word.md +++ b/docs/design/rules/H1-title-and-one-name-word.md @@ -16,7 +16,7 @@ ``` "Elizabeth II, Queen" → given="Elizabeth" "John III, Sir" → given="John" - "Anne, Princess" → given="Anne" + "Anne, Swami" → given="Anne" "Sir John" family-first → given="John" "John III, Dr." → family="John" · boundary ``` @@ -51,7 +51,7 @@ "Her Majesty Queen Elizabeth" → family="" "Smith Sir." → family="" ``` -- A listing record whose given field holds only a given-name title reads that title's reading, so `Smith, Sir` (a row with the given name missing) reads given `Smith` with the family empty, as `Sir Smith` does: the input names one word and one title, and the title is the only evidence there is. 1.4.0 read the word before the comma as the last name in these rows (`Elizabeth II, Queen`, `John III, Sir`, `Smith, Sir`) but for `Anne, Princess`, which it read as first `Anne`. An ambiguous particle no comma settled, or a bare one, is a word the order placed, and reads given. +- A listing record whose given field holds only a given-name title reads that title's reading, so `Smith, Sir` (a row with the given name missing) reads given `Smith` with the family empty, as `Sir Smith` does: the input names one word and one title, and the title is the only evidence there is. 1.4.0 read the word before the comma as the last name in these rows (`Elizabeth II, Queen`, `John III, Sir`, `Smith, Sir`) but for `Anne, Swami`, which it read as first `Anne`. An ambiguous particle no comma settled, or a bare one, is a word the order placed, and reads given. ``` "Smith, Sir" → family="" "Sheik Abu Bakar" family-first → given="Abu Bakar" diff --git a/docs/design/rules/H7-joined-name-unit-carrying-title-vocabulary.md b/docs/design/rules/H7-joined-name-unit-carrying-title-vocabulary.md index b55c3a1b3..b7b63ff4b 100644 --- a/docs/design/rules/H7-joined-name-unit-carrying-title-vocabulary.md +++ b/docs/design/rules/H7-joined-name-unit-carrying-title-vocabulary.md @@ -1,16 +1,16 @@ # H7 — a joined name unit carrying title vocabulary -**When:** the one name unit a name leaves standing is more than one word and carries title vocabulary, as in "John of Prince". +**When:** the one name unit a name leaves standing is more than one word and carries title vocabulary, as in "John of Bishop". **Then:** one name UNIT of more than one word carrying title vocabulary reports `title-or-name`, the fork there being whether the title word inside the unit is a title at all. - **A join or a particle chain.** Usually a join (P3), and a particle chain (P4) is the same shape and reports too — `St van Bishop` reads family "van Bishop" with `bishop` title vocabulary inside it. ``` - "John of Prince" → ambiguities=("title-or-name",) + "John of Bishop" → ambiguities=("title-or-name",) "St van Bishop" → family="van Bishop" "St van Bishop" → ambiguities=("particle-or-given", "title-or-name") ``` -- **The reach is every such join.** The clause reaches EVERY join whose non-leading member is TITLES vocabulary, not the one word that prompted it: `Smith and Pope`, `John and Pope`, `Smith and Bishop` and `John of Judge` all report it, as `John of Prince` and `Smith and Prince` do. +- **The reach is every such join.** The clause reaches EVERY join whose non-leading member is TITLES vocabulary, not the one word that prompted it: `Smith and Pope`, `John and Pope`, `Smith and Bishop` and `John of Judge` all report it, as `John of Bishop` does. ``` "Smith and Pope" → ambiguities=("title-or-name",) "John of Judge" → ambiguities=("title-or-name",) @@ -22,7 +22,7 @@ ``` - **Nothing in front of the join silences the clause**, a title, a maiden name or a claimed word each deciding which FIELD the unit takes and none of them whether the word inside it is a title. The other measured inputs are pinned in the case table rather than here. ``` - "Dr. Smith and Prince" → ambiguities=("title-or-name",) + "Dr. Smith and Bishop" → ambiguities=("title-or-name",) ``` - **A unit of one word is H4's**: where the title peel leaves one word standing and that word is title vocabulary, H4's title half reports the same kind. diff --git a/docs/design/rules/H9-title-phrase.md b/docs/design/rules/H9-title-phrase.md index 03397ea97..516d3854d 100644 --- a/docs/design/rules/H9-title-phrase.md +++ b/docs/design/rules/H9-title-phrase.md @@ -24,6 +24,7 @@ "King Curtis" → given="King" "Sultana Begum" → given="Sultana" "Mr Shaikh Ahmed" → given="Shaikh" + "Ms Princess Smith" → given="Princess" ``` - **A modifier in the leading run of titles before the first comma** has its phrase in a head title after it in that run, in `of` after it, or in the object of `of` or `the` there. A modifier outside that run, ending the name or after a comma, is read as any title is, save one that may be a given name, which is read everywhere as it is in that run. ``` @@ -97,7 +98,7 @@ - A modifier whose head is not a listed title loses the title, as with duke, which the vocabulary refuses, and so does a modifier written after its head with no `of` behind it. ``` "Grand Duke of Tuscany" → given="Grand" - "Princess Royal Anne" → given="Royal" + "Her Royal Highness Princess Royal Anne" → given="Royal" ``` - In the given part after a family comma a modifier that is not also a given name is read as listed, so the listing form and the written order of one name read it differently, the cost decision 10 took for the parts where a lone title word is a role. ``` @@ -122,12 +123,14 @@ "Gyani Zail Singh" → given="Gyani" "Lord Buddha Tamang" → given="Buddha" ``` -- A ruler written with the bare title in front reads it as the given name, a style before it or `of` after it keeping the title; the record data at hand writes the word there almost only as a given name, and rulers that way mostly in news text. +- A ruler or a royal written with the bare title in front reads it as a name word, the given name in the default order, a style before it or `of` after it keeping the title; the record data at hand writes the word there almost only as a given name, and rulers and royals that way mostly in news text. ``` "King Henry" → given="King" "Sultan Hassanal Bolkiah" → given="Sultan" "Shaikh Hamad bin Isa" → given="Shaikh" + "Prince Harry" → given="Prince" "His Majesty King Charles" → title="His Majesty King" + "Prince of Wales" → title="Prince of Wales" ``` - Once a partner has made the word a title, a coordinating join behind it takes the next word into the title too. ``` diff --git a/docs/design/rules/O5-lone-name-words-convention-and-reporting-it.md b/docs/design/rules/O5-lone-name-words-convention-and-reporting-it.md index 80699cc71..36b6f55a7 100644 --- a/docs/design/rules/O5-lone-name-words-convention-and-reporting-it.md +++ b/docs/design/rules/O5-lone-name-words-convention-and-reporting-it.md @@ -33,7 +33,7 @@ ``` - **Where the one name unit carries title vocabulary** in a word beside the one it places, or is itself title vocabulary left standing by the title peel, the doubt reported is `title-or-name` instead, which H4 and H7 state — so a title silences THIS kind, not every report at the site. ``` - "John of Prince" → ambiguities=("title-or-name",) + "John of Bishop" → ambiguities=("title-or-name",) ``` - **A script whose own convention settles the order (W4)** decides the word's field, and the report is silenced. ``` diff --git a/docs/migrate.rst b/docs/migrate.rst index b7deab611..d4c26fd4c 100644 --- a/docs/migrate.rst +++ b/docs/migrate.rst @@ -663,7 +663,7 @@ as well; 2.1 and 2.2 read every one of them as 1.4 did. The release log's 2.3, 2.4, 2.5 and 2.6 sections carry the reasoning; these are the shapes to grep your fixtures for, with what 1.4 read: -- ``"Her Majesty Queen Elizabeth"``, ``"Prince Harry"`` (2.3) — a lone +- ``"Her Majesty Queen Elizabeth"``, ``"His Royal Highness Prince Harry"`` (2.3) — a lone name after a title that addresses by given name is the given name: 1.4 read last ``Elizabeth`` and ``Harry``. 2.3 matched a run of titles by its last one (``Her Majesty Queen``, ``Rev Sir``) and added titles @@ -754,7 +754,7 @@ grep your fixtures for, with what 1.4 read: 'MA' >>> HumanName("Her Majesty Queen Elizabeth").first 'Elizabeth' - >>> HumanName("Prince Harry").first + >>> HumanName("His Royal Highness Prince Harry").first 'Harry' >>> king = HumanName("Dr King Jr") >>> king.title, king.last, king.suffix diff --git a/docs/release_log.rst b/docs/release_log.rst index 235e6dcbf..9ba56a9f4 100644 --- a/docs/release_log.rst +++ b/docs/release_log.rst @@ -18,6 +18,7 @@ Release Log - **Read the Brazilian agnomens and French fils as suffixes where the name has a word to spare.** ``Pedro Alves Filho`` and ``Alexandre Dumas fils`` give last ``Alves`` and ``Dumas``, suffix ``Filho`` and ``fils``, where 1.4.0 through 2.6.0 gave middle ``Alves`` and ``Dumas``, last ``Filho`` and ``fils``; ``Neto``, ``Netto``, ``Sobrinho`` and the feminines ``Filha``, ``Neta``, ``Sobrinha`` read the same way. Each is a surname too, so a name of two words keeps it as the last name (``Ana Neto``, ``PEDRO FILHO``) and ``Fils`` in Title case in a mixed-case name stays the last name (``Marie Fils``), the parse reports the choice as a ``suffix-or-name`` ambiguity. ``Lexicon.suffix_words_ambiguous`` lists the words and ``Lexicon.agnomens`` the ones read by the word count alone. :issue:`843`, :issue:`752` - **Read a credential that is also a name, written in capitals in a mixed-case name, as settled.** ``John Smith MA`` reports no ``suffix-or-name`` ambiguity, where 2.0.0 through 2.6.0 reported one, and ``Smith, John MA Jones`` gives suffix ``MA Jones``, where 2.0.0 through 2.6.0 gave middle ``MA Jones`` and 1.4.0 middle ``Jones``, suffix ``MA``. A name written in one case still reports (``JOHN SMITH MA``), and with no comma a name word behind the capitals keeps them a name word, since they may be initials (``Maria Ana MA Silva`` keeps last ``Silva``). :issue:`785`, :issue:`752` - **Read a title that is also a given name as a title only inside a title phrase.** ``Chief Justice John Roberts`` gives title ``Chief Justice``, first ``John``, where 1.4.0 through 2.6.0 gave title ``Chief``, first ``Justice``; ``Field Marshal Bernard Montgomery``, ``Dean of Students Jane Smith`` and ``Major General John Smith`` give the phrase as the title too. Outside a phrase the word is still a name, so ``Dean Smith`` and ``Grace Smith`` give first ``Dean`` and ``Grace``; ``Dean Smith`` now reports a ``title-or-name`` ambiguity unless a comma has marked the given name (``Smith, Dean``), while ``Grace``, a title only in a phrase such as ``His Grace``, reports nothing. Listing the word as a title still makes it one everywhere (``Lexicon.default().add(titles={"dean"})``). A v1 ``Constants().titles`` still lists ``King``, ``Mahdi`` and the other titles 2.6.0 listed, and removing one reads it as a name everywhere, but adding one there no longer makes it a title outside a phrase; that takes the ``Lexicon`` spelling. :issue:`752`, :issue:`853` + - **Fix the given names Prince and Princess reading as titles.** ``Prince Fielder`` and ``Mr Prince Smith`` give first ``Prince``, where 1.4.0 through 2.6.0 gave title ``Prince`` and ``Mr Prince``; ``Smith, Princess`` reads the same. A royal written with the bare title reads it as a first name too (``Prince Harry`` gives first ``Prince``, last ``Harry``), where a style keeps it (``His Royal Highness Prince Harry``), and so does ``of`` (``Prince of Wales``). :issue:`752`, :issue:`348`, :issue:`853` - **Fix the name Shaikh reading as a title.** ``Shaikh Ahmed Khan`` and ``Mr Shaikh Ahmed`` give first ``Shaikh``, where 1.4.0 through 2.6.0 gave title ``Shaikh`` and ``Mr Shaikh``; ``Khan, Shaikh`` reads the same. A ruler written with the bare title reads it as a first name too (``Shaikh Hamad bin Isa`` gives first ``Shaikh``), where a style keeps it (``His Highness Shaikh Hamad``); the spellings ``Sheikh`` and ``Shekh`` are still titles. :issue:`752`, :issue:`853` - **Fix the given names Sultan and Sultana reading as titles.** ``Sultan Khan`` and ``Sultana Begum`` give first ``Sultan`` and ``Sultana``, where 1.4.0 through 2.6.0 gave title ``Sultan`` and ``Sultana`` with no first name; ``Mr Sultan Khan`` and ``Khan, Sultan`` read the same. A sultan written with the bare title reads it as a first name too (``Sultan Hassanal Bolkiah`` gives first ``Sultan``), where a style keeps it (``His Majesty Sultan Hassanal Bolkiah``). :issue:`752`, :issue:`853` - **Fix the given name King reading as a title.** ``King Curtis`` and ``Mr King Smith`` give first ``King``, where 1.4.0 through 2.6.0 gave title ``King`` and ``Mr King``; ``SMITH, KING`` reads the same. A monarch written with the bare title reads it as a first name too (``King Henry`` gives first ``King``, last ``Henry``), where a style keeps it (``His Majesty King Henry``). :issue:`752`, :issue:`348` diff --git a/nameparser/_pipeline/_assign.py b/nameparser/_pipeline/_assign.py index c1848ce1f..7255dc427 100644 --- a/nameparser/_pipeline/_assign.py +++ b/nameparser/_pipeline/_assign.py @@ -615,7 +615,7 @@ def as_a_name(i: int) -> PendingReading: # rules/H7: "one name UNIT of more than one word carrying # title vocabulary reports `title-or-name`" (history: # decisions/H7, decisions/H4 #518) -- one branch, its detail - # naming a field only in H7's shape ('John of Prince', + # naming a field only in H7's shape ('John of Bishop', # 'Attorney General of Minnesota'), where the unit is more # than the title word. # A LONE title word never reaches here ('Dr.', 'Prince of diff --git a/nameparser/_types.py b/nameparser/_types.py index 3f1d0dbc9..49ae4c3c8 100644 --- a/nameparser/_types.py +++ b/nameparser/_types.py @@ -611,7 +611,7 @@ class AmbiguityKind(StrEnum): #: standing by itself, the peel left no word to be read as a #: name, and no fork was taken. #: One name word that is a JOIN carrying title vocabulary reports - #: this kind too ("John of Prince"): the unit is read as a name, + #: this kind too ("John of Bishop"): the unit is read as a name, #: and whether the title word inside it is a title is the fork. #: Not the title-vs-given-name collision on a word like "Baron", #: which is a question about the VOCABULARY and is not this kind. diff --git a/nameparser/config/_compiled.py b/nameparser/config/_compiled.py index 7c5a7a6e7..ee1f1a991 100644 --- a/nameparser/config/_compiled.py +++ b/nameparser/config/_compiled.py @@ -591,8 +591,6 @@ 'primate', 'prime', 'prin', - 'prince', - 'princess', 'principal', 'printer', 'printmaker', @@ -967,6 +965,8 @@ 'mahdi', 'major', 'marshal', + 'prince', + 'princess', 'shaikh', 'siddha', 'sultan', diff --git a/nameparser/vocab/en.toml b/nameparser/vocab/en.toml index d9a410b14..4ac66f9c8 100644 --- a/nameparser/vocab/en.toml +++ b/nameparser/vocab/en.toml @@ -433,11 +433,15 @@ nobility = {} [[word]] text = "prince" -nobility = { addresses = "given", gender = "m", issue = 519, note = "addresses by the GIVEN name ('Prince Harry', 'Princess Anne'); membership decides only which field the one word behind it takes, and 'Prince Fielder' is #348's collision either way" } +nobility = { addresses = "given", gender = "m", issue = 752, decided = 2026-10-27, note = "a title only inside a title phrase, its given reading the clash (rules/H9): 'His Royal Highness Prince Harry' and 'Prince of Wales' read the title, 'Prince Fielder' and 'Mr Prince Smith' the given name, unreported, since no listed phrase holds it; inside a phrase it addresses by the GIVEN name (#519)" } +given = { us_ssa = 24151, wikidata = 204, as_of = 2026-10-27, note = "US SSA: male and female births added; Wikidata is a lower bound (United States 53, Ghana 19, Nigeria 10); nam_dict band 1 in the U.S.A. and India/Sri Lanka" } +family = { us_census_2010 = 47168, wikidata = 525, as_of = 2026-10-27, note = "US Census rank 743" } [[word]] text = "princess" -nobility = { addresses = "given", gender = "f", issue = 519, note = "addresses by the GIVEN name ('Prince Harry', 'Princess Anne'); membership decides only which field the one word behind it takes, and 'Prince Fielder' is #348's collision either way" } +nobility = { addresses = "given", gender = "f", issue = 752, decided = 2026-10-27, note = "a title only inside a title phrase, its given reading the clash (rules/H9): 'Her Royal Highness Princess Anne' reads the title, 'Princess Smith' and 'Ms Princess Smith' the given name, unreported, since no listed phrase holds it; inside a phrase it addresses by the GIVEN name (#519)" } +given = { us_ssa = 15982, wikidata = 29, as_of = 2026-10-27, note = "US SSA: female and male births added; Wikidata is a lower bound (Nigeria 6, Ghana 3); nam_dict band 1 in the U.S.A." } +family = { wikidata = 1, as_of = 2026-10-27, note = "US Census: under 100 bearers, not listed" } [[word]] text = "queen" diff --git a/tests/v2/cases.py b/tests/v2/cases.py index 7a0fc7a71..32ff523ed 100644 --- a/tests/v2/cases.py +++ b/tests/v2/cases.py @@ -10541,7 +10541,8 @@ def _check_cjk_shape_purity(self) -> None: # ranks (Lord Peter, Lady Diana) and title or surname for every # peer and every wife (Lord Byron, Lady Thatcher), and the set # has no way to say "sometimes" -- the reason `venerable` stayed - # out. + # out. Since #752 phase 2j both are titles only inside a title + # phrase (rules/H9), so the prince rows write the style in front. Case("title_run_princess_addresses_by_given_name", "Her Royal Highness Princess Anne", {"title": "Her Royal Highness Princess", "given": "Anne"}, @@ -10550,27 +10551,22 @@ def _check_cjk_shape_purity(self) -> None: "vocabulary question it filed as #519; `princess` now " "IS a given-name title, so the run's last word " "addresses by given name and the family is empty"), - Case("prince_and_one_name_word_is_a_given_name", "Prince Harry", - {"title": "Prince", "given": "Harry"}, + Case("prince_and_one_name_word_is_a_given_name", + "His Royal Highness Prince Harry", + {"title": "His Royal Highness Prince", "given": "Harry"}, classification="fix(#519)", - notes="the name the release note advertises: 1.4.0 through " - "2.2.0 read family 'Harry'. H1's fold is pinned by the " - "Sir John rows; this pins the membership"), - Case("prince_licences_the_bound_given_join", "Prince abdul Rahman", - {"title": "Prince", "given": "abdul Rahman"}, + notes="1.4.0 read last 'Harry'. H1's fold is pinned by the Sir " + "John rows; this pins the membership. The style keeps " + "'prince' a title (rules/H9): the bare 'Prince Harry' " + "this row held until #752 phase 2j reads given 'Prince'"), + Case("prince_licences_the_bound_given_join", + "His Royal Highness Prince abdul Rahman", + {"title": "His Royal Highness Prince", "given": "abdul Rahman"}, classification="fix(#519)", notes="the second site that reads the set, rules/P5's " "licence: behind a given-name title there is no family " "to spare, so the bound word joins forward as it does " - "behind Sir. Read family 'Rahman' before #519"), - Case("prince_as_a_given_name_is_still_the_collision", "Prince Fielder", - {"title": "Prince", "given": "Fielder"}, - classification="fix(#519)", - notes="wrong either way -- Prince is his given name (#348). " - "Membership only decides which field the one word " - "behind the title takes; it does not decide whether " - "the word IS a title, and that is #348's question, " - "not this one's"), + "behind Sir. 1.4.0 read last 'Rahman'"), Case("lord_stays_a_surname_title", "Lord Byron", {"title": "Lord", "family": "Byron"}, notes="negative control for #519: `lord` addresses a duke's " @@ -10599,14 +10595,15 @@ def _check_cjk_shape_purity(self) -> None: classification="feat(#491)", notes="the first word is the name and the rest the run; only " "the word made into a name reports"), - Case("lone_joined_unit_carrying_title_vocabulary", "John of Prince", - {"given": "John of Prince"}, ambiguities=("title-or-name",), + Case("lone_joined_unit_carrying_title_vocabulary", "John of Bishop", + {"given": "John of Bishop"}, ambiguities=("title-or-name",), classification="feat(#491)", notes="rules/O5's exception: the one name unit is a join " "(P3) carrying title vocabulary, so the doubt is " - "whether `Prince` is a title rather than which field " - "the unit takes -- one of the inputs measured to reach " - "that branch, `prince` being in TITLES"), + "whether `Bishop` is a title rather than which field " + "the unit takes, `bishop` being in TITLES. The row held " + "`John of Prince` until #752 phase 2j gave `prince` a " + "given reading, which reports given-or-family"), Case("a_joined_unit_h1_moves_is_reported_in_the_field_it_lands_in", "Attorney General of Minnesota", {"title": "Attorney", "family": "General of Minnesota"}, @@ -10671,7 +10668,7 @@ def _check_cjk_shape_purity(self) -> None: ambiguities=("title-or-name",), classification="feat(#491)", notes="the clause reaches every join whose non-leading member " - "is TITLES vocabulary, not just `prince`: `John and " + "is TITLES vocabulary, not just `bishop`: `John and " "Pope`, `Smith and Bishop` and `John of Judge` report " "it too. That is the pope/judge/bishop collision set " "(decisions/vocabulary-collisions) met inside a " @@ -10685,8 +10682,8 @@ def _check_cjk_shape_purity(self) -> None: "chains into a title run (H3) and never reaches the " "assignment site at all, so it reports nothing -- the " "same silence as a lone `Dr.`"), - Case("lone_joined_unit_behind_a_peeled_title", "Dr. Smith and Prince", - {"title": "Dr.", "family": "Smith and Prince"}, + Case("lone_joined_unit_behind_a_peeled_title", "Dr. Smith and Bishop", + {"title": "Dr.", "family": "Smith and Bishop"}, ambiguities=("title-or-name",), classification="parity", notes="the join clause (rules/H7, split from H4) asks whether " "a WORD is a title, so a title peeled in FRONT of the unit " @@ -12211,12 +12208,12 @@ def _check_cjk_shape_purity(self) -> None: "title vocabulary, so the word arrives in the trailing " "slot as any other piece would"), Case("title_word_trailing_leaves_a_joined_title_unit_standing", - "John of Prince Prof.", - {"title": "Prof.", "family": "John of Prince"}, + "John of Bishop Prof.", + {"title": "Prof.", "family": "John of Bishop"}, ambiguities=("title-or-name",), classification="fix(#316)", notes="H7's join clause, reached through the trailing walk: " "the unit left standing is the one H7 already reports " - "for on its own ('John of Prince'), and the walk is " + "for on its own ('John of Bishop'), and the walk is " "what makes it the only one. The single-word half of " "H4 cannot be reached this way -- a lone title-" "vocabulary word in front of a trailing title is taken " @@ -12663,6 +12660,44 @@ def _check_cjk_shape_purity(self) -> None: classification="fix(#752)", notes="H9: a style read as a name word is no title there, so it " "partners nothing; read title 'Shaikh Sultan' before"), + Case("given_name_title_prince_at_the_head", "Prince Fielder", + {"given": "Prince", "family": "Fielder"}, + classification="fix(#348)", + notes="H9; read title 'Prince', given 'Fielder' 2.3.0 through " + "2.6.0 and last 'Fielder' in 1.4.0 (#752 phase 2j)"), + Case("given_name_title_prince_after_a_salutation", "Mr Prince Smith", + {"title": "Mr", "given": "Prince", "family": "Smith"}, + classification="fix(#853)", + notes="H9: a salutation is no partner; read title 'Mr Prince' " + "before"), + Case("given_name_title_princess_after_a_salutation", + "Ms Princess Smith", + {"title": "Ms", "given": "Princess", "family": "Smith"}, + classification="fix(#853)", + notes="H9: a salutation is no partner; read title " + "'Ms Princess' before"), + Case("given_name_title_princess_after_a_family_comma", + "Smith, Princess", + {"given": "Princess", "family": "Smith"}, classification="fix(#752)", + notes="H9; read title 'Princess', given 'Smith' before"), + Case("given_name_title_prince_before_a_family_comma", + "Prince Smith, John", + {"given": "John", "family": "Prince Smith"}, + notes="H6 peels only a title, so the surname keeps the word, as " + "1.4.0 read it; master read title 'Prince'"), + Case("royal_with_a_bare_leading_prince", "Prince Harry", + {"given": "Prince", "family": "Harry"}, + classification="fix(#752)", + notes="H9's Accepted clause, the class 'king' and 'sultan' " + "took; read title 'Prince', given 'Harry' 2.3.0 through " + "2.6.0 and last 'Harry' in 1.4.0"), + Case("princess_behind_a_style_and_a_trailing_modifier", + "Her Royal Highness Princess Royal Anne", + {"title": "Her Royal Highness Princess", "given": "Royal", + "family": "Anne"}, + notes="H9's Accepted clause: the style keeps 'princess' a title, " + "and 'royal' written after its head loses its own, as " + "master read it"), Case("given_name_modifier_after_a_style", "Hon. Wing Lau", {"title": "Hon.", "given": "Wing", "family": "Lau"}, notes="H9: the modifier's test, not a contested word's style " diff --git a/tests/v2/pipeline/test_assign.py b/tests/v2/pipeline/test_assign.py index b8fdc67ba..f86c047a7 100644 --- a/tests/v2/pipeline/test_assign.py +++ b/tests/v2/pipeline/test_assign.py @@ -276,8 +276,8 @@ def test_leading_particle_detail_names_the_field_the_word_lands_in( "'Rinpoche' is post-nominal vocabulary with no name word beside " "it; read as a {role} name rather than a post-nominal, nothing " "else being left to be the name"), - ("John of Prince", AmbiguityKind.TITLE_OR_NAME, - "'John of Prince' is the only name unit and joins title " + ("John of Bishop", AmbiguityKind.TITLE_OR_NAME, + "'John of Bishop' is the only name unit and joins title " "vocabulary to a name word; read as a {role} name by convention"), ]) def test_convention_details_name_the_field_the_word_lands_in( @@ -292,7 +292,7 @@ def test_convention_details_name_the_field_the_word_lands_in( # shape ("Lord Chancellor") deliberately names none, because H1 # retags that word after assign under the default order. lex = _LEX.add(suffix_words={"rinpoche"}, conjunctions={"of"}, - titles={"prince"}) + titles={"bishop"}) (amb,) = _reported(text, policy, lexicon=lex) assert amb.kind is kind assert amb.detail == detail.format(role=role) diff --git a/tests/v2/rules_budget.json b/tests/v2/rules_budget.json index 16d910ff6..3ef5ee419 100644 --- a/tests/v2/rules_budget.json +++ b/tests/v2/rules_budget.json @@ -23,9 +23,9 @@ "H4": {"words": 410, "then_words": 183, "because_sentences": 3, "except": 1, "precedence": 1, "accepted": 1, "accepted_words": 127}, "H5": {"words": 757, "then_words": 289, "because_sentences": 2, "except": 0, "precedence": 5, "accepted": 1, "accepted_words": 117}, "H6": {"words": 316, "then_words": 79, "because_sentences": 3, "except": 4, "precedence": 0, "accepted": 2, "accepted_words": 100}, - "H7": {"words": 343, "then_words": 274, "because_sentences": 2, "except": 0, "precedence": 0, "accepted": 1, "accepted_words": 54}, + "H7": {"words": 339, "then_words": 270, "because_sentences": 2, "except": 0, "precedence": 0, "accepted": 1, "accepted_words": 54}, "H8": {"words": 431, "then_words": 68, "because_sentences": 3, "except": 3, "precedence": 3, "accepted": 3, "accepted_words": 128}, - "H9": {"words": 704, "then_words": 263, "because_sentences": 3, "except": 0, "precedence": 5, "accepted": 9, "accepted_words": 342}, + "H9": {"words": 704, "then_words": 263, "because_sentences": 3, "except": 0, "precedence": 5, "accepted": 9, "accepted_words": 354}, "M1": {"words": 231, "then_words": 120, "because_sentences": 2, "except": 1, "precedence": 2, "accepted": 0, "accepted_words": 0}, "M2": {"words": 714, "then_words": 435, "because_sentences": 1, "except": 4, "precedence": 1, "accepted": 6, "accepted_words": 209}, "M3": {"words": 234, "then_words": 84, "because_sentences": 2, "except": 2, "precedence": 2, "accepted": 1, "accepted_words": 80}, diff --git a/tests/v2/test_cases.py b/tests/v2/test_cases.py index eacb9f5cc..3a1507ca8 100644 --- a/tests/v2/test_cases.py +++ b/tests/v2/test_cases.py @@ -145,7 +145,7 @@ def test_a_report_names_the_field_its_word_lands_in( over master's parser (26cdb891) fails 14 parses, every one a report worded at assign -- nine title-or-name join reports saying 'given' of a unit H1 moved to the family behind a title (`Attorney General - of Minnesota`, `John of Prince Prof.`, `Freiherr St MA`, `Freiherr + of Minnesota`, `John of Bishop Prof.`, `Freiherr St MA`, `Freiherr von Bishop X.Y.Z.` and five more rows, as declared; on 2026-10-08 `St St née` stood where `Freiherr St John Smith MA` does), `Kim Min Do` under FAMILY_FIRST ('middle', family, P6), `de Kim Ma` under diff --git a/tools/differential/corpus_rules.jsonl b/tools/differential/corpus_rules.jsonl index 9e10baf06..08f77b51c 100644 --- a/tools/differential/corpus_rules.jsonl +++ b/tools/differential/corpus_rules.jsonl @@ -55,7 +55,7 @@ "Anna Greve" "Anna z (domu) Nowak" "Anna z Nowak" -"Anne, Princess" +"Anne, Swami" "Antonio Pavlović mlađi" "Antonio Pavlović mlađi Jones" "Antonio ‌Negri" @@ -170,7 +170,7 @@ "Dr. Smith Jr., AD" "Dr. Smith Sir." "Dr. Smith V, AD" -"Dr. Smith and Prince" +"Dr. Smith and Bishop" "Dr. Smith née Jones" "Dr. Smith, John" "Dr. St. Pierre, Ed" @@ -232,6 +232,7 @@ "Hassan, Mohamad Ahmad Ali" "Her Majesty Queen Elizabeth" "Her Royal Highness Princess Anne" +"Her Royal Highness Princess Royal Anne" "His Excellency Lord Duncan" "His Grace John Smith" "His Majesty King Charles" @@ -543,8 +544,8 @@ "John nee Prof. ba MA" "John née Jones Smith Ma" "John née Jones Smith V" +"John of Bishop" "John of Judge" -"John of Prince" "John van Buren, Ed" "John van Mc" "John van der Berg" @@ -654,6 +655,7 @@ "Mr. and Mrs. Wing Lau" "Mrs Ma. Liza Cruz" "Mrs. Garcia" +"Ms Princess Smith" "MÜLLER WEIß, HANS" "Ménil Christophe de" "Ménil de" @@ -697,9 +699,9 @@ "Pieter Bruegel stariji Jones" "Pope Smith, John" "President of the United States Barack Obama" +"Prince Harry" "Prince of Wales" "Prince of Wales Jr" -"Princess Royal Anne" "Prof. Dr. Brühl, Ada" "Prof. Smith, Dr. John" "Prof. Smith, John, PhD" diff --git a/tools/differential/snapshot.jsonl b/tools/differential/snapshot.jsonl index ded919eaa..460b5e447 100644 --- a/tools/differential/snapshot.jsonl +++ b/tools/differential/snapshot.jsonl @@ -236,7 +236,7 @@ {"name": "Anne Berit Bernhard Nilsen", "given": "Anne", "middle": "Berit Bernhard", "family": "Nilsen", "initials": "A. B. B. N."} {"name": "Anne Sepp", "given": "Anne", "family": "Sepp", "initials": "A. S."} {"name": "Anne Sofie Holm Hansen", "given": "Anne", "middle": "Sofie Holm", "family": "Hansen", "initials": "A. S. H. H."} -{"name": "Anne, Princess", "title": "Princess", "given": "Anne", "initials": "A."} +{"name": "Anne, Swami", "title": "Swami", "given": "Anne", "initials": "A."} {"name": "Anne-Pierre de Montesquiou-Fézensac", "given": "Anne-Pierre", "family": "de Montesquiou-Fézensac", "initials": "A. M."} {"name": "Annebault, Claude d'", "given": "Claude", "family": "d' Annebault", "initials": "C. A."} {"name": "Annelise Weber", "given": "Annelise", "family": "Weber", "initials": "A. W."} @@ -825,7 +825,7 @@ {"name": "Dr. Smith Jr., AD", "title": "Dr.", "family": "Smith", "suffix": "Jr., AD", "ambiguities": ["SUFFIX_OR_NAME"], "alternatives": ["SUFFIX_OR_NAME: name as given (position)"], "initials": "S."} {"name": "Dr. Smith Sir.", "title": "Dr. Sir.", "family": "Smith", "initials": "S."} {"name": "Dr. Smith V, AD", "title": "Dr.", "given": "AD", "family": "Smith V", "initials": "A. S. V.", "capitalized_force": "Dr. Ad Smith V"} -{"name": "Dr. Smith and Prince", "title": "Dr.", "family": "Smith and Prince", "ambiguities": ["TITLE_OR_NAME"], "alternatives": ["TITLE_OR_NAME: title as title (vocabulary)"], "initials": "S. P."} +{"name": "Dr. Smith and Bishop", "title": "Dr.", "family": "Smith and Bishop", "ambiguities": ["TITLE_OR_NAME"], "alternatives": ["TITLE_OR_NAME: title as title (vocabulary)"], "initials": "S. B."} {"name": "Dr. Smith née Jones", "title": "Dr.", "family": "Smith", "maiden": "Jones", "initials": "S."} {"name": "Dr. Smith, John", "title": "Dr.", "given": "John", "family": "Smith", "initials": "J. S."} {"name": "Dr. St. Pierre, Ed", "title": "Dr.", "given": "Ed", "family": "St. Pierre", "ambiguities": ["SUFFIX_OR_NAME"], "alternatives": ["SUFFIX_OR_NAME: credential as suffix (vocabulary)"], "initials": "E. P.", "capitalized_force": "Dr. Ed st. Pierre"} @@ -1238,6 +1238,7 @@ {"name": "Hempel, Ludwig", "given": "Ludwig", "family": "Hempel", "initials": "L. H."} {"name": "Her Majesty Queen Elizabeth", "title": "Her Majesty Queen", "given": "Elizabeth", "initials": "E."} {"name": "Her Royal Highness Princess Anne", "title": "Her Royal Highness Princess", "given": "Anne", "initials": "A."} +{"name": "Her Royal Highness Princess Royal Anne", "title": "Her Royal Highness Princess", "given": "Royal", "family": "Anne", "initials": "R. A."} {"name": "Hera Hilmarsdóttir", "given": "Hera", "family": "Hilmarsdóttir", "initials": "H. H."} {"name": "Hera Hjartardóttir", "given": "Hera", "family": "Hjartardóttir", "initials": "H. H."} {"name": "Herma Studeny", "given": "Herma", "family": "Studeny", "initials": "H. S."} @@ -1885,8 +1886,8 @@ {"name": "John nee Prof. ba MA", "family": "John", "suffix": "MA", "maiden": "Prof. ba", "ambiguities": ["SUFFIX_OR_NAME"], "alternatives": ["SUFFIX_OR_NAME: credential as suffix (vocabulary)"], "initials": "J.", "capitalized_force": "John (Prof. Ba) MA"} {"name": "John née Jones Smith Ma", "family": "John", "maiden": "Jones Smith Ma", "ambiguities": ["SUFFIX_OR_NAME"], "alternatives": ["SUFFIX_OR_NAME: credential as suffix (vocabulary)"], "initials": "J."} {"name": "John née Jones Smith V", "family": "John", "maiden": "Jones Smith V", "ambiguities": ["SUFFIX_OR_NAME"], "alternatives": ["SUFFIX_OR_NAME: generation as suffix (vocabulary)"], "initials": "J."} +{"name": "John of Bishop", "given": "John of Bishop", "ambiguities": ["TITLE_OR_NAME"], "alternatives": ["TITLE_OR_NAME: title as title (vocabulary)"], "initials": "J. B."} {"name": "John of Judge", "given": "John of Judge", "ambiguities": ["TITLE_OR_NAME"], "alternatives": ["TITLE_OR_NAME: title as title (vocabulary)"], "initials": "J. J."} -{"name": "John of Prince", "given": "John of Prince", "ambiguities": ["TITLE_OR_NAME"], "alternatives": ["TITLE_OR_NAME: title as title (vocabulary)"], "initials": "J. P."} {"name": "John of the Doe", "given": "John of the Doe", "ambiguities": ["GIVEN_OR_FAMILY"], "alternatives": ["GIVEN_OR_FAMILY: name as family (position)"], "initials": "J. D."} {"name": "John van Buren, Ed", "given": "John", "family": "van Buren", "suffix": "Ed", "ambiguities": ["SUFFIX_OR_NAME"], "alternatives": ["SUFFIX_OR_NAME: name as given (declared)"], "initials": "J. B.", "capitalized_force": "John van Buren ED"} {"name": "John van Mc", "given": "John", "family": "van Mc", "initials": "J. v. M.", "capitalized_force": "John Van Mc"} @@ -2601,6 +2602,7 @@ {"name": "Mrs. Garcia", "title": "Mrs.", "family": "Garcia", "initials": "G."} {"name": "Ms A.J. Smith", "title": "Ms", "given": "A.J.", "family": "Smith", "initials": "A. S."} {"name": "Ms Hon Solo", "title": "Ms Hon", "family": "Solo", "initials": "S."} +{"name": "Ms Princess Smith", "title": "Ms", "given": "Princess", "family": "Smith", "initials": "P. S."} {"name": "Ms. Rebecca Teichman", "title": "Ms.", "given": "Rebecca", "family": "Teichman", "initials": "R. T."} {"name": "Mudane Bertram Wilberforce Henry Robert Wooster MP", "given": "Mudane", "middle": "Bertram Wilberforce Henry Robert", "family": "Wooster", "suffix": "MP", "initials": "M. B. W. H. R. W."} {"name": "Mueller Kathy", "order": "FAMILY_FIRST", "given": "Kathy", "family": "Mueller", "initials": "K. M."} @@ -2832,11 +2834,11 @@ {"name": "Prema", "given": "Prema", "ambiguities": ["GIVEN_OR_FAMILY"], "alternatives": ["GIVEN_OR_FAMILY: name as family (position)"], "initials": "P."} {"name": "Prema", "order": "FAMILY_FIRST", "family": "Prema", "ambiguities": ["GIVEN_OR_FAMILY"], "alternatives": ["GIVEN_OR_FAMILY: name as given (position)"], "initials": "P."} {"name": "President of the United States Barack Obama", "title": "President of the United States", "given": "Barack", "family": "Obama", "initials": "B. O."} -{"name": "Prince Charles", "title": "Prince", "given": "Charles", "initials": "C."} -{"name": "Prince Fielder", "title": "Prince", "given": "Fielder", "initials": "F."} +{"name": "Prince Charles", "given": "Prince", "family": "Charles", "initials": "P. C."} +{"name": "Prince Fielder", "given": "Prince", "family": "Fielder", "initials": "P. F."} +{"name": "Prince Harry", "given": "Prince", "family": "Harry", "initials": "P. H."} {"name": "Prince of Wales", "title": "Prince of Wales"} {"name": "Prince of Wales Jr", "title": "Prince of Wales", "family": "Jr", "initials": "J."} -{"name": "Princess Royal Anne", "title": "Princess", "given": "Royal", "family": "Anne", "initials": "R. A."} {"name": "Prof. Dk. Salima Farida mwana Hamisi Musa M.D. Ph.D.", "title": "Prof. Dk.", "given": "Salima", "middle": "Farida mwana Hamisi", "family": "Musa", "suffix": "M.D. Ph.D.", "initials": "S. F. m. H. M.", "capitalized_force": "Prof. Dk. Salima Farida Mwana Hamisi Musa M.D. Ph.D."} {"name": "Prof. Dr. Ada Cornelia Cesar Martin von Bruhl Jr, MD DDS", "title": "Prof. Dr.", "given": "Ada", "middle": "Cornelia Cesar Martin", "family": "von Bruhl", "suffix": "Jr, MD DDS", "initials": "A. C. C. M. B."} {"name": "Prof. Dr. Ada Cornelia Cesar Martín von Bruhl Jr, M.D., Ph.D.", "title": "Prof. Dr.", "given": "Ada", "middle": "Cornelia Cesar Martín", "family": "von Bruhl", "suffix": "Jr, M.D., Ph.D.", "initials": "A. C. C. M. B."}