Skip to content

Glued honorific: "田中さん, V." does not peel where "田中さん, PhD" does #319

Description

@derek73

Same credential, three spellings, two answers:

parse("田中さん, PhD")     # title PhD, family 田中, suffix さん      ← peels
parse("田中さん, V.")      # family '田中さん', given 'V.'            ← does not
parse("田中さん, Ph. D.")  # family '田中さん', suffix 'Ph. D.'       ← does not

Not a regression — all three are byte-identical to 1.4.0 and to pre-#312 — but #312 fixed the first and left its siblings, so which behavior you get depends on whether the post-comma token passes an initial veto.

Why

#312 scoped the peel's site to the name-bearing runs: segments[:2] under FAMILY_COMMA, segments[0] otherwise. That rests on segments[1] being name text under a family comma. It usually is — but not always.

_segment.py picks SUFFIX_COMMA only when suffixy(groups[1]) and len(groups[0]) > 1. When the post-comma part is entirely suffix-shaped and the pre-comma part is a single word, the structure falls through to FAMILY_COMMA with segments[1] holding post-nominals rather than given-name text. _assign agrees with that reading — it runs _peel_leading_titles over that run and routes it to title/suffix.

So the peel walks into the one kind of run it was scoped away from, and the gap it was scoped against bites:

  • segment() admits a post-comma run on is_suffix_lenient
  • _is_post_nominal asks is_suffix_strict
  • the initial-shaped suffix words fall between them — measured, V., V, I are lenient-True and strict-False

An initial-shaped token therefore becomes the peel site, ends in no listed tail, and the peel is silently abandoned. Adding a word before the comma (Dr 田中さん, V.) flips the structure to SUFFIX_COMMA and it peels correctly.

Why it was not fixed in #318

The clean condition is "include segments[1] only when it is actually name text", which is what segment()'s own suffixy already decides. But suffixy is a closure inside segment(), and its comment warns it must stay in sync with group's _PH/_D merge — so a copy in _script_segment would be a third definition of one rule.

The cheap substitute was measured and rejected: all(is_suffix_lenient) fixes V. and Jr. but not Ph. D. (because Ph. alone is not lenient-suffix), leaving PhD and Ph. D. inconsistent — trading one arbitrary split for another.

田中さん, V. is pinned as-is by a parity case row in #318 so the limit is recorded rather than latent.

What the fix probably looks like

Extract suffixy from segment() into _pipeline/_vocab.py alongside is_suffix_lenient/is_suffix_strict, so segment, group and script_segment share one definition of "this run is post-nominals, not name". Then the peel's scope becomes: include the second run under a family comma unless suffixy says it is a suffix run.

Care needed on the Ph./D. merge — suffixy treats an adjacent pair as one unit, and group has a matching merge that the comment says must not drift.

Worth doing alongside anything else that wants the same predicate; it is the third caller that makes the extraction pay.

Found by whole-branch review on #318 (#312).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions