Skip to content

Allow adding nickname delimiter patterns at runtime#190

Merged
derek73 merged 4 commits into
masterfrom
feat/nickname-delimiters-runtime-config
Jul 1, 2026
Merged

Allow adding nickname delimiter patterns at runtime#190
derek73 merged 4 commits into
masterfrom
feat/nickname-delimiters-runtime-config

Conversation

@derek73

@derek73 derek73 commented Jul 1, 2026

Copy link
Copy Markdown
Owner

Summary

  • Fixes the "adding a regex at runtime has no effect" half of Dynamic changes #112: parse_nicknames() looped over a hardcoded tuple of three named regexes, so overriding an existing pattern in CONSTANTS.regexes and re-parsing already worked, but there was no way to add a new delimiter pattern.
  • Constants now exposes nickname_delimiters, a named TupleManager of delimiter patterns (seeded with the existing quoted_word/double_quotes/parenthesis regexes), and parse_nicknames() iterates it instead of a literal tuple.
  • Add a new pattern under a new key (hn.C.nickname_delimiters['curly_braces'] = re.compile(...)) and call parse_full_name() again to pick it up — no subclassing or monkeypatching required.
  • Docs updated (docs/customize.rst) with a worked example.

Test plan

  • New test test_add_custom_nickname_delimiter in tests/test_nicknames.py reproduces the runtime-add scenario from the issue thread
  • Full suite passes: 982 passed, 4 skipped, 22 xfailed
  • Verified pickling/deepcopy still round-trip the new attribute correctly

Closes #112 (the nickname-delimiter case discussed in the thread; further generalization to other config groups mentioned in the issue is left as future work if a concrete need comes up).

🤖 Generated with Claude Code

parse_nicknames() looped over a hardcoded tuple of three named regexes,
so overriding an existing pattern in CONSTANTS.regexes and re-parsing
worked, but adding a brand new delimiter had no effect since nothing
iterated a variable set of patterns.

Constants now exposes nickname_delimiters, a named TupleManager of
delimiter patterns (seeded with the existing quoted_word/double_quotes/
parenthesis regexes) that parse_nicknames() iterates. Adding an entry
and calling parse_full_name() again picks it up.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@derek73 derek73 added this to the v1.3.0 milestone Jul 1, 2026
@derek73 derek73 self-assigned this Jul 1, 2026
Multi-agent review of PR #190 caught a critical regression: snapshotting
quoted_word/double_quotes/parenthesis into nickname_delimiters at
Constants.__init__ time silently broke the pre-existing, documented
customization path of overriding CONSTANTS.regexes.parenthesis (etc.)
and re-parsing, since the snapshot never saw later changes to regexes.

parse_nicknames() now reads the three built-ins live from self.C.regexes
(restoring that override path) and additionally iterates a renamed,
initially-empty extra_nickname_delimiters collection for new patterns,
matching what issue #112 actually asked for (add, not replace).

Also: added extra_nickname_delimiters to conftest.py's autouse
snapshot/restore list (it was missing, so mutating the global CONSTANTS
copy in a test would have leaked into later tests), added regression/
removal/pickle-roundtrip/suffix-interaction tests, and fixed the stale
parse_nicknames() docstring.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@derek73

derek73 commented Jul 1, 2026

Copy link
Copy Markdown
Owner Author

Ran a multi-agent review pass (code, tests, comments) on the original commit and it caught a real regression before merge, now fixed in the second commit:

Critical bug found: the original approach snapshotted quoted_word/double_quotes/parenthesis into a new nickname_delimiters dict at Constants.__init__ time. That silently broke the pre-existing, documented customization path — overriding CONSTANTS.regexes.parenthesis and calling parse_full_name() again — because the snapshot never saw later changes to regexes. Verified directly: worked on master, broken on the first commit here.

Fix: parse_nicknames() now reads the three built-ins live from self.C.regexes (restoring that override path), and additionally iterates a renamed, initially-empty extra_nickname_delimiters collection for genuinely new patterns — matching what #112 actually asked for (add a pattern, don't have to replace one).

Also addressed from review:

  • extra_nickname_delimiters was missing from tests/conftest.py's autouse snapshot/restore list, so a test mutating the global CONSTANTS copy would have leaked state into later tests — added.
  • Added a removal test, a regression test for the override path, a pickle round-trip assertion, and a test confirming the suffix/nickname disambiguation logic in handle_match() applies uniformly through a custom delimiter, not just the three built-ins.
  • Fixed the now-stale parse_nicknames() docstring.

Full suite: 990 passed, 4 skipped, 22 xfailed.

derek73 and others added 2 commits July 1, 2026 01:32
Extension Patterns had guidance for adding a scalar Constants attribute
but nothing for a mutable/collection one, which is how extra_nickname_delimiters
almost shipped without being added to conftest.py's autouse snapshot/restore list.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Multi-agent review of PR #190 flagged two coverage gaps: no test for
registering multiple extra delimiters together, and no dedicated
deepcopy round-trip test for extra_nickname_delimiters itself (only
incidental coverage via conftest's autouse snapshot/restore). Also add
assertIsNone/assertIsNotNone to HumanNameTestBase, needed by the new
deepcopy test, and a note in AGENTS.md to add a deepcopy test whenever
a new mutable Constants collection is introduced.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@derek73 derek73 merged commit 2e55728 into master Jul 1, 2026
8 checks passed
@derek73 derek73 deleted the feat/nickname-delimiters-runtime-config branch July 1, 2026 09:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Dynamic changes

1 participant