Add maiden name field with delimiter routing (#22)#199
Merged
Conversation
Mirrors the existing nickname field at the data-model level: property, setter, _members entry, constructor kwarg, and as_dict/iteration/slicing participation. Delimiter routing (parse_nicknames generalization) is not part of this change. Also fixes tests/test_python_api.py::test_slice, whose hardcoded slice indices/lengths depended on the exact size of _members and shifted by one now that maiden has been added.
…en_delimiters buckets parse_nicknames() now iterates two named delimiter buckets instead of the unreleased extra_nickname_delimiters: nickname_delimiters (holds the three built-ins by default, plus any caller-added patterns) and maiden_delimiters (empty by default). Built-in entries store the string name of a regexes entry rather than a copied pattern, so overriding e.g. CONSTANTS.regexes.parenthesis keeps affecting nickname/maiden parsing; moving a key between the two dicts routes it to a different bucket without losing that live link. Also fixes a latent bug in TupleManager surfaced by this task: constructing a subscripted generic like TupleManager[re.Pattern[str] | str](...) causes typing's GenericAlias.__call__ to set __orig_class__ on the new instance, which TupleManager's dict-backed __setattr__ silently turned into a bogus dict entry. __setattr__/__delattr__ now guard dunder names the same way __getattr__ already does.
Closes the gap the final feature review flagged: repr() and as_dict() now always include maiden, but usage.rst's walkthrough examples predate that field and were never updated. Also corrects the as_dict() example's key order to match actual _members iteration order (was already stale/mismatched before this branch, unrelated to maiden -- fixed here since the line was already being touched). Verified via `sphinx-build -b doctest`: failure count for the whole docs/ tree drops from 26 to 21 with this change, and none of the remaining failures reference maiden -- they're pre-existing cross-example CONSTANTS state leaks already noted in AGENTS.md's doctest gotcha, unrelated to this feature.
…elimiter sentinel nickname_delimiters/maiden_delimiters string values that don't resolve to a real Constants.regexes key used to fall back to RegexTupleManager's EMPTY_REGEX default. That's not a harmless no-op: EMPTY_REGEX matches at every character position, so handle_match() fired repeatedly and appended '' into the bucket's list each time, producing a truthy whitespace-only nickname/maiden while leaving the intended delimiter's content (e.g. literal parentheses) unstripped elsewhere in the name. Found independently by two review agents with working reproductions while auditing PR #199. Now raises ValueError naming the bad key instead. To keep Constants(regexes=<minimal custom set>) working (confirmed via the existing test_override_regex), nickname_delimiters is only seeded with a built-in name if it's actually present in the regexes passed to the constructor -- so a caller who deliberately drops e.g. "parenthesis" from a custom regexes set doesn't end up with a dangling sentinel that looks like a mistake.
nickname_delimiters/maiden_delimiters' construction already fixed a latent bug where TupleManager[X](...) leaked __orig_class__ into the dict itself (commit 5bd82b2), but nothing in the suite pinned it down directly -- a future "simplification" of __setattr__/__delattr__ back to bare dict.__setitem__/__delitem__ aliases would silently corrupt nickname/maiden parsing again with no test catching it. Flagged by a review agent auditing PR #199.
Six repr() examples in customize.rst (Hon Solo x2, dean title x3, the suffix-attribute-list example) never got the maiden: '' line every real HumanName.__repr__() now emits -- these predate the maiden field and are unrelated to the nickname-delimiter sections this feature actually touched, so they were missed. Also fixes usage.rst's name[1:-2] slice example, which needed to become name[1:-3] once _members grew by one (the corresponding test_python_api.py::test_slice update was already made in this branch; the doc example was not). Verified via sphinx-build -b doctest: total failure count across docs/ drops from 21 (after the earlier usage.rst-only fix) to 15, with no remaining maiden-related mismatches. The rest are pre-existing cross-example CONSTANTS state leaks already documented in AGENTS.md's doctest gotcha, unrelated to this change. Found by review agents auditing PR #199.
Owner
Author
|
Ran a multi-agent review (code, tests, comments, silent-failures, type-design) against this branch. Summary and fixes pushed: Fixed:
Reviewed and judged not worth acting on:
Full suite: 1196 passed, 22 xfailed. mypy and ruff clean. |
…string Not added as :param: entries since they aren't __init__ arguments (always set internally, unlike every other entry in that block) -- that would make Sphinx's generated docs imply Constants(nickname_delimiters=...) works. Documented as a plain note instead, pointing at the customization docs for the full mechanism.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
maidenfield toHumanName, mirroringnickname(property, setter,as_dict/iteration/slicing).extra_nickname_delimiterswith per-bucketnickname_delimiters/maiden_delimitersonConstants, so a delimiter (e.g. parenthesis) can be routed tomaideninstead ofnicknamefor alternate/maiden surnames, e.g."Baker (Johnson), Jenny"→first="Jenny",last="Baker",maiden="Johnson".Constants.regexesvia a string-sentinel mechanism, preserving the existing, documentedCONSTANTS.regexes.parenthesis = ...customization path.HumanNamenow raisesValueErrorifnickname_delimiters/maiden_delimiterscontains a string that doesn't name a realConstants.regexeskey (e.g. a typo, or a key missing from a customregexesoverride). Previously this silently fell back toEMPTY_REGEX, which doesn't just skip the delimiter — it matches at every character position and corrupts the parse (injects a whitespace-only truthy value intonickname/maiden, leaves the real delimiter content unstripped elsewhere).Constants(regexes=<minimal custom set>)still works: the built-in sentinels are only seeded for names actually present in theregexespassed to the constructor.TupleManagerbug: constructing a subscripted generic (TupleManager[X](...)) was silently corrupting the dict via__orig_class__leaking through__setattr__.maidenis off by default and not included in the defaultstring_format.docs/customize.rst/docs/release_log.rst, and updatesAGENTS.md(architecture notes, extension patterns, new gotchas) anddocs/usage.rst(repr/as_dict examples) accordingly.Closes #22.
Test plan
uv run pytest— 1196 passed, 22 xfaileduv run mypy nameparser/— cleanuv run ruff check nameparser/ tests/— cleansphinx-build -b doctestspot-checked for the new/changed doc examples (not CI-covered, but verified manually); total doc-tree failure count reduced from a 26 baseline to 15, none maiden-related"Baker (Johnson), Jenny"and"Jenny Baker (Johnson)"nicknameunless explicitly reconfigured)ValueErrorinstead of silently corrupting output;Constants(regexes=<minimal set>)still works unaffectedSee the review comment below for the full multi-agent review this branch went through after the initial commits, and what it found/fixed.