Skip to content

Parenthesized (née Jones) parses as a nickname where the bare née Jones gives maiden #335

Description

@derek73
>>> parse("Jane Smith née Jones").maiden
'Jones'
>>> parse("Jane Smith (née Jones)").maiden
''
>>> parse("Jane Smith (née Jones)").nickname
'née Jones'

The marker is right there in the clause, so the parse has enough information to know Jones is a birth surname — but ( ) is a nickname_delimiters pair by default and maiden_delimiters is empty, so the clause is claimed as a nickname before anything looks inside it.

Setting Policy(maiden_delimiters=frozenset({("(", ")")})) fixes this one shape, but it is a whole-parser switch for what is really a per-clause fact, and it reroutes every parenthesis away from nicknames.

Also affected

>>> parse('Jane "Janey" Smith (née Jones)').nickname
'Janey née Jones'          # two clauses merged into one nickname
>>> parse("Anna Müller (geb. Schmidt)").maiden
''
>>> parse("山田 花子(旧姓 佐藤)").maiden
''                          # bare form gives '佐藤'

The mechanism is already in the tree

_pipeline/_extract.py already lets clause content overrule the delimiter's verdict. _suffix_shaped is the precedent: "Andrew Perkins (MBA)" is not a nickname, because the content is suffix-shaped, so extract masks only the two delimiter spans and lets the inner content join the main token stream.

The same treatment gives the requested behavior for free — strip the parens, and #274's existing bare-marker consuming rule produces exactly what née Jones produces, rather than a parallel implementation that could drift from it.

The predicate is small, and extract already imports Lexicon and _normalize and holds state.lexicon:

def _maiden_marked(content: str, lexicon: Lexicon) -> bool:
    head = content.split()[:1]
    return bool(head) and _normalize(head[0]) in lexicon.maiden_markers

Prototyped against the shapes that matter (2026-08-06): née Jones, nee Jones, geb. Schmidt (normalization strips the period) and 旧姓 佐藤 all return True; MBA, Janey, Jones née and 旧姓:佐藤 all return False.

Out of scope

山田(旧姓:佐藤) stays broken. The fullwidth colon is no separator tokenize knows, so marker and name arrive as one token and there is nothing to drop — that is the head-peel #317 tracks. Worth doing the two together, so "delimited maiden markers work" is one story rather than two partial ones.

Why this is not a 2.1 change

It is a default-on parse change, and the work is in the blast radius rather than the code:

  • 山田 花子(旧姓 佐藤) is in corpus_cjk.jsonl, so the differential gate sees it and expected_since_2.0.0.toml needs the row reclassified out of the CJK order-flip rule.
  • Three case rows need rewriting: maiden_marker_delimited, maiden_marker_delimited_unaccented (both currently require Policy(maiden_delimiters=...) and would work by default) and maiden_marker_kyusei_delimited.
  • tools/differential/README.md's "What this gate does not cover" section uses this exact example as the thing the gate cannot see. That section stops being true.
  • It needs a release-log entry.

The deciding factor is the release story rather than the effort. Jane Smith (née Jones) is Latin-only and is in no corpus, so the gate would go on reporting 0 of N changed names are Latin-only while a real Latin-affecting change shipped — measured-true and substantively misleading. Fixing that means adding Latin corpus rows, which makes the count non-zero, which is a change to 2.1's central claim that only CJK-bearing names moved.

In 2.2 it lands clean: the new ledger picks it up as a matter of course, and the Latin diff is expected rather than an exception to a headline.

Related: #329 (the marker inside a configured maiden clause), #274 (the bare-marker consuming rule this would reuse), #317 (the glued/colon form left out of scope).

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions