from getpass import getuser
from dataclasses import dataclass, asdict as dc_asdict
from types import get_original_bases
-from typing import Any, Callable, Optional, Sequence
+from typing import Any, Callable, Optional, Self, Sequence
# ourselves
from ircplom.tui_base import (BaseTui, PromptWidget, TuiEvent, Window,
CMD_SHORTCUTS)
path: tuple[str, ...]
value: Optional[Any] = None
+ @property
+ def key(self) -> str:
+ 'Name of item or attribute to be processed.'
+ return self.path[0]
+
+ def decremented(self) -> Self:
+ 'Create copy with .path reduced by leftmost step.'
+ return self.__class__(self.path[1:], self.value)
+
class _UpdatingNode(AutoAttrMixin):
log_scopes: dict[str, LogScope] = {'': LogScope.SERVER}
def recursive_set_and_report_change(
self, update: _Update) -> Optional[tuple[LogScope, Any]]:
'Apply update, return if that actually made a difference.'
- node = self._get(update.path[0])
+ node = self._get(update.key)
if len(update.path) > 1:
- return node.recursive_set_and_report_change(
- _Update(update.path[1:], update.value))
+ 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
) -> Optional[tuple[LogScope, Any]]:
- scope = self._scope(update.path[0])
+ scope = self._scope(update.key)
if update.value is None:
- if not self._is_set(update.path[0]):
+ if not self._is_set(update.key):
return None
- self._unset(update.path[0])
+ self._unset(update.key)
return (scope, None)
if old_value == update.value:
return None
- self._set(update.path[0], update.value)
+ self._set(update.key, update.value)
return (scope, update.value)
def _get(self, key: str):
def _focused_set_and_report_change(
self, old_value: '_UpdatingNode', update: _Update
) -> Optional[tuple[LogScope, Any]]:
- scope = self._scope(update.path[0])
- if update.path[0] == 'topic':
+ scope = self._scope(update.key)
+ if update.key == 'topic':
if super()._focused_set_and_report_change(old_value, update):
return (scope,
f'RAW:{self.topic.who} set topic: {self.topic.what}')
return None
- assert update.path[0] == 'user_ids'
+ assert update.key == 'user_ids'
assert isinstance(update.value, tuple)
d = {'NUHS:joining': tuple(id_ for id_ in update.value
if id_ not in self.user_ids)
self, old_value: '_UpdatingNode', update: _Update
) -> Optional[tuple[LogScope, Any]]:
assert isinstance(update.value, str)
- if update.path[0] == 'modes':
+ if update.key == 'modes':
return super()._focused_set_and_report_change(old_value, update)
if super()._focused_set_and_report_change(old_value, update):
- scope = self._scope(update.path[0])
+ scope = self._scope(update.key)
msg = 'RAW: '
- if update.path[0] == 'nick':
+ if update.key == 'nick':
return scope, msg + f'{self.prev} renames {update.value}'
- if update.path[0] == 'exit_msg' and update.value:
+ 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: