Skip to content

Commit 020e5ad

Browse files
derek73claude
andcommitted
fix: .get() on the regexes proxy is no longer swallowed by __getattr__
1.4's #256 deprecation told users ".get() remains available for intentional soft access". On CONSTANTS.capitalization_exceptions that holds -- TupleManager subclasses dict, so .get() comes for free. The regexes proxy is not a dict, and its catch-all __getattr__ claimed the name `get` as a regex lookup, so the escape hatch the deprecation message pointed at raised AttributeError instead. Define get() explicitly, with dict.get semantics. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent bf1141c commit 020e5ad

2 files changed

Lines changed: 18 additions & 0 deletions

File tree

nameparser/_config_shim.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,12 @@ def __iter__(self) -> Iterator[str]:
524524
def keys(self) -> KeysView[str]:
525525
return self._regexes().keys()
526526

527+
def get(self, name: str, default: object = None) -> object:
528+
# Defined explicitly because __getattr__ would otherwise claim
529+
# `get` as a regex name. The sibling managers inherit this from
530+
# dict; #256's deprecation text promised it on both.
531+
return self._regexes().get(name, default)
532+
527533
def __setattr__(self, name: str, value: object) -> None:
528534
self._raise_readonly(name)
529535

tests/v2/test_config_shim.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
CONSTANTS, Constants, SetManager, TupleManager, _DelimiterManager,
1212
_RegexesProxy, _cached_parser,
1313
)
14+
from nameparser.config.regexes import EMPTY_REGEX, REGEXES
1415

1516
_DATA_DIR = Path(__file__).parent / "data"
1617

@@ -195,6 +196,17 @@ def test_regexes_membership_iteration_and_deepcopy() -> None:
195196
assert isinstance(copy.deepcopy(r), _RegexesProxy)
196197

197198

199+
def test_regexes_get_is_the_soft_access_escape_hatch() -> None:
200+
# 1.4's #256 deprecation told users ".get() remains available for
201+
# intentional soft access"; __getattr__ must not swallow `get`
202+
# itself. capitalization_exceptions inherits it from dict -- the
203+
# regexes proxy is not a dict, so it has to say so explicitly.
204+
r = _RegexesProxy()
205+
assert r.get("word") is REGEXES["word"]
206+
assert r.get("typo") is None
207+
assert r.get("typo", EMPTY_REGEX) is EMPTY_REGEX
208+
209+
198210
def test_constants_default_fields_present() -> None:
199211
c = Constants()
200212
assert "dr" in c.titles

0 commit comments

Comments
 (0)