diff --git a/docs/design/decisions/H9-title-phrase.md b/docs/design/decisions/H9-title-phrase.md index 11bfda8c8..406c80cbc 100644 --- a/docs/design/decisions/H9-title-phrase.md +++ b/docs/design/decisions/H9-title-phrase.md @@ -106,3 +106,10 @@ - THE COST, accepted by Derek on 2026-10-27: `FISH, ROYAL SR` reads given 'FISH' and no family, `sr` being a title as well as a suffix, so `ROYAL SR` is a title run with a head and H1 reads the word before the comma as the given name; one FEC name. A phrase with nothing behind it still names its last word (`Princess Royal` → title 'Princess', given 'Royal'), H4's reading of an input that is all vocabulary. - MEASURED (2026-10-27, against master `598167f4`, which holds the queen batch, py3.11, `uv run python tools/differential/measure.py --base `, 16 steps). Fields: fec-individuals 49, 47 fixes, nearly every one `AA, ROYAL…`, where the queen head read title 'ROYAL' and no given name, 1 broken (above) and 1 input that names one person twice; jrc-names 6 spellings, `Princess Royal Anne`'s and a `consort marquise of X`; PSC and orcid-researchers agreement no record moved (ORCID 1,831,533 scored). Reports only: orcid-researchers 548 (`prince` 329, `princess` 103, `king` 70, `queen` 24, `royal` 15, a few behind `Dr.` or `Prof.`), PSC 310 records (`prince` 119, `princess` 58, `king` 49, `queen` 13, the rest `royal` and salutation forms), jrc-names 154 spellings, ctgov-officials 17, nepal-candidates 3, the committed corpora 13; tse-donors, tw-donors and ukec-individuals none; spelling pairs jrc-names 0 now alike and 1 apart; CLDR and GND agreement do not move. A v1 `Constants().titles` keeps all four royal titles, and `royal` and `consort` reach it as titles with no edit. Recompute: `uv run python tools/differential/measure.py --base `. +- **2026-10-28 #913, `chancellor`, AND `judge` KEPT A TITLE (Derek) — THE LAST 2.8 TITLE BATCH: ONE TITLE BORNE AS A GIVEN NAME, AND THE PHRASES THAT KEEP JUDICIAL AND ACADEMIC TITLES WHOLE.** `judge` and `chancellor` were proposed together; Derek shipped `chancellor` alone and kept `judge` a title on 2026-10-28. `chancellor` gains a dated `given` reading and is a title only inside a title phrase: `Chancellor Smith`, `Mr Chancellor Smith` and `Smith, Chancellor` read given 'Chancellor', where 1.4.0 through 2.7.0 read the title. Before a family comma H6 no longer peels it (`Chancellor Case, Nancy` → family 'Chancellor Case', 1.4.0's reading). The phrases keep it: a modifier (`Vice Chancellor`, `Associate Chancellor`), `of` (`Chancellor of the Exchequer`), and `attaches` data added here for the phrases a modifier does not reach: `lord` attaches to `chancellor` and `justice` and `lady` to `justice` (`Lord Chancellor`, `Lord Justice`, `Lady Justice`), `deputy` to the office kind as `chief` does (`Deputy Chancellor`, `Deputy Judge`), `pro` to `chancellor` (`Pro Chancellor`), and `magistrate` to `judge` (`Magistrate Judge`, the US federal office, which with `judge` moved had lost its second word). `Lord Justice Leveson` and `Lady Justice Arden` now read the one title, where 1.4.0, which listed no `justice`, through 2.7.0, where it is contested (phase 2i), read title 'Lord', given 'Justice'. Since `Vice Chancellor` and `Lord Chancellor` are listed phrases, a bare `Chancellor` opening a name reports `title-or-name`, as `Dean Smith` does. Phrases that read the same on master and stay out of scope: `Circuit Judge`, `Probate Judge`, `His Honour Judge` and the hyphenated `Vice-Chancellor`. + - `judge` KEPT A TITLE, its evidence recorded in the note on its title reading so a later batch meets it: given US SSA 3,826 births (all male), Wikidata 7, nam_dict band 1 in the U.S.A.; family Census 10,453 (rank 3,414), Wikidata 133; in PSC 0 filers put it in the forename box and 0 in the title box. Measured as a contested title against master `f207e4f1`, it broke 13 FEC records, every one a judge filing `FAMILY, JUDGE GIVEN` (9) or `FAMILY, JUDGE` alone (4), and 2 jrc-names spellings of news text before a surname, against 2 fixes in all the local corpora (one ORCID and one PSC filer whose given name it is). The `TEST_NAMES` judges (`Judge James M. Moody`) and every example that uses `judge` as an ordinary surname in TITLES (the H section's Background, rules/H5, rules/H6 and rules/H7) keep it. + - THE COUNTS for `chancellor`, recorded on the word (`uv run python tools/name_usage.py chancellor`, 2026-10-28): given US SSA 2,648 births (2,643 male), Wikidata 13 (United States 3); family Census 4,147 (rank 7,974), Wikidata 77 (United Kingdom 11, United States 8). + - THE COST, accepted by Derek on 2026-10-28: a chancellor written with the bare title reads it as the given name (`Chancellor Merkel` → given 'Chancellor', family 'Merkel', where 1.4.0 through 2.7.0 read title 'Chancellor'), so does one alone after a full name and a comma (`John Smith, Chancellor` reverses to given 'Chancellor', family 'John Smith', the role-word class `John Smith, Dean` accepted), and a bare first-word `Chancellor` reports `title-or-name`. + - WORKED EXAMPLES MOVED. The v1 tests that add a custom title and parse it (`tests/test_constants.py`, `tests/test_python_api.py`) add `bursar`, in no default set, where they added `chancellor`, which v1's `Constants().titles` still holds; rules/H9 gains the `Lord Chancellor` and `Chancellor Smith` examples. + - MEASURED (2026-10-28, against master `f207e4f1`, py3.11, `uv run python tools/differential/measure.py --base `, 16 steps). fec-individuals 10, all fixes: 4 `AA, CHANCELLOR` alone, which had read no given name, 1 `AA, CHANCELLOR A.`, 2 `AA, CHANCELLOR MR.`, and 3 with a two-word surname opening with the word before the comma, which had read it as the title; jrc-names 5 spellings, 3 fixed (`Lord Justice` and `Lady Justice` before a surname) and 2 broken, spellings of one head of government written with the bare title, now reporting `title-or-name`; ctgov-officials 1 fix (a `Deputy` and an office title after a comma, now one title through `deputy`'s attaches); orcid-researchers, psc-individuals, nepal-candidates, tse-donors, tw-donors and ukec-individuals none; ORCID (1,831,533 scored) and PSC (1,039,145 scored) agreement do not move; spelling pairs jrc-names 0 now alike and 0 apart; CLDR and GND agreement do not move. The committed corpora move by `Chancellor Jane Smith` (given 'Chancellor') beside the batch's rule examples. A v1 `Constants().titles` keeps `chancellor` and `judge` with no edit, and `c.titles.remove('chancellor')` turns every title reading of it off (the v1 title list entry above). + Recompute: `uv run python tools/differential/measure.py --base `. diff --git a/docs/design/decisions/vocabulary-model.md b/docs/design/decisions/vocabulary-model.md index 33d705b2f..70a56b730 100644 --- a/docs/design/decisions/vocabulary-model.md +++ b/docs/design/decisions/vocabulary-model.md @@ -219,6 +219,7 @@ Open: #913 (the title words phase 2j left, read as titles though borne as names) - `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-28 #913, `chancellor`, and `judge` kept a title (Derek) — A #913 TITLE BATCH: `chancellor` has a dated `given` reading**, US SSA 2,648 births and Census rank 7,974 as a surname, so it is a title only inside a title phrase. `Chancellor Smith` and `Smith, Chancellor` read given 'Chancellor'; a chancellor written with the bare title does too (`Chancellor Merkel`), accepted by Derek on 2026-10-28. `Vice Chancellor`, `Chancellor of the Exchequer` and, through new `attaches` data, `Lord Chancellor`, `Deputy Chancellor` and `Pro Chancellor` keep the title; the same data makes `Lord Justice`, `Lady Justice` and `Magistrate Judge` one title. `judge` was proposed in the same batch and kept a title by Derek on 2026-10-28, the counts against moving it (13 FEC judges filing `FAMILY, JUDGE …` against 2 fixes) recorded in the note on its title reading. The measurement is decisions/H9's entry of this date. - **2026-10-27 #913, royal title phrases (Derek) — `king`, `queen`, `prince` and `princess` CARRY `attaches`, `consort` IS A NEW MODIFIER AND `royal` HAS A DATED `given` READING.** `king` and `prince` attach to `consort`, `queen` to `consort` and `mother`, `princess` to `consort` and `royal`; `consort` (no bearers found) and `royal` address by the given name, so `Queen Consort Camilla` and `Princess Royal Anne` read the phrase as the title and the given name behind it. `royal`'s given reading keeps `BALES, ROYAL` the listing form's given name. The bare royal words now report `title-or-name`, a listed phrase holding them, accepted by Derek on 2026-10-27. The measurement and the rule change are decisions/H9's entry of this date. - **2026-10-27 #913, `queen` (Derek) — A #913 TITLE BATCH: `queen` has a dated `given` reading**, US SSA 16,123 births and Census rank 1,945 as a surname, so it is a title only inside a title phrase. `Queen Latifah`, `Ms Queen Smith` and `Smith, Queen` read given 'Queen' and the word behind it as the family; a monarch written with the bare title does too (`Queen Elizabeth II`), the class accepted for `king`, accepted by Derek on 2026-10-27. `Her Majesty Queen Elizabeth` and `Queen of England` keep the title. `Mary II, Dame` replaces `Elizabeth II, Queen` as rules/H1's example. The measurement is decisions/H9's entry of this date. - **2026-10-27 #913, `deacon`, `burgess` and `ranger` (Derek) — A #913 TITLE BATCH: each has a dated `given` reading** on its en.toml entry, so each is a title only inside a title phrase. `Deacon Jones`, `Burgess Meredith` and `Ranger Smith` read the given name, and `Burgess Smith, John` keeps the surname whole; a cleric written with the bare title or behind `Rev.` does too (`The Rev. Deacon John Smith`), the religious class accepted for `buddha` and `gyani`, accepted by Derek on 2026-10-27. `Deacon of the Church Jane Smith` keeps the title. Derek chose the three, with `marquis` and `marquise` (#923), from #913's ranking on 2026-10-27. The measurement is decisions/H9's entry of this date. diff --git a/docs/design/rules/H9-title-phrase.md b/docs/design/rules/H9-title-phrase.md index f2c10c25d..e3820e9bb 100644 --- a/docs/design/rules/H9-title-phrase.md +++ b/docs/design/rules/H9-title-phrase.md @@ -14,6 +14,7 @@ "His Grace John Smith" → title="His Grace" "Field Marshal Bernard Montgomery" → title="Field Marshal" "Sergeant Major John Smith" → title="Sergeant Major" + "Lord Chancellor John Smith" → title="Lord Chancellor" "Mr Dean Smith" → given="Dean" "SMITH, DEAN MR." → given="DEAN" "General Major John Smith" → given="Major" @@ -28,6 +29,7 @@ "Marquis Johnson" → given="Marquis" "Mr Deacon Smith" → given="Deacon" "Ms Queen Smith" → given="Queen" + "Chancellor Smith" → given="Chancellor" "Cheikh Anta Diop" → given="Cheikh" "Queen Mother Elizabeth" → title="Queen Mother" ``` @@ -54,6 +56,7 @@ "Dean Smith, MD" → ambiguities=("title-or-name",) "Prince Fielder" → ambiguities=("title-or-name",) "Dr. King" → ambiguities=("title-or-name",) + "Chancellor Smith" → ambiguities=("title-or-name",) "Grace Smith" → ambiguities=() "Bard Larsen" → ambiguities=() "GRACE SMITH" → ambiguities=() diff --git a/docs/migrate.rst b/docs/migrate.rst index cc4947cca..a387b715b 100644 --- a/docs/migrate.rst +++ b/docs/migrate.rst @@ -901,6 +901,11 @@ grep your fixtures for, with what 1.4 read: after a family comma is the first name: 1.4 read title ``Prince``, first ``Consort``; title ``Princess Royal``, last ``Anne``; and title ``Royal``, first ``Bales``. +- ``"Chancellor Smith"`` and ``"Lord Justice Leveson"`` (2.8) — + ``Chancellor`` is a title only inside a title phrase (``"Lord + Chancellor John Smith"``), and ``Lord Justice`` and ``Lady Justice`` are + one title: 1.4 read title ``Chancellor``, and title ``Lord``, first + ``Justice``. .. doctest:: @@ -1058,3 +1063,9 @@ grep your fixtures for, with what 1.4 read: ('Prince Consort', 'Albert') >>> HumanName("Princess Royal Anne").first, HumanName("Bales, Royal").first ('Anne', 'Royal') + >>> HumanName("Chancellor Smith").first + 'Chancellor' + >>> HumanName("Lord Chancellor John Smith").title + 'Lord Chancellor' + >>> HumanName("Lord Justice Leveson").title + 'Lord Justice' diff --git a/docs/release_log.rst b/docs/release_log.rst index b0ae14f5d..8b087fbe2 100644 --- a/docs/release_log.rst +++ b/docs/release_log.rst @@ -10,6 +10,7 @@ Release Log **Behavior Changes** + - **Fix the given name Chancellor reading as a title, and read Lord Justice as one title.** ``Chancellor Smith`` gives first ``Chancellor``, where 1.4.0 through 2.7.0 gave title ``Chancellor``; ``Smith, Chancellor`` reads the same. A chancellor written with the bare title reads it as a first name too (``Chancellor Merkel``), where a modifier, ``of`` or ``Lord`` keeps it (``Vice Chancellor Jane Smith``, ``Chancellor of the Exchequer``, ``Lord Chancellor John Smith``), and so do ``Deputy`` and ``Pro``. Since a listed title phrase holds it, a bare ``Chancellor`` opening a name reports a ``title-or-name`` ambiguity. ``Lord Justice Leveson`` and ``Lady Justice Arden`` give title ``Lord Justice`` and ``Lady Justice``, where 1.4.0 through 2.7.0 gave title ``Lord``, first ``Justice``. :issue:`913` - **Read the royal title phrases Queen Mother, King Consort, Queen Consort, Prince Consort, Princess Consort and Princess Royal as one title.** ``Prince Consort Albert`` gives title ``Prince Consort``, first ``Albert``, where 2.7.0 gave first ``Prince``, middle ``Consort``, last ``Albert``, and 1.4.0 title ``Prince``, first ``Consort``; ``Princess Royal Anne`` gives first ``Anne``. ``Royal`` after a family comma is the first name (``Bales, Royal`` gives first ``Royal``, where 1.4.0 through 2.7.0 gave title ``Royal``). Since a listed title phrase holds them, a bare ``King``, ``Queen``, ``Prince``, ``Princess`` or ``Royal`` opening a name now reports a ``title-or-name`` ambiguity, as ``Dean Smith`` does (``Prince Fielder``, ``Dr. King``). :issue:`913` - **Fix the given name Queen reading as a title.** ``Queen Latifah`` and ``Ms Queen Smith`` give first ``Queen``, where 1.4.0 through 2.7.0 gave title ``Queen`` and ``Ms Queen``; ``Smith, Queen`` reads the same. A monarch written with the bare title reads it as a first name too (``Queen Elizabeth II`` and ``Elizabeth II, Queen`` give first ``Queen``, last ``Elizabeth``), where a style keeps it (``Her Majesty Queen Elizabeth``), and so does ``of`` (``Queen of England``). :issue:`913` - **Fix the given names Deacon, Burgess and Ranger reading as titles.** ``Deacon Jones``, ``Burgess Meredith`` and ``Ranger Smith`` give first ``Deacon``, ``Burgess`` and ``Ranger``, where 1.4.0 through 2.7.0 gave title ``Deacon``, ``Burgess`` and ``Ranger``; ``Smith, Deacon`` reads the same. A cleric written with the bare title, or behind a salutation or ``Rev.``, reads it as a first name too (``The Rev. Deacon John Smith`` gives first ``Deacon``), where ``of`` keeps it (``Deacon of the Church Jane Smith``). ``Burgess Meredith`` reports a ``title-or-name`` ambiguity, since ``Chief Burgess`` is a title phrase. :issue:`913` diff --git a/nameparser/config/_compiled.py b/nameparser/config/_compiled.py index e02f5adbb..7edec1de6 100644 --- a/nameparser/config/_compiled.py +++ b/nameparser/config/_compiled.py @@ -190,7 +190,6 @@ 'ch.mo', 'chair', 'chairs', - 'chancellor', 'chaplain', 'charge', 'chargé', @@ -946,6 +945,7 @@ 'bard', 'buddha', 'burgess', + 'chancellor', 'cheikh', 'deacon', 'dean', @@ -1316,11 +1316,90 @@ 'chief wo5', 'chief न्यायमूर्ति', 'chief বিচারপতি', + 'deputy administrator', + 'deputy alderman', + 'deputy almoner', + 'deputy ambassador', + 'deputy arbitrator', + 'deputy attache', + 'deputy attaché', + 'deputy bailiff', + 'deputy burgess', + 'deputy ceo', + 'deputy cfo', + 'deputy chair', + 'deputy chairs', + 'deputy chancellor', + 'deputy charge', + 'deputy chargé', + 'deputy clerk', + 'deputy cllr', + 'deputy co-chair', + 'deputy co-chairs', + 'deputy commissioner', + 'deputy comptroller', + 'deputy controller', + 'deputy councillor', + 'deputy counsel', + 'deputy courtier', + "deputy d'affaires", + 'deputy dean', + 'deputy delegate', + 'deputy dir', + 'deputy director', + 'deputy dpty', + 'deputy envoy', + 'deputy gov', + 'deputy governor', + 'deputy headman', + 'deputy intendant', + 'deputy judge', + 'deputy justice', + 'deputy leader', + 'deputy mag', + 'deputy mag-judge', + 'deputy mag/judge', + 'deputy magistrate', + 'deputy magistrate-judge', + 'deputy mayor', + 'deputy member', + 'deputy minister', + 'deputy prefect', + 'deputy premier', + 'deputy pres', + 'deputy president', + 'deputy prin', + 'deputy principal', + 'deputy provost', + 'deputy pslc', + 'deputy pursuivant', + 'deputy registrar', + 'deputy rep', + 'deputy representative', + 'deputy secretary', + 'deputy senator', + 'deputy senior-judge', + 'deputy sheriff', + 'deputy speaker', + 'deputy swordbearer', + 'deputy sysselmann', + 'deputy treasurer', + 'deputy vc', + 'deputy verderer', + 'deputy vizier', + 'deputy warden', + 'deputy न्यायमूर्ति', + 'deputy বিচারপতি', 'king consort', + 'lady justice', + 'lord chancellor', + 'lord justice', + 'magistrate judge', 'major general', 'prince consort', 'princess consort', 'princess royal', + 'pro chancellor', 'queen consort', 'queen mother', 'sergeant major', diff --git a/nameparser/vocab/en.toml b/nameparser/vocab/en.toml index 87975aea7..ac116e97f 100644 --- a/nameparser/vocab/en.toml +++ b/nameparser/vocab/en.toml @@ -119,7 +119,7 @@ academic = { expands = "the address of a nurse, 'Nurse Smith'" } [[word]] text = "pro" -academic = { issue = 9, expands = "Pro Se Law Clerk", note = "academic rather than modifier since 2026-10-25 (#752): a part after a comma written 'Pro' is the person's role, which decision 10's modifier rule would read out of the title (decisions/vocabulary-model)" } +academic = { issue = 9, attaches = ["chancellor"], expands = "Pro Se Law Clerk", note = "attaches: Pro Chancellor (rules/H9, #913); academic rather than modifier since 2026-10-25 (#752): a part after a comma written 'Pro' is the person's role, which decision 10's modifier rule would read out of the title (decisions/vocabulary-model)" } [[word]] text = "abbess" @@ -403,11 +403,11 @@ nobility = { gender = "m", expands = "the rank the post-nominal knt names", issu [[word]] text = "lady" -nobility = { gender = "f", note = "stays out of GIVEN_NAME_TITLES, decided: the given-name form ('Lady Diana') is a courtesy style for the daughters of the senior ranks alone, while every wife takes the title or surname ('Lady Thatcher'), and the text does not carry the rank (#519)" } +nobility = { gender = "f", attaches = ["justice"], note = "attaches: Lady Justice (rules/H9, #913); stays out of GIVEN_NAME_TITLES, decided: the given-name form ('Lady Diana') is a courtesy style for the daughters of the senior ranks alone, while every wife takes the title or surname ('Lady Thatcher'), and the text does not carry the rank (#519)" } [[word]] text = "lord" -nobility = { gender = "m", note = "stays out of GIVEN_NAME_TITLES, decided: the given-name form ('Lord Peter') is a courtesy style for the children of the senior ranks alone, while every peer takes the title or surname ('Lord Byron'), and the text does not carry the rank (#519)" } +nobility = { gender = "m", attaches = ["chancellor", "justice"], note = "attaches: Lord Chancellor, Lord Justice (rules/H9, #913); stays out of GIVEN_NAME_TITLES, decided: the given-name form ('Lord Peter') is a courtesy style for the children of the senior ranks alone, while every peer takes the title or surname ('Lord Byron'), and the text does not carry the rank (#519)" } [[word]] text = "marchess" @@ -939,7 +939,9 @@ office = { same_as = "chair" } [[word]] text = "chancellor" -office = {} +office = { issue = 913, decided = 2026-10-28, note = "a title only inside a title phrase, its given reading the clash (rules/H9): 'Lord Chancellor Smith' and 'Vice Chancellor Jones' read the title, 'Chancellor Smith' the given name" } +given = { us_ssa = 2648, wikidata = 13, as_of = 2026-10-28, note = "US SSA: male births 2,643, female 5; Wikidata is a lower bound (United States 3)" } +family = { us_census_2010 = 4147, wikidata = 77, as_of = 2026-10-28, note = "US Census rank 7,974; Wikidata United Kingdom 11, United States 8" } [[word]] text = "chargé" @@ -1005,7 +1007,7 @@ office = {} [[word]] text = "deputy" -office = {} +office = { attaches = ["office"], issue = 913, note = "attaches: Deputy Chancellor, Deputy Judge (rules/H9), as chief does" } [[word]] text = "dpty" @@ -1041,7 +1043,7 @@ office = {} [[word]] text = "judge" -office = {} +office = { issue = 913, note = "kept a title, decided 2026-10-28 (decisions/H9): US SSA 3,826 births (all male), Census 10,453 (rank 3,414), Wikidata 7 given and 133 family, but in PSC 0 filers put it in the forename box and 0 in the title box, and in FEC 13 judges file it before their given name (FAMILY, JUDGE GIVEN, or alone after the comma) and would lose the title, against 2 fixes in all the local corpora (one ORCID, one PSC forename). The given count stands here rather than as a given reading, which would make it a title only inside a title phrase (rules/H9)" } [[word]] text = "justice" @@ -1055,7 +1057,7 @@ office = {} [[word]] text = "magistrate" -office = {} +office = { attaches = ["judge"], issue = 913, note = "attaches: Magistrate Judge, the US federal office (rules/H9)" } [[word]] text = "mag" diff --git a/tests/test_constants.py b/tests/test_constants.py index 7c85f6185..3e3386c30 100644 --- a/tests/test_constants.py +++ b/tests/test_constants.py @@ -32,10 +32,10 @@ class CustomConstants(Constants): pass c = CustomConstants() - c.titles.add('chancellor') - hn = HumanName("Chancellor Jane Smith", constants=c) + c.titles.add('bursar') + hn = HumanName("Bursar Jane Smith", constants=c) self.assertIs(hn.C, c) - self.m(hn.title, "Chancellor", hn) + self.m(hn.title, "Bursar", hn) self.m(hn.first, "Jane", hn) self.m(hn.last, "Smith", hn) diff --git a/tests/test_python_api.py b/tests/test_python_api.py index 3aff9024f..66d576a18 100644 --- a/tests/test_python_api.py +++ b/tests/test_python_api.py @@ -126,15 +126,15 @@ def test_name_instance_pickle_preserves_instance_config(self) -> None: """ # Passing None as the second argument gives this name its own Constants. hn = HumanName("Smith, Dr. John", Constants()) - hn.C.titles.add('chancellor') + hn.C.titles.add('bursar') hn.parse_full_name() # Safe: round-tripping a HumanName the test just built, not untrusted data. restored = pickle.loads(pickle.dumps(hn)) - self.assertIn('chancellor', restored.C.titles) - restored.full_name = "Chancellor Jane Smith" - self.assertEqual(restored.title, "Chancellor") + self.assertIn('bursar', restored.C.titles) + restored.full_name = "Bursar Jane Smith" + self.assertEqual(restored.title, "Bursar") def test_name_instance_deepcopy(self) -> None: """copy.deepcopy of a HumanName must round-trip. @@ -153,12 +153,12 @@ def test_name_instance_deepcopy(self) -> None: def test_name_instance_deepcopy_isolates_instance_config(self) -> None: """A deep-copied HumanName with its own config must be independent.""" hn = HumanName("Smith, Dr. John", Constants()) - hn.C.titles.add('chancellor') + hn.C.titles.add('bursar') dup = copy.deepcopy(hn) dup.C.titles.add('marker') - self.assertIn('chancellor', dup.C.titles) + self.assertIn('bursar', dup.C.titles) self.assertNotIn('marker', hn.C.titles) def test_pickle_default_name_preserves_singleton_identity(self) -> None: @@ -184,7 +184,7 @@ def test_pickle_default_name_preserves_singleton_identity(self) -> None: def test_pickle_instance_config_name_preserves_own_config(self) -> None: """A HumanName with its own Constants must not be collapsed onto CONSTANTS after pickle.""" hn = HumanName("Smith, Dr. John", Constants()) - hn.C.titles.add('chancellor') + hn.C.titles.add('bursar') hn.parse_full_name() self.assertTrue(hn.has_own_config) self.assertIsNot(hn.C, CONSTANTS) @@ -194,7 +194,7 @@ def test_pickle_instance_config_name_preserves_own_config(self) -> None: self.assertTrue(restored.has_own_config) self.assertIsNot(restored.C, CONSTANTS) - self.assertIn('chancellor', restored.C.titles) + self.assertIn('bursar', restored.C.titles) def test_shallow_copy_default_name_preserves_singleton_identity(self) -> None: """copy.copy of a default HumanName shares the CONSTANTS reference without hooks.""" diff --git a/tests/v2/cases.py b/tests/v2/cases.py index 8552a821d..aa73d3c68 100644 --- a/tests/v2/cases.py +++ b/tests/v2/cases.py @@ -12990,6 +12990,37 @@ def _check_cjk_shape_purity(self) -> None: {"given": "Ranger", "family": "Smith"}, classification="fix(#913)", notes="H9; read title 'Ranger' 1.4.0 through 2.7.0"), + Case("given_name_title_chancellor_reports_title_or_name", + "Chancellor Smith", + {"given": "Chancellor", "family": "Smith"}, + ambiguities=("title-or-name",), classification="fix(#913)", + notes="H9: 'Vice Chancellor' and 'Lord Chancellor' hold it; read " + "title 'Chancellor' 1.4.0 through 2.7.0"), + Case("chancellor_keeps_the_title_behind_lord", + "Lord Chancellor John Smith", + {"title": "Lord Chancellor", "given": "John", "family": "Smith"}, + classification="parity", + notes="H9: 'lord' attaches to 'chancellor' (#913)"), + Case("chancellor_keeps_the_title_behind_deputy", + "Deputy Chancellor Ann Lee", + {"title": "Deputy Chancellor", "given": "Ann", "family": "Lee"}, + classification="parity", + notes="H9: 'deputy' attaches to the office kind, as 'chief' does " + "(#913)"), + Case("chancellor_keeps_the_title_behind_pro", "Pro Chancellor Ann Lee", + {"title": "Pro Chancellor", "given": "Ann", "family": "Lee"}, + classification="parity", + notes="H9: 'pro' attaches to 'chancellor' (#913)"), + Case("lord_justice_is_one_title", "Lord Justice Leveson", + {"title": "Lord Justice", "family": "Leveson"}, + classification="fix(#913)", + notes="H9: 'lord' attaches to 'justice'; 1.4.0 through 2.7.0 read " + "title 'Lord', given 'Justice'"), + Case("lady_justice_is_one_title", "Lady Justice Arden", + {"title": "Lady Justice", "family": "Arden"}, + classification="fix(#913)", + notes="H9: 'lady' attaches to 'justice'; 1.4.0 through 2.7.0 read " + "title 'Lady', given 'Justice'"), 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/test_cases.py b/tests/v2/test_cases.py index b422293c4..d93d9c18d 100644 --- a/tests/v2/test_cases.py +++ b/tests/v2/test_cases.py @@ -302,10 +302,12 @@ def test_the_field_sweep_sees_the_claims_it_checks() -> None: # Meredith', reporting title-or-name under three orders; 1415 -> # 1448 the same day, #913's royal title phrases: ten rows of bare # King, Queen, Prince and Princess now reporting title-or-name, and - # 'Royal Smith', each under three orders. - assert claims == 1448, ( - f"the field sweep checks {claims} claims, recorded as 1448 on " - f"2026-10-27") + # 'Royal Smith', each under three orders; 1448 -> 1451 on 2026-10-28, + # #913's 'Chancellor Smith', reporting title-or-name under three + # orders. + assert claims == 1451, ( + f"the field sweep checks {claims} claims, recorded as 1451 on " + f"2026-10-28") #: The kinds that report a fork between two readings of a word, so carry diff --git a/tools/differential/corpus_rules.jsonl b/tools/differential/corpus_rules.jsonl index bd38e596e..15d121b9d 100644 --- a/tools/differential/corpus_rules.jsonl +++ b/tools/differential/corpus_rules.jsonl @@ -97,6 +97,7 @@ "Carod i" "Carod i Rovira, Josep" "Carod y de Rovira i" +"Chancellor Smith" "Chas. Smith" "Chas. Smith, Ed" "Cheikh Anta Diop" @@ -634,6 +635,7 @@ "Lloret Palol II, Josep Antoni" "Lord Buddha Tamang" "Lord Chancellor" +"Lord Chancellor John Smith" "López, Ana García" "MSc Dr. med. univ." "Ma." diff --git a/tools/differential/snapshot.jsonl b/tools/differential/snapshot.jsonl index 248b99e0b..1839b7cd6 100644 --- a/tools/differential/snapshot.jsonl +++ b/tools/differential/snapshot.jsonl @@ -517,7 +517,8 @@ {"name": "Cecilija Hemiš Šteber", "given": "Cecilija", "middle": "Hemiš", "family": "Šteber", "initials": "C. H. Š."} {"name": "Cerda y Aragón, Tomás Antonio de la", "given": "Tomás", "middle": "Antonio", "family": "de la Cerda y Aragón", "ambiguities": ["PARTICLE_OR_GIVEN"], "alternatives": ["PARTICLE_OR_GIVEN: name as middle (declared)"], "initials": "T. A. C. A."} {"name": "Cetto, August von", "given": "August", "family": "von Cetto", "ambiguities": ["PARTICLE_OR_GIVEN"], "alternatives": ["PARTICLE_OR_GIVEN: name as middle (declared)"], "initials": "A. C."} -{"name": "Chancellor Jane Smith", "title": "Chancellor", "given": "Jane", "family": "Smith", "initials": "J. S."} +{"name": "Chancellor Jane Smith", "given": "Chancellor", "middle": "Jane", "family": "Smith", "ambiguities": ["TITLE_OR_NAME"], "alternatives": ["TITLE_OR_NAME: title as title (vocabulary)"], "initials": "C. J. S."} +{"name": "Chancellor Smith", "given": "Chancellor", "family": "Smith", "ambiguities": ["TITLE_OR_NAME"], "alternatives": ["TITLE_OR_NAME: title as title (vocabulary)"], "initials": "C. S."} {"name": "Chang, Andy C I", "given": "Andy", "middle": "C", "family": "Chang", "suffix": "I", "initials": "A. C. C."} {"name": "Charles Claude de La Billarderie d'Angiviller", "given": "Charles", "middle": "Claude", "family": "de La Billarderie d'Angiviller", "initials": "C. C. B. d.", "capitalized_force": "Charles Claude de la Billarderie D'Angiviller"} {"name": "Charles Wilkins", "given": "Charles", "family": "Wilkins", "initials": "C. W."} @@ -2293,6 +2294,7 @@ {"name": "Lon (Jr.) Williams", "given": "Lon", "middle": "Jr.", "family": "Williams", "initials": "L. J. W."} {"name": "Lord Buddha Tamang", "title": "Lord", "given": "Buddha", "family": "Tamang", "initials": "B. T."} {"name": "Lord Chancellor", "title": "Lord", "family": "Chancellor", "ambiguities": ["TITLE_OR_NAME"], "alternatives": ["TITLE_OR_NAME: title as title (vocabulary)"], "initials": "C."} +{"name": "Lord Chancellor John Smith", "title": "Lord Chancellor", "given": "John", "family": "Smith", "initials": "J. S."} {"name": "Lord God Almighty", "title": "Lord", "given": "God", "family": "Almighty", "initials": "G. A."} {"name": "Lord and of the Universe", "title": "Lord and of the Universe"} {"name": "Lord of the Universe", "title": "Lord of the Universe"}