Skip to content

Post-rc1 API polish: StrEnum Role, Parser conveniences, dead-vocabulary repair#290

Merged
derek73 merged 21 commits into
v2/core-foundationfrom
claude/v2-core-api-critique-91a960
Jul 26, 2026
Merged

Post-rc1 API polish: StrEnum Role, Parser conveniences, dead-vocabulary repair#290
derek73 merged 21 commits into
v2/core-foundationfrom
claude/v2-core-api-critique-91a960

Conversation

@derek73

@derek73 derek73 commented Jul 26, 2026

Copy link
Copy Markdown
Owner

Summary

Fourteen commits fixing the eight findings from the post-rc1 critique of the v2 core API, plus three issues the review rounds surfaced. Everything here lands before 2.0.0 final; two commits are breaking-window items (StrEnum Role, keyword-only as_dict) that could not ship after it.

  • Role is a StrEnum — members compare and stringify as their field names, matching AmbiguityKind; tokens_for() coerces Role | str and raises ValueError for unknown roles instead of silently returning nothing
  • New Parser conveniencesParser.matches, Parser.capitalized, and Parser.revise (tag-preserving field replacement via a sub-parse harvest), because the ParsedName equivalents silently fall back to default config for custom-parser workflows; Policy.patched(patch) applies a PolicyPatch without a dummy Locale
  • API surface polishSTABLE_TAGS exported with a user-facing docstring; PolicyPatch gets the bounded deviation-only repr its siblings have (and a never-raise _order_repr); ParsedName.as_dict(include_empty=...) keyword-only; HumanName subscripting accepts Role members
  • Vocabulary repairchargé d'affaires split into two chainable title entries (dead since 2013, now recognized); seven multi-word credential acronyms removed (inert in every release, verified against 1.4.0 on PyPI); storing a new multi-word entry now warns, with the warning frame-walked to the caller's own line
  • Upgrade path guarded — a restored 1.3/1.4 Constants pickle drops the eight legacy dead entries instead of warning about vocabulary the user never added

The release log gains a "Changed since 2.0.0rc1" section for rc testers.

Test Plan

  • Full suite: 2382 passed, 5 skipped, 11 xfailed (uv run pytest -q)
  • uv run mypy (91 files) and uv run ruff check clean
  • Sphinx html + doctest builds clean (163 doctests)
  • Differential corpus vs pinned 1.4.0: 652 names, 0 unexplained diffs
  • Every commit individually spec-reviewed and quality-reviewed; key tests mutation-checked (FOLDED_TAG strip, name_order guard, facade Role keys)

🤖 Generated with Claude Code

derek73 and others added 18 commits July 26, 2026 01:56
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Every Lexicon vocabulary field except given_name_titles is matched one
word at a time, so a multi-word entry can never match -- the library
itself shipped eight such dead entries for years (repaired in the
previous commit). Per the inert-not-harmful convention a raise is
forbidden (see the given_name_titles Gotcha in AGENTS.md); warn
instead, from _normset (all per-word vocab fields) and _normpairs
(capitalization_exceptions keys), through every entry path --
constructor, add(), union, unpickle re-validation, and the v1 shim's
snapshot.

Also fixes tests/v2/test_properties.py's shared _VOCAB hypothesis pool,
which drew a multi-word phrase ("grand duke") into every Lexicon field
even though its own comment says it's "legal only in given_name_titles"
-- the fuzzer applied it everywhere, so it now tripped the new warning
in every per-word field. Split it into a separate _TITLE_VOCAB used
only for given_name_titles.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… sweep

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ribution

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ntness

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@derek73 derek73 self-assigned this Jul 26, 2026
@derek73 derek73 added this to the v2.0 milestone Jul 26, 2026
derek73 and others added 3 commits July 26, 2026 13:05
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@derek73
derek73 merged commit 17cc254 into v2/core-foundation Jul 26, 2026
1 check passed
derek73 added a commit that referenced this pull request Jul 26, 2026
rc2 is rc1 plus the post-rc1 API-polish bundle (PR #290): Role as a
StrEnum, the Parser conveniences (matches/capitalized/revise and
Policy.patched), the dead-vocabulary repair, the multi-word-entry
warning, and the legacy-pickle guard. The release log's "Changed
since 2.0.0rc1" section lists what an rc1 tester would notice.

Verified: __version__ == "2.0.0rc2" (packaging confirms
is_prerelease), the wheel/sdist carry it, and twine check passes on
both.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@derek73
derek73 deleted the claude/v2-core-api-critique-91a960 branch July 26, 2026 20:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant