From: Christian Heller Date: Fri, 19 Sep 2025 12:28:21 +0000 (+0200) Subject: Replace complexity of UpdatingNode.recursive_set_and_report_change by more state... X-Git-Url: https://plomlompom.com/repos/booking/todos?a=commitdiff_plain;h=e9ecd21062f86f939f22f8930d50c191cb777f0d;p=ircplom Replace complexity of UpdatingNode.recursive_set_and_report_change by more state in Update. --- diff --git a/ircplom/client_tui.py b/ircplom/client_tui.py index 74d9058..3e577f4 100644 --- a/ircplom/client_tui.py +++ b/ircplom/client_tui.py @@ -1,7 +1,7 @@ 'TUI adaptions to Client.' # built-ins from getpass import getuser -from typing import Any, Callable, Optional, Self, Sequence +from typing import Any, Callable, Optional, Sequence # ourselves from ircplom.tui_base import (BaseTui, PromptWidget, TuiEvent, Window, CMD_SHORTCUTS) @@ -24,21 +24,25 @@ _LOG_PREFIX_IN = '<' class _Update: + old_value: Any + results: list[tuple[LogScope, Any]] - def __init__(self, path: tuple[str, ...], value: Any, force_log=False - ) -> None: - self.path = path + def __init__(self, path: tuple[str, ...], value: Any) -> None: + self.full_path = path + self.rel_path = self.full_path[:] self.value = value - self.force_log = force_log + self.old_value = None + self.force_log = False + self.results = [] @property def key(self) -> str: 'Name of item or attribute to be processed.' - return self.path[0] + return self.rel_path[0] - def decremented(self) -> Self: - 'Create copy with .path reduced by leftmost step.' - return self.__class__(self.path[1:], self.value, self.force_log) + def decrement_path(self) -> None: + 'Remove first element from .rel_path.' + self.rel_path = self.rel_path[1:] class _UpdatingNode(AutoAttrMixin): @@ -55,28 +59,26 @@ class _UpdatingNode(AutoAttrMixin): scopes = c.log_scopes | scopes return scopes.get(key, scopes['']) - def recursive_set_and_report_change( - self, update: _Update) -> tuple[tuple[LogScope, Any], ...]: - 'Apply update, return if that actually made a difference.' + def recursive_set_and_report_change(self, update: _Update) -> None: + 'Apply update, and, if it makes a difference, add to its .results.' update.force_log = update.force_log or (not self._is_set(update.key)) node = self._get(update.key) - if len(update.path) > 1: - return node.recursive_set_and_report_change(update.decremented()) - return self._focused_set_and_report_change(node, update) - - def _focused_set_and_report_change( - self, old_value: '_UpdatingNode', update: _Update - ) -> tuple[tuple[LogScope, Any], ...]: - scope = self._scope(update.key) - do_report = update.force_log - if update.value is None: - if self._is_set(update.key): - self._unset(update.key) + if len(update.rel_path) > 1: + update.decrement_path() + node.recursive_set_and_report_change(update) + else: + update.old_value = node + scope = self._scope(update.key) + do_report = update.force_log + if update.value is None: + if self._is_set(update.key): + self._unset(update.key) + do_report |= True + elif update.old_value != update.value: + self._set(update.key, update.value) do_report |= True - elif old_value != update.value: - self._set(update.key, update.value) - do_report |= True - return ((scope, update.value),) if do_report else tuple() + if do_report: + update.results += [(scope, update.value)] def _get(self, key: str) -> Any: return getattr(self, key) @@ -213,58 +215,46 @@ class _UpdatingChannel(_UpdatingNode, Channel): log_scopes = {'': LogScope.CHAT} user_ids: set[str] - def _focused_set_and_report_change( - self, old_value: '_UpdatingNode', update: _Update - ) -> tuple[tuple[LogScope, Any], ...]: + def recursive_set_and_report_change(self, update: _Update) -> None: + super().recursive_set_and_report_change(update) if update.key == 'user_ids': - assert isinstance(update.value, set) - d = ({'NUHS:joining': tuple(sorted(id_ for id_ in update.value - if id_ not in self.user_ids))} - if self.user_ids - else {'NICKS:residents': tuple(sorted(update.value))}) - if super()._focused_set_and_report_change(old_value, update): - return ((self._scope(update.key), d),) - return tuple() - return super()._focused_set_and_report_change(old_value, update) + if update.old_value: + d = {'NUHS:joining': tuple(sorted( + id_ for id_ in update.value + if id_ not in update.old_value))} + else: + d = {'NICKS:residents': tuple(sorted(update.value))} + update.results = [(self._scope(update.key), d)] class _UpdatingUser(_UpdatingNode, User): log_scopes = {'exit_msg': LogScope.USER} prev_nick = '?' - def _focused_set_and_report_change( - self, old_value: '_UpdatingNode', update: _Update - ) -> tuple[tuple[LogScope, Any], ...]: - assert isinstance(update.value, str) - if (result := super()._focused_set_and_report_change(old_value, - update)): - if update.key not in {'nick', 'exit_msg'}: - return result + def recursive_set_and_report_change(self, update: _Update) -> None: + super().recursive_set_and_report_change(update) + if update.key in {'nick', 'exit_msg'}: msg = 'RAW:' if update.key == 'nick': - if self.prev_nick != '?': - result = result + ( - (LogScope.USER, - msg + f'{self.prev} renames {update.value}'),) - return result - if update.key == 'exit_msg' and update.value: - msg += f'{self} ' - msg += 'quits' if update.value[0] == 'Q' else 'parts' - if len(update.value) > 1: - msg += ': ' + update.value[1:] - return ((self._scope(update.key), msg),) - return tuple() + self.prev_nick = update.old_value + if update.old_value != '?': + update.results += [ + (LogScope.USER, + msg + f'{self.prev} renames {update.value}')] + elif update.key == 'exit_msg': + update.results.clear() + if update.value: + msg += f'{self} ' + msg += 'quits' if update.value[0] == 'Q' else 'parts' + if len(update.value) > 1: + msg += ': ' + update.value[1:] + update.results += [(self._scope(update.key), msg)] @property def prev(self) -> str: 'Return .nickuserhost with .prev_nick as .nick.' return str(NickUserHost(self.prev_nick, self.user, self.host)) - def __setattr__(self, key: str, value) -> None: - if key == 'nick': - self.prev_nick = self.nick - super().__setattr__(key, value) - class _UpdatingServerCapability(_UpdatingNode, ServerCapability): pass @@ -345,15 +335,15 @@ class _ClientWindowsManager: def update_db(self, update: _Update) -> bool: 'Apply update to .db, and if changing anything, log and trigger.' - result = self.db.recursive_set_and_report_change(update) - if not result: + self.db.recursive_set_and_report_change(update) + if not update.results: return False - for t in result: + for t in update.results: scope, value = t - log_path = ':'.join(update.path) + log_path = ':'.join(update.full_path) log_kwargs: dict[str, Any] = {'scope': scope} if scope in {LogScope.CHAT, LogScope.USER}: - log_kwargs |= {'target': update.path[1]} + log_kwargs |= {'target': update.full_path[1]} if value is None: self.log(f'{log_path} cleared', **log_kwargs) elif isinstance(value, Topic):