You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Simplify and speed up SetManager normalization paths
The operand-normalization work left a compounding perf regression:
operators delegated to the ABC mixins, whose _from_iterable re-entered
__init__ and re-validated the entire result element by element, and
Constants() re-checked ~1,400 already-normalized default constants on
every construction. Measured on the headline per-instance-config path,
HumanName(constants=None) was 6.8x slower than master (101 -> 690us)
and Constants() 21.6x slower (7.5 -> 162us).
Build operator results with plain set ops on already-normalized
elements via a private _from_normalized constructor (also dropping the
super()-delegation type ignores), short-circuit SetManager operands in
_normalized_elements (a SetManager is normalized by construction), and
validate the nine default config sets once at import, copied on
identity-checked defaults. Back to master parity: Constants() 8.2us,
HumanName(constants=None) 58us.
Also fold the single-caller _reject_bare_string into
_normalized_elements, note the deliberate bytes-policy divergence from
add_with_encoding(), merge two tests that pinned the same |= parse
end-to-end, trim the triple-stated operator rationale, and update the
stale AGENTS.md SetManager normalization note.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: AGENTS.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -85,7 +85,7 @@ Most modules define a plain Python set of known name pieces; `capitalization.py`
85
85
86
86
`config/__init__.py` wraps everything into `SetManager` and `TupleManager` instances inside a `Constants` class. A module-level singleton `CONSTANTS` is shared across all `HumanName` instances by default.
87
87
88
-
**Two-tier config pattern**: `CONSTANTS` is global; passing `None` as the second arg to `HumanName` creates a fresh per-instance `Constants()`. After modifying per-instance config you must call `hn.parse_full_name()` again. `SetManager.add()`/`remove()` normalizes inputs to lowercase with no periods, so callers don't need to worry about case.
88
+
**Two-tier config pattern**: `CONSTANTS` is global; passing `None` as the second arg to `HumanName` creates a fresh per-instance `Constants()`. After modifying per-instance config you must call `hn.parse_full_name()` again. `SetManager` normalizes elements (lowercase, leading/trailing periods stripped) at every entry point — constructor, `add()`/`remove()`, and set operators — and raises `TypeError` for bare strings/bytes and non-str elements, so callers don't need to worry about case.
89
89
90
90
**`_CachedUnionMember` descriptor**: The four PST-contributing attrs (`prefixes`, `suffix_acronyms`, `suffix_not_acronyms`, `titles`) are managed by this descriptor, which stores their values under the *private* name (`_prefixes`, `_titles`, etc.) in the instance `__dict__` so that the descriptor's `__set__` owns every assignment and can wire the cache-invalidation callback. Any code that inspects `__dict__` directly (e.g. `__getstate__`) must map `_xxx` → `xxx` for descriptor-managed attrs rather than filtering on `not k.startswith('_')`.
0 commit comments