Skip to content

Add ParsedName.patronymic, the words naming the bearer's parent (3.0, 4c) - #948

Merged
derek73 merged 6 commits into
masterfrom
feat/v3-4c-patronymic-view
Oct 30, 2026
Merged

derek73 merged 6 commits into
masterfrom
feat/v3-4c-patronymic-view

Conversation

@derek73

@derek73 derek73 commented Oct 30, 2026 •

Copy link
Copy Markdown
Owner

Sub-phase 4c of #754: the patronymic view, rules/R9 (the patronymic view), decisions/R9.

What it does

ParsedName.patronymic holds the words read as a patronymic, in whatever field the parse put them. family and middle keep those words.

>>> parse("Mahathir bin Mohamad").patronymic
'bin Mohamad'                     # family is still 'bin Mohamad'
>>> parser_for(locales.RU).parse("Ivan Ivanovich Ivanov").patronymic
'Ivanovich'                       # middle is still 'Ivanovich'
>>> parser_for(locales.TR_AZ).parse("Aliyev, Heydar Alirza oglu").patronymic
'Alirza oglu'
>>> parse("Anwar Ibrahim").patronymic
''                                # no particle and no rule, so no guess from position
  • It is a render() key. It is not in as_dict(), --json, comparison_key() or the repr.
  • Token.reading takes ReadingKind.PATRONYMIC, which 4a added and nothing used until now.
  • No new Lexicon field, and no new field on any pickled type.

Decisions the spec left open

  1. Every word of a particle's patronymic reads patronymic. The view is the tokens of that kind, and its text has to be bin Mohamad.
    • The particle's source is vocabulary, and its files are ar ms for bin.
    • Each word after it reads by position and names no file.
  2. The run is the particle's field, read at assemble from the final roles, not from group's pieces. P1's fold and P6's attachment move words after group runs.
    • A nickname inside the run is skipped, and a suffix ends it.
    • ibn Ali Hasan gives ibn Ali Hasan by default and ibn Ali under a family-first order, matching the family.
    • Under middle_as_family the run follows the field the word stands as.
  3. A particle names a parent only when a word follows it in its field. The exception is a particle P6 attached to the family written before it: Mohamad, Mahathir bin gives bin Mohamad, in the family's order. P6 marks the words it attaches (vocab:attached, a private tag dropped at assemble like vocab:patronymic), so the attachment is recorded rather than inferred from the folded mark that O3's middle fold also writes. Bakar, Ali bin Abu gives bin Abu Bakar, and the exception holds under middle_as_family without misreading a particle P6 declined (Rahman, Al bin gives nothing). An attached particle names a parent only where the family holds a word P6 and O3 did not fold, so one P6 attaches as the whole family behind an empty head (, Siti Aminah binti) reads nothing under any policy.
    • The first draft read Fritz Freiherr und von Bar as patronymic Bar (the German family name, spelled like the Hebrew particle). The snapshot showed it.
  4. The kind is read at classify from the reading index, as 4b does for suffix words.
    • _vocab.is_patronymic_particle calls _reading_index.holds_kind. It ignores the reading's default.
    • The vocab:patronymic tag is dropped from published tokens. A 2.8.0-wheel pickle of Mahathir bin Mohamad is a new fixture, and it compares equal.
    • Every patronymic particle has only that particle kind.
    • ben stays out: the vocabulary excludes it as a patronymic.
  5. The reading not taken moves with the reading taken. A leading bin read as a given name used to name particle as family as its alternative. It now names patronymic as family (_vocab.particle_reading, at both of assign's particle alternatives).
  6. The ending rules read a word wherever the policy turns them on, not only where O1's or O2's rotation fires.
    • East Slavic: a middle word carrying O1's ending. The family is excluded, since Roman Abramovich is a surname.
    • Turkic: a marker with the name word before it in the same comma part, in a name field or the maiden name. Aliyev, oglu and oglu Ali read nothing. The father's name is read only once its marker reads as a name word, so a marker a caller lists as a connective reads nothing.
    • The patterns moved from _post_rules to _vocab as has_patronymic_ending / is_patronymic_marker. The rotations and assemble ask the same predicates, and the packs' hand copies are pinned against them there.
  7. No Icelandic rule, as asked. It is listed as Open in decisions/R9, along with the Ukrainian -ївна ending.

Measured (2026-10-29, against a9884bf)

Snapshot

  • Of the base's 6,570 readings, 23 gain a patronymic key. Each is a particle's run.
  • One alternative moves: bin Stromae Elizabeth Windsor Maria Teresa MP under FAMILY_FIRST, from particle as family to patronymic as family.
  • No field moves.
  • R9's examples add 31 names, for 6,601 readings in all.

Agreement records

  • cldr_agreement.py now scores patronymic on its own, as its PENDING_ROLES were written to do once the attribute existed.
  • New entries: Wikidata 334, native-script 17, conventions 6. Each is a stated patronymic the default does not read.
  • No false positives, and no other field moved in any record.
  • Under RU, Wikidata's patronymic strata agree 126/126, 41/41 and 61/62. The one miss is a Ukrainian -ївна.
  • Malay names agree 4/9. The five misses are written without bin.

Frames per parse (sys.setprofile, re-taken after the review fixes)

  • Default policy: unchanged for the reference row (369) and John Smith (153).
  • +2 per patronymic particle (217 → 219).
  • +9 for P6's attached shape, which rebuilds the family's tokens (Mohamad, Mahathir bin 263 → 272, Bakar, Ali bin Abu 289 → 298).
  • RU: +1 per middle word read as a name.
  • TR_AZ: +1 per parse, +1 per word in a name field or the maiden name, and +2 per marker found; the father's token is built once, at its marker (John Smith 153 → 156, Ali Ahmad Vali oglu 243 → 251). Guarded by a new patronymic_rules row in test_benchmark.py's _POLICY_SHAPES.
  • The serial benchmarks pass.

Checks

  • uv run pytest: 32,880 passed
  • uv run pytest -n0 -m serial: passed
  • uv run --python 3.15 pytest: passed
  • mypy, ruff and tools/vocab/build.py --check: clean
  • Sphinx doctest: clean
  • Patch lines covered: 87/87

The comma shapes, all three orders and the bound-given interaction (Abdul Rahman bin Ahmad) are swept in test_types.py and R9's examples, and a grid invariant holds middle_as_family to the default policy's patronymic words wherever R2 reads the particles alike (it guards the attached word standing as the family under the fold; the D2 and empty-head shapes, whose R2 marks differ, are held by explicit rows). test_cases.py's view walk now also holds that the patronymic names only words of given, middle and family.

🤖 Generated with Claude Code

… 4c)

A patronymic particle the shipped vocabulary holds (bin, binti, ibn, bint,
bar, bat and the native-script forms) and the words after it in its field
read `patronymic`, and so do a middle word carrying the East Slavic ending
and a Turkic marker with the name before it, wherever RU or TR_AZ turns
the rule on. The view is a render key, not a field: family and middle keep
the words. Classify tags the particle's kind from the reading index and
assemble drops the tag, so 2.x pickles still compare equal. rules/R9,
decisions/R9; the snapshot and the agreement records gain the view.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@derek73 derek73 added this to the 3.0 milestone Oct 30, 2026
@derek73 derek73 added enhancement vocabulary Per-word vocabulary model and language packs labels Oct 30, 2026
@derek73 derek73 self-assigned this Oct 30, 2026
derek73 and others added 5 commits October 29, 2026 20:25
P6's attachment and O3's fold both write the folded mark, so the
attached particle is now told by its shape, not its field. A Turkic
father is read only once its marker reads as a name word, and the arm
reads the maiden name as the particle arm does. The user docs no
longer say the ending rules fill the view under every order. Each
clause the review found untested has a test, a benchmark row guards the
opt-in arms, and R9 records the accepted shapes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…(4c)

The attachment was inferred from the folded mark's shape, which lost the
family behind a second attached particle (Bakar, Ali bin Abu) and read a
particle P6 declined and O3 folded as attached (Rahman, Al bin). P6 now
marks what it attaches, assemble drops the mark, and a word P6 attached
stands as the family under the fold. A Turkic father is built once, at
its marker. An invariant grid holds middle_as_family to the default's
patronymic wherever R2 reads alike; R9 records the cases it does not.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Behind an empty head P6 attaches the particle as the whole family; O3's
fold gave it a base, and it read as an attached patronymic alone
(', Siti Aminah binti' under middle_as_family). An attached particle
now needs a family word not folded, the condition the shape test held.
The stage headers and mechanisms.md name the attached tag; the grid
test says what it cannot see. Third review fixes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A generator resumed a frame per word. Rows for an empty head under
FAMILY_FIRST_GIVEN_LAST, behind a nickname-only head and before a third
comma part; R9 shows the empty-head attachment.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@derek73
derek73 merged commit 8a1e6f5 into master Oct 30, 2026
13 checks passed
@derek73
derek73 deleted the feat/v3-4c-patronymic-view branch October 30, 2026 04:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement vocabulary Per-word vocabulary model and language packs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant