From 775734ceb80e23bd2d34ab3e04dcb6e9efa264bb Mon Sep 17 00:00:00 2001 From: Sasa Junuzovic <44276455+microsasa@users.noreply.github.com> Date: Wed, 8 Apr 2026 22:01:42 -0700 Subject: [PATCH] refactor: replace string-based getattr loop in VSCodeLogSummary.__post_init__ (#873) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the for-loop using object.__getattribute__ with explicit attribute reads to comply with the 'no getattr/hasattr' coding guideline. Behaviour is identical — frozen dataclass still requires object.__setattr__ for writes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/copilot_usage/vscode_parser.py | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/copilot_usage/vscode_parser.py b/src/copilot_usage/vscode_parser.py index 1a62a4f4..25cbcd35 100644 --- a/src/copilot_usage/vscode_parser.py +++ b/src/copilot_usage/vscode_parser.py @@ -83,18 +83,24 @@ class VSCodeLogSummary: def __post_init__(self) -> None: _wrap = types.MappingProxyType - for attr in ( - "requests_by_model", - "duration_by_model", - "requests_by_category", - "requests_by_date", - ): - val = object.__getattribute__(self, attr) - if val is _EMPTY_MAPPING: - continue - # Always snapshot into a new MappingProxyType so the caller - # cannot mutate the summary through a retained dict reference. - object.__setattr__(self, attr, _wrap(dict(val))) + # Always snapshot into a new MappingProxyType so the caller + # cannot mutate the summary through a retained dict reference. + if self.requests_by_model is not _EMPTY_MAPPING: + object.__setattr__( + self, "requests_by_model", _wrap(dict(self.requests_by_model)) + ) + if self.duration_by_model is not _EMPTY_MAPPING: + object.__setattr__( + self, "duration_by_model", _wrap(dict(self.duration_by_model)) + ) + if self.requests_by_category is not _EMPTY_MAPPING: + object.__setattr__( + self, "requests_by_category", _wrap(dict(self.requests_by_category)) + ) + if self.requests_by_date is not _EMPTY_MAPPING: + object.__setattr__( + self, "requests_by_date", _wrap(dict(self.requests_by_date)) + ) _GLOB_PATTERN: Final[str] = (