From 83234a0f66a366f23185a278c15a3e1f50d28650 Mon Sep 17 00:00:00 2001 From: Alex Hadley Date: Wed, 26 Jun 2024 13:00:45 -0700 Subject: [PATCH] Fix ParamDict dunder attributes --- CHANGELOG.md | 7 +++++++ paramdb/_param_data/_collections.py | 7 ++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a50825..723a31b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,13 @@ project adheres to clauses 1–8 of [Semantic Versioning](https://semver.org/spe ## [Unreleased] +## [0.15.1] (Jun 25 2024) + +### Fixed + +- `ParamDict` treats dunder names (e.g. `__init__`) as attributes, allowing internal + Python functionalities to work. + ## [0.15.0] (Jun 21 2024) ### Added diff --git a/paramdb/_param_data/_collections.py b/paramdb/_param_data/_collections.py index 0f1d3fd..4cfdc82 100644 --- a/paramdb/_param_data/_collections.py +++ b/paramdb/_param_data/_collections.py @@ -210,8 +210,8 @@ def __delattr__(self, name: str) -> None: def _is_attribute(self, name: str) -> bool: """ - If the given name matches an existing attribute or has a corresponding class - type hint, treat it as the name of an attribute. + If the given name matches an existing attribute, has a corresponding class type + hint, or is a dunder name (e.g. __init__), treat it as the name of an attribute. """ try: self.__getattribute__(name) # pylint: disable=unnecessary-dunder-call @@ -221,4 +221,5 @@ def _is_attribute(self, name: str) -> bool: class_annotations: dict[str, Any] = {} for cls in type(self).mro(): class_annotations |= getattr(cls, "__annotations__", {}) - return existing_attribute or name in class_annotations + dunder = name.startswith("__") and name.endswith("__") + return existing_attribute or name in class_annotations or dunder