From dd5bc93d875ef5a6732328ff6b15b9b22d5a9767 Mon Sep 17 00:00:00 2001 From: Chuck Date: Mon, 13 Jul 2026 09:03:52 -0400 Subject: [PATCH] fix: initialise wifi-status throttle state in __init__ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Codacy (pylint access-member-before-definition) on #403: the throttled early-return read _wifi_status_last_result relying on the non-local invariant that the first call always passes the throttle window and assigns it. Correct at runtime, but fragile — initialise both throttle fields in the constructor and drop the getattr fallback. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01FqzC1nzTWL4kaqgMaQZFam --- src/display_controller.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/display_controller.py b/src/display_controller.py index 7fc895af..402011e6 100644 --- a/src/display_controller.py +++ b/src/display_controller.py @@ -199,6 +199,10 @@ class DisplayController: self.wifi_status_file = WIFI_STATUS_FILE self.wifi_status_active = False self.wifi_status_expires_at: Optional[float] = None + # _check_wifi_status_message throttle state (checked at frame rate, + # stat'd at most once per second) + self._wifi_status_check_ts = 0.0 + self._wifi_status_last_result: Optional[Dict[str, Any]] = None # Plugin display() signature cache — must be initialised before the plugin # loading loop below so the .pop() invalidation at load time is always safe. @@ -2357,8 +2361,9 @@ class DisplayController: # Throttle the existence stat to ~1 Hz: this runs on every render # iteration (60+ fps), and the file usually doesn't exist — the # status message's lifetime is measured in seconds anyway. + # Both attributes are initialised in __init__. now = time.time() - if (now - getattr(self, '_wifi_status_check_ts', 0.0)) < 1.0: + if (now - self._wifi_status_check_ts) < 1.0: return self._wifi_status_last_result self._wifi_status_check_ts = now self._wifi_status_last_result = None