Skip to content

Commit 8cb9358

Browse files
derek73claude
andcommitted
docs: fix what the second review round found in the first round's fixes
- The initials exception gives way to an unlisted word of EITHER kind beside the letters ("MJ X.Y.Z.", "G.J. XYZ"), not only the same kind, where that word's own field reads it. - "Since 2.4" marked two of the dotted field's positions when the whole field is new in 2.4, implying the others were older; the section intro now says both fields are new in 2.4, once. - The dotted spelling reports the BARE initials reading; behind a title ("Ms G.J.") nothing is reported. - The extra_suffix_delimiters example, and two migrate.rst mappings, spelled set fields as bare set literals, which fail mypy against the frozenset annotations; now frozenset(...), checked with mypy --strict against the old spelling as a control. - The Policy table claimed to list every field but omitted script_orders and segment_scripts; both get short rows linking to the East Asian section, which gains a label. The script order winning over every name_order was measured. - docs/AGENTS.md: only the eight STAGES modules carry Reads: lines; _vocab.py and _pieces.py read the lexicon without one. And the first pass LEFT the five unlinked rows; the review found them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 127aa83 commit 8cb9358

3 files changed

Lines changed: 27 additions & 13 deletions

File tree

‎docs/AGENTS.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ The rules below were distilled from PR #588, which restructured `customize.rst`
66

77
## Structure
88

9-
**A table is an index.** A row states what the field does and its default, in a sentence or two, and links to a section with `:ref:`. Detail, boundary cases and examples go in the section. A description cell past about five lines is the signal that the row has stopped being an index. Rows grow by accretion — each fix adds its boundary case where the field is already described — so when you have a new case to document, add it to the section, never to the row. `customize.rst`'s Policy table is the model: every row whose field has a section links to it, and a field that needs no more than its row (`middle_as_family`) has no section at all. A row that has a section and does not link to it is a dead end — #588's first pass found five.
9+
**A table is an index.** A row states what the field does and its default, in a sentence or two, and links to a section with `:ref:`. Detail, boundary cases and examples go in the section. A description cell past about five lines is the signal that the row has stopped being an index. Rows grow by accretion — each fix adds its boundary case where the field is already described — so when you have a new case to document, add it to the section, never to the row. `customize.rst`'s Policy table is the model: every row whose field has a section links to it, and a field that needs no more than its row (`middle_as_family`) has no section at all. A row that has a section and does not link to it is a dead end — #588's first pass left five.
1010

1111
**One topic per paragraph; subheadings for a section with several.** A paragraph that answers more than one question gets split, and a section holding more than one task gets subheadings named for what the reader came to do ("Routing a pair to maiden names", "Teaching the splitter a surname"), not for the mechanism. Keep an existing section title when you add subheadings under it: other pages link to titles (`` `Words that are also ordinary names`_ ``), and renaming breaks them.
1212

@@ -40,7 +40,7 @@ The rules below were distilled from PR #588, which restructured `customize.rst`
4040

4141
**Check a claim end to end, through the call the reader makes.** "One `phd` key covers `Phd`" was true of the key match and false of `capitalized()`'s output, which leaves mixed case alone unless `force=True`. Verify against what the reader would observe, not an intermediate step.
4242

43-
**A claim about code needs the code.** "An empty `honorific_tails` stops the peel at its first guard" is checked by reading the guard, not by parsing a name. Find it through the stage headers: each `nameparser/_pipeline/*.py` module declares the `Policy`/`Lexicon` fields it reads on a `Reads:` line, so grepping those for the field names the stage to read.
43+
**A claim about code needs the code.** "An empty `honorific_tails` stops the peel at its first guard" is checked by reading the guard, not by parsing a name. Find it through the stage headers: each stage module (the eight in `nameparser/_pipeline/__init__.py`'s `STAGES`) declares the `Policy`/`Lexicon` fields it reads on a `Reads:` line. The shared helpers `_vocab.py` and `_pieces.py` have no such line and read the lexicon too, so grep them as well.
4444

4545
## Linking
4646

‎docs/customize.rst‎

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,16 @@ listed below.
486486
John" puts the family name first); a comma that only sets off
487487
suffixes ("John Smith, Jr.") leaves it governing the name part.
488488
See :ref:`name-order`.
489+
* - ``script_orders``
490+
- pairs of ``Script`` and an order
491+
- Assigns a name in one of these scripts in the paired order,
492+
whatever ``name_order`` says. Defaults to family-first for a
493+
name wholly in Han or Hangul, or mixing kanji with kana. See
494+
:ref:`east-asian-defaults`.
495+
* - ``segment_scripts``
496+
- ``frozenset[Script]``
497+
- Scripts whose unspaced names are split into surname and given
498+
name. Defaults to Hangul. See :ref:`east-asian-defaults`.
489499
* - ``patronymic_rules``
490500
- ``frozenset[PatronymicRule]``
491501
- Reorders patronymic-shaped names via opt-in detectors — East
@@ -718,6 +728,8 @@ so leaves a real question to answer.
718728
`Words that are also ordinary names`_ covers dropping a word from a
719729
vocabulary, or moving one between those two sets.
720730

731+
.. _east-asian-defaults:
732+
721733
East Asian defaults, and turning them off
722734
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
723735

@@ -984,7 +996,7 @@ is bad enough to be the reason you'd go looking:
984996
>>> name = parse("Jane Smith, RN - CRNA")
985997
>>> name.given, name.family, name.suffix
986998
('RN', 'Jane Smith', 'CRNA')
987-
>>> policy = Policy(extra_suffix_delimiters={" - "})
999+
>>> policy = Policy(extra_suffix_delimiters=frozenset({" - "}))
9881000
>>> name = Parser(policy=policy).parse("Jane Smith, RN - CRNA")
9891001
>>> name.given, name.family, name.suffix
9901002
('Jane', 'Smith', 'RN, CRNA')
@@ -994,7 +1006,8 @@ is bad enough to be the reason you'd go looking:
9941006
Credentials the vocabulary doesn't list
9951007
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9961008

997-
No suffix list holds every post-nominal, so two ``Policy`` fields read
1009+
No suffix list holds every post-nominal, so two ``Policy`` fields, both
1010+
new in 2.4, read
9981011
an unlisted word as a credential from how it is written: in periods
9991012
(``X.Y.Z.``), or in capitals (``XYZ``). The writing cannot settle it
10001013
alone, because a surname can be written either way, so both fields
@@ -1005,12 +1018,13 @@ Both fields share one exception. Two letters alone right after a comma
10051018
are how a person's initials are written, and the words before the comma
10061019
may be one surname of two words, so ``"García Márquez, G.J."`` and
10071020
``"García Márquez, MJ"`` keep given ``G.J.`` and ``MJ``. The dotted
1008-
spelling reports that reading as a fork; the capitals do not.
1021+
spelling reports the bare reading as a fork; the capitals do not.
10091022

10101023
The exception gives way to evidence that the letters are a credential:
10111024
an unambiguous post-nominal in front of them that is not also a title,
1012-
or another unlisted word of the same kind beside them. A title in front
1013-
of them says the opposite:
1025+
or another unlisted dotted or all-caps word beside them that its own
1026+
field reads as a credential. A title in front of them says the
1027+
opposite:
10141028

10151029
.. doctest::
10161030

@@ -1029,9 +1043,9 @@ Dotted acronyms
10291043

10301044
``unlisted_dotted_suffixes`` is on by default. It reads a token of two
10311045
or more period-separated chunks as a credential at the end of a name,
1032-
right after a comma behind two or more name words, and — since 2.4 —
1033-
at the end of the given part after a family comma and at the end of a
1034-
maiden marker's clause. Case is irrelevant; the periods are the signal.
1046+
right after a comma behind two or more name words, at the end of the
1047+
given part after a family comma, and at the end of a maiden marker's
1048+
clause. Case is irrelevant; the periods are the signal.
10351049
With nothing to spare in front of it, the word stays a name. At the end
10361050
of a name, given part or clause, either reading reports the fork as a
10371051
``suffix-or-name`` ambiguity, so a record that reads wrong can still be

‎docs/migrate.rst‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ Attribute map
148148
- Same three knobs, now call-site arguments to
149149
:meth:`~nameparser.ParsedName.initials`
150150
* - ``suffix_delimiter``
151-
- ``Policy(extra_suffix_delimiters={...})``
151+
- ``Policy(extra_suffix_delimiters=frozenset({...}))``
152152
- Moves from a ``HumanName``/``Constants`` scalar to a ``Policy``
153153
set field, so more than one custom delimiter can be active at
154154
once. It is the *set* that moved, not just the name: passing the
@@ -366,8 +366,8 @@ rendering argument, where the 2.0 equivalent isn't config at all):
366366
- 2.0 equivalent
367367
- Note
368368
* - ``patronymic_name_order``
369-
- ``Policy(patronymic_rules={PatronymicRule.EAST_SLAVIC,
370-
PatronymicRule.TURKIC})``
369+
- ``Policy(patronymic_rules=frozenset({PatronymicRule.EAST_SLAVIC,
370+
PatronymicRule.TURKIC}))``
371371
- v1's single flag enabled both detectors at once; pick one rule
372372
(or a locale pack, see :doc:`locales`) if you only want one
373373
tradition

0 commit comments

Comments
 (0)