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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion docs/design/decisions.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,33 @@ The mechanism shipped twice before anyone wrote down its criterion. Sizes as of
uv run python -c "from nameparser import Parser; L=Parser().lexicon; print({s: len(getattr(L,s)) for s in ('particles','particles_ambiguous','suffix_words','suffix_acronyms','suffix_acronyms_ambiguous','titles')})"

- 2026-08-16 (collision keystone; #348, #360, #342, #385) — the 58%-vs-0.65% gap is BASE RATE, not disagreement. Both sets apply the same test; most particles are short words that double as names (van, bin, le, do, bar, mac) while most credential acronyms are not (abpp, acp). Recorded because the gap reads as an inconsistency and is not one — a reviewer who "harmonizes" the two shares will break one of them.
- **C-i, vocabulary vs. name.** A word belongs in its set's ambiguous subset iff it is also borne as an ordinary name (given or family) in some tradition. Under uncertainty, default to AMBIGUOUS. This generalizes the evidence standard already stated in NON_GIVEN_NAME_PARTICLES' docstring — a wrong unambiguous claim misparses a real person, a wrong ambiguous marking only adds a flag — from "which set" to "which subset". Applies uniformly to particles, suffix_acronyms and titles.
- **C-i, vocabulary vs. name.** A word belongs in its set's ambiguous subset iff it is borne as an ordinary name IN THE POSITION THE VOCABULARY CLAIM ACTS ON. Existence of a bearer anywhere is not the test, and the first draft of this criterion (recorded 2026-08-16, corrected 2026-08-17) got that wrong. Under uncertainty, default to AMBIGUOUS. This generalizes the evidence standard already stated in NON_GIVEN_NAME_PARTICLES' docstring — a wrong unambiguous claim misparses a real person, a wrong ambiguous marking only adds a flag — from "which set" to "which subset". Applies uniformly to particles, suffix_acronyms and titles.
- **C-ii, vocabulary vs. vocabulary.** Where two sets claim a word and NEITHER reading is a name, precedence is a frequency judgment recorded per word. vd is the live case: never-given particle AND credential acronym (the British Volunteer Decoration), neither of them a name. Decision: the Dutch van der reading, as the more common. That is what unblocks #380, whose trailing-orphan half is a separate decision recorded under its own rule.
- 2026-08-17 — C-i CORRECTED: the position qualifier. Writing the
per-word records for the never-given particles falsified the first
draft on the set's most load-bearing member. "De" is a borne Bengali
and Odia surname (parse("Bimal De").family == "De"), so C-i as first
written said mark `de` AMBIGUOUS -- which would break "de la Vega"
and every leading-particle reading. Nothing had tested the criterion
against `de`, and the error pointed at the safe side, so it would
never have announced itself as a misparse.
The qualifier the existing set was already obeying: P1 acts on the
LEADING position or a lone particle in the GIVEN role, so what
matters is whether the naming use occupies THAT position.
van Vietnamese Văn in given position collides ambiguous
bar Bar Refaeli, given position collides ambiguous
do Đỗ leads a surname collides ambiguous
de "De" is a TRAILING surname no clash never-given
Consequence, and the reason this is not merely tidier: `das` was
called ambiguous on #360 under the old reading because Das is a
borne Bengali surname. Measured, "Anjali Das" and "Bimal Das" are
unchanged by never-given `das` (the surname is trailing, the rule
acts leading) while "Maria das Neves" GAINS its particle --
family="Neves" today, family="das Neves" with it. The old reading
would have declined a fix. `lo` and `el` need re-judging on the same
axis; `Lo` does lead in romanized Chinese ("Lo Wei"), so it may
genuinely collide where `das` does not.
Corrected on #360, which carried the wrong table publicly.
- The concrete demonstration is "do", which three vocabularies claim — titles, particles/ambiguous, suffix_acronyms/ambiguous. Two mark it ambiguous; the third, TITLES, is the one that actually decides "Do Quang Minh" (title="Do", given="Quang") and reports nothing. Same word behind #385's "Anh Do".
- Applications, each still its own work: #360 (mc, ste — neither is a borne given name, so both leave the ambiguous half); #342 (rai — Rai IS a borne surname, so it earns the marking rather than moving); #385 (do — resolved at decisions.md#R2).
- C-ii's per-word framing versus a rule stated for a SHAPE: measured 2026-08-16, the words that are both particle and suffix vocabulary are vd, do and mc — three, not the one this criterion adjudicated. rules.md#P6 states its precedence for the shape, so do and mc inherit vd's answer without being weighed. Recorded rather than papered over: stating a per-word judgement as a general clause is how an unexamined word acquires a decision, and the two are named here so the next reader knows which one was actually argued.
Expand Down
64 changes: 42 additions & 22 deletions nameparser/config/particles.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,28 +36,48 @@
#: subset of :py:data:`PARTICLES` and disjoint from
#: :py:data:`~nameparser.config.bound_given_names.BOUND_GIVEN_NAMES`.
NON_GIVEN_NAME_PARTICLES = frozenset({
"'t",
'af',
'auf',
'av',
'bint',
'de',
"de'",
'degli',
'dei',
'delle',
'delli',
'dello',
'dem',
'der',
'dos',
'het',
'ibn',
'op',
'ter',
'vd',
'vom',
'zu',
# Latin-script members. Every entry here is a grammatical particle --
# an article, a preposition, or a patronymic marker -- and that is the
# form a never-given record has to take. One attested bearer settles
# the AMBIGUOUS side; no amount of searching settles absence, so what
# is recorded is what the word IS rather than a failed search.
#
# The test is POSITIONAL (decisions.md#vocabulary-collisions C-i,
# corrected 2026-08-17): membership asks whether the word is borne as
# a name in the position this rule ACTS on -- leading, or alone in the
# given role -- not whether a bearer exists anywhere. 'de' is why the
# qualifier is needed: "De" is a borne Bengali/Odia surname, but a
# TRAILING one, so it never meets the rule.
#
# A BARE entry, here or in PARTICLES below, means nobody has examined
# it. Absence of a comment is the audit record.
"'t", # Dutch contraction of 'het' ("'t Hooft"): the article itself
'af', # Danish/Norwegian nobiliary "of"
'auf', # German "upon" ("auf der Heide")
'av', # Swedish/Norwegian "of"
'bint', # Arabic "daughter of"; native-script بنت below
'de', # French/Iberian/Italian "of". "De" IS a borne Bengali and
# Odia surname -- trailing, so it never reaches this rule.
# The case that forced C-i's positional qualifier.
"de'", # Italian elided "dei" ("de' Medici")
'degli', # Italian "of the", masc. pl.
'dei', # Italian "of the", masc. pl.
'delle', # Italian "of the", fem. pl.
'delli', # Italian "of the", regional variant of 'dei'
'dello', # Italian "of the", masc. sg.
'dem', # German dative article
'der', # German article ("von der Leyen")
'dos', # Portuguese "of the", masc. pl.
'het', # Dutch definite article
'ibn', # Arabic "son of"; native-script ابن below
'op', # Dutch "at/on" ("op den Berg")
'ter', # Dutch "at the" ("ter Horst")
'vd', # Dutch abbreviation of "van der". Also the British
# Volunteer Decoration, a suffix acronym: two non-name
# readings, so C-ii decides it on frequency and the Dutch
# one wins (decisions.md#vocabulary-collisions).
'vom', # German "from the"
'zu', # German "at/to", nobiliary ("zu Guttenberg")

# #269: Arabic native-script patronymic/clan particles. Unlike their
# Latin transliterations, these live in a script namespace with no
Expand Down