Skip to content

Commit 1e76761

Browse files
derek73claude
andcommitted
Label the CLI output sections; document the tussenvoegsel sort
The default output printed three things, two of them unlabeled ParsedName reprs — the parse and the capitalized view. For input that is already correctly cased those two are byte-identical, so the CLI looked like it was printing the same thing twice, and there was no way to tell which block was which. The third line was already labeled "Initials:", so the inconsistency was internal to the command. Label all three. usage.rst gains an intro to that section framing the CLI as the quick way to check how a string parses — trying a variation of a name that came out wrong, or a locale pack before wiring it into code — plus the real output, which the section previously showed only for --json. The family_base example gains its reason for existing. #130 asked for the surname split specifically for tussenvoegsels, the Dutch particle that directories file a name *under* rather than *by*. Naming the convention gives the searchable term, and the contrast doctest shows what the split avoids: sorting on family files van Gogh under "v" and de la Vega under "d". Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent b23b08f commit 1e76761

3 files changed

Lines changed: 56 additions & 2 deletions

File tree

docs/usage.rst

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,10 @@ while ``given_names`` and ``surnames`` roll several fields together —
131131
the same sense in which a passport form asks for your "given names" as
132132
one blank that can hold more than one word.
133133

134-
``family_base`` is what you want for alphabetizing, since it drops the
135-
particles a phone book ignores:
134+
``family_base`` is the one to sort on. Dutch and Belgian directories
135+
file a name under the base surname and ignore the *tussenvoegsel* — the
136+
``van``, ``de`` or ``van der`` in front of it — and the same convention
137+
applies wherever particles are common:
136138

137139
.. doctest::
138140

@@ -141,6 +143,14 @@ particles a phone book ignores:
141143
>>> [n.family_base for n in sorted(names, key=lambda n: n.family_base.lower())]
142144
['Gogh', 'Smith', 'Vega']
143145

146+
Sorting on ``family`` instead files those under "d", "S" and "v", which
147+
is the problem the split exists to solve:
148+
149+
.. doctest::
150+
151+
>>> [n.family for n in sorted(names, key=lambda n: n.family.lower())]
152+
['de la Vega', 'Smith', 'van Gogh']
153+
144154
Dicts and strings
145155
------------------
146156

@@ -358,6 +368,34 @@ everything else carried over.
358368
Command line
359369
------------
360370

371+
``python -m nameparser`` parses one name and prints what it found. It
372+
is the quickest way to see how a particular string comes out — worth
373+
reaching for when a name parsed unexpectedly and you want to check a
374+
variation of it, or when trying a locale pack before wiring one into
375+
code:
376+
377+
::
378+
379+
$ python -m nameparser "dr. juan de la vega iii"
380+
Parsed:
381+
<ParsedName: [
382+
title: 'dr.'
383+
given: 'juan'
384+
family: 'de la vega'
385+
suffix: 'iii'
386+
]>
387+
Capitalized:
388+
<ParsedName: [
389+
title: 'Dr.'
390+
given: 'Juan'
391+
family: 'de la Vega'
392+
suffix: 'III'
393+
]>
394+
Initials: j. v.
395+
396+
``--json`` prints the fields as a single line instead, which is the
397+
form to pipe somewhere:
398+
361399
::
362400

363401
$ python -m nameparser --json "Doe, John"

nameparser/__main__.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,12 @@ def main(argv: list[str] | None = None) -> int:
3333
if args.json:
3434
print(json.dumps(n.as_dict(), ensure_ascii=False))
3535
return 0
36+
# Label each section: the two reprs are byte-identical for input
37+
# that is already correctly cased, so without labels there is no
38+
# telling which is the parse and which is the capitalized view.
39+
print("Parsed:")
3640
print(repr(n))
41+
print("Capitalized:")
3742
print(repr(n.capitalized()))
3843
print("Initials:", n.initials())
3944
return 0

tests/v2/test_cli.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,17 @@ def test_cli_prints_repr_capitalized_and_initials() -> None:
1515
assert "Initials:" in out
1616

1717

18+
def test_cli_labels_each_section() -> None:
19+
# two of the three outputs were unlabeled ParsedName reprs, and for
20+
# already-cased input they are byte-identical -- the reader cannot
21+
# tell which is the parse and which is the capitalized view
22+
out = _run("Dr. Juan de la Vega III").stdout
23+
assert out.count("<ParsedName:") == 2 # still both shown
24+
assert "Parsed:" in out
25+
assert "Capitalized:" in out
26+
assert out.index("Parsed:") < out.index("Capitalized:")
27+
28+
1829
def test_cli_json() -> None:
1930
proc = _run("John Smith", "--json")
2031
data = json.loads(proc.stdout)

0 commit comments

Comments
 (0)